From e5bc39ef95c9743947bab8ff53dd60dd1d98e4a5 Mon Sep 17 00:00:00 2001 From: Lucid Programmer Date: Tue, 26 Mar 2024 19:39:15 +0500 Subject: [PATCH] Deployed 7df737f to 7.2 with MkDocs 1.5.3 and mike 2.0.0 --- 7.2/404.html | 1 + 7.2/Advanced/advanced_topics/index.html | 11 + 7.2/Advanced/alternative_charts/index.html | 20 + 7.2/Advanced/index.html | 10 + 7.2/Advanced/ingress_configuration/index.html | 10 + 7.2/Advanced/ingress_nginx_config/index.html | 308 + 7.2/Advanced/ingress_urls/index.html | 10 + 7.2/Advanced/nginx_ingress_config/index.html | 10 + 7.2/Architecture/db_architecture/index.html | 10 + 7.2/Architecture/img.png | Bin 0 -> 95525 bytes 7.2/Architecture/index.html | 10 + .../index.html | 10 + 7.2/GettingStarted/aks/index.html | 10 + 7.2/GettingStarted/eks/index.html | 10 + 7.2/GettingStarted/index.html | 10 + 7.2/GettingStarted/installation/index.html | 28 + 7.2/GettingStarted/k3s/index.html | 10 + 7.2/GettingStarted/kind/index.html | 10 + .../preparation_and_prerequisites/index.html | 15 + 7.2/GettingStarted/quickstart/index.html | 29 + 7.2/Help/help_and_tutorials/index.html | 10 + 7.2/Monitoring/logs/index.html | 10 + .../metrics_and_monitoring/index.html | 10 + 7.2/Operations/backup_and_restore/index.html | 10 + 7.2/Operations/index.html | 10 + 7.2/Operations/otel/index.html | 10 + 7.2/Operators/k3s/index.html | 24 + 7.2/Operators/k8s/index.html | 34 + 7.2/Operators/kind/index.html | 18 + 7.2/Operators/kinetica-operators/index.html | 218 + 7.2/Reference/database/index.html | 90 + .../helm_kinetica_operators/index.html | 10 + 7.2/Reference/index.html | 10 + .../kinetica_cluster_admins/index.html | 101 + .../kinetica_cluster_backups/index.html | 228 + .../kinetica_cluster_grants/index.html | 111 + .../kinetica_cluster_reference/index.html | 10 + .../index.html | 46 + .../kinetica_cluster_restores/index.html | 107 + .../kinetica_cluster_roles/index.html | 66 + .../kinetica_cluster_schemas/index.html | 37 + .../kinetica_cluster_users/index.html | 91 + 7.2/Reference/kinetica_clusters/index.html | 6383 ++++++++++++++++ 7.2/Reference/kinetica_workbench/index.html | 10 + 7.2/Reference/workbench/index.html | 47 + 7.2/Setup/index.html | 10 + 7.2/Support/index.html | 10 + .../troubleshooting/index.html | 10 + 7.2/assets/distributed.png | Bin 0 -> 67356 bytes 7.2/assets/favicon.ico | Bin 0 -> 15406 bytes 7.2/assets/images/favicon.png | Bin 0 -> 1870 bytes 7.2/assets/javascripts/bundle.c8d2eff1.min.js | 29 + .../javascripts/bundle.c8d2eff1.min.js.map | 7 + 7.2/assets/javascripts/glightbox.min.js | 1 + .../javascripts/lunr/min/lunr.ar.min.js | 1 + .../javascripts/lunr/min/lunr.da.min.js | 18 + .../javascripts/lunr/min/lunr.de.min.js | 18 + .../javascripts/lunr/min/lunr.du.min.js | 18 + .../javascripts/lunr/min/lunr.el.min.js | 1 + .../javascripts/lunr/min/lunr.es.min.js | 18 + .../javascripts/lunr/min/lunr.fi.min.js | 18 + .../javascripts/lunr/min/lunr.fr.min.js | 18 + .../javascripts/lunr/min/lunr.he.min.js | 1 + .../javascripts/lunr/min/lunr.hi.min.js | 1 + .../javascripts/lunr/min/lunr.hu.min.js | 18 + .../javascripts/lunr/min/lunr.hy.min.js | 1 + .../javascripts/lunr/min/lunr.it.min.js | 18 + .../javascripts/lunr/min/lunr.ja.min.js | 1 + .../javascripts/lunr/min/lunr.jp.min.js | 1 + .../javascripts/lunr/min/lunr.kn.min.js | 1 + .../javascripts/lunr/min/lunr.ko.min.js | 1 + .../javascripts/lunr/min/lunr.multi.min.js | 1 + .../javascripts/lunr/min/lunr.nl.min.js | 18 + .../javascripts/lunr/min/lunr.no.min.js | 18 + .../javascripts/lunr/min/lunr.pt.min.js | 18 + .../javascripts/lunr/min/lunr.ro.min.js | 18 + .../javascripts/lunr/min/lunr.ru.min.js | 18 + .../javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + .../javascripts/lunr/min/lunr.sv.min.js | 18 + .../javascripts/lunr/min/lunr.ta.min.js | 1 + .../javascripts/lunr/min/lunr.te.min.js | 1 + .../javascripts/lunr/min/lunr.th.min.js | 1 + .../javascripts/lunr/min/lunr.tr.min.js | 18 + .../javascripts/lunr/min/lunr.vi.min.js | 1 + .../javascripts/lunr/min/lunr.zh.min.js | 1 + 7.2/assets/javascripts/lunr/tinyseg.js | 206 + 7.2/assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + 7.2/assets/kinetica_aws.png | Bin 0 -> 38166 bytes 7.2/assets/kinetica_logo.png | Bin 0 -> 12494 bytes 7.2/assets/logo_purple.png | Bin 0 -> 6266 bytes 7.2/assets/stylesheets/glightbox.min.css | 1 + 7.2/assets/stylesheets/main.7e359304.min.css | 1 + .../stylesheets/main.7e359304.min.css.map | 1 + .../stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + 7.2/assets/three_bars_background_lit.png | Bin 0 -> 49061 bytes 7.2/blog/index.html | 10 + 7.2/images/columnar-1024x373.png | Bin 0 -> 49252 bytes 7.2/images/find_storage_class.gif | Bin 0 -> 41172 bytes 7.2/images/gadmin.png | Bin 0 -> 462506 bytes 7.2/images/get_nodes.gif | Bin 0 -> 41284 bytes 7.2/images/helm_alternative_versions.gif | Bin 0 -> 53419 bytes 7.2/images/helm_install.gif | Bin 0 -> 100000 bytes 7.2/images/helm_repo_add.gif | Bin 0 -> 99351 bytes 7.2/images/massivley_parallel.png | Bin 0 -> 930878 bytes 7.2/images/vectorized.png | Bin 0 -> 94933 bytes 7.2/index.html | 10 + 7.2/index.yaml | 202 + 7.2/kinetica-operators-0.1.0.tgz | Bin 0 -> 387022 bytes 7.2/kinetica-operators-7.2.0-2.de-5.tgz | Bin 0 -> 386540 bytes 7.2/kinetica-operators-7.2.0-2.dev-3.tgz | Bin 0 -> 426805 bytes 7.2/kinetica-operators-7.2.0-2.rc-2.tgz | Bin 0 -> 386585 bytes 7.2/kinetica-operators-7.2.0-2.rc-5.tgz | Bin 0 -> 387000 bytes 7.2/kinetica-operators-7.2.0-3.de-1.tgz | Bin 0 -> 387064 bytes 7.2/kinetica-operators-7.2.0-3.dev-2.tgz | Bin 0 -> 387066 bytes 7.2/kinetica-operators-7.2.0-3.dev-3.tgz | Bin 0 -> 387126 bytes 7.2/kinetica-operators-7.2.0-3.rc-3.tgz | Bin 0 -> 387482 bytes 7.2/search/search_index.json | 1 + 7.2/sitemap.xml | 243 + 7.2/sitemap.xml.gz | Bin 0 -> 600 bytes latest | 1 + versions.json | 9 + 125 files changed, 16031 insertions(+) create mode 100644 7.2/404.html create mode 100644 7.2/Advanced/advanced_topics/index.html create mode 100644 7.2/Advanced/alternative_charts/index.html create mode 100644 7.2/Advanced/index.html create mode 100644 7.2/Advanced/ingress_configuration/index.html create mode 100644 7.2/Advanced/ingress_nginx_config/index.html create mode 100644 7.2/Advanced/ingress_urls/index.html create mode 100644 7.2/Advanced/nginx_ingress_config/index.html create mode 100644 7.2/Architecture/db_architecture/index.html create mode 100644 7.2/Architecture/img.png create mode 100644 7.2/Architecture/index.html create mode 100644 7.2/Architecture/kinetica_for_kubernetes_architecture/index.html create mode 100644 7.2/GettingStarted/aks/index.html create mode 100644 7.2/GettingStarted/eks/index.html create mode 100644 7.2/GettingStarted/index.html create mode 100644 7.2/GettingStarted/installation/index.html create mode 100644 7.2/GettingStarted/k3s/index.html create mode 100644 7.2/GettingStarted/kind/index.html create mode 100644 7.2/GettingStarted/preparation_and_prerequisites/index.html create mode 100644 7.2/GettingStarted/quickstart/index.html create mode 100644 7.2/Help/help_and_tutorials/index.html create mode 100644 7.2/Monitoring/logs/index.html create mode 100644 7.2/Monitoring/metrics_and_monitoring/index.html create mode 100644 7.2/Operations/backup_and_restore/index.html create mode 100644 7.2/Operations/index.html create mode 100644 7.2/Operations/otel/index.html create mode 100644 7.2/Operators/k3s/index.html create mode 100644 7.2/Operators/k8s/index.html create mode 100644 7.2/Operators/kind/index.html create mode 100644 7.2/Operators/kinetica-operators/index.html create mode 100644 7.2/Reference/database/index.html create mode 100644 7.2/Reference/helm_kinetica_operators/index.html create mode 100644 7.2/Reference/index.html create mode 100644 7.2/Reference/kinetica_cluster_admins/index.html create mode 100644 7.2/Reference/kinetica_cluster_backups/index.html create mode 100644 7.2/Reference/kinetica_cluster_grants/index.html create mode 100644 7.2/Reference/kinetica_cluster_reference/index.html create mode 100644 7.2/Reference/kinetica_cluster_resource_groups/index.html create mode 100644 7.2/Reference/kinetica_cluster_restores/index.html create mode 100644 7.2/Reference/kinetica_cluster_roles/index.html create mode 100644 7.2/Reference/kinetica_cluster_schemas/index.html create mode 100644 7.2/Reference/kinetica_cluster_users/index.html create mode 100644 7.2/Reference/kinetica_clusters/index.html create mode 100644 7.2/Reference/kinetica_workbench/index.html create mode 100644 7.2/Reference/workbench/index.html create mode 100644 7.2/Setup/index.html create mode 100644 7.2/Support/index.html create mode 100644 7.2/Troubleshooting/troubleshooting/index.html create mode 100644 7.2/assets/distributed.png create mode 100644 7.2/assets/favicon.ico create mode 100644 7.2/assets/images/favicon.png create mode 100644 7.2/assets/javascripts/bundle.c8d2eff1.min.js create mode 100644 7.2/assets/javascripts/bundle.c8d2eff1.min.js.map create mode 100644 7.2/assets/javascripts/glightbox.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 7.2/assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 7.2/assets/javascripts/lunr/tinyseg.js create mode 100644 7.2/assets/javascripts/lunr/wordcut.js create mode 100644 7.2/assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 7.2/assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 7.2/assets/kinetica_aws.png create mode 100644 7.2/assets/kinetica_logo.png create mode 100644 7.2/assets/logo_purple.png create mode 100644 7.2/assets/stylesheets/glightbox.min.css create mode 100644 7.2/assets/stylesheets/main.7e359304.min.css create mode 100644 7.2/assets/stylesheets/main.7e359304.min.css.map create mode 100644 7.2/assets/stylesheets/palette.06af60db.min.css create mode 100644 7.2/assets/stylesheets/palette.06af60db.min.css.map create mode 100644 7.2/assets/three_bars_background_lit.png create mode 100644 7.2/blog/index.html create mode 100644 7.2/images/columnar-1024x373.png create mode 100644 7.2/images/find_storage_class.gif create mode 100644 7.2/images/gadmin.png create mode 100644 7.2/images/get_nodes.gif create mode 100644 7.2/images/helm_alternative_versions.gif create mode 100644 7.2/images/helm_install.gif create mode 100644 7.2/images/helm_repo_add.gif create mode 100644 7.2/images/massivley_parallel.png create mode 100644 7.2/images/vectorized.png create mode 100644 7.2/index.html create mode 100644 7.2/index.yaml create mode 100644 7.2/kinetica-operators-0.1.0.tgz create mode 100644 7.2/kinetica-operators-7.2.0-2.de-5.tgz create mode 100644 7.2/kinetica-operators-7.2.0-2.dev-3.tgz create mode 100644 7.2/kinetica-operators-7.2.0-2.rc-2.tgz create mode 100644 7.2/kinetica-operators-7.2.0-2.rc-5.tgz create mode 100644 7.2/kinetica-operators-7.2.0-3.de-1.tgz create mode 100644 7.2/kinetica-operators-7.2.0-3.dev-2.tgz create mode 100644 7.2/kinetica-operators-7.2.0-3.dev-3.tgz create mode 100644 7.2/kinetica-operators-7.2.0-3.rc-3.tgz create mode 100644 7.2/search/search_index.json create mode 100644 7.2/sitemap.xml create mode 100644 7.2/sitemap.xml.gz create mode 120000 latest create mode 100644 versions.json diff --git a/7.2/404.html b/7.2/404.html new file mode 100644 index 0000000..452a6b2 --- /dev/null +++ b/7.2/404.html @@ -0,0 +1 @@ + Kinetica for Kubernetes
\ No newline at end of file diff --git a/7.2/Advanced/advanced_topics/index.html b/7.2/Advanced/advanced_topics/index.html new file mode 100644 index 0000000..0a46c30 --- /dev/null +++ b/7.2/Advanced/advanced_topics/index.html @@ -0,0 +1,11 @@ + Advanced Topics - Kinetica for Kubernetes
Skip to content

Advanced Topics

Install from a development/pre-release chart version

Find all alternative chart versions with:

Find alternative chart versions
helm search repo kinetica-operators --devel --versions
+

helm_alternative_versions

Then append --devel --version [CHART-DEVEL-VERSION] to the end of the Helm install command. See here.



Using your own OpenTelemetry Collector

Coming Soon


Configuring Ingress Records

ingress-nginx

Coming Soon

nginx-ingress

Coming Soon


Bare Metal LoadBalancer

kube-vip

kube-vip provides Kubernetes clusters with a virtual IP and load balancer for both the control plane (for building a highly-available cluster) and Kubernetes Services of type LoadBalancer without relying on any external hardware or software.

Coming Soon

## Integration with Kerberos

Coming Soon

\ No newline at end of file diff --git a/7.2/Advanced/alternative_charts/index.html b/7.2/Advanced/alternative_charts/index.html new file mode 100644 index 0000000..e8631b0 --- /dev/null +++ b/7.2/Advanced/alternative_charts/index.html @@ -0,0 +1,20 @@ + Alternative Charts - Kinetica for Kubernetes
Skip to content

Using Alternative Helm Charts

If requested by Kinetica Support you can search and use pre-release versions of the Kinetica Helm Charts.

Install from a development/pre-release chart version

Find all alternative chart versions with:

Find alternative chart versions
helm search repo kinetica-operators --devel --versions
+

helm_alternative_versions

Then append --devel --version [CHART-DEVEL-VERSION] to the end of the Helm install command.

Helm install kinetica-operators
helm -n kinetica-system install \
+kinetica-operators kinetica-operators/kinetica-operators \
+--create-namespace \
+--devel \
+--version 72.0 \
+--values values.onPrem.k8s.yaml \
+--set db.gpudbCluster.license="LICENSE-KEY" \
+--set dbAdminUser.password="PASSWORD" \
+--set global.defaultStorageClass="DEFAULT-STORAGE-CLASS"
+

Advanced Topics

Home

\ No newline at end of file diff --git a/7.2/Advanced/index.html b/7.2/Advanced/index.html new file mode 100644 index 0000000..924067e --- /dev/null +++ b/7.2/Advanced/index.html @@ -0,0 +1,10 @@ + Advanced Topics - Kinetica for Kubernetes
Skip to content

Advanced Topics

  • Find alternative chart versions


    How to use pre-release or development Chart version if requested to by Kinetica Support.

    Alternative Charts

  • Configuring Ingress Records


    How to expose Kinetica via Kubernetes Ingress.

    Ingress Configuration

  • Using your own OpenTelemetry Collector


    How to configure Kinetica for Kubernetes to use your open OpenTelemetry collector.

    External OTEL


Home

\ No newline at end of file diff --git a/7.2/Advanced/ingress_configuration/index.html b/7.2/Advanced/ingress_configuration/index.html new file mode 100644 index 0000000..50d7933 --- /dev/null +++ b/7.2/Advanced/ingress_configuration/index.html @@ -0,0 +1,10 @@ + Ingress Configuration - Kinetica for Kubernetes
Skip to content
\ No newline at end of file diff --git a/7.2/Advanced/ingress_nginx_config/index.html b/7.2/Advanced/ingress_nginx_config/index.html new file mode 100644 index 0000000..8f6ffea --- /dev/null +++ b/7.2/Advanced/ingress_nginx_config/index.html @@ -0,0 +1,308 @@ + ingress-nginx Ingress Configuration - Kinetica for Kubernetes
Skip to content

ingress-nginx Ingress Configuration

To use an 'external' ingress-nginx controller i.e. not the one optionally installed by the KInetica Helm chart it is necessary to disable ingress in the KineticaCluster CR.

the field spec.ingressController: nginx zhould be set to spec.ingressController: none.

It is then necessary to create the required Ingress CRs by hand. Below is a list of the Ingress paths that need to be exposed along with sample ingress-nginx CRs.

Required Ingress Routes

Ingress Routes

GAdmin Paths

Path Service Port
/gadmin cluster-name-gadmin-service gadmin (8080/TCP)
/tableau cluster-name-gadmin-service gadmin (8080/TCP)
/files cluster-name^-gadmin-service gadmin (8080/TCP)

where cluster-name is the name of the Kinetica Cluster i.e. what is in the .spec.gpudbCluster.clusterName in the KineticaCluster CR.

Workbench Paths

Path Service Port
/ workbench-workbench-service workbench-port (8000/TCP)

DB rank-0 Paths

Path Service Port
/cluster-145025b8(/gpudb-0(/.*|$)) cluster-145025b8-rank0-service httpd (8082/TCP)
/cluster-145025b8/gpudb-0/hostmanager(.*) cluster-145025b8-rank0-service hostmanager (9300/TCP)

DB rank-N Paths

Path Service Port
/cluster-145025b8(/gpudb-N(/.*|$)) cluster-145025b8-rank1-service httpd (8082/TCP)
/cluster-145025b8/gpudb-N/hostmanager(.*) cluster-145025b8-rank1-service hostmanager (9300/TCP)

Reveal Paths

Path Service Port
/reveal cluster-name-reveal-service reveal (8088/TCP)
/caravel cluster-name-reveal-service reveal (8088/TCP)
/static cluster-name-reveal-service reveal (8088/TCP)
/logout cluster-name-reveal-service reveal (8088/TCP)
/resetmypassword cluster-name-reveal-service reveal (8088/TCP)
/dashboardmodelview cluster-name-reveal-service reveal (8088/TCP)
/dashboardmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/slicemodelview cluster-name-reveal-service reveal (8088/TCP)
/slicemodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/sliceaddview cluster-name-reveal-service reveal (8088/TCP)
/databaseview cluster-name-reveal-service reveal (8088/TCP)
/databaseasync cluster-name-reveal-service reveal (8088/TCP)
/databasetablesasync cluster-name-reveal-service reveal (8088/TCP)
/tablemodelview cluster-name-reveal-service reveal (8088/TCP)
/csstemplatemodelview cluster-name-reveal-service reveal (8088/TCP)
/csstemplatemodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/users cluster-name-reveal-service reveal (8088/TCP)
/roles cluster-name-reveal-service reveal (8088/TCP)
/userstatschartview cluster-name-reveal-service reveal (8088/TCP)
/permissions cluster-name-reveal-service reveal (8088/TCP)
/viewmenus cluster-name-reveal-service reveal (8088/TCP)
/permissionviews cluster-name-reveal-service reveal (8088/TCP)
/accessrequestsmodelview cluster-name-reveal-service reveal (8088/TCP)
/accessrequestsmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/logmodelview cluster-name-reveal-service reveal (8088/TCP)
/logmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/userinfoeditview cluster-name-reveal-service reveal (8088/TCP)
/tablecolumninlineview cluster-name-reveal-service reveal (8088/TCP)
/sqlmetricinlineview cluster-name-reveal-service reveal (8088/TCP)

Example Ingress CRs

Example GAdmin Ingress CR

Example GAdmin Ingress CR

Example GAdmin Ingress CR
apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name:  cluster-name-gadmin-ingress #(1)!
+  namespace: gpudb
+spec:
+  ingressClassName: nginx
+  tls:
+    - hosts:
+        - cluster-name.example.com #(1)!
+      secretName: kinetica-tls
+  rules:
+    - host: cluster-name.example.com #(1)!
+      http:
+        paths:
+          - path: /gadmin
+            pathType: Prefix
+            backend:
+              service:
+                name: cluster-name-gadmin-service #(1)!
+                port:
+                  name: gadmin
+          - path: /tableau
+            pathType: Prefix
+            backend:
+              service:
+                name: cluster-name-gadmin-service #(1)!
+                port:
+                  name: gadmin
+          - path: /files
+            pathType: Prefix
+            backend:
+              service:
+                name: cluster-name-gadmin-service #(1)!
+                port:
+                  name: gadmin
+
1. where cluster-name is the name of the Kinetica Cluster

Example Rank Ingress CR

Example Rank Ingress CR
Example Rank Ingress CR
apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: cluster-name-rank1-ingress
+  namespace: gpudb
+spec:
+  ingressClassName: nginx
+  tls:
+    - hosts:
+        - cluster-name.example.com
+      secretName: kinetica-tls
+  rules:
+    - host: cluster-name.example.com
+      http:
+        paths:
+          - path: /cluster-name(/gpudb-1(/.*|$))
+            pathType: Prefix
+            backend:
+              service:
+                name: cluster-name-rank1-service
+                port:
+                  name: httpd
+          - path: /cluster-name/gpudb-1/hostmanager(.*)
+            pathType: Prefix
+            backend:
+              service:
+                name: cluster-name-rank1-service
+                port:
+                  name: hostmanager
+
  1. where cluster-name is the name of the Kinetica Cluster

Example Reveal Ingress CR

Example Reveal Ingress CR

Example Reveal Ingress CR
    apiVersion: networking.k8s.io/v1
+    kind: Ingress
+    metadata:
+      name: cluster-name-reveal-ingress
+      namespace: gpudb
+    spec:
+      ingressClassName: nginx
+      tls:
+        - hosts:
+            - cluster-name.example.com
+          secretName: kinetica-tls
+      rules:
+        - host: cluster-name.example.com
+          http:
+            paths:
+              - path: /reveal
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /caravel
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /static
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /logout
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /resetmypassword
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /dashboardmodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /dashboardmodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /slicemodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /slicemodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /sliceaddview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /databaseview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /databaseasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /databasetablesasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /tablemodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /tablemodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /csstemplatemodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /csstemplatemodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /users
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /roles
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /userstatschartview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /permissions
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /viewmenus
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /permissionviews
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /accessrequestsmodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /accessrequestsmodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /logmodelview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /logmodelviewasync
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /userinfoeditview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /tablecolumninlineview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+              - path: /sqlmetricinlineview
+                pathType: Prefix
+                backend:
+                  service:
+                    name: cluster-name-reveal-service
+                    port:
+                      name: reveal
+
1. where cluster-name is the name of the Kinetica Cluster

Exposing the Postgres Proxy Port

In order to access Kinetica's Postgres functionality some TCP (not HTTP) ports need to be open externally.

For ingress-nginx a configuration file needs to be created to enable port 5432.

tcp-services.yaml
apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: tcp-services
+  namespace: kinetica-system # (1)!
+data:
+  '5432': gpudb/kinetica-k8s-sample-rank0-service:5432 #(2)!
+  '9002': gpudb/kinetica-k8s-sample-rank0-service:9002 #(3)!
+
1. Change the namespace to the namespace your ingress-nginx controller is running in. e.g. ingress-nginx
2. This exposes the postgres proxy port on the default 5432 port. If you wish to change this to a non-standard port then it needs to be changed here but also in the Helm values.yaml to match.
3. This port is the Table Monitor port and should always be exposed alongside the Postgres Proxy.


Ingress Configuration

Advanced Topics

\ No newline at end of file diff --git a/7.2/Advanced/ingress_urls/index.html b/7.2/Advanced/ingress_urls/index.html new file mode 100644 index 0000000..8747ecd --- /dev/null +++ b/7.2/Advanced/ingress_urls/index.html @@ -0,0 +1,10 @@ + Ingress urls - Kinetica for Kubernetes
Skip to content

Ingress urls

GAdmin Paths

Path Service Port
/gadmin cluster-name-gadmin-service gadmin (8080/TCP)
/tableau cluster-name-gadmin-service gadmin (8080/TCP)
/files cluster-name^-gadmin-service gadmin (8080/TCP)

where cluster-name is the name of the Kinetica Cluster i.e. what is in the .spec.gpudbCluster.clusterName in the KineticaCluster CR.

Workbench Paths

Path Service Port
/ workbench-workbench-service workbench-port (8000/TCP)

DB rank-0 Paths

Path Service Port
/cluster-145025b8(/gpudb-0(/.*|$)) cluster-145025b8-rank0-service httpd (8082/TCP)
/cluster-145025b8/gpudb-0/hostmanager(.*) cluster-145025b8-rank0-service hostmanager (9300/TCP)

DB rank-N Paths

Path Service Port
/cluster-145025b8(/gpudb-N(/.*|$)) cluster-145025b8-rank1-service httpd (8082/TCP)
/cluster-145025b8/gpudb-N/hostmanager(.*) cluster-145025b8-rank1-service hostmanager (9300/TCP)

Reveal Paths

Path Service Port
/reveal cluster-name-reveal-service reveal (8088/TCP)
/caravel cluster-name-reveal-service reveal (8088/TCP)
/static cluster-name-reveal-service reveal (8088/TCP)
/logout cluster-name-reveal-service reveal (8088/TCP)
/resetmypassword cluster-name-reveal-service reveal (8088/TCP)
/dashboardmodelview cluster-name-reveal-service reveal (8088/TCP)
/dashboardmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/slicemodelview cluster-name-reveal-service reveal (8088/TCP)
/slicemodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/sliceaddview cluster-name-reveal-service reveal (8088/TCP)
/databaseview cluster-name-reveal-service reveal (8088/TCP)
/databaseasync cluster-name-reveal-service reveal (8088/TCP)
/databasetablesasync cluster-name-reveal-service reveal (8088/TCP)
/tablemodelview cluster-name-reveal-service reveal (8088/TCP)
/csstemplatemodelview cluster-name-reveal-service reveal (8088/TCP)
/csstemplatemodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/users cluster-name-reveal-service reveal (8088/TCP)
/roles cluster-name-reveal-service reveal (8088/TCP)
/userstatschartview cluster-name-reveal-service reveal (8088/TCP)
/permissions cluster-name-reveal-service reveal (8088/TCP)
/viewmenus cluster-name-reveal-service reveal (8088/TCP)
/permissionviews cluster-name-reveal-service reveal (8088/TCP)
/accessrequestsmodelview cluster-name-reveal-service reveal (8088/TCP)
/accessrequestsmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/logmodelview cluster-name-reveal-service reveal (8088/TCP)
/logmodelviewasync cluster-name-reveal-service reveal (8088/TCP)
/userinfoeditview cluster-name-reveal-service reveal (8088/TCP)
/tablecolumninlineview cluster-name-reveal-service reveal (8088/TCP)
/sqlmetricinlineview cluster-name-reveal-service reveal (8088/TCP)
\ No newline at end of file diff --git a/7.2/Advanced/nginx_ingress_config/index.html b/7.2/Advanced/nginx_ingress_config/index.html new file mode 100644 index 0000000..6825d0c --- /dev/null +++ b/7.2/Advanced/nginx_ingress_config/index.html @@ -0,0 +1,10 @@ + nginx-ingress Ingress Configuration - Kinetica for Kubernetes
Skip to content
\ No newline at end of file diff --git a/7.2/Architecture/db_architecture/index.html b/7.2/Architecture/db_architecture/index.html new file mode 100644 index 0000000..4c62560 --- /dev/null +++ b/7.2/Architecture/db_architecture/index.html @@ -0,0 +1,10 @@ + Core Database Architecture - Kinetica for Kubernetes
Skip to content

Architecture

Kinetica is a distributed, vectorized, memory-first, columnar database with tiered storage that is optimized for high speed and performance – particularly on streaming analytics and geospatial workloads.

Kinetica has been uniquely designed for fast and flexible analytics on large volumes of changing data with incredible performance.

Database Architecture

Scale-out Architecture

Kinetica has a distributed architecture that has been designed for data processing at scale. A standard cluster consists of identical nodes run on commodity hardware. A single node is chosen to be the head aggregation node.

massivley_parallel A cluster can be scaled up at any time to increase storage capacity and processing power, with near-linear scale processing improvements for most operations. Sharding of data can be done automatically, or specified and optimized by the user.

Distributed Ingest & Query

Kinetica uses a shared-nothing data distribution across worker nodes. The head node receives a query and breaks it down into small tasks that can be spread across worker nodes. To avoid bottlenecks at the head node, ingestion can also be organized in parallel by all the worker nodes. Kinetica is able to distribute data client-side before sending it to designated worker nodes. This streamlines communication and processing time.

For the client application, there is no need to be aware of how many nodes are in the cluster, where they are, or how the data is distributed across them!

architecture

Column Oriented

Columnar data structures lend themselves to low-latency reads of data. But from a user's perspective, Kinetica behaves very similarly to a standard relational database – with tables of rows and columns and it can be queried with SQL or through APIs. Available column types include the standard base types (int, long, float, double, string, & bytes), as well as numerous sub-types supporting date/time, geospatial, and other data forms.

columnar

Vectorized Functions

Vectorization is Kinetica’s secret sauce and the key feature that underpins its blazing fast performance.

Advanced vectorized kernels are optimized to use vectorized CPUs and GPUs for faster performance. The query engine automatically assigns tasks to the processor where they will be most performant. Aggregations, filters, window functions, joins and geospatial rendering are some of the capabilities that see performance improvements.

vectorized

Memory-First, Tiered Storage

Tiered storage makes it possible to optimize where data lives for performance and cost. Recent data (such as all data where the timestamp is within the last 2 weeks) can be held in-memory, while older data can be moved to disk, or even to external storage services.

Kinetica operates on an entire data corpus by intelligently managing data across GPU memory, system memory, SIMD, disk / SSD, HDFS, and cloud storage like S3 for optimal performance.

Kinetica can also query and process data stored in data lakes, joining it with data managed by Kinetica in highly parallelized queries.

Performant Key-Value Lookup

Kinetica is able to generate distributed key-value lookups, from columnar data, for high-performance and concurrency. Sharding logic is embedded directly within client APIs enabling linear scale-out as clients can lookup data directly from the node where the data lives.


\ No newline at end of file diff --git a/7.2/Architecture/img.png b/7.2/Architecture/img.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc5230a47845c130fb5f82faa604293b91a88c7 GIT binary patch literal 95525 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%0AAQ%U1MYQ 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%0A9tyB-oBw_R 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 literal 0 HcmV?d00001 diff --git a/7.2/Architecture/index.html b/7.2/Architecture/index.html new file mode 100644 index 0000000..357a4c8 --- /dev/null +++ b/7.2/Architecture/index.html @@ -0,0 +1,10 @@ + Architecture - Kinetica for Kubernetes

Architecture

Kinetica is a distributed, vectorized, memory-first, columnar database with tiered storage that is optimized for high speed and performance – particularly on streaming analytics and geospatial workloads.

Kinetica has been uniquely designed for fast and flexible analytics on large volumes of changing data with incredible performance.

  • Kinetica Database Architecture


    Install the Kinetica DB with helm and get up and running in minutes

    Core Database Architecture

  • Kinetica for Kubernetes Architecture


    Install the Kinetica DB with helm and get up and running in minutes

    Kubernetes Architecture

\ No newline at end of file diff --git a/7.2/Architecture/kinetica_for_kubernetes_architecture/index.html b/7.2/Architecture/kinetica_for_kubernetes_architecture/index.html new file mode 100644 index 0000000..c5b3e32 --- /dev/null +++ b/7.2/Architecture/kinetica_for_kubernetes_architecture/index.html @@ -0,0 +1,10 @@ + Kubernetes Architecture - Kinetica for Kubernetes

Kubernetes Architecture

Coming Soon

\ No newline at end of file diff --git a/7.2/GettingStarted/aks/index.html b/7.2/GettingStarted/aks/index.html new file mode 100644 index 0000000..ba9e969 --- /dev/null +++ b/7.2/GettingStarted/aks/index.html @@ -0,0 +1,10 @@ + Azure AKS - Kinetica for Kubernetes

Azure AKS Specifics

This page covers any Microsoft Azure AKS cluster installation specifics.

\ No newline at end of file diff --git a/7.2/GettingStarted/eks/index.html b/7.2/GettingStarted/eks/index.html new file mode 100644 index 0000000..00c5033 --- /dev/null +++ b/7.2/GettingStarted/eks/index.html @@ -0,0 +1,10 @@ + Amazon EKS - Kinetica for Kubernetes

Amazon EKS Specifics

This page covers any Amazon EKS kubernetes cluster installation specifics.

EBS CSI driver

Warning

Make sure you have enabled the ebs-csi driver in your EKS cluster. This is required for the default storage class to work.

Please refer to this AWS documentation for more information.

\ No newline at end of file diff --git a/7.2/GettingStarted/index.html b/7.2/GettingStarted/index.html new file mode 100644 index 0000000..ab8ee42 --- /dev/null +++ b/7.2/GettingStarted/index.html @@ -0,0 +1,10 @@ + Getting Started - Kinetica for Kubernetes

Getting Started

  • Set up in 15 minutes (local install)


    Install the Kinetica DB locally on Kind or k3s with helm to get up and running in minutes (Dev/Test).

    Quickstart

  • Prepare to Install


    What you need to know & do before beginning an installation.

    Preparation and Prerequisites

  • Production Installation


    Install the Kinetica DB with helm to get up and running quickly (Production).

    Installation

  • Channel Your Inner Ninja


    Advanced Installation Topics which go beyond the basic installation.

    Advanced Topics

\ No newline at end of file diff --git a/7.2/GettingStarted/installation/index.html b/7.2/GettingStarted/installation/index.html new file mode 100644 index 0000000..024a7cb --- /dev/null +++ b/7.2/GettingStarted/installation/index.html @@ -0,0 +1,28 @@ + Installation - Kinetica for Kubernetes

Installation

For managed Kubernetes solutions (AKS, EKS, GKE) or on-prem (kubeadm) Kubernetes variants, follow this generic guide to install the Kinetica Operators, Database and Workbench.

Preparation & Prequisites

Please make sure you have followed the Preparation & Prequisites steps

4. Install the helm chart

Run the following Helm install command after substituting values from section 3

Helm install kinetica-operators
helm -n kinetica-system install \
+kinetica-operators kinetica-operators/kinetica-operators \
+--create-namespace \
+--values values.onPrem.k8s.yaml \
+--set db.gpudbCluster.license="LICENSE-KEY" \
+--set dbAdminUser.password="PASSWORD" \
+--set global.defaultStorageClass="DEFAULT-STORAGE-CLASS"
+

5. Check installation progress

After a few moments, follow the progression of the main database pod startup with:

Monitor the Kinetica installation progress
kubectl -n gpudb get po gpudb-0 -w
+

until it reaches "gpudb-0 3/3 Running" at which point the database should be ready and all other software installed in the cluster. You may have to run this command in a different terminal if the helm command from step 4 has not yet returned to the system prompt. Once running, you can quit this kubectl watch command using ctrl-c.

6. Accessing the Kinetica installation

Target Platform Specifics

If you are installing into a managed Kubernetes environment and the NGINX ingress controller that is installed as part of this install creates a LoadBalancer service, you may need to associate the LoadBalancer with the domain you plan to use.

As of now, the kinetica-operator chart installs NGINX ingress controller. So after the installation is complete, you may need to edit the KineticaCluster Custom Resource and Workbench Custom Resource with the correct domain name.

Option 1: Use the LoadBalancer domain

Set your FQDN in Kinetica
kubectl get svc -n kinetica-system
+# look at the loadbalancer dns name, copy it
+
+kubectl -n gpudb edit $(kubectl -n gpudb get kc -o name)
+# replace local.kinetica with the loadbalancer dns name
+kubectl -n gpudb edit $(kubectl -n gpudb get wb -o name)
+# replace local.kinetica with the loadbalancer dns name
+# save and exit
+# you should be able to access the workbench from the loadbalancer dns name
+

Option 2: Use your custom domain Create a record in your DNS server pointing to the LoadBalancer DNS. Then edit the KineticaCluster Custom Resource and Workbench Custom Resource with the correct domain name, as mentioned above.

Installing on a local machine which does not have a domain name, you can add the following entry to your /etc/hosts file or equivalent:

Configure local acces - /etc/hosts
127.0.0.1  local.kinetica
+

Note

The default chart configuration points to local.kinetica but this is configurable.

Installing on a bare metal machines which do not have an external hardware loadbalancer requires an Ingress controller along with a software loadbalancer in order to be accessible.

Kinetica for Kubernetes has been tested with kube-vip


\ No newline at end of file diff --git a/7.2/GettingStarted/k3s/index.html b/7.2/GettingStarted/k3s/index.html new file mode 100644 index 0000000..9b4d3ef --- /dev/null +++ b/7.2/GettingStarted/k3s/index.html @@ -0,0 +1,10 @@ + k3s - Kinetica for Kubernetes

k3s Installation Specifics

This page covers any k3s kubernetes cluster installation specifics.

\ No newline at end of file diff --git a/7.2/GettingStarted/kind/index.html b/7.2/GettingStarted/kind/index.html new file mode 100644 index 0000000..65676a4 --- /dev/null +++ b/7.2/GettingStarted/kind/index.html @@ -0,0 +1,10 @@ + KinD - Kinetica for Kubernetes

KinD Installation Specifics

This page covers any kind kubernetes cluster installation specifics.

\ No newline at end of file diff --git a/7.2/GettingStarted/preparation_and_prerequisites/index.html b/7.2/GettingStarted/preparation_and_prerequisites/index.html new file mode 100644 index 0000000..9307f52 --- /dev/null +++ b/7.2/GettingStarted/preparation_and_prerequisites/index.html @@ -0,0 +1,15 @@ + Preparation & Prerequisites - Kinetica for Kubernetes

Preparation & Prerequisites

Checks & steps to ensure a smooth installation.

Obtain a Kinetica License Key

A product license key will be required for install. Please contact Kinetica Support to request a trial key.

Failing to provide a license key at installation time will prevent the DB from starting.

Preparation and prerequisites

Free Resources

Your Kubernetes cluster version should be >= 1.22.x and have a minimum of 8 CPU, 8GB Ram and
SSD or SATA 7200RPM hard drive(s) with 4X memory capacity.

GPU Support

For GPU enabled clusters the cards below have been tested in large-scale production environments and provide the best performance for the database.

GPU Driver
P4/P40/P100 525.X (or higher)
V100 525.X (or higher)
T4 525.X (or higher)
A10/A40/A100 525.X (or higher)

Kubernetes Cluster Connectivity

Installation requires Helm3 and access to an on-prem or CSP managed Kubernetes cluster. and the Kubernetes CLI kubectl.

The context for the desired target cluster must be selected from your ~/.kube/config file and set via the KUBECONFIG environment variable or kubectl ctx (if installed). Check to see if you have the correct context with,

show the current kubernetes context
kubectl config current-context
+

and that you can access this cluster correctly with,

list kubernetes cluster nodes
kubectl get nodes
+

Find get_nodes

If you do not see a list of nodes for your K8s cluster the helm installation will not work. Please check your Kubernetes installation or access credentials (kubeconfig).

Air-Gapped Environments

If you are installing Kinetica with Helm in an air-gapped environment you will either need a Registry Proxy to pass the requests through or to download the images and push them to your internal Registry.

Required Container Images

docker.io (Required Kinetica Images for All Installations)

  • docker.io/kineticastagingcloud/kinetica-k8s-operator:v7.2.0-3.rc-3
    • docker.io/kineticastagingcloud/kinetica-k8s-cpu:v7.2.0-3.rc-3 or
    • docker.io/kineticastagingcloud/kinetica-k8s-cpu-avx512:v7.2.0-3.rc-3 or
    • docker.io/kineticastagingcloud/kinetica-k8s-gpu:v7.2.0-3.rc-3
  • docker.io/kineticastagingcloud/workbench-operator:v7.2.0-3.rc-3
  • docker.io/kineticastagingcloud/workbench:v7.2.0-3.rc-3
  • docker.io/kineticastagingcloud/kinetica-k8s-monitor:v7.2.0-3.rc-3
  • docker.io/kineticastagingcloud/busybox:v7.2.0-3.rc-3
  • docker.io/kineticastagingcloud/fluent-bit:v7.2.0-3.rc-3
  • docker.io/kinetica/kagent:7.1.9.15.20230823123615.ga

nvcr.io (Required Kinetica Images for GPU Installations using kinetica-k8s-gpu)

  • nvcr.io/nvidia/gpu-operator:v23.9.1

registry.k8s.io (Required Kinetica Images for GPU Installations using kinetica-k8s-gpu)

  • registry.k8s.io/nfd/node-feature-discovery:v0.14.2

docker.io (Required Supporting Images)

  • docker.io/bitnami/openldap:2.6.7
  • docker.io/alpine/openssl:latest (used by bitnami/openldap)
  • docker.io/otel/opentelemetry-collector-contrib:0.95.0

quay.io (Required Supporting Images)

  • quay.io/brancz/kube-rbac-proxy:v0.14.2

Optional Container Images

These images are only required if certain features are enabled as part of the Helm installation: -

  • CertManager
  • ingress-ninx

quay.io (Optional Supporting Images)

  • quay.io/jetstack/cert-manager-cainjector:v1.13.3 (if optionally installing CertManager via Kinetica Helm Chart)
  • quay.io/jetstack/cert-manager-controller:v1.13.3 (if optionally installing CertManager via Kinetica Helm Chart)
  • quay.io/jetstack/cert-manager-webhook:v1.13.3 (if optionally installing CertManager via Kinetica Helm Chart)

registry.k8s.io (Optional Supporting Images)

  • registry.k8s.io/ingress-nginx/controller:v1.9.4 (if optionally installing Ingress nGinx via Kinetica Helm Chart)
  • registry.k8s.io/ingress-nginx/controller:v1.9.6@sha256:1405cc613bd95b2c6edd8b2a152510ae91c7e62aea4698500d23b2145960ab9c

Which Kinetica Core Image do I use?

Container Image Intel (AMD64) Intel (AMD64 AVX512) Amd (AMD64) Graviton (aarch64) Apple Silicon (aarch64)
kinetica-k8s-cpu (1)
kinetica-k8s-cpu-avx512
kinetica-k8s-gpu (2) (2) (2)
  1. It is preferable on an Intel AVX512 enabled CPU to use the kinetica-k8s-cpu-avx512 container image
  2. With a supported nVidia GPU.

Install the kinetica-operators chart

This chart will install the Kinetica K8s operators together with a default configured database and workbench UI.

1. Add the Kinetica chart repository

Add the repo locally as kinetica-operators:

Helm repo add
helm repo add kinetica-operators https://kineticadb.github.io/charts
+

Helm Repo Add

2. Obtain the default Helm values file

For the generic Kubernetes install use the following values file without modification. Advanced users with specific requirements may need to adjust parameters in this file.

Helm values.yaml download
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k8s.yaml
+

3. Determine the following prior to the chart install

Default Admin User

the default admin user in the Helm chart is kadmin but this is configurable. Non-ASCII characters and typographical symbols in the password must be escaped with a "\". For example, --set dbAdminUser.password="MyPassword\!"

  1. Obtain a LICENSE-KEY as described in the introduction above.
  2. Choose a PASSWORD for the initial administrator user
  3. As the storage class name varies between K8s flavor and/or there can be multiple, this must be prescribed in the chart installation. Obtain the DEFAULT-STORAGE-CLASS name with the command:


Find the default storageclass
kubectl get sc -o name 
+

Find Storage Class

use the name found after the /, For example, in storageclass.storage.k8s.io/local-path use "local-path" as the parameter.

Amazon EKS

If installing on Amazon EKS See here

\ No newline at end of file diff --git a/7.2/GettingStarted/quickstart/index.html b/7.2/GettingStarted/quickstart/index.html new file mode 100644 index 0000000..dbfbf8c --- /dev/null +++ b/7.2/GettingStarted/quickstart/index.html @@ -0,0 +1,29 @@ + Quickstart - Kinetica for Kubernetes

Quickstart

For the quickstart we have examples for Kind or k3s.

  • Kind - is suitable for CPU only installations.
  • k3s - is suitable for CPU or GPU installations.

Kubernetes >= 1.25

The current version of the chart supports kubernetes version 1.25 and above.

Please select your target Kubernetes variant:

Kind (kubernetes in docker kind.sigs.k8s.io)

This installation in a kind cluster is for trying out the operators and the database in a non-production environment.

CPU Only

This method currently only supports installing a CPU version of the database.

Please contact Kinetica Support to request a trial key.

Create Kind Cluster 1.29

Create a new Kind Cluster
kind create cluster --config charts/kinetica-operators/kind.yaml
+

Kind - Install kinetica-operators including a sample db to try out

Review the values file charts/kinetica-operators/values.onPrem.kind.yaml. This is trying to install the operators and a simple db with workbench installation for a non production try out.

As you can see it is trying to create an ingress pointing towards local.kinetica. If you have a domain pointing to your machine, replace it with the correct domain name.

Kind - Install the Kinetica-Operators Chart
Kind - Install the Kinetca-Operators Chart
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.kind.yaml
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.kind.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+

or if you have been asked by the Kinetica Support team to try a development version

Using a development version
helm search repo kinetica-operators --devel --versions
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators/ --create-namespace --values values.onPrem.kind.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password" --devel --version 7.2.0-2.rc-2
+

Accessing the Workbench

You should be able to access the workbench at http://local.kinetica

k3s (k3s.io)

Install k3s 1.29

Install k3s
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik  --node-name kinetica-master --token 12345" K3S_KUBECONFIG_OUTPUT=~/.kube/config_k3s K3S_KUBECONFIG_MODE=644 INSTALL_K3S_VERSION=v1.29.2+k3s1 sh -
+

K3s - Install kinetica-operators including a sample db to try out

Review the values file charts/kinetica-operators/values.onPrem.k3s.yaml. This is trying to install the operators and a simple db with workbench installation for a non production try out.

As you can see it is trying to create an ingress pointing towards local.kinetica. If you have a domain pointing to your machine, replace it with the correct domain name.

If you are on a local machine which is not having a domain name, you add the following entry to your /etc/hosts file or equivalent.

Configure local acces - /etc/hosts
127.0.0.1  local.kinetica
+

K3S - Install the Kinetica-Operators Chart (CPU)

Bash
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k3s.yaml
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.k3s.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+

or if you have been asked by the Kinetica Support team to try a development version

Using a development version
helm search repo kinetica-operators --devel --versions
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.k3s.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password" --devel --version 7.2.0-2.rc-2
+

K3S - Install the Kinetica-Operators Chart (GPU)

If you wish to try out the GPU capabilities, you can use the following values file, provided you are in a nvidia gpu capable machine.

k3s GPU Installation
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k3s.gpu.yaml
+
+helm -n kinetica-system install kinetica-operators charts/kinetica-operators/ --create-namespace --values values.onPrem.k3s.gpu.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+

Accessing the Workbench

You should be able to access the workbench at http://local.kinetica

Uninstall k3s

uninstall k3s
/usr/local/bin/k3s-uninstall.sh
+

Default User

Username as per the values file mentioned above is kadmin and password is Kinetica1234!

\ No newline at end of file diff --git a/7.2/Help/help_and_tutorials/index.html b/7.2/Help/help_and_tutorials/index.html new file mode 100644 index 0000000..f4efc4c --- /dev/null +++ b/7.2/Help/help_and_tutorials/index.html @@ -0,0 +1,10 @@ + Help & Tutorials - Kinetica for Kubernetes

Help & Tutorials

  • Tutorials


    Tutorials

  • Help


    Help

Coming Soon

\ No newline at end of file diff --git a/7.2/Monitoring/logs/index.html b/7.2/Monitoring/logs/index.html new file mode 100644 index 0000000..cb950fd --- /dev/null +++ b/7.2/Monitoring/logs/index.html @@ -0,0 +1,10 @@ + Logs - Kinetica for Kubernetes
\ No newline at end of file diff --git a/7.2/Monitoring/metrics_and_monitoring/index.html b/7.2/Monitoring/metrics_and_monitoring/index.html new file mode 100644 index 0000000..268411c --- /dev/null +++ b/7.2/Monitoring/metrics_and_monitoring/index.html @@ -0,0 +1,10 @@ + Metrics & Monitoring - Kinetica for Kubernetes

MetricsCollection & Display

Coming Soon

\ No newline at end of file diff --git a/7.2/Operations/backup_and_restore/index.html b/7.2/Operations/backup_and_restore/index.html new file mode 100644 index 0000000..84dfe95 --- /dev/null +++ b/7.2/Operations/backup_and_restore/index.html @@ -0,0 +1,10 @@ + Kinetica Backup & Restore - Kinetica for Kubernetes

Kinetica Backup & Restore

Velero Installation

Backup & Restore requires that v is installed into the Kubernetes Cluster.

Coming Soon

\ No newline at end of file diff --git a/7.2/Operations/index.html b/7.2/Operations/index.html new file mode 100644 index 0000000..49bb2e8 --- /dev/null +++ b/7.2/Operations/index.html @@ -0,0 +1,10 @@ + Operations - Kinetica for Kubernetes

Operations

  • Metrics


    Collecting and storing metrics as time series data.

    Metrics

  • Logs


    Log aggregation.

    Logs

  • Distribution


    Metrics & Logs can be distributed to other systems using OpenTelemetry.

    OpenTelemety

  • Backup & Restore


    Backup & Restore of the Kinetica DB.

    Backup & Restore

\ No newline at end of file diff --git a/7.2/Operations/otel/index.html b/7.2/Operations/otel/index.html new file mode 100644 index 0000000..85a9aa8 --- /dev/null +++ b/7.2/Operations/otel/index.html @@ -0,0 +1,10 @@ + OpenTelemetry - Kinetica for Kubernetes

OpenTelemetry Integration for Metric & Log Distribution

Coming Soon

\ No newline at end of file diff --git a/7.2/Operators/k3s/index.html b/7.2/Operators/k3s/index.html new file mode 100644 index 0000000..c2bf9f8 --- /dev/null +++ b/7.2/Operators/k3s/index.html @@ -0,0 +1,24 @@ + Overview - Kinetica for Kubernetes

Overview

Kinetica Operators can be installed in any on-prem kubernetes cluster. This document provides instructions to install the operators in k3s. If you are on another distribution, you should be able to change the values file to suit your environment.

You will need a license key for this to work. Please contact Kinetica Support.

Kinetica on k3s (k3s.io)

Current version of the chart supports kubernetes version 1.25 and above.

Install k3s 1.29

Bash
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik  --node-name kinetica-master --token 12345" K3S_KUBECONFIG_OUTPUT=~/.kube/config_k3s K3S_KUBECONFIG_MODE=644 INSTALL_K3S_VERSION=v1.29.2+k3s1 sh -
+

K3s -Install kinetica-operators including a sample db to try out

Review the values file charts/kinetica-operators/values.onPrem.k3s.yaml. This is trying to install the operators and a simple db with workbench installation for a non production try out.

As you can see it is trying to create an ingress pointing towards local.kinetica. If you have a domain pointing to your machine, replace it with the correct domain name.

If you are on a local machine which is not having a domain name, you add the following entry to your /etc/hosts file or equivalent.

Text Only
127.0.0.1 local.kinetica
+
K3s - Install the kinetica-operators chart
Bash
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k3s.yaml
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.k3s.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+
+# if you want to try out a development version,
+helm search repo kinetica-operators --devel --versions
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.k3s.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password" --devel --version 7.2.0-2.rc-2
+
K3s - Install the kinetica-operators chart (GPU Capable Machine)

If you wish to try out the GPU capabilities, you can use the following values file, provided you are in a nvidia gpu capable machine.

Bash
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k3s.gpu.yaml
+
+helm -n kinetica-system install kinetica-operators charts/kinetica-operators/ --create-namespace --values values.onPrem.k3s.gpu.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+

You should be able to access the workbench at http://local.kinetica

Username as per the values file mentioned above is kadmin and password is Kinetica1234!

Uninstall k3s

Bash
/usr/local/bin/k3s-uninstall.sh
+
\ No newline at end of file diff --git a/7.2/Operators/k8s/index.html b/7.2/Operators/k8s/index.html new file mode 100644 index 0000000..62a69b6 --- /dev/null +++ b/7.2/Operators/k8s/index.html @@ -0,0 +1,34 @@ + Overview - Kinetica for Kubernetes

Overview

For managed Kubernetes solutions (AKS, EKS, GKE) or other on-prem K8s flavors, follow this generic guide to install the Kinetica Operators, Database and Workbench. A product license key will be required for install. Please contact Kinetica Support to request a trial key.

Preparation and prerequisites

Installation requires Helm3 and access to an on-prem or CSP managed Kubernetes cluster. kubectl is optional but highly recommended. The context for the desired target cluster must be selected from your ~/.kube/config file or set via the KUBECONFIG environment variable. Check to see if you have the correct context with,

Bash
kubectl config current-context
+

and that you can access this cluster correctly with,

Bash
kubectl get nodes
+

If you do not see a list of nodes for your K8s cluster the helm installation will not work. Please check your Kubernetes installation or access credentials (kubeconfig).

Install the kinetica-operators chart

This chart will install the Kinetica K8s operators together with a default configured database and workbench UI.

If you are installing into a managed Kubernetes environment and the NGINX ingress controller that is installed as part of this install creates a LoadBalancer service, you may need to associate the LoadBalancer with the domain you plan to use.

Alternatively, if you are installing on a local machine which does not have a domain name, you can add the following entry to your /etc/hosts file or equivalent:

Bash
127.0.0.1  local.kinetica
+

Note that the default chart configuration points to local.kinetica but this is configurable.

1. Add the Kinetica chart repository

Add the repo locally as kinetica-operators:

Bash
helm repo add kinetica-operators https://kineticadb.github.io/charts
+

2. Obtain the default Helm values file

For the generic Kubernetes install use the following values file without modification. Advanced users with specific requirements may need to adjust parameters in this file.

Bash
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.k8s.yaml
+

3. Determine the following prior to the chart install

(a) Obtain a LICENSE-KEY as described in the introduction above. (b) Choose a PASSWORD for the initial administrator user (Note: the default in the chart for this user is kadmin but this is configurable). Non-ASCII characters and typographical symbols in the password must be escaped with a "\". For example, --set dbAdminUser.password="MyPassword\!" © As storage class name varies between K8s flavor and/or there can be multiple, this must be prescribed in the chart installation. Obtain DEFAULT-STORAGE-CLASS name with the command:

Bash
kubectl get sc -o name 
+

use the name found after the /, For example, in "storageclass.storage.k8s.io/TheName" use "TheName" as the parameter.

4. Install the helm chart

Run the following Helm install command after substituting values from section 3 above:

Bash
helm -n kinetica-system install \
+kinetica-operators kinetica-operators/kinetica-operators \
+--create-namespace \
+--values values.onPrem.k8s.yaml \
+--set db.gpudbCluster.license="LICENSE-KEY" \
+--set dbAdminUser.password="PASSWORD" \
+--set global.defaultStorageClass="DEFAULT-STORAGE-CLASS"
+

5. Check installation progress

After a few moments, follow the progression of the main database pod startup with:

Bash
kubectl -n gpudb get po gpudb-0 -w
+

until it reaches "gpudb-0 3/3 Running" at which point the database should be ready and all other software installed in the cluster. You may have to run this command in a different terminal if the helm command from step 4 has not yet returned to the system prompt. Once running, you can quit this kubectl watch command using ctrl-c.

6. Accessing the Kinetica installation

(Optional) Install a development chart version

Find all alternative chart versions with:

Bash
helm search repo kinetica-operators --devel --versions
+

Then append --devel --version [CHART-DEVEL-VERSION] to the end of the Helm install command in section 4 above.

K8s Flavour specific notes

EKS

EBS CSI driver

Make sure you have enabled the ebs-csi driver in your EKS cluster. This is required for the default storage class to work. Please refer to this AWS documentation for more information.

Ingress

As of now, the kinetica-operator chart installs NGINX ingress controller. So after the installation is complete, you may need to edit the KineticaCluster Custom Resource and Workbench Custom Resource with the correct domain name.

Option 1: Use the LoadBalancer domain
Bash
kubectl get svc -n kinetica-system
+# look at the loadbalancer dns name, copy it
+
+kubectl -n gpudb edit $(kubectl -n gpudb get kc -o name)
+# replace local.kinetica with the loadbalancer dns name
+kubectl -n gpudb edit $(kubectl -n gpudb get wb -o name)
+# replace local.kinetica with the loadbalancer dns name
+# save and exit
+# you should be able to access the workbench from the loadbalancer dns name
+
Option 1: Use your custom domain

Create a record in your DNS server pointing to the LoadBalancer DNS. Then edit the KineticaCluster Custom Resource and Workbench Custom Resource with the correct domain name, as mentioned above.

\ No newline at end of file diff --git a/7.2/Operators/kind/index.html b/7.2/Operators/kind/index.html new file mode 100644 index 0000000..fe2c02b --- /dev/null +++ b/7.2/Operators/kind/index.html @@ -0,0 +1,18 @@ + Overview - Kinetica for Kubernetes

Overview

This installation in a kind cluster is for trying out the operators and the database in a non production environment. This method currently only supports installing a CPU version of the database.

You will need a license key for this to work. Please contact Kinetica Support.

Kind (kubernetes in docker kind.sigs.k8s.io)

Create Kind Cluster 1.29

Bash
kind create cluster --config charts/kinetica-operators/kind.yaml
+

Kind - Install kinetica-operators including a sample db to try out

Review the values file charts/kinetica-operators/values.onPrem.kind.yaml. This is trying to install the operators and a simple db with workbench installation for a non production try out.

As you can see it is trying to create an ingress pointing towards local.kinetica. If you have a domain pointing to your machine, replace it with the correct domain name.

Kind - Install the kinetica-operators chart
Bash
wget https://raw.githubusercontent.com/kineticadb/charts/master/kinetica-operators/values.onPrem.kind.yaml
+
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators --create-namespace --values values.onPrem.kind.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password"
+
+# if you want to try out a development version,
+helm search repo kinetica-operators --devel --versions
+helm -n kinetica-system install kinetica-operators kinetica-operators/kinetica-operators/ --create-namespace --values values.onPrem.kind.yaml --set db.gpudbCluster.license="your_license_key" --set dbAdminUser.password="your_password" --devel --version 7.2.0-2.rc-2
+

You should be able to access the workbench at http://local.kinetica

Username as per the values file mentioned above is kadmin and password is Kinetica1234!

\ No newline at end of file diff --git a/7.2/Operators/kinetica-operators/index.html b/7.2/Operators/kinetica-operators/index.html new file mode 100644 index 0000000..30aad59 --- /dev/null +++ b/7.2/Operators/kinetica-operators/index.html @@ -0,0 +1,218 @@ + Kinetica DB Operator Helm Charts - Kinetica for Kubernetes

Kinetica DB Operator Helm Charts

To install all the required operators in a single command perform the following: -

Bash
helm install -n kinetica-system \
+kinetica-operators kinetica-operators/kinetica-operators --create-namespace
+

This will install all the Kubernetes Operators required into the kinetica-system namespace and create the namespace if it is not currently present.

Note

Depending on what target platform you are installing to it may be necessary to supply an additional parameter pointing to a values file to successfully provision the DB.

Bash
helm install -n kinetica-system -f values.yaml --set provider=aks \
+kinetica-operators kinetica-operators/kinetica-operators --create-namespace
+

The command above uses a custom values.yaml for helm and sets the install platform to Microsoft Azure AKS.

Currently supported providers are: -

  • aks - Microsoft Azure AKS
  • eks - Amazon AWS EKS
  • local - Generic 'On-Prem' Kubernetes Clusters e.g. one deployed using kubeadm

Example Helm values.yaml for different Cloud Providers/On-Prem installations: -

values.yaml
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
namespace: kinetica-system
+
+db:
+  serviceAccount: {}
+  image:
+    # Kinetica DB Operator installer image
+    repository: "registry.harbor.kinetica.com/kinetica/kinetica-k8s-operator"
+    #  Kinetica DB Operator installer image tag
+    tag: ""
+
+  parameters:
+    # <base64 encode of kubeconfig> of the Kubernetes Cluster to deploy to
+    kubeconfig: ""
+    # The storage class to use for PVCs
+    storageClass: "managed-premium"
+
+  storageClass:
+    persist:
+      # Workbench Operator Persistent Volume Storage Class
+      provisioner: "disk.csi.azure.com"
+    procs:
+      # Workbench Operator Procs Volume Storage Class
+      provisioner: "disk.csi.azure.com"
+    cache:
+      # Workbench Operator Cache Volume Storage Class
+      provisioner: "disk.csi.azure.com"
+

15 storageClass: "managed-premium" - sets the appropriate storageClass for Microsoft Azure AKS Persistent Volume (PV)

20 provisioner: "disk.csi.azure.com" - sets the appropriate disk provisioner for the DB (Persist) filesystem for Microsoft Azure

23 provisioner: "disk.csi.azure.com" - sets the appropriate disk provisioner for the DB Procs filesystem for Microsoft Azure

26 provisioner: "disk.csi.azure.com" - sets the appropriate disk provisioner for the DB Cache filesystem for Microsoft Azure

values.yaml
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
namespace: kinetica-system
+
+db:
+  serviceAccount: {}
+  image:
+    # Kinetica DB Operator installer image
+    repository: "registry.harbor.kinetica.com/kinetica/kinetica-k8s-operator"
+    #  Kinetica DB Operator installer image tag
+    tag: ""
+
+  parameters:
+    # <base64 encode of kubeconfig> of the Kubernetes Cluster to deploy to
+    kubeconfig: ""
+    # The storage class to use for PVCs
+    storageClass: "gp2"
+
+  storageClass:
+    persist:
+      # Workbench Operator Persistent Volume Storage Class
+      provisioner: "kubernetes.io/aws-ebs"
+    procs:
+      # Workbench Operator Procs Volume Storage Class
+      provisioner: "kubernetes.io/aws-ebs"
+    cache:
+      # Workbench Operator Cache Volume Storage Class
+      provisioner: "kubernetes.io/aws-ebs"
+

15 storageClass: "gp2" - sets the appropriate storageClass for Amazon EKS Persistent Volume (PV)

20 provisioner: "kubernetes.io/aws-ebs" - sets the appropriate disk provisioner for the DB (Persist) filesystem for Microsoft Azure

23 provisioner: "kubernetes.io/aws-ebs" - sets the appropriate disk provisioner for the DB Procs filesystem for Microsoft Azure

26 provisioner: "kubernetes.io/aws-ebs" - sets the appropriate disk provisioner for the DB Cache filesystem for Microsoft Azure

values.yaml
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
namespace: kinetica-system
+
+db:
+  serviceAccount: {}
+  image:
+    # Kinetica DB Operator installer image
+    repository: "registry.harbor.kinetica.com/kinetica/kinetica-k8s-operator"
+    #  Kinetica DB Operator installer image tag
+    tag: ""
+
+  parameters:
+    # <base64 encode of kubeconfig> of the Kubernetes Cluster to deploy to
+    kubeconfig: ""
+    # the type of installation e.g. aks, eks, local
+    environment: "local"
+    # The storage class to use for PVCs
+    storageClass: "standard"
+
+  storageClass:
+    procs: {}
+    persist: {}
+    cache: {}
+

15 environment: "local" - tells the DB Operator to deploy the DB as a 'local' instance to the Kubernetes Cluster

17 storageClass: "standard" - sets the appropriate storageClass for the On-Prem Persistent Volume Provisioner

storageClass

The storageClass should be present in the target environment.

A list of available storageClass can be obtained using: -

Bash
kubectl get sc
+

Components

The kinetica-db Helm Chart wraps the deployment of a number of sub-components: -

Installation/Upgrading/Deletion of the Kinetica Operators is done via two CRs which leverage porter.sh as the orchestrator. The corresponding Porter Operator, DB Operator & Workbench Operator CRs are submitted by running the appropriate helm command i.e.

  • install
  • upgrade
  • uninstall

Porter Operator

Database Operator

The Kinetica DB Operator installation CR for the porter.sh operator is: -

YAML
apiVersion: porter.sh/v1
+kind: Installation
+metadata:
+  annotations:
+    meta.helm.sh/release-name: kinetica-operators
+    meta.helm.sh/release-namespace: kinetica-system
+  labels:
+    app.kubernetes.io/instance: kinetica-operators
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: kinetica-operators
+    app.kubernetes.io/version: 0.1.0
+    helm.sh/chart: kinetica-operators-0.1.0
+    installVersion: 0.38.10
+  name: kinetica-operators-operator-install
+  namespace: kinetica-system
+spec:
+  action: install
+  agentConfig:
+    volumeSize: '0'
+  parameters:
+    environment: local
+    storageclass: managed-premium
+  reference: docker.io/kinetica/kinetica-k8s-operator:v7.1.9-7.rc3
+

Workbench Operator

The Kinetica Workbench installation CR for the porter.sh operator is: -

YAML
apiVersion: porter.sh/v1
+kind: Installation
+metadata:
+  annotations:
+    meta.helm.sh/release-name: kinetica-operators
+    meta.helm.sh/release-namespace: kinetica-system
+  labels:
+    app.kubernetes.io/instance: kinetica-operators
+    app.kubernetes.io/managed-by: Helm
+    app.kubernetes.io/name: kinetica-operators
+    app.kubernetes.io/version: 0.1.0
+    helm.sh/chart: kinetica-operators-0.1.0
+    installVersion: 0.38.10
+  name: kinetica-operators-wb-operator-install
+  namespace: kinetica-system
+spec:
+  action: install
+  agentConfig:
+    volumeSize: '0'
+  parameters:
+    environment: local
+  reference: docker.io/kinetica/workbench-operator:v7.1.9-7.rc3
+

Overriding Images Tags

Bash
1
+2
+3
+4
+5
+6
+7
helm install -n kinetica-system kinetica-operators kinetica-operators/kinetica-operators \
+--create-namespace \
+--set provider=aks  
+--set dbOperator.image.tag=v7.1.9-7.rc3 \
+--set dbOperator.image.repository=docker.io/kinetica/kinetica-k8s-operator \
+--set wbOperator.image.repository=docker.io/kinetica/workbench-operator \
+--set wbOperator.image.tag=v7.1.9-7.rc3
+
\ No newline at end of file diff --git a/7.2/Reference/database/index.html b/7.2/Reference/database/index.html new file mode 100644 index 0000000..786d03a --- /dev/null +++ b/7.2/Reference/database/index.html @@ -0,0 +1,90 @@ + Kinetica Database Configuration - Kinetica for Kubernetes

Kinetica Database Configuration

  • kubectl (yaml)

KineticaCluster

To deploy a new Database Instance into a Kubernetes cluster...

Using kubetctl a CustomResource of type KineticaCluster is used to define a new Kinetica DB Cluster in a yaml file.

The basic Group, Version, Kind or GVK to instantiate a Kinetica DB Cluster is as follows: -

kineticacluster.yaml
1
+2
apiVersion: app.kinetica.com/v1
+kind: KineticaCluster
+

Metadata

to which we add a metadata: block for the name of the DB CR along with the namespace into which we are targetting the installation of the DB cluster.

kineticacluster.yaml
1
+2
+3
+4
+5
+6
apiVersion: app.kinetica.com/v1
+kind: KineticaCluster
+metadata:
+  name: my-kinetica-db-cr
+  namespace: gpudb
+spec:
+

Spec

Under the spec: section of the KineticaCLuster CR we have a number of sections supporting different aspects of the deployed DB cluster:-

gpudbCluster

Configuartion items specific to the DB itself.

kineticacluster.yaml - gpudbCluster
1
+2
+3
+4
+5
+6
+7
apiVersion: app.kinetica.com/v1
+kind: KineticaCluster
+metadata:
+  name: my-kinetica-db-cr
+  namespace: gpudb
+spec:
+  gpudbCluster:
+
gpudbCluster
cluster name & size
1
+2
+3
+4
+5
+6
+7
clusterName: kinetica-cluster 
+clusterSize: 
+  tshirtSize: M 
+  tshirtType: LargeCPU 
+fqdn: kinetica-cluster.saas.kinetica.com
+haRingName: default
+hasPools: false    
+

1. clusterName - the user defined name of the Kinetica DB Cluster

2. clusterSize - block that defines the number of DB Ranks to run

3. tshirtSize - sets the cluster size to a defined size based upon the t-shirt size. Valid sizes are: -

  • XS - 1 DB Rank
  • S - 2 DB Ranks
  • M - 4 DB Ranks
  • L - 8 DB Ranks
  • XL - 16 DB Ranks
  • XXL - 32 DB Ranks
  • XXXL - 64 DB Ranks

4. tshirtType - block that defines the tyoe DB Ranks to run: -

  • SmallCPU -
  • LargeCPU -
  • SmallGPU -
  • LargeGPU -

5. fqdn - The fully qualified URL for the DB cluster. Used on the Ingress records for any exposed services.

6. haRingName - Default: default

7. hasPools - Whether to enable the separate node 'pools' for "infra", "compute" pod scheduling. Default: false +optional

autoSuspend

The DB Cluster autosuspend section allows for the spinning down of the core DB Pods to release the underlying Kubernetes nodes to reduce infrastructure costs when the DB is not in use.

kineticacluster.yaml - autoSuspend
1
+2
+3
+4
+5
+6
+7
+8
+9
apiVersion: app.kinetica.com/v1
+kind: KineticaCluster
+metadata:
+  name: my-kinetica-db-cr
+  namespace: gpudb
+spec:
+  autoSuspend:
+    enabled: false
+    inactivityDuration: 1h0m0s
+

7. the start of the autoSuspend definition

8. enabled when set to true auto suspend of the DB cluster is enabled otherwise set to false and no automatic suspending of the DB takes place. If omitted it defaults to false

9. inactivityDuration the duration after which if no DB activity has taken place the DB will be suspended

Horizontal Pod Autoscaler

In order for autoSuspend to work correctly the Kubernetes Horizontal Pod Autoscaler needs to be deployed to the cluster.

gadmin

GAdmin the Database Administration Console

GAdmin

kineticacluster.yaml - gadmin
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
apiVersion: app.kinetica.com/v1
+kind: KineticaCluster
+metadata:
+  name: my-kinetica-db-cr
+  namespace: gpudb
+spec:
+  gadmin:
+    containerPort:
+      containerPort: 8080
+      name: gadmin
+      protocol: TCP
+    isEnabled: true
+

7. gadmin configuration block definition

8. containerPort configuration block i.e. where gadmin is exposed on the DB Pod

9. containerPort the port number as an integer. Default: 8080

10. name the name of the port being exposed. Default: gadmin

11. protocol network protocal used. Default: TCP

12. isEnabled whether gadmin is exposed from the DB pod. Default: true

KineticaUser

KineticaGrant

KineticaSchema

KineticaResourceGroup

\ No newline at end of file diff --git a/7.2/Reference/helm_kinetica_operators/index.html b/7.2/Reference/helm_kinetica_operators/index.html new file mode 100644 index 0000000..c1c4d6b --- /dev/null +++ b/7.2/Reference/helm_kinetica_operators/index.html @@ -0,0 +1,10 @@ + Kinetica Operators - Kinetica for Kubernetes

Kinetica Operators Helm Chart Reference

Coming Soon

\ No newline at end of file diff --git a/7.2/Reference/index.html b/7.2/Reference/index.html new file mode 100644 index 0000000..da59f2e --- /dev/null +++ b/7.2/Reference/index.html @@ -0,0 +1,10 @@ + Reference Section - Kinetica for Kubernetes

Reference Section

  • Kinetica Operators Helm


    Kinetica Operators Helm charts & values file reference data.

    Charts

  • Kinetica Core DB CRDs


    Kinetica DB Kubernetes CRD & ConfigMap reference data.

    Cluster CRDs

  • Kinetica Workbench CRDs


    Kinetica Workbench Kubernetes CRD & ConfigMap reference data.

    Workbench

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_admins/index.html b/7.2/Reference/kinetica_cluster_admins/index.html new file mode 100644 index 0000000..5ef28f4 --- /dev/null +++ b/7.2/Reference/kinetica_cluster_admins/index.html @@ -0,0 +1,101 @@ + Kinetica Cluster Admins Reference - Kinetica for Kubernetes

Kinetica Cluster Admins Reference

Full KineticaClusterAdmin CR Structure

kineticaclusteradmins.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaClusterAdmin
+metadata: {}
+# KineticaClusterAdminSpec defines the desired state of
+# KineticaClusterAdmin
+spec:
+  # ForceDBStatus - Force a Status of the DB.
+  forceDbStatus: string
+  # Name - The name of the cluster to target.
+  kineticaClusterName: string
+  # Offline - Pause/Resume of the DB.
+  offline:
+    # Set to true if desired state is offline. The supported values are:
+    # true false
+    offline: false
+    # Optional parameters. The default value is an empty map (
+    # {} ). Supported Parameters: flush_to_disk Flush to disk when
+    # going offline The supported values are: true false
+    options: {}
+  # Rebalance of the DB.
+  rebalance:
+    # Optional parameters. The default value is an empty map (
+    # {} ). Supported Parameters: rebalance_sharded_data        If true,
+    # sharded data will be rebalanced approximately equally across the
+    # cluster. Note that for clusters with large amounts of sharded
+    # data, this data transfer could be time-consuming and result in
+    # delayed query responses. The default value is true. The supported
+    # values are: true false rebalance_unsharded_data   If true,
+    # unsharded data (a.k.a. randomly-sharded) will be rebalanced
+    # approximately equally across the cluster. Note that for clusters
+    # with large amounts of unsharded data, this data transfer could be
+    # time-consuming and result in delayed query responses. The default
+    # value is true. The supported values are: true false
+    # table_includes                Comma-separated list of unsharded table names
+    # to rebalance. Not applicable to sharded tables because they are
+    # always rebalanced. Cannot be used simultaneously with
+    # table_excludes. This parameter is ignored if
+    # rebalance_unsharded_data is false.
+    # table_excludes                Comma-separated list of unsharded table names
+    # to not rebalance. Not applicable to sharded tables because they
+    # are always rebalanced. Cannot be used simultaneously with
+    # table_includes. This parameter is ignored if rebalance_
+    # unsharded_data is false. aggressiveness               Influences how much
+    # data is moved at a time during rebalance. A higher aggressiveness
+    # will complete the rebalance faster. A lower aggressiveness will
+    # take longer but allow for better interleaving between the
+    # rebalance and other queries. Valid values are constants from 1
+    # (lowest) to 10 (highest). The default value is '1'.
+    # compact_after_rebalance   Perform compaction of deleted records
+    # once the rebalance completes to reclaim memory and disk space.
+    # Default is true, unless repair_incorrectly_sharded_data is set to
+    # true. The default value is true. The supported values are: true
+    # false compact_only                If set to true, ignore rebalance options
+    # and attempt to perform compaction of deleted records to reclaim
+    # memory and disk space without rebalancing first. The default
+    # value is false. The supported values are: true false
+    # repair_incorrectly_sharded_data       Scans for any data sharded
+    # incorrectly and re-routes the data to the correct location. Only
+    # necessary if /admin/verifydb reports an error in sharding
+    # alignment. This can be done as part of a typical rebalance after
+    # expanding the cluster or in a standalone fashion when it is
+    # believed that data is sharded incorrectly somewhere in the
+    # cluster. Compaction will not be performed by default when this is
+    # enabled. If this option is set to true, the time necessary to
+    # rebalance and the memory used by the rebalance may increase. The
+    # default value is false. The supported values are: true false
+    options: {}
+  # RegenerateDBConfig - Force regenerate of DB ConfigMap. true -
+  # restarts DB Pods after config generation false - writes new
+  # configuration without restarting the DB Pods
+  regenerateDBConfig:
+    # Restart - Scales down the DB STS and back up once the DB
+    # Configuration has been regenerated.
+    restart: false
+# KineticaClusterAdminStatus defines the observed state of
+# KineticaClusterAdmin
+status:
+  # Phase - The current phase/state of the Admin request
+  phase: string
+  # Processed - Indicates if the admin request has already been
+  # processed. Avoids the request being rerun in the case the Operator
+  # gets restarted.
+  processed: false
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_backups/index.html b/7.2/Reference/kinetica_cluster_backups/index.html new file mode 100644 index 0000000..0e4352c --- /dev/null +++ b/7.2/Reference/kinetica_cluster_backups/index.html @@ -0,0 +1,228 @@ + Kinetica Cluster Backups Reference - Kinetica for Kubernetes

Kinetica Cluster Backups Reference

Full KineticaClusterBackup CR Structure

kineticaclusterbackups.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaClusterBackup 
+metadata: {}
+# Fields specific to the linked backup engine
+provider:
+  # Name of the backup/restore provider. FOR INTERNAL USE ONLY.
+  backupProvider: "velero"
+  # Name of the backup in the linked BackupProvider. FOR INTERNAL USE
+  # ONLY.
+  linkedItemName: ""
+# BackupSpec defines the specification for a Velero backup.
+spec:
+  # DefaultVolumesToRestic specifies whether restic should be used to
+  # take a backup of all pod volumes by default.
+  defaultVolumesToRestic: true
+  # ExcludedNamespaces contains a list of namespaces that are not
+  # included in the backup.
+  excludedNamespaces: ["string"]
+  # ExcludedResources is a slice of resource names that are not included
+  # in the backup.
+  excludedResources: ["string"]
+  # Hooks represent custom behaviors that should be executed at
+  # different phases of the backup.
+  hooks:
+    # Resources are hooks that should be executed when backing up
+    # individual instances of a resource.
+    resources:
+    - excludedNamespaces: ["string"]
+      # ExcludedResources specifies the resources to which this hook
+      # spec does not apply.
+      excludedResources: ["string"]
+      # IncludedNamespaces specifies the namespaces to which this hook
+      # spec applies. If empty, it applies to all namespaces.
+      includedNamespaces: ["string"]
+      # IncludedResources specifies the resources to which this hook
+      # spec applies. If empty, it applies to all resources.
+      includedResources: ["string"]
+      # LabelSelector, if specified, filters the resources to which this
+      # hook spec applies.
+      labelSelector:
+        # matchExpressions is a list of label selector requirements. The
+        # requirements are ANDed.
+        matchExpressions:
+        - key: string
+          # operator represents a key's relationship to a set of values.
+          # Valid operators are In, NotIn, Exists and DoesNotExist.
+          operator: string
+          # values is an array of string values. If the operator is In
+          # or NotIn, the values array must be non-empty. If the
+          # operator is Exists or DoesNotExist, the values array must
+          # be empty. This array is replaced during a strategic merge
+          # patch.
+          values: ["string"]
+        # matchLabels is a map of {key,value} pairs. A single
+        # {key,value} in the matchLabels map is equivalent to an
+        # element of matchExpressions, whose key field is "key", the
+        # operator is "In", and the values array contains only "value".
+        # The requirements are ANDed.
+        matchLabels: {}
+      # Name is the name of this hook.
+      name: string
+      # PostHooks is a list of BackupResourceHooks to execute after
+      # storing the item in the backup. These are executed after
+      # all "additional items" from item actions are processed.
+      post:
+      - exec:
+          # Command is the command and arguments to execute.
+          command: ["string"]
+          # Container is the container in the pod where the command
+          # should be executed. If not specified, the pod's first
+          # container is used.
+          container: string
+          # OnError specifies how Velero should behave if it encounters
+          # an error executing this hook.
+          onError: string
+          # Timeout defines the maximum amount of time Velero should
+          # wait for the hook to complete before considering the
+          # execution a failure.
+          timeout: string
+      # PreHooks is a list of BackupResourceHooks to execute prior to
+      # storing the item in the backup. These are executed before
+      # any "additional items" from item actions are processed.
+      pre:
+      - exec:
+          # Command is the command and arguments to execute.
+          command: ["string"]
+          # Container is the container in the pod where the command
+          # should be executed. If not specified, the pod's first
+          # container is used.
+          container: string
+          # OnError specifies how Velero should behave if it encounters
+          # an error executing this hook.
+          onError: string
+          # Timeout defines the maximum amount of time Velero should
+          # wait for the hook to complete before considering the
+          # execution a failure.
+          timeout: string
+  # IncludeClusterResources specifies whether cluster-scoped resources
+  # should be included for consideration in the backup.
+  includeClusterResources: true
+  # IncludedNamespaces is a slice of namespace names to include objects
+  # from. If empty, all namespaces are included.
+  includedNamespaces: ["string"]
+  # IncludedResources is a slice of resource names to include in the
+  # backup. If empty, all resources are included.
+  includedResources: ["string"]
+  # LabelSelector is a metav1.LabelSelector to filter with when adding
+  # individual objects to the backup. If empty or nil, all objects are
+  # included. Optional.
+  labelSelector:
+    # matchExpressions is a list of label selector requirements. The
+    # requirements are ANDed.
+    matchExpressions:
+    - key: string
+      # operator represents a key's relationship to a set of values.
+      # Valid operators are In, NotIn, Exists and DoesNotExist.
+      operator: string
+      # values is an array of string values. If the operator is In or
+      # NotIn, the values array must be non-empty. If the operator is
+      # Exists or DoesNotExist, the values array must be empty. This
+      # array is replaced during a strategic merge patch.
+      values: ["string"]
+    # matchLabels is a map of {key,value} pairs. A single {key,value} in
+    # the matchLabels map is equivalent to an element of
+    # matchExpressions, whose key field is "key", the operator is "In",
+    # and the values array contains only "value". The requirements are
+    # ANDed.
+    matchLabels: {} metadata: labels: {}
+  # OrderedResources specifies the backup order of resources of specific
+  # Kind. The map key is the Kind name and value is a list of resource
+  # names separated by commas. Each resource name has
+  # format "namespace/resourcename".  For cluster resources, simply
+  # use "resourcename".
+  orderedResources: {}
+  # SnapshotVolumes specifies whether to take cloud snapshots of any
+  # PV's referenced in the set of objects included in the Backup.
+  snapshotVolumes: true
+  # StorageLocation is a string containing the name of a
+  # BackupStorageLocation where the backup should be stored.
+  storageLocation: string
+  # TTL is a time.Duration-parseable string describing how long the
+  # Backup should be retained for.
+  ttl: string
+  # VolumeSnapshotLocations is a list containing names of
+  # VolumeSnapshotLocations associated with this backup.
+  volumeSnapshotLocations: ["string"] status:
+  # ClusterSize the current number of ranks & type i.e. CPU or GPU of
+  # the cluster when the backup took place.
+  clusterSize:
+    # ClusterSizeEnum - T-Shirt size of the Kinetica DB Cluster i.e. a
+    # representation of the number of nodes in a simple to understand
+    # T-Short size scheme. This indicates the size of the cluster i.e.
+    # the number of nodes. It does not identify the size of the cloud
+    # provider nodes. For node size see ClusterTypeEnum. Supported
+    # Values are: - XS S M L XL XXL XXXL
+    tshirtSize: string
+    # ClusterTypeEnum - An Enum of the node types of a KineticaCluster
+    # e.g. CPU, GPU along with the Cloud Provider node size e.g. size
+    # of the VM.
+    tshirtType: string coldTierBackup: string
+  # CompletionTimestamp records the time a backup was completed.
+  # Completion time is recorded even on failed backups. Completion time
+  # is recorded before uploading the backup object. The server's time
+  # is used for CompletionTimestamps
+  completionTimestamp: string
+  # Errors is a count of all error messages that were generated during
+  # execution of the backup.  The actual errors are in the backup's log
+  # file in object storage.
+  errors: 1
+  # Expiration is when this Backup is eligible for garbage-collection.
+  expiration: string
+  # FormatVersion is the backup format version, including major, minor,
+  # and patch version.
+  formatVersion: string
+  # Phase is the current state of the Backup.
+  phase: string
+  # Progress contains information about the backup's execution progress.
+  # Note that this information is best-effort only -- if Velero fails
+  # to update it during a backup for any reason, it may be
+  # inaccurate/stale.
+  progress:
+    # ItemsBackedUp is the number of items that have actually been
+    # written to the backup tarball so far.
+    itemsBackedUp: 1
+    # TotalItems is the total number of items to be backed up. This
+    # number may change throughout the execution of the backup due to
+    # plugins that return additional related items to back up, the
+    # velero.io/exclude-from-backup label, and various other filters
+    # that happen as items are processed.
+    totalItems: 1
+  # StartTimestamp records the time a backup was started. Separate from
+  # CreationTimestamp, since that value changes on restores. The
+  # server's time is used for StartTimestamps
+  startTimestamp: string
+  # ValidationErrors is a slice of all validation errors
+  # (if applicable).
+  validationErrors: ["string"]
+  # Version is the backup format major version. Deprecated: Please see
+  # FormatVersion
+  version: 1
+  # VolumeSnapshotsAttempted is the total number of attempted volume
+  # snapshots for this backup.
+  volumeSnapshotsAttempted: 1
+  # VolumeSnapshotsCompleted is the total number of successfully
+  # completed volume snapshots for this backup.
+  volumeSnapshotsCompleted: 1
+  # Warnings is a count of all warning messages that were generated
+  # during execution of the backup. The actual warnings are in the
+  # backup's log file in object storage.
+  warnings: 1
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_grants/index.html b/7.2/Reference/kinetica_cluster_grants/index.html new file mode 100644 index 0000000..dfae744 --- /dev/null +++ b/7.2/Reference/kinetica_cluster_grants/index.html @@ -0,0 +1,111 @@ + Kinetica Cluster Grants Reference - Kinetica for Kubernetes

Kinetica Cluster Grants CRD Reference

Full KineticaGrant CR Structure

kineticagrants.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaGrant 
+metadata: {}
+# KineticaGrantSpec defines the desired state of KineticaGrant
+spec:
+  # Grants system-level and/or table permissions to a user or role.
+  addGrantAllOnSchemaRequest:
+    # Name of the user or role that will be granted membership in input
+    # parameter role. Must be an existing user or role.
+    member: string
+    # Optional parameters. The default value is an empty map ( {} ).
+    options: {}
+    # SchemaName - name of the schema on which to perform the Grant All
+    schemaName: string
+  # Grants system-level and/or table permissions to a user or role.
+  addGrantPermissionRequest:
+    # Optional parameters. The default value is an empty map ( {} ).
+    options: {}
+    # Permission to grant to the user or role. Supported
+    # Values    Description system_admin    Full access to all data and
+    # system functions. system_user_admin   Access to administer users
+    # and roles that do not have system_admin permission.
+    # system_write  Read and write access to all tables.
+    # system_read   Read-only access to all tables.
+    systemPermission:
+      # UID of the user or role to which the permission will be granted.
+      # Must be an existing user or role.
+      name: string
+      # Optional parameters. The default value is an empty map (
+      # {} ). Supported Parameters: resource_group  Name of an existing
+      # resource group to associate with this role.
+      options: {}
+      # Permission to grant to the user or role. Supported
+      # Values  Description table_admin Full read/write and
+      # administrative access to the table. table_insert    Insert access
+      # to the table. table_update  Update access to the table.
+      # table_delete    Delete access to the table. table_read  Read access
+      # to the table.
+      permission: string
+    # Permission to grant to the user or role. Supported
+    # Values    Description<br/> system_admin   Full access to all data and
+    # system functions.<br/> system_user_admin  Access to administer
+    # users and roles that do not have system_admin permission.<br/>
+    # system_write  Read and write access to all tables.<br/>
+    # system_read   Read-only access to all tables.<br/>
+    tablePermissions:
+    - filter_expression: ""
+      # UID of the user or role to which the permission will be granted.
+      # Must be an existing user or role.
+      name: string
+      # Optional parameters. The default value is an empty map (
+      # {} ). Supported Parameters: resource_group  Name of an existing
+      # resource group to associate with this role.
+      options: {}
+      # Permission to grant to the user or role. Supported
+      # Values  Description table_admin Full read/write and
+      # administrative access to the table. table_insert    Insert access
+      # to the table. table_update  Update access to the table.
+      # table_delete    Delete access to the table. table_read  Read access
+      # to the table.
+      permission: string
+      # Name of the table for which the Permission is to be granted
+      table_name: string
+  # Grants membership in a role to a user or role.
+  addGrantRoleRequest:
+    # Name of the user or role that will be granted membership in input
+    # parameter role. Must be an existing user or role.
+    member: string
+    # Optional parameters. The default value is an empty map ( {} ).
+    options: {}
+    # Name of the role in which membership will be granted. Must be an
+    # existing role.
+    role: string
+  # Debug debug the call
+  debug: false
+  # RingName is the name of the kinetica ring that this user belongs
+  # to.
+  ringName: string
+# KineticaGrantStatus defines the observed state of KineticaGrant
+status:
+  # DBStringResponse - The GPUdb server embeds the endpoint response
+  # inside a standard response structure which contains status
+  # information and the actual response to the query.
+  db_response: data: string
+    # This embedded JSON represents the result of the endpoint
+    data_str: string
+    # API Call Specific
+    data_type: string
+    # Empty if success or an error message
+    message: string
+    # 'OK' or 'ERROR'
+    status: string 
+    ldap_response: string
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_reference/index.html b/7.2/Reference/kinetica_cluster_reference/index.html new file mode 100644 index 0000000..0675590 --- /dev/null +++ b/7.2/Reference/kinetica_cluster_reference/index.html @@ -0,0 +1,10 @@ + Kinetica Core DB CRDs - Kinetica for Kubernetes

Kinetica Core DB CRDs

  • DB Clusters


    Core Kinetica Database Cluster Management CRD & sample CR.

    KineticaCluster

  • DB Users


    Kinetica Database User Management CRD & sample CR.

    KineticaUser

  • DB Roles


    Kinetica Database Role Management CRD & sample CR.

    KineticaRole

  • DB Schemas


    Kinetica Database Schema Management CRD & sample CR.

    KineticaSchema

  • DB Grants


    Kinetica Database Grant Management CRD & sample CR.

    KineticaGrant

  • DB Resource Groups


    Kinetica Database Resource Group Management CRD & sample CR.

    KineticaResourceGroup

  • DB Administration


    Kinetica Database Administration CRD & sample CR.

    KineticaAdmin

  • DB Backups


    Kinetica Database Backup Management CRD & sample CR.

    Note

    This requires Velero to be installed on the Kubernetes Cluster.

    KineticaBackup

  • DB Restore


    Kinetica Database Restore CRD & sample CR.

    Note

    This requires Velero to be installed on the Kubernetes Cluster.

    KineticaRestore

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_resource_groups/index.html b/7.2/Reference/kinetica_cluster_resource_groups/index.html new file mode 100644 index 0000000..f38e67f --- /dev/null +++ b/7.2/Reference/kinetica_cluster_resource_groups/index.html @@ -0,0 +1,46 @@ + Kinetica Cluster Resource Groups Reference - Kinetica for Kubernetes

Kinetica Cluster Resource Groups CRD Reference

Full KineticaResourceGroup CR Structure

kineticaclusterresourcegroups.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaClusterResourceGroup 
+metadata: {}
+# KineticaClusterResourceGroupSpec defines the desired state of
+# KineticaClusterResourceGroup
+spec: 
+  db_create_resource_group_request:
+    # AdjoiningResourceGroup -
+    adjoining_resource_group: ""
+    # Name - name of the DB ResourceGroup
+    # https://docs.kinetica.com/7.1/azure/sql/resource_group/?search-highlight=resource+group#id-baea5b60-769c-5373-bff1-53f4f1ca5c21
+    name: string
+    # Options - DB Options used when creating the ResourceGroup
+    options: {}
+    # Ranking - Indicates the relative ranking among existing resource
+    # groups where this new resource group will be placed. When using
+    # before or after, specify which resource group this one will be
+    # inserted before or after in input parameter
+    # adjoining_resource_group. The supported values are: first last
+    # before after
+    ranking: ""
+  # RingName is the name of the kinetica ring that this user belongs
+  # to.
+  ringName: string
+# KineticaClusterResourceGroupStatus defines the observed state of
+# KineticaClusterResourceGroup
+status: 
+  provisioned: string
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_restores/index.html b/7.2/Reference/kinetica_cluster_restores/index.html new file mode 100644 index 0000000..e07966d --- /dev/null +++ b/7.2/Reference/kinetica_cluster_restores/index.html @@ -0,0 +1,107 @@ + Kinetica Cluster Restores Reference - Kinetica for Kubernetes

Kinetica Cluster Restores Reference

Full KineticaClusterRestore CR Structure

kineticaclusterrestores.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaClusterRestore 
+metadata: {}
+# RestoreSpec defines the specification for a Velero restore.
+spec:
+  # BackupName is the unique name of the Velero backup to restore from.
+  backupName: string
+  # ExcludedNamespaces contains a list of namespaces that are not
+  # included in the restore.
+  excludedNamespaces: ["string"]
+  # ExcludedResources is a slice of resource names that are not included
+  # in the restore.
+  excludedResources: ["string"]
+  # IncludeClusterResources specifies whether cluster-scoped resources
+  # should be included for consideration in the restore. If null,
+  # defaults to true.
+  includeClusterResources: true
+  # IncludedNamespaces is a slice of namespace names to include objects
+  # from. If empty, all namespaces are included.
+  includedNamespaces: ["string"]
+  # IncludedResources is a slice of resource names to include in the
+  # restore. If empty, all resources in the backup are included.
+  includedResources: ["string"]
+  # LabelSelector is a metav1.LabelSelector to filter with when
+  # restoring individual objects from the backup. If empty or nil, all
+  # objects are included. Optional.
+  labelSelector:
+    # matchExpressions is a list of label selector requirements. The
+    # requirements are ANDed.
+    matchExpressions:
+    - key: string
+      # operator represents a key's relationship to a set of values.
+      # Valid operators are In, NotIn, Exists and DoesNotExist.
+      operator: string
+      # values is an array of string values. If the operator is In or
+      # NotIn, the values array must be non-empty. If the operator is
+      # Exists or DoesNotExist, the values array must be empty. This
+      # array is replaced during a strategic merge patch.
+      values: ["string"]
+    # matchLabels is a map of {key,value} pairs. A single {key,value} in
+    # the matchLabels map is equivalent to an element of
+    # matchExpressions, whose key field is "key", the operator is "In",
+    # and the values array contains only "value". The requirements are
+    # ANDed.
+    matchLabels: {}
+  # NamespaceMapping is a map of source namespace names to target
+  # namespace names to restore into. Any source namespaces not included
+  # in the map will be restored into namespaces of the same name.
+  namespaceMapping: {}
+  # RestorePVs specifies whether to restore all included PVs from
+  # snapshot (via the cloudprovider).
+  restorePVs: true
+  # ScheduleName is the unique name of the Velero schedule to restore
+  # from. If specified, and BackupName is empty, Velero will restore
+  # from the most recent successful backup created from this schedule.
+  scheduleName: string status: coldTierRestore: ""
+  # CompletionTimestamp records the time the restore operation was
+  # completed. Completion time is recorded even on failed restore. The
+  # server's time is used for StartTimestamps
+  completionTimestamp: string
+  # Errors is a count of all error messages that were generated during
+  # execution of the restore. The actual errors are stored in object
+  # storage.
+  errors: 1
+  # FailureReason is an error that caused the entire restore to fail.
+  failureReason: string
+  # Phase is the current state of the Restore
+  phase: string
+  # Progress contains information about the restore's execution
+  # progress. Note that this information is best-effort only -- if
+  # Velero fails to update it during a restore for any reason, it may
+  # be inaccurate/stale.
+  progress:
+    # ItemsRestored is the number of items that have actually been
+    # restored so far
+    itemsRestored: 1
+    # TotalItems is the total number of items to be restored. This
+    # number may change throughout the execution of the restore due to
+    # plugins that return additional related items to restore
+    totalItems: 1
+  # StartTimestamp records the time the restore operation was started.
+  # The server's time is used for StartTimestamps
+  startTimestamp: string
+  # ValidationErrors is a slice of all validation errors(if applicable)
+  validationErrors: ["string"]
+  # Warnings is a count of all warning messages that were generated
+  # during execution of the restore. The actual warnings are stored in
+  # object storage.
+  warnings: 1
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_roles/index.html b/7.2/Reference/kinetica_cluster_roles/index.html new file mode 100644 index 0000000..f232016 --- /dev/null +++ b/7.2/Reference/kinetica_cluster_roles/index.html @@ -0,0 +1,66 @@ + Kinetica Cluster Roles Reference - Kinetica for Kubernetes

Kinetica Cluster Roles CRD

Full KineticaRole CR Structure

kineticaroles.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaRole 
+metadata: {}
+# KineticaRoleSpec defines the desired state of KineticaRole
+spec:
+  # AlterRoleRequest Kinetica DB REST API Request Format Object.
+  alter_role:
+    # Action - Modification operation to be applied to the role.
+    action: string
+    # Role UID - Name of the role to be altered. Must be an existing
+    # role.
+    name: string
+    # Optional parameters. The default value is an empty map ( {} ).
+    options: {}
+    # Value - The value of the modification, depending on input
+    # parameter action.
+    value: string
+  # Debug debug the call
+  debug: false
+  # RingName is the name of the kinetica ring that this user belongs
+  # to.
+  ringName: string
+  # AddRoleRequest Kinetica DB REST API Request Format Object.
+  role:
+    # User UID
+    name: string
+    # Optional parameters. The default value is an empty map (
+    # {} ). Supported Parameters: resource_group    Name of an existing
+    # resource group to associate with this role.
+    options: {}
+    # ResourceGroupName of an existing resource group to associate with
+    # this role
+    resourceGroupName: ""
+# KineticaRoleStatus defines the observed state of KineticaRole
+status:
+  # DBStringResponse - The GPUdb server embeds the endpoint response
+  # inside a standard response structure which contains status
+  # information and the actual response to the query.
+  db_response: data: string
+    # This embedded JSON represents the result of the endpoint
+    data_str: string
+    # API Call Specific
+    data_type: string
+    # Empty if success or an error message
+    message: string
+    # 'OK' or 'ERROR'
+    status: string 
+    ldap_response: string
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_schemas/index.html b/7.2/Reference/kinetica_cluster_schemas/index.html new file mode 100644 index 0000000..2d1515d --- /dev/null +++ b/7.2/Reference/kinetica_cluster_schemas/index.html @@ -0,0 +1,37 @@ + Kinetica Cluster Schemas Reference - Kinetica for Kubernetes

Kinetica Cluster Schemas CRD Reference

Full Kinetica Cluster Schemas CR Structure

kineticaclusterschemas.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaClusterSchema 
+metadata: {}
+# KineticaClusterSchemaSpec defines the desired state of
+# KineticaClusterSchema
+spec: 
+  db_create_schema_request:
+    # Name - the name of the resource group to create in the DB
+    name: string
+    # Optional parameters. The default value is an empty map (
+    # {} ). Supported Parameters: "max_cpu_concurrency", "max_data"
+    options: {}
+  # RingName is the name of the kinetica ring that this user belongs
+  # to.
+  ringName: string
+# KineticaClusterSchemaStatus defines the observed state of
+# KineticaClusterSchema
+status: 
+  provisioned: string
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_cluster_users/index.html b/7.2/Reference/kinetica_cluster_users/index.html new file mode 100644 index 0000000..d525b80 --- /dev/null +++ b/7.2/Reference/kinetica_cluster_users/index.html @@ -0,0 +1,91 @@ + Kinetica Cluster Users Reference - Kinetica for Kubernetes

Kinetica Cluster Users CRD Reference

Full KineticaUser CR Structure

kineticausers.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaUser
+metadata: {}
+# KineticaUserSpec defines the desired state of KineticaUser
+spec:
+  # Action field contains UserActionEnum field indicating whether it is
+  # an Upsert or Change Password operation. For deletion delete the
+  # KineticaUser CR and a finalizer will remove the user from LDAP.
+  action: string
+  # ChangePassword specific fields
+  changePassword:
+    # PasswordSecret - Not the actual user password but the name of a
+    # Kubernetes Secret containing a Data element with a Password
+    # attribute. The secret is removed on user creation. Must be in the
+    # same namespace as the Kinetica Cluster. Must contain the
+    # following fields: - oldPassword newPassword
+    passwordSecret: string
+  # Debug debug the call
+  debug: false
+  # GroupID - Organisation or Team Id the user belongs to.
+  groupId: string
+  # Create the user in Reveal
+  reveal: true
+  # RingName is the name of the kinetica ring that this user belongs
+  # to.
+  ringName: string
+  # UID is the username (not UUID UID).
+  uid: string
+  # Upsert specific fields
+  upsert:
+    # CreateHomeDirectory - when true, a home directory in KiFS is
+    # created for this user The default value is true. The supported
+    # values are: true false
+    createHomeDirectory: true
+    # DB Memory user data size limit
+    dataLimit: "10Gi"
+    # DisplayName
+    displayName: string
+    # GivenName is Firstname also called Christian name. givenName in
+    # LDAP terms.
+    givenName: string
+    # KIFs user data size limit
+    kifsDataLimit: "2Gi"
+    # LastName refers to last name or surname. sn in LDAP terms.
+    lastName: string
+    # Options -
+    options: {}
+    # PasswordSecret - Not the actual user password but the name of a
+    # Kubernetes Secret containing a Data element with a Password
+    # attribute. The secret is removed on user creation. Must be in the
+    # same namespace as the Kinetica Cluster.
+    passwordSecret: string
+    # UPN or UserPrincipalName - e.g. guyt@cp.com  
+    # Looks like an email address.
+    userPrincipalName: string
+  # UUID is the user unique UUID from the Control Plane.
+  uuid: string
+# KineticaUserStatus defines the observed state of KineticaUser
+status:
+  # DBStringResponse - The GPUdb server embeds the endpoint response
+  # inside a standard response structure which contains status
+  # information and the actual response to the query.
+  db_response: data: string
+    # This embedded JSON represents the result of the endpoint
+    data_str: string
+    # API Call Specific
+    data_type: string
+    # Empty if success or an error message
+    message: string
+    # 'OK' or 'ERROR'
+    status: string 
+    ldap_response: string 
+    reveal_admin: string
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_clusters/index.html b/7.2/Reference/kinetica_clusters/index.html new file mode 100644 index 0000000..c4c2a6a --- /dev/null +++ b/7.2/Reference/kinetica_clusters/index.html @@ -0,0 +1,6383 @@ + Kinetica Clusters Reference - Kinetica for Kubernetes

Kinetica Clusters CRD Reference

This page covers the Kinetica Cluster Kubernetes CRD.

Full KineticaCluster CR Structure

kineticaclusters.app.kinetica.com_sample.yaml
# APIVersion defines the versioned schema of this representation of an
+# object. Servers should convert recognized schemas to the latest
+# internal value, and may reject unrecognized values. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+apiVersion: app.kinetica.com/v1
+# Kind is a string value representing the REST resource this object
+# represents. Servers may infer this from the endpoint the client
+# submits requests to. Cannot be updated. In CamelCase. More info:
+# https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+kind: KineticaCluster 
+metadata: {}
+# KineticaClusterSpec defines the configuration for KineticaCluster DB
+spec:
+  # An optional duration after which the database is stopped and DB
+  # resources are freed
+  autoSuspend: 
+    enabled: false
+    # InactivityDuration - the duration which the cluster should be idle
+    # before auto-pausing the DB Cluster.
+    inactivityDuration: "1h"
+  # The platform infrastructure provider e.g. azure, aws, gcp, on-prem
+  # etc.
+  awsConfig:
+    # ClusterName - AWS name of the EKS Cluster. NOTE: Marked as
+    # optional but is mandatory
+    clusterName: string
+    # MarketplaceAppConfig - Amazon AWS specific DB Cluster
+    # information.
+    marketplaceApp:
+      # KmsKeyId - Key for disk encryption. The full Amazon Resource
+      # Name of the key to use when encrypting the volume. If none is
+      # supplied but encrypted is true, a key is generated by AWS. See
+      # AWS docs for valid ARN value.
+      kmsKeyId: string
+      # ProductCode - used to uniquely identify a product in AWS
+      # Marketplace. The product code should be the same as the one
+      # used during the publishing of a new product.
+      productCode: "1cmucncoyp9pi8xjdwqjimlf8"
+      # PublicKeyVersion - Public Key Version provided by AWS
+      # Marketplace
+      publicKeyVersion: 1
+      # ParentResourceGroup - The resource group of the ManagedApp
+      # itself ParentResourceGroup     string
+      # `json:"parentResourceGroup"` ResourceId - Identifier of the
+      # resource against which usage is emitted Format is GUID
+      # (UUID)
+      # https://github.com/microsoft/commercial-marketplace-openapi/blob/main/Microsoft.Marketplace.Metering/2018-08-31/meteringapi.v1.json
+      # Optional only if that exactly of  ResourceId or ResourceUri is
+      # specified.
+      resourceId: string
+    # NodeGroups - List of NodeGroups for this cluster MUST contain at
+    # least one of the following keys: - 
+    #   * none
+    #   * infra 
+    #   * infra_public 
+    #   * compute 
+    #   * compute-gpu 
+    #   * aaw_cpu 
+    # NOTE: Marked as optional but is mandatory
+    nodeGroups: {}
+    # OTELTracing - OpenTelemetry Tracing Specifics
+    otelTracing:
+      # Endpoint - Set the OpenTelemetry reporting Endpoint
+      endpoint: ""
+      # Key - KineticaCluster specific Key required to send Telemetry
+      # information to the Cloud
+      key: string
+      # MaxBatchSize - Telemetry Reporting Interval to use in seconds.
+      maxBatchInterval: 10
+      # MaxBatchSize - Telemetry Maximum Batch Size to send.
+      maxBatchSize: 1024
+  # The platform infrastructure provider e.g. azure, aws, gcp, on-prem
+  # etc.
+  azureConfig:
+    # App Insights Specifics
+    appInsights:
+      # Endpoint - Override the default AppInsights reporting Endpoint
+      endpoint: ""
+      # Key - KineticaCluster specific Application Insights Key required
+      # to send Telemetry information to the Azure Portal
+      key: string
+      # MaxBatchSize - Telemetry Reporting Interval to use in seconds.
+      maxBatchInterval: 10
+      # MaxBatchSize - Telemetry Maximum Batch Size to send.
+      maxBatchSize: 1024
+    # AzureManagedAppConfig - Microsoft Azure specific DB Cluster
+    # information.
+    managedApp:
+      # DiskEncryptionSetID - By default, managed disks use
+      # platform-managed encryption keys. All managed disks, snapshots,
+      # images, and data written to existing managed disks are
+      # automatically encrypted-at-rest with platform-managed keys. You
+      # can choose to manage encryption at the level of each managed
+      # disk, with your own keys. When you specify a customer-managed
+      # key, that key is used to protect and control access to the key
+      # that encrypts your data. Customer-managed keys offer greater
+      # flexibility to manage access controls.
+      diskEncryptionSetId: string
+      # PlanId - The Azure Marketplace Plan/Offer identifier selected by
+      # the customer for this DB cluster e.g. BYOL, Pay-As-You-Go etc.
+      planId: string
+      # ParentResourceGroup - The resource group of the ManagedApp
+      # itself ParentResourceGroup     string
+      # `json:"parentResourceGroup"` ResourceId - Identifier of the
+      # resource against which usage is emitted Format is GUID
+      # (UUID)
+      # https://github.com/microsoft/commercial-marketplace-openapi/blob/main/Microsoft.Marketplace.Metering/2018-08-31/meteringapi.v1.json
+      # Optional only if that exactly of  ResourceId or ResourceUri is
+      # specified.
+      resourceId: string
+      # ResourceUri - Identifier of the managed app resource against
+      # which usage is emitted
+      # https://github.com/microsoft/commercial-marketplace-openapi/blob/main/Microsoft.Marketplace.Metering/2018-08-31/meteringapi.v1.json
+      # Optional only if that exactly of  ResourceId or ResourceUri is
+      # specified.
+      resourceUri: string
+  # Tells the operator we want to run in Debug mode.
+  debug: false
+  # Identifies the type of Kubernetes deployment.
+  deploymentType:
+    # CloudRegionEnum - The target Kubernetes type to deploy to.
+    # Supported Values are: - aws_useast_1 aws_useast_2 aws_uswest_1
+    # az_useast_1 az_uswest_1
+    region: string
+    # DeploymentTypeEnum - The type of the Deployment. Supported Values
+    # are: - Managed FreeSaaS DedicatedSaaS OnPrem
+    type: string
+  # The platform infrastructure provider e.g. azure, aws, gcp, on-prem
+  # etc.
+  devEditionConfig:
+    # Host IPv4 address. Used by KiND based Developer Edition where
+    # ingress paths set to *. Provides qualified, routable URLs to
+    # workbench.
+    hostIpAddress: ""
+  # The GAdmin Dashboard Configuration for the Kinetica Cluster.
+  gadmin:
+    # The port that GAdmin will be running on. It runs only on the head
+    # node pod in the cluster. Default: 8080
+    containerPort:
+      # Number of port to expose on the pod's IP address. This must be a
+      # valid port number, 0 < x < 65536.
+      containerPort: 1
+      # What host IP to bind the external port to.
+      hostIP: string
+      # Number of port to expose on the host. If specified, this must be
+      # a valid port number, 0 < x < 65536. If HostNetwork is
+      # specified, this must match ContainerPort. Most containers do
+      # not need this.
+      hostPort: 1
+      # If specified, this must be an IANA_SVC_NAME and unique within
+      # the pod. Each named port in a pod must have a unique name. Name
+      # for the port that can be referred to by services.
+      name: string
+      # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+      # to "TCP".
+      protocol: "TCP"
+    # The Ingress Endpoint that GAdmin will be running on.
+    ingressPath:
+      # backend defines the referenced service endpoint to which the
+      # traffic will be forwarded to.
+      backend:
+        # resource is an ObjectRef to another Kubernetes resource in the
+        # namespace of the Ingress object. If resource is specified,
+        # serviceName and servicePort must not be specified.
+        resource:
+          # APIGroup is the group for the resource being referenced. If
+          # APIGroup is not specified, the specified Kind must be in
+          # the core API group. For any other third-party types,
+          # APIGroup is required.
+          apiGroup: string
+          # Kind is the type of resource being referenced
+          kind: KineticaCluster
+          # Name is the name of resource being referenced
+          name: string
+        # serviceName specifies the name of the referenced service.
+        serviceName: string
+        # servicePort Specifies the port of the referenced service.
+        servicePort: 
+      # path is matched against the path of an incoming request.
+      # Currently it can contain characters disallowed from the
+      # conventional "path" part of a URL as defined by RFC 3986. Paths
+      # must begin with a '/' and must be present when using PathType
+      # with value "Exact" or "Prefix".
+      path: string
+      # pathType determines the interpretation of the path matching.
+      # PathType can be one of the following values: * Exact: Matches
+      # the URL path exactly. * Prefix: Matches based on a URL path
+      # prefix split by '/'. Matching is done on a path element by
+      # element basis. A path element refers is the list of labels in
+      # the path split by the '/' separator. A request is a match for
+      # path p if every p is an element-wise prefix of p of the request
+      # path. Note that if the last element of the path is a substring
+      # of the last element in request path, it is not a match
+      # (e.g. /foo/bar matches /foo/bar/baz, but does not
+      # match /foo/barbaz). * ImplementationSpecific: Interpretation of
+      # the Path matching is up to the IngressClass. Implementations
+      # can treat this as a separate PathType or treat it identically
+      # to Prefix or Exact path types. Implementations are required to
+      # support all path types. Defaults to ImplementationSpecific.
+      pathType: string
+    # Whether to enable the GAdmin Dashboard on the Cluster. Default:
+    # true
+    isEnabled: true
+  # Gaia - gaia.properties configuration
+  gaia: admin:
+      # AdminLoginOnlyGpudbDown - When GPUdb is down, only allow admin
+      # user to login
+      admin_login_only_gpudb_down: true
+      # Username - We do check for admin username in various places
+      admin_username: "admin"
+      # LoginAnimationEnabled - Display any animation in login page
+      login_animation_enabled: true
+      # AdminLoginOnlyGpudbDown - Convenience settings for dev mode
+      login_bypass_enabled: false
+      # RequireStrongPassword - Convenience settings for dev mode
+      require_strong_password: true
+      # SSLTruststorePasswordScript - Display any animation in login
+      # page
+      ssl_truststore_password_script: string
+    # DemoSchema - Schema-related configuration
+    demo_schema: "demo" gpudb:
+      # DataFileStringNullValue - Table import/export null value string
+      data_file_string_null_value: "\\N"
+      gpudb_ext_url: "http://127.0.0.1:8082/gpudb-0"
+      # URL - Current instance of gpudb, when running in HA mode change
+      # this to load balancer endpoint
+      gpudb_url: "http://127.0.0.1:9191"
+      # LoggingLogFileName - Which file to use when displaying logging
+      # on Cluster page.
+      logging_log_file_name: "gpudb.log"
+      # SampleRepoURL - Table import/export null value string
+      sample_repo_url: "//s3.amazonaws.com/kinetica-ce-data" hm:
+      gpudb_ext_hm_url: "http://127.0.0.1:8082/gpudb-host-manager"
+      gpudb_hm_url: "http://127.0.0.1:9300" http:
+      # ClientTimeout - Number of seconds for proxy request timeout
+      http_client_timeout: 3600
+      # ClientTimeoutV2 - Force override of previous default with 0 as
+      # infinite timeout
+      http_client_timeout_v2: 0
+      # TomcatPathKey - Name of folder where Tomcat apps are installed
+      tomcat_path_key: "tomcat"
+      # WebappContext - Web App context
+      webapp_context: "gadmin"
+    # GAdminIsRemote - True if the gadmin application is running on a
+    # remote machine (not on same node as gpudb). If running on a
+    # remote machine the manage options will be disabled.
+    is_remote: false
+    # KAgentCLIPath - Schema-related configuration
+    kagent_cli_path: "/opt/gpudb/kagent/bin/kagent"
+    # KIO - KIO-related configuration
+    kio: kio_log_file_path: "/opt/gpudb/kitools/kio/logs/gadmin.log"
+    kio_log_level: "DEBUG" kio_log_size_limit: 10485760 kisql:
+      # QueryResultsLimit - KiSQL limit on the number of results in each
+      # query
+      kisql_query_results_limit: 10000
+      # QueryTimezone - KiSQL TimeZoneId setting for queries
+      # (use "system" for local system time)
+      kisql_query_timezone: "GMT" license:
+      # Status - Stub for license manager
+      status: "ok"
+      # Type - Stub for license manager
+      type: "unlimited"
+    # MaxConcurrentUserSessions - Session management configuration
+    max_concurrent_user_sessions: 0
+    # PublicSchema - Schema-related configuration
+    public_schema: "ki_home"
+    # RevealDBInfoFile - Path to file containing Reveal DB location
+    reveal_db_info_file: "/opt/gpudb/connectors/reveal/var/REVEAL_DB_DIR"
+    # RootSchema - Schema-related configuration
+    root_schema: "root" stats:
+      # GraphanaURL -
+      graphana_url: "http://127.0.0.1:3000"
+      # GraphiteURL
+      graphite_url: "http://127.0.0.1:8181"
+      # StatsGrafanaURL - Port used to host the Grafana user interface
+      # and embeddable metric dashboards in GAdmin. Note: If this value
+      # is defaulted then it will be replaced by the name of the Stats
+      # service if it is deployed & Grafana is enabled e.g.
+      # cluster-1234.gpudb.svc.cluster.local
+      stats_grafana_url: "http://127.0.0.1:9091"
+  # https://github.com/kubernetes-sigs/controller-tools/issues/622 if we
+  # want to set usePools as false, need to set defaults GPUDBCluster is
+  # an instance of a Kinetica DB Cluster i.e. it's StatefulSet,
+  # Service, Ingress, ConfigMap etc.
+  gpudbCluster:
+    # Affinity - is a group of affinity scheduling rules.
+    affinity:
+      # Describes node affinity scheduling rules for the pod.
+      nodeAffinity:
+        # The scheduler will prefer to schedule pods to nodes that
+        # satisfy the affinity expressions specified by this field, but
+        # it may choose a node that violates one or more of the
+        # expressions. The node that is most preferred is the one with
+        # the greatest sum of weights, i.e. for each node that meets
+        # all of the scheduling requirements (resource request,
+        # requiredDuringScheduling affinity expressions, etc.), compute
+        # a sum by iterating through the elements of this field and
+        # adding "weight" to the sum if the node matches the
+        # corresponding matchExpressions; the node(s) with the highest
+        # sum are the most preferred.
+        preferredDuringSchedulingIgnoredDuringExecution:
+        - preference:
+            # A list of node selector requirements by node's labels.
+            matchExpressions:
+            - key: string
+              # Represents a key's relationship to a set of values.
+              # Valid operators are In, NotIn, Exists, DoesNotExist.
+              # Gt, and Lt.
+              operator: string
+              # An array of string values. If the operator is In or
+              # NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. If the operator is Gt or Lt, the values
+              # array must have a single element, which will be
+              # interpreted as an integer. This array is replaced
+              # during a strategic merge patch.
+              values: ["string"]
+            # A list of node selector requirements by node's fields.
+            matchFields:
+            - key: string
+              # Represents a key's relationship to a set of values.
+              # Valid operators are In, NotIn, Exists, DoesNotExist.
+              # Gt, and Lt.
+              operator: string
+              # An array of string values. If the operator is In or
+              # NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. If the operator is Gt or Lt, the values
+              # array must have a single element, which will be
+              # interpreted as an integer. This array is replaced
+              # during a strategic merge patch.
+              values: ["string"]
+          # Weight associated with matching the corresponding
+          # nodeSelectorTerm, in the range 1-100.
+          weight: 1
+        # If the affinity requirements specified by this field are not
+        # met at scheduling time, the pod will not be scheduled onto
+        # the node. If the affinity requirements specified by this
+        # field cease to be met at some point during pod execution
+        # (e.g. due to an update), the system may or may not try to
+        # eventually evict the pod from its node.
+        requiredDuringSchedulingIgnoredDuringExecution:
+          # Required. A list of node selector terms. The terms are
+          # ORed.
+          nodeSelectorTerms:
+          - matchExpressions:
+            - key: string
+              # Represents a key's relationship to a set of values.
+              # Valid operators are In, NotIn, Exists, DoesNotExist.
+              # Gt, and Lt.
+              operator: string
+              # An array of string values. If the operator is In or
+              # NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. If the operator is Gt or Lt, the values
+              # array must have a single element, which will be
+              # interpreted as an integer. This array is replaced
+              # during a strategic merge patch.
+              values: ["string"]
+            # A list of node selector requirements by node's fields.
+            matchFields:
+            - key: string
+              # Represents a key's relationship to a set of values.
+              # Valid operators are In, NotIn, Exists, DoesNotExist.
+              # Gt, and Lt.
+              operator: string
+              # An array of string values. If the operator is In or
+              # NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. If the operator is Gt or Lt, the values
+              # array must have a single element, which will be
+              # interpreted as an integer. This array is replaced
+              # during a strategic merge patch.
+              values: ["string"]
+      # Describes pod affinity scheduling rules (e.g. co-locate this pod
+      # in the same node, zone, etc. as some other pod(s)).
+      podAffinity:
+        # The scheduler will prefer to schedule pods to nodes that
+        # satisfy the affinity expressions specified by this field, but
+        # it may choose a node that violates one or more of the
+        # expressions. The node that is most preferred is the one with
+        # the greatest sum of weights, i.e. for each node that meets
+        # all of the scheduling requirements (resource request,
+        # requiredDuringScheduling affinity expressions, etc.), compute
+        # a sum by iterating through the elements of this field and
+        # adding "weight" to the sum if the node has pods which matches
+        # the corresponding podAffinityTerm; the node(s) with the
+        # highest sum are the most preferred.
+        preferredDuringSchedulingIgnoredDuringExecution:
+        - podAffinityTerm:
+            # A label query over a set of resources, in this case pods.
+            labelSelector:
+              # matchExpressions is a list of label selector
+              # requirements. The requirements are ANDed.
+              matchExpressions:
+              - key: string
+                # operator represents a key's relationship to a set of
+                # values. Valid operators are In, NotIn, Exists and
+                # DoesNotExist.
+                operator: string
+                # values is an array of string values. If the operator
+                # is In or NotIn, the values array must be non-empty.
+                # If the operator is Exists or DoesNotExist, the values
+                # array must be empty. This array is replaced during a
+                # strategic merge patch.
+                values: ["string"]
+              # matchLabels is a map of {key,value} pairs. A single
+              # {key,value} in the matchLabels map is equivalent to an
+              # element of matchExpressions, whose key field is "key",
+              # the operator is "In", and the values array contains
+              # only "value". The requirements are ANDed.
+              matchLabels: {}
+            # A label query over the set of namespaces that the term
+            # applies to. The term is applied to the union of the
+            # namespaces selected by this field and the ones listed in
+            # the namespaces field. null selector and null or empty
+            # namespaces list means "this pod's namespace". An empty
+            # selector ({}) matches all namespaces.
+            namespaceSelector:
+              # matchExpressions is a list of label selector
+              # requirements. The requirements are ANDed.
+              matchExpressions:
+              - key: string
+                # operator represents a key's relationship to a set of
+                # values. Valid operators are In, NotIn, Exists and
+                # DoesNotExist.
+                operator: string
+                # values is an array of string values. If the operator
+                # is In or NotIn, the values array must be non-empty.
+                # If the operator is Exists or DoesNotExist, the values
+                # array must be empty. This array is replaced during a
+                # strategic merge patch.
+                values: ["string"]
+              # matchLabels is a map of {key,value} pairs. A single
+              # {key,value} in the matchLabels map is equivalent to an
+              # element of matchExpressions, whose key field is "key",
+              # the operator is "In", and the values array contains
+              # only "value". The requirements are ANDed.
+              matchLabels: {}
+            # namespaces specifies a static list of namespace names that
+            # the term applies to. The term is applied to the union of
+            # the namespaces listed in this field and the ones selected
+            # by namespaceSelector. null or empty namespaces list and
+            # null namespaceSelector means "this pod's namespace".
+            namespaces: ["string"]
+            # This pod should be co-located (affinity) or not
+            # co-located (anti-affinity) with the pods matching the
+            # labelSelector in the specified namespaces, where
+            # co-located is defined as running on a node whose value of
+            # the label with key topologyKey matches that of any node
+            # on which any of the selected pods is running. Empty
+            # topologyKey is not allowed.
+            topologyKey: string
+          # weight associated with matching the corresponding
+          # podAffinityTerm, in the range 1-100.
+          weight: 1
+        # If the affinity requirements specified by this field are not
+        # met at scheduling time, the pod will not be scheduled onto
+        # the node. If the affinity requirements specified by this
+        # field cease to be met at some point during pod execution
+        # (e.g. due to a pod label update), the system may or may not
+        # try to eventually evict the pod from its node. When there are
+        # multiple elements, the lists of nodes corresponding to each
+        # podAffinityTerm are intersected, i.e. all terms must be
+        # satisfied.
+        requiredDuringSchedulingIgnoredDuringExecution:
+        - labelSelector:
+            # matchExpressions is a list of label selector requirements.
+            # The requirements are ANDed.
+            matchExpressions:
+            - key: string
+              # operator represents a key's relationship to a set of
+              # values. Valid operators are In, NotIn, Exists and
+              # DoesNotExist.
+              operator: string
+              # values is an array of string values. If the operator is
+              # In or NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. This array is replaced during a
+              # strategic merge patch.
+              values: ["string"]
+            # matchLabels is a map of {key,value} pairs. A single
+            # {key,value} in the matchLabels map is equivalent to an
+            # element of matchExpressions, whose key field is "key",
+            # the operator is "In", and the values array contains
+            # only "value". The requirements are ANDed.
+            matchLabels: {}
+          # A label query over the set of namespaces that the term
+          # applies to. The term is applied to the union of the
+          # namespaces selected by this field and the ones listed in
+          # the namespaces field. null selector and null or empty
+          # namespaces list means "this pod's namespace". An empty
+          # selector ({}) matches all namespaces.
+          namespaceSelector:
+            # matchExpressions is a list of label selector requirements.
+            # The requirements are ANDed.
+            matchExpressions:
+            - key: string
+              # operator represents a key's relationship to a set of
+              # values. Valid operators are In, NotIn, Exists and
+              # DoesNotExist.
+              operator: string
+              # values is an array of string values. If the operator is
+              # In or NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. This array is replaced during a
+              # strategic merge patch.
+              values: ["string"]
+            # matchLabels is a map of {key,value} pairs. A single
+            # {key,value} in the matchLabels map is equivalent to an
+            # element of matchExpressions, whose key field is "key",
+            # the operator is "In", and the values array contains
+            # only "value". The requirements are ANDed.
+            matchLabels: {}
+          # namespaces specifies a static list of namespace names that
+          # the term applies to. The term is applied to the union of
+          # the namespaces listed in this field and the ones selected
+          # by namespaceSelector. null or empty namespaces list and
+          # null namespaceSelector means "this pod's namespace".
+          namespaces: ["string"]
+          # This pod should be co-located (affinity) or not co-located
+          # (anti-affinity) with the pods matching the labelSelector in
+          # the specified namespaces, where co-located is defined as
+          # running on a node whose value of the label with key
+          # topologyKey matches that of any node on which any of the
+          # selected pods is running. Empty topologyKey is not
+          # allowed.
+          topologyKey: string
+      # Describes pod anti-affinity scheduling rules (e.g. avoid putting
+      # this pod in the same node, zone, etc. as some other pod(s)).
+      podAntiAffinity:
+        # The scheduler will prefer to schedule pods to nodes that
+        # satisfy the anti-affinity expressions specified by this
+        # field, but it may choose a node that violates one or more of
+        # the expressions. The node that is most preferred is the one
+        # with the greatest sum of weights, i.e. for each node that
+        # meets all of the scheduling requirements (resource request,
+        # requiredDuringScheduling anti-affinity expressions, etc.),
+        # compute a sum by iterating through the elements of this field
+        # and adding "weight" to the sum if the node has pods which
+        # matches the corresponding podAffinityTerm; the node(s) with
+        # the highest sum are the most preferred.
+        preferredDuringSchedulingIgnoredDuringExecution:
+        - podAffinityTerm:
+            # A label query over a set of resources, in this case pods.
+            labelSelector:
+              # matchExpressions is a list of label selector
+              # requirements. The requirements are ANDed.
+              matchExpressions:
+              - key: string
+                # operator represents a key's relationship to a set of
+                # values. Valid operators are In, NotIn, Exists and
+                # DoesNotExist.
+                operator: string
+                # values is an array of string values. If the operator
+                # is In or NotIn, the values array must be non-empty.
+                # If the operator is Exists or DoesNotExist, the values
+                # array must be empty. This array is replaced during a
+                # strategic merge patch.
+                values: ["string"]
+              # matchLabels is a map of {key,value} pairs. A single
+              # {key,value} in the matchLabels map is equivalent to an
+              # element of matchExpressions, whose key field is "key",
+              # the operator is "In", and the values array contains
+              # only "value". The requirements are ANDed.
+              matchLabels: {}
+            # A label query over the set of namespaces that the term
+            # applies to. The term is applied to the union of the
+            # namespaces selected by this field and the ones listed in
+            # the namespaces field. null selector and null or empty
+            # namespaces list means "this pod's namespace". An empty
+            # selector ({}) matches all namespaces.
+            namespaceSelector:
+              # matchExpressions is a list of label selector
+              # requirements. The requirements are ANDed.
+              matchExpressions:
+              - key: string
+                # operator represents a key's relationship to a set of
+                # values. Valid operators are In, NotIn, Exists and
+                # DoesNotExist.
+                operator: string
+                # values is an array of string values. If the operator
+                # is In or NotIn, the values array must be non-empty.
+                # If the operator is Exists or DoesNotExist, the values
+                # array must be empty. This array is replaced during a
+                # strategic merge patch.
+                values: ["string"]
+              # matchLabels is a map of {key,value} pairs. A single
+              # {key,value} in the matchLabels map is equivalent to an
+              # element of matchExpressions, whose key field is "key",
+              # the operator is "In", and the values array contains
+              # only "value". The requirements are ANDed.
+              matchLabels: {}
+            # namespaces specifies a static list of namespace names that
+            # the term applies to. The term is applied to the union of
+            # the namespaces listed in this field and the ones selected
+            # by namespaceSelector. null or empty namespaces list and
+            # null namespaceSelector means "this pod's namespace".
+            namespaces: ["string"]
+            # This pod should be co-located (affinity) or not
+            # co-located (anti-affinity) with the pods matching the
+            # labelSelector in the specified namespaces, where
+            # co-located is defined as running on a node whose value of
+            # the label with key topologyKey matches that of any node
+            # on which any of the selected pods is running. Empty
+            # topologyKey is not allowed.
+            topologyKey: string
+          # weight associated with matching the corresponding
+          # podAffinityTerm, in the range 1-100.
+          weight: 1
+        # If the anti-affinity requirements specified by this field are
+        # not met at scheduling time, the pod will not be scheduled
+        # onto the node. If the anti-affinity requirements specified by
+        # this field cease to be met at some point during pod
+        # execution (e.g. due to a pod label update), the system may or
+        # may not try to eventually evict the pod from its node. When
+        # there are multiple elements, the lists of nodes corresponding
+        # to each podAffinityTerm are intersected, i.e. all terms must
+        # be satisfied.
+        requiredDuringSchedulingIgnoredDuringExecution:
+        - labelSelector:
+            # matchExpressions is a list of label selector requirements.
+            # The requirements are ANDed.
+            matchExpressions:
+            - key: string
+              # operator represents a key's relationship to a set of
+              # values. Valid operators are In, NotIn, Exists and
+              # DoesNotExist.
+              operator: string
+              # values is an array of string values. If the operator is
+              # In or NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. This array is replaced during a
+              # strategic merge patch.
+              values: ["string"]
+            # matchLabels is a map of {key,value} pairs. A single
+            # {key,value} in the matchLabels map is equivalent to an
+            # element of matchExpressions, whose key field is "key",
+            # the operator is "In", and the values array contains
+            # only "value". The requirements are ANDed.
+            matchLabels: {}
+          # A label query over the set of namespaces that the term
+          # applies to. The term is applied to the union of the
+          # namespaces selected by this field and the ones listed in
+          # the namespaces field. null selector and null or empty
+          # namespaces list means "this pod's namespace". An empty
+          # selector ({}) matches all namespaces.
+          namespaceSelector:
+            # matchExpressions is a list of label selector requirements.
+            # The requirements are ANDed.
+            matchExpressions:
+            - key: string
+              # operator represents a key's relationship to a set of
+              # values. Valid operators are In, NotIn, Exists and
+              # DoesNotExist.
+              operator: string
+              # values is an array of string values. If the operator is
+              # In or NotIn, the values array must be non-empty. If the
+              # operator is Exists or DoesNotExist, the values array
+              # must be empty. This array is replaced during a
+              # strategic merge patch.
+              values: ["string"]
+            # matchLabels is a map of {key,value} pairs. A single
+            # {key,value} in the matchLabels map is equivalent to an
+            # element of matchExpressions, whose key field is "key",
+            # the operator is "In", and the values array contains
+            # only "value". The requirements are ANDed.
+            matchLabels: {}
+          # namespaces specifies a static list of namespace names that
+          # the term applies to. The term is applied to the union of
+          # the namespaces listed in this field and the ones selected
+          # by namespaceSelector. null or empty namespaces list and
+          # null namespaceSelector means "this pod's namespace".
+          namespaces: ["string"]
+          # This pod should be co-located (affinity) or not co-located
+          # (anti-affinity) with the pods matching the labelSelector in
+          # the specified namespaces, where co-located is defined as
+          # running on a node whose value of the label with key
+          # topologyKey matches that of any node on which any of the
+          # selected pods is running. Empty topologyKey is not
+          # allowed.
+          topologyKey: string
+    # Annotations - Annotations labels to be applied to the Statefulset
+    # DB pods.
+    annotations: {}
+    # The name of the cluster to form.
+    clusterName: string
+    # The Ingress Endpoint that GAdmin will be running on.
+    clusterSize:
+      # ClusterSizeEnum - T-Shirt size of the Kinetica DB Cluster i.e. a
+      # representation of the number of nodes in a simple to understand
+      # T-Short size scheme. This indicates the size of the cluster
+      # i.e. the number of nodes. It does not identify the size of the
+      # cloud provider nodes. For node size see ClusterTypeEnum.
+      # Supported Values are: - XS S M L XL XXL XXXL
+      tshirtSize: string
+      # ClusterTypeEnum - An Enum of the node types of a KineticaCluster
+      # e.g. CPU, GPU along with the Cloud Provider node size e.g. size
+      # of the VM.
+      tshirtType: string
+    # Config Kinetica DB Configuration Object
+    config: ai: apiKey: string
+        # Provider - AI API provider type. The default is "sqlgpt"
+        apiProvider: "sqlgpt" apiUrl: string
+      # AlertManagerConfig
+      alertManager:
+        # AlertManager IP address (run on head node) default port
+        # is "2003"
+        ipAddress: "${gaia.host0.address}" port: 2003
+      # AlertConfig
+      alerts: alertDiskAbsolute: [integer]
+        # Trigger an alert if available disk space on any given node
+        # falls to or below a certain threshold, either absolute
+        # (number of bytes) or percentage of total disk space. For
+        # multiple thresholds, use a comma-delimited list of values.
+        alertDiskPercentage: [1,5,10,20]
+        # Trigger generic error message alerts, in cases of various
+        # significant runtime errors.
+        alertErrorMessages: true
+        # Executable to run when an alert condition occurs. This
+        # executable will only be run on **rank0** and does not need to
+        # be present on other nodes.
+        alertExe: ""
+        # Trigger an alert whenever the status of a host or rank
+        # changes.
+        alertHostStatus: true
+        # Optionally, filter host alerts for a comma-delimited list of
+        # statuses. If a filter is empty, every host status change will
+        # trigger an alert.
+        alertHostStatusFilter: "fatal_init_error"
+        # The maximum number of triggered alerts guaranteed to be stored
+        # at any given time. When this number of alerts is exceeded,
+        # older alerts may be discarded to stay within the limit.
+        alertMaxStoredAlerts: 100 alertMemoryAbsolute: [integer]
+        # Trigger an alert if available memory on any given node falls
+        # to or below a certain threshold, either absolute (number of
+        # bytes) or percentage of total memory. For multiple
+        # thresholds, use a comma-delimited list of values.
+        alertMemoryPercentage: [1,5,10,20]
+        # Trigger an alert if a CUDA error occurs on a rank.
+        alertRankCudaError: true
+        # Trigger alerts when the fallback allocator is employed; e.g.,
+        # host memory is allocated because GPU allocation fails. NOTE:
+        # To prevent a flooding of alerts, if a fallback allocator is
+        # triggered in bursts, not every use will generate an alert.
+        alertRankFallbackAllocator: true
+        # Trigger an alert whenever the status of a rank changes.
+        alertRankStatus: true
+        # Optionally, filter rank alerts for a comma-delimited list of
+        # statuses. If a filter is empty, every rank status change will
+        # trigger an alert.
+        alertRankStatusFilter:
+        ["fatal_init_error","not_responding","terminated"]
+        # Enable the alerting system.
+        enableAlerts: true
+        # Directory where the trace event and summary files are stored.
+        # Must be a fully qualified path with sufficient free space for
+        # required volume of data.
+        traceDirectory: "/tmp"
+        # The maximum number of trace events to be collected
+        traceEventBufferSize: 1000000
+      # Audit - This section controls the request auditor, which will
+      # audit all requests received by the server in full or in part
+      # based on the settings.
+      audit:
+        # Controls whether the body of each request is audited (in JSON
+        # format). If 'enable_audit' is "false" this setting has no
+        # effect. NOTE: For requests that insert data records, this
+        # setting does not control the auditing of the records being
+        # inserted, only the rest of the request body; see 'audit_data'
+        # below to control this. audit_body = false
+        body: false
+        # Controls whether records being inserted are audited (in JSON
+        # format) for requests that insert data records. If
+        # either 'enable_audit' or 'audit_body' is "false", this
+        # setting has no effect. NOTE: Enabling this setting during
+        # bulk ingestion of data will rapidly produce very large audit
+        # logs and may cause disk space exhaustion; use with caution.
+        # audit_data = false
+        data: false
+        # Controls whether request auditing is enabled. If set
+        # to "true", the following information is audited for every
+        # request: Job ID, URI, User, and Client Address. The settings
+        # below control whether additional information about each
+        # request is also audited. If set to "false", all auditing is
+        # disabled. enable_audit = false
+        enable: false
+        # Controls whether HTTP headers are audited for each request.
+        # If 'enable_audit' is "false" this setting has no effect.
+        # audit_headers = false
+        headers: true
+        # Controls whether the above audit settings can be altered at
+        # runtime via the /alter/system/properties endpoint. In a
+        # secure environment where auditing is required at all times,
+        # this should be set to "true" to lock the settings to what is
+        # set in this file. lock_audit = false
+        lock: false
+        # Controls whether response information is audited for each
+        # request. If 'enable_audit' is "false" this setting has no
+        # effect. audit_response = false
+        response: false
+      # EventConfig
+      events:
+        # Run a statistics server to collect information about Kinetica
+        # and the machines it runs on.
+        internal: true
+        # Statistics server IP address (run on head node) default port
+        # is "2003"
+        ipAddress: "${gaia.host0.address}" port: 2003
+        # Statistics server namespace - should be a machine identifier
+        statsServerNamespace: "gpudb"
+      # ExternalFilesConfig
+      externalFiles:
+        # Defines the directory from which external files can be loaded
+        directory: "/opt/gpudb/persist"
+        # # Parquet files compression type egress_parquet_compression =
+        #   snappy
+        egressParquetCompression: "snappy"
+        # Max file size (in MB) to allow saving to a single file. May be
+        # overridden by target limitations. egress_single_file_max_size
+        # = 100
+        egressSingleFileMaxSize: "100"
+        # Maximum number of simultaneous threads allocated to a given
+        # external file read request, on each rank. Note that thread
+        # allocation may also be limited by resource group limits, the
+        # subtask_concurrency_limit setting, or system load.
+        readerNumTasks: "-1"
+      # GeneralConfig - the root of the gpudb.conf configuration in the
+      # CRD
+      general:
+        # Timeout (in seconds) to wait for a rank to start during a
+        # cluster event (ex: failover) event is considered failed.
+        clusterEventTimeoutStartupRank: "300"
+        # Enable (if "true") multiple kernels to run concurrently on the
+        # same GPU
+        concurrentKernelExecution: true
+        # Time-to-live in minutes of non-protected tables before they
+        # are automatically deleted from the database.
+        defaultTTL: "20"
+        # Disallow the /clear/table request to clear all tables.
+        disableClearAll: true
+        # Enable overlapped-equi-join filters
+        enableOverlappedEquiJoin: true
+        # Enable predicate-equi-join filter plan type
+        enablePredicateEquiJoin: true
+        # If "true" then all filter execution will be host-only
+        # (i.e. CPU). This can be useful for high-concurrency
+        # situations and when PCIe bandwidth is a limiting factor.
+        forceHostFilterExecution: false
+        # Maximum number of kernels that can be running at the same time
+        # on a given GPU. Set to "0" for no limit. Only takes effect
+        # if 'concurrent_kernel_execution' is "true"
+        maxConcurrentKernels: "0"
+        # Maximum number of records that data retrieval requests such
+        # as /get/records and /aggregate/groupby will return per
+        # request.
+        maxGetRecordsSize: 20000
+        # Set an optional executable command that will be run once when
+        # Kinetica is ready for client requests. This can be used to
+        # perform any initialization logic that needs to be run before
+        # clients connect. It will be run as the "gpudb" user, so you
+        # must ensure that any required permissions are set on the file
+        # to allow it to be executed.  If the command cannot be
+        # executed or returns a non-zero error code, then Kinetica will
+        # be stopped.  Output from the startup script will be logged
+        # to "/opt/gpudb/core/logs/gpudb-on-start.log" (and its dated
+        # relatives).  The "gpudb_env.sh" script is run directly before
+        # the command, so the path will be set to include the supplied
+        # Python runtime. Example: on_startup_script
+        # = /home/gpudb/on-start.sh param1 param2 ...
+        onStartupScript: ""
+        # Size in bytes of the pinned memory pool per-rank process to
+        # speed up copying data to the GPU.  Set to "0" to disable.
+        pinnedMemoryPoolSize: 2000000000
+        # Tables and collections with these names will not be deleted
+        # (comma separated).
+        protectedSets: "MASTER,_MASTER,_DATASOURCE"
+        # Timeout (in minutes) for filter-type requests
+        requestTimeout: "20"
+        # Timeout (in seconds) to wait for a rank to exit gracefully
+        # before it is force-killed. Machines with slow disk drives may
+        # require longer times and data may be lost if a drive is not
+        # responsive.
+        timeoutShutdownRank: "300"
+        # Timeout (in seconds) to wait for each database subsystem to
+        # exit gracefully before it is force-killed.
+        timeoutShutdownSubsystem: "20"
+        # Timeout (in seconds) to wait for each database subsystem to
+        # startup. Subsystems include the Query Planner, Graph,
+        # Stats, & HTTP servers, as well as external text-search
+        # ranks.
+        timeoutStartupSubsystem: "60"
+      # GraphConfig
+      graph:
+        # Enable the graph server
+        enable: false
+        # List of GPU devices to be used by graph server The server
+        # would ideally be run on a different node with dedicated GPU
+        # (s)
+        gpuList: ""
+        # Specify where the graph server should be run, defaults to head
+        # node
+        ipAddress: "${gaia.rank0_ip_address}"
+        # Maximum memory that can be used by the graph server, set
+        # to "0" to disable memory restriction
+        maxMemory: 0
+        # Port used for responses from the graph server to the database
+        # server
+        pullPort: 8100
+        # Port used for requests from the database server to the graph
+        # server
+        pushPort: 8099
+        # Number of seconds the graph client will wait for a response
+        # from the graph server
+        timeout: 1200
+      # HardwareConfig
+      hardware:
+        # Rank0HardwareConfig
+        rank0:
+          # Specify the GPU to use for all calculations on the HTTP
+          # server node, **rank0**. NOTE: The **rank0** GPU may be
+          # shared with another rank.
+          gpu: 0
+          # Set the head HTTP **rank0** numa node(s). If left empty,
+          # there will be no thread affinity or preferred memory node.
+          # The node list may be either a single node number or a
+          # range; e.g., "1-5,7,10". If there will be many simultaneous
+          # users, specify as many nodes as possible that won't overlap
+          # the **rank1** to **rankN** worker numa nodes that the GPUs
+          # are on. If there will be few simultaneous users and WMS
+          # speed is important, choose the numa node the 'rank0.gpu' is
+          # on.
+          numaNode: ranks:
+        - baseNumaNode: string
+          # Set each worker rank's preferred data numa node for CPU
+          # affinity and memory allocation.
+          # The 'rank<#>.data_numa_node' is the node or nodes that data
+          # intensive threads will run in and should be set to the same
+          # numa node that the GPU specified by the
+          # corresponding 'rank<#>.taskcalc_gpu' is on for best
+          # performance. If the 'rank<#>.taskcalc_gpu' is specified
+          # the 'rank<#>.data_numa_node' will be automatically set to
+          # the node the GPU is attached to, otherwise there will be no
+          # CPU thread affinity or preferred node for memory allocation
+          # if not specified or left empty. The node list may be a
+          # single node number or a range; e.g., "1-5,7,10".
+          dataNumaNode: string
+          # Set the GPU device for each worker rank to use. If no GPUs
+          # are specified, each rank will round-robin the available
+          # GPUs per host system. Add 'rank<#>.taskcalc_gpu' as needed
+          # for the worker ranks, where *#* ranges from "1" to the
+          # highest *rank #* among the 'rank<#>.host' parameters
+          # Example setting the GPUs to use for ranks 1 and 2: 
+          #  #   rank1.taskcalc_gpu = 0 #   rank2.taskcalc_gpu = 1
+          taskCalcGPU: kafka:
+        # Maximum number of records to be ingested in a single batch
+        # kafka.batch_size = 1000
+        batchSize: 1000
+        # Maximum time (milliseconds) for each poll to get records from
+        # kafka kafka.poll_timeout = 0
+        pollTimeout: 1
+        # Maximum wait time (seconds) to buffer records received from
+        # kafka before ingestion kafka.wait_time = 30
+        waitTime: 30
+      # KifsConfig
+      kifs:
+        # KIFs user data size limit
+        dataLimit: "4Gi"
+        # sudo usermod -a -G gpudb_proc <user>
+        enable: false
+        # Parent directory of the mount point for the KiFS file system.
+        # Must be a fully qualified path. The actual mount point will
+        # be a subdirectory *mount* below this directory. Note that
+        # this folder must have read, write and execute permissions for
+        # the "gpudb" user and the "gpudb_proc" group, and it cannot be
+        # a path on an NFS.
+        mountPoint: "/gpudb/kifs" useManagedCredentials: true
+      # Etcd *ETCDConfig `json:"etcd,omitempty"` HA        HAConfig
+      # `json:"ha,omitempty"`
+      ml:
+        # Enable the ML server.
+        enable: false
+      # NetworkConfig
+      network:
+        # HAAddress - An optional address to allow inter-cluster
+        # communication with HA when 'address' is not routable between
+        # clusters.
+        HAAddress: string
+        # CompressNetworkData - Enables compression of inter-node
+        # network data transfers.
+        compressNetworkData: false
+        # EnableHTTPDProxy - Start an HTTP server as a proxy to handle
+        # LDAP and/or Kerberos authentication. Each host will run an
+        # HTTP server and access to each rank is available through
+        # http://host:8082/gpudb-1, where port "8082" is defined
+        # by 'httpd_proxy_port'. NOTE: HTTP external endpoints are not
+        # affected by the 'use_https' parameter above. If you wish to
+        # enable HTTPS, you must edit
+        # the "/opt/gpudb/httpd/conf/httpd.conf" and setup HTTPS as per
+        # the Apache httpd documentation at
+        # https://httpd.apache.org/docs/2.2/
+        enableHTTPDProxy: true
+        # EnableWorkerHTTPServers - Enable worker HTTP servers; each
+        # process runs its own server for multi-head ingest.
+        enableWorkerHTTPServers: true
+        # GlobalManagerLocalPubPort - ?
+        globalManagerLocalPubPort: 5554
+        # GlobalManagerPortOne - Internal communication ports -  Host
+        # manager status notification channel
+        globalManagerPortOne: 5552
+        # GlobalManagerPubPort - Host manager synchronization message
+        # publishing channel port
+        globalManagerPubPort: 5553
+        # HeadIPAddress - Head HTTP server IP address. Set to the
+        # publicly accessible IP address of the first
+        # process, **rank0**.
+        headIPAddress: "172.20.0.10"
+        # HeadPort - Head HTTP server port to use
+        # for 'head_ip_address'.
+        headPort: 9191
+        # HostManagerHTTPPort - HTTP port for web portal of the host
+        # manager
+        hostManagerHTTPPort: 9300
+        # HTTPAllowOrigin - Value to return via
+        # Access-Control-Allow-Origin HTTP header (for Cross-Origin
+        # Resource Sharing). Set to empty to not return the header and
+        # disallow CORS.
+        httpAllowOrigin: "*"
+        # HTTPKeepAlive - Keep HTTP connections alive between requests
+        httpKeepAlive: false
+        # HTTPDProxyPort - TCP port that the httpd auth proxy server
+        # will listen on if 'enable_httpd_proxy' is "true".
+        httpdProxyPort: 8082
+        # HTTPDProxyUseHTTPS - Set to "true" if the httpd auth proxy
+        # server is configured to use HTTPS.
+        httpdProxyUseHTTPS: false
+        # HTTPSCertFile - File containing the SSL certificate  e.g.
+        # cert.pem If required, a self-signed certificate(expires after
+        # 10 years) can be generated via the command: e.g. cert.pem
+        # openssl req -newkey rsa:2048 -new -nodes -x509 \ -days
+        # 3650 -keyout key.pem -out cert.pem
+        httpsCertFile: ""
+        # HTTPSKeyFile - File containing the SSL private Key e.g.
+        # key.pem If required, a self-signed certificate (expires after
+        # 10 years) can be generated via the command: openssl
+        # req -newkey rsa:2048 -new -nodes -x509 \ -days 3650 -keyout
+        # key.pem -out cert.pem
+        httpsKeyFile: ""
+        # Rank0IPAddress - Internal use IP address of the head HTTP
+        # server, **rank0**. Set to either a second internal network
+        # accessible by all ranks or to '${gaia.head_ip_address}'.
+        rank0IPAddress: "${gaia.rank0.host}" ranks:
+        - communicatorPort:
+            # Number of port to expose on the pod's IP address. This
+            # must be a valid port number, 0 < x < 65536.
+            containerPort: 1
+            # What host IP to bind the external port to.
+            hostIP: string
+            # Number of port to expose on the host. If specified, this
+            # must be a valid port number, 0 < x < 65536. If
+            # HostNetwork is specified, this must match ContainerPort.
+            # Most containers do not need this.
+            hostPort: 1
+            # If specified, this must be an IANA_SVC_NAME and unique
+            # within the pod. Each named port in a pod must have a
+            # unique name. Name for the port that can be referred to by
+            # services.
+            name: string
+            # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+            # to "TCP".
+            protocol: "TCP"
+          # Specify the hosts to run each rank worker process in the
+          # cluster. For a single machine system, use "127.0.0.1", but
+          # if using two or more machines, a hostname or IP address
+          # must be specified for each rank that is accessible from the
+          # other ranks. See also 'head_ip_address'
+          # and 'rank0_ip_address'.
+          host: string
+          # Optionally, specify the worker HTTP server ports. The
+          # default is to use ('head_port' + *rank #*) for each worker
+          # process where rank number is from "1" to number of ranks
+          # in 'rank<#>.host' below.
+          httpServerPort:
+            # Number of port to expose on the pod's IP address. This
+            # must be a valid port number, 0 < x < 65536.
+            containerPort: 1
+            # What host IP to bind the external port to.
+            hostIP: string
+            # Number of port to expose on the host. If specified, this
+            # must be a valid port number, 0 < x < 65536. If
+            # HostNetwork is specified, this must match ContainerPort.
+            # Most containers do not need this.
+            hostPort: 1
+            # If specified, this must be an IANA_SVC_NAME and unique
+            # within the pod. Each named port in a pod must have a
+            # unique name. Name for the port that can be referred to by
+            # services.
+            name: string
+            # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+            # to "TCP".
+            protocol: "TCP"
+          # This is the Kubernetes pod IP Address of the current rank
+          # which we need to populate in the operator. NOTE: Internal
+          # Attribute
+          podIP: string
+          # Optionally, specify a public URL for each worker HTTP server
+          # that clients should use to connect for multi-head
+          # operations. NOTE: If specified for any ranks, a public URL
+          # must be specified for all ranks.
+          publicURL: "https://:8082/gpudb-{{.Rank}}"
+          # Define the rank number of this rank.
+          rank: 1
+        # SetMonitorPort - Set monitor ZMQ publisher server port (-1 to
+        # disable), uses the 'head_ip_address' interface.
+        setMonitorPort: 9002
+        # SetMonitorProxyPort - Set monitor ZMQ publisher internal proxy
+        # server port ("-1" to disable), uses the 'head_ip_address'
+        # interface. IMPORTANT:  Disabling this port effectively
+        # prevents worker nodes from publishing set monitor
+        # notifications when multi-head ingest is enabled
+        # (see 'enable_worker_http_servers').
+        setMonitorProxyPort: 9003
+        # SetMonitorQueueSize - Set monitor queue size
+        setMonitorQueueSize: 1000
+        # TriggerPort - Trigger ZMQ publisher server port ("-1" to
+        # disable), uses the 'head_ip_address' interface.
+        triggerPort: -1
+        # UseHTTPS - Set to "true" to use HTTPS; if "true"
+        # then 'https_key_file' and 'https_cert_file' must be provided
+        useHttps: false
+      # PersistenceConfig
+      persistence:
+        # Removed in 7.2
+        IndexDBFlushImmediate: true
+        # DataLoadingSchema Startup data-loading scheme
+        buildMaterializedViewsOnStart: "on_demand"
+        # DataLoadingSchema Startup data-loading scheme
+        buildPKIndexOnStart: "on_demand"
+        # Target maximum data size for any one column in a chunk
+        # (512 MB) (0 = disable). chunk_max_memory = 8192000000
+        chunkColumnMaxMemory: 8192000000
+        # Target maximum total data size for all columns in a chunk
+        # (8 GB) (0 = disable).
+        chunkMaxMemory: 512000000
+        # Number of records per chunk ("0" disables chunking)
+        chunkSize: 8000000
+        # Determines whether to execute kernels on host (CPU) or device
+        # (GPU). Possible values are: 
+        #  * "default"   : engine decides * "host"      : execute only
+        #     host * "device"    : execute only device * *<rows>*    :
+        #     execute on the host if chunked column contains the given
+        #     number of *rows* or fewer; otherwise, execute on device.
+        executionMode: "device"
+        # Removed in 7.2
+        fsyncIndexDBImmediate: true
+        # Removed in 7.2
+        fsyncInodesImmediate: true
+        # Removed in 7.2
+        fsyncMetadataImmediate: true
+        # Removed in 7.2
+        fsyncOnInterval: true
+        # Maximum number of open files for IndexedDb object file store.
+        # Removed in 7.2
+        indexDBMaxOpenFiles: 
+        # Table of contents size for IndexedDb object file store.
+        # Removed in 7.2
+        indexDBTOCSize: 
+        # Disable detection of sparse file support and use the full file
+        # length which may be an over-estimate of the actual usage in
+        # the persist tier. Removed in 7.2
+        indexDBTierByFileLength: false
+        # Startup data-loading scheme: 
+        #  * "always"    : load all the data into memory before
+        #     accepting requests * "lazy"      : load the necessary
+        #     data to start, but load the remainder
+        #     lazily * "on_demand" : only load data as requests use it
+        loadVectorsOnStart: "on_demand"
+        # Removed in 7.2
+        metadataFlushImmediate: true
+        # Specify a base directory to store persistence data files.
+        persistDirectory: "/opt/gpudb/persist"
+        # Whether to use synchronous persistence file writing.
+        # If "false", files will be written asynchronously. Removed in
+        # 7.2
+        persistSync: true
+        # Duration in seconds, for which persistence files will be
+        # force-synced if out of sync, once per minute. NOTE: Files are
+        # always opportunistically saved; this simply enforces a
+        # maximum time a file can be out of date. Set to a very high
+        # number to disable.
+        persistSyncTime: 5
+        # The maximum number of bytes in the shadow aggregate cache
+        shadowAggSize: 100000000
+        # Whether to enable chunk caching
+        shadowCubeEnabled: true
+        # The maximum number of bytes in the shadow filter cache
+        shadowFilterSize: 100000000
+        # Base directory to store hashed strings.
+        smsDirectory: "${gaia.persist_directory}"
+        # Maximum number of open files (per-TOM) for the SMS
+        # (string) store.
+        smsMaxOpenFiles: 128
+        # Synchronous compression: compress vectors on set compression.
+        synchronousCompression: false
+        # Directory for GPUdb to use to store temporary files. Must be a
+        # fully qualified path, have at least 100Mb of free space, and
+        # execute permission.
+        tempDirectory: "${gaia.persist_directory}/tmp"
+        # Base directory to store the text search index.
+        textIndexDirectory: "${gaia.persist_directory}"
+        # Enable checksum protection on the wal entries. New in 7.2
+        walChecksum: true
+        # Specifies how frequently wal entries are written with
+        # background sync. New in 7.2
+        walFlushFrequency: 60
+        # Maximum size of each wal segment file New in 7.2
+        walMaxSegmentSize: 500000000
+        # Approximate number of segment files to split the wal across. A
+        # minimum of two is required. The size of the wal is limited by
+        # segment_count * max_segment_size. (per rank and per tom) Set
+        # to 0 to remove a size limit on the wal itself, but still be
+        # bounded by rank tier limits. Set to -1 to have the database
+        # decide automatically per table. New in 7.2
+        walSegmentCount: 
+        # Sync mode to use when persisting wal entries to disk: 
+        #  "none"       : Disable the wal "background" : Wal entries are
+        #   periodically written instead of immediately after each
+        #   operation "flush"      : Protects entries in the event of a
+        #   database crash "fsync"      : Protects entries in the event
+        #   of an OS crash New in 7.2
+        walSyncPolicy: "flush"
+        # If true, any table that is found to be corrupt after replaying
+        # its wal at startup will automatically be truncated so that
+        # the table becomes operable. If false, the user will be
+        # responsible for resolving the issue via sql REPAIR TABLE or
+        # similar. New in 7.2
+        walTruncateCorruptTablesOnStart: true
+      # PostgresProxy
+      postgresProxy:
+        # Postgres Proxy Server Start an Postgres(TCP) server as a proxy
+        # to handle postgres wire protocol messages.
+        enablePostgresProxy: false
+        # Set idle connection  timeout in seconds. (default: "1200")
+        idleConnectionTimeout: 1200
+        # Set max number of queued server connections. (default: "1")
+        maxQueuedConnections: 1
+        # Set max number of server threads to spawn. (default: "64")
+        maxThreads: 64
+        # Set min number of server threads to spawn. (default: "2")
+        minThreads: 2
+        # TCP port that the postgres  proxy server will listen on
+        # if 'enable_postgres_proxy' is "true".
+        port:
+          # Number of port to expose on the pod's IP address. This must
+          # be a valid port number, 0 < x < 65536.
+          containerPort: 1
+          # What host IP to bind the external port to.
+          hostIP: string
+          # Number of port to expose on the host. If specified, this
+          # must be a valid port number, 0 < x < 65536. If HostNetwork
+          # is specified, this must match ContainerPort. Most
+          # containers do not need this.
+          hostPort: 1
+          # If specified, this must be an IANA_SVC_NAME and unique
+          # within the pod. Each named port in a pod must have a unique
+          # name. Name for the port that can be referred to by
+          # services.
+          name: string
+          # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+          # to "TCP".
+          protocol: "TCP"
+        # Set to "true" to use SSL; if "true" then 'ssl_key_file'
+        # and 'ssl_cert_file' must be provided
+        ssl: false sslCertFile: ""
+        # Files containing the SSL private Key and the SSL certificate
+        # for. If required, a self signed certificate (expires after 10
+        # years) can be generated via the command: openssl req -newkey
+        # rsa:2048 -new -nodes -x509 \ -days 3650 -keyout key.pem -out
+        # cert.pem
+        sslKeyFile: ""
+      # ProcessesConfig
+      processes:
+        # Set the maximum number of threads per tom for table
+        # initialization on startup
+        initTablesNumThreadsPerTom: 8
+        # Set the number of parallel calculation threads to use for data
+        # processing use -1 to use the max number of threads
+        # (not recommended)
+        kernelOmpThreads: 3
+        # The maximum number of web server threads to spawn
+        maxHttpThreads: 512
+        # Set the maximum number of threads (both workers and masters)
+        # to be passed to TBB on initialization.  Generally
+        # speaking, 'max_tbb_threads_per_rank' - "1" TBB workers will
+        # be created.  Use "-1" for no limit.
+        maxTbbThreadsPerRank: "-1"
+        # The minimum number of web server threads to spawn
+        minHttpThreads: 8
+        # Set the number of parallel jobs to create for multi-child set
+        # calulations use "-1" to use the max number of threads
+        # (not recommended)
+        smOmpThreads: 2
+        # Maximum number of simultaneous threads allocated to a given
+        # request, on each rank. Note that thread allocation may also
+        # be limted by resource group limits and/or system load.
+        subtaskConcurrentyLimit: "-1"
+        # Set the number of TaskCalculators per TOM, GPU data
+        # processors.
+        tcsPerTom: "-1"
+        # Set the number of TOMs (data container shards) per rank
+        tomsPerRank: 1
+        # Set the number of TaskProcessors per TOM, CPU data
+        # processors.
+        tpsPerTom: "-1"
+      # ProcsConfig
+      procs:
+        # Directory where proc files are stored at runtime. Must be a
+        # fully qualified path with execute permission. If not
+        # specified, 'temp_directory' will be used.
+        directory:
+          # PersistentVolumeClaim is a user's request for and claim to a
+          # persistent volume
+          persistVolumeClaim:
+            # APIVersion defines the versioned schema of this
+            # representation of an object. Servers should convert
+            # recognized schemas to the latest internal value, and may
+            # reject unrecognized values. More info:
+            # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            apiVersion: app.kinetica.com/v1
+            # Kind is a string value representing the REST resource this
+            # object represents. Servers may infer this from the
+            # endpoint the client submits requests to. Cannot be
+            # updated. In CamelCase. More info:
+            # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            kind: KineticaCluster
+            # Standard object's metadata. More info:
+            # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+            metadata: {}
+            # spec defines the desired characteristics of a volume
+            # requested by a pod author. More info:
+            # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+            spec:
+              # accessModes contains the desired access modes the volume
+              # should have. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+              accessModes: ["string"]
+              # dataSource field can be used to specify either: * An
+              # existing VolumeSnapshot object
+              # (snapshot.storage.k8s.io/VolumeSnapshot) * An existing
+              # PVC (PersistentVolumeClaim) If the provisioner or an
+              # external controller can support the specified data
+              # source, it will create a new volume based on the
+              # contents of the specified data source. When the
+              # AnyVolumeDataSource feature gate is enabled, dataSource
+              # contents will be copied to dataSourceRef, and
+              # dataSourceRef contents will be copied to dataSource
+              # when dataSourceRef.namespace is not specified. If the
+              # namespace is specified, then dataSourceRef will not be
+              # copied to dataSource.
+              dataSource:
+                # APIGroup is the group for the resource being
+                # referenced. If APIGroup is not specified, the
+                # specified Kind must be in the core API group. For any
+                # other third-party types, APIGroup is required.
+                apiGroup: string
+                # Kind is the type of resource being referenced
+                kind: KineticaCluster
+                # Name is the name of resource being referenced
+                name: string
+              # dataSourceRef specifies the object from which to
+              # populate the volume with data, if a non-empty volume is
+              # desired. This may be any object from a non-empty API
+              # group (non core object) or a PersistentVolumeClaim
+              # object. When this field is specified, volume binding
+              # will only succeed if the type of the specified object
+              # matches some installed volume populator or dynamic
+              # provisioner. This field will replace the functionality
+              # of the dataSource field and as such if both fields are
+              # non-empty, they must have the same value. For backwards
+              # compatibility, when namespace isn't specified in
+              # dataSourceRef, both fields (dataSource and
+              # dataSourceRef) will be set to the same value
+              # automatically if one of them is empty and the other is
+              # non-empty. When namespace is specified in
+              # dataSourceRef, dataSource isn't set to the same value
+              # and must be empty. There are three important
+              # differences between dataSource and dataSourceRef: *
+              # While dataSource only allows two specific types of
+              # objects, dataSourceRef allows any non-core object, as
+              # well as PersistentVolumeClaim objects. * While
+              # dataSource ignores disallowed values (dropping them),
+              # dataSourceRef preserves all values, and generates an
+              # error if a disallowed value is specified. * While
+              # dataSource only allows local objects, dataSourceRef
+              # allows objects in any namespaces. (Beta) Using this
+              # field requires the AnyVolumeDataSource feature gate to
+              # be enabled. (Alpha) Using the namespace field of
+              # dataSourceRef requires the
+              # CrossNamespaceVolumeDataSource feature gate to be
+              # enabled.
+              dataSourceRef:
+                # APIGroup is the group for the resource being
+                # referenced. If APIGroup is not specified, the
+                # specified Kind must be in the core API group. For any
+                # other third-party types, APIGroup is required.
+                apiGroup: string
+                # Kind is the type of resource being referenced
+                kind: KineticaCluster
+                # Name is the name of resource being referenced
+                name: string
+                # Namespace is the namespace of resource being
+                # referenced Note that when a namespace is specified, a
+                # gateway.networking.k8s.io/ReferenceGrant object is
+                # required in the referent namespace to allow that
+                # namespace's owner to accept the reference. See the
+                # ReferenceGrant documentation for details.(Alpha) This
+                # field requires the CrossNamespaceVolumeDataSource
+                # feature gate to be enabled.
+                namespace: string
+              # resources represents the minimum resources the volume
+              # should have. If RecoverVolumeExpansionFailure feature
+              # is enabled users are allowed to specify resource
+              # requirements that are lower than previous value but
+              # must still be higher than capacity recorded in the
+              # status field of the claim. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+              resources:
+                # Claims lists the names of resources, defined in
+                # spec.resourceClaims, that are used by this container.
+                # This is an alpha field and requires enabling the
+                # DynamicResourceAllocation feature gate. This field is
+                # immutable. It can only be set for containers.
+                claims:
+                - name: string
+                # Limits describes the maximum amount of compute
+                # resources allowed. More info:
+                # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                limits: {}
+                # Requests describes the minimum amount of compute
+                # resources required. If Requests is omitted for a
+                # container, it defaults to Limits if that is
+                # explicitly specified, otherwise to an
+                # implementation-defined value. Requests cannot exceed
+                # Limits. More info:
+                # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                requests: {}
+              # selector is a label query over volumes to consider for
+              # binding.
+              selector:
+                # matchExpressions is a list of label selector
+                # requirements. The requirements are ANDed.
+                matchExpressions:
+                - key: string
+                  # operator represents a key's relationship to a set of
+                  # values. Valid operators are In, NotIn, Exists and
+                  # DoesNotExist.
+                  operator: string
+                  # values is an array of string values. If the operator
+                  # is In or NotIn, the values array must be non-empty.
+                  # If the operator is Exists or DoesNotExist, the
+                  # values array must be empty. This array is replaced
+                  # during a strategic merge patch.
+                  values: ["string"]
+                # matchLabels is a map of {key,value} pairs. A single
+                # {key,value} in the matchLabels map is equivalent to
+                # an element of matchExpressions, whose key field
+                # is "key", the operator is "In", and the values array
+                # contains only "value". The requirements are ANDed.
+                matchLabels: {}
+              # storageClassName is the name of the StorageClass
+              # required by the claim. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+              storageClassName: string
+              # volumeMode defines what type of volume is required by
+              # the claim. Value of Filesystem is implied when not
+              # included in claim spec.
+              volumeMode: string
+              # volumeName is the binding reference to the
+              # PersistentVolume backing this claim.
+              volumeName: string
+            # status represents the current information/status of a
+            # persistent volume claim. Read-only. More info:
+            # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+            status:
+              # accessModes contains the actual access modes the volume
+              # backing the PVC has. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+              accessModes: ["string"]
+              # allocatedResources is the storage resource within
+              # AllocatedResources tracks the capacity allocated to a
+              # PVC. It may be larger than the actual capacity when a
+              # volume expansion operation is requested. For storage
+              # quota, the larger value from allocatedResources and
+              # PVC.spec.resources is used. If allocatedResources is
+              # not set, PVC.spec.resources alone is used for quota
+              # calculation. If a volume expansion capacity request is
+              # lowered, allocatedResources is only lowered if there
+              # are no expansion operations in progress and if the
+              # actual volume capacity is equal or lower than the
+              # requested capacity. This is an alpha field and requires
+              # enabling RecoverVolumeExpansionFailure feature.
+              allocatedResources: {}
+              # capacity represents the actual resources of the
+              # underlying volume.
+              capacity: {}
+              # conditions is the current Condition of persistent volume
+              # claim. If underlying persistent volume is being resized
+              # then the Condition will be set to 'ResizeStarted'.
+              conditions:
+              - lastProbeTime: string
+                # lastTransitionTime is the time the condition
+                # transitioned from one status to another.
+                lastTransitionTime: string
+                # message is the human-readable message indicating
+                # details about last transition.
+                message: string
+                # reason is a unique, this should be a short, machine
+                # understandable string that gives the reason for
+                # condition's last transition. If it
+                # reports "ResizeStarted" that means the underlying
+                # persistent volume is being resized.
+                reason: string status: string
+                # PersistentVolumeClaimConditionType is a valid value of
+                # PersistentVolumeClaimCondition.Type
+                type: string
+              # phase represents the current phase of
+              # PersistentVolumeClaim.
+              phase: string
+              # resizeStatus stores status of resize operation.
+              # ResizeStatus is not set by default but when expansion
+              # is complete resizeStatus is set to empty string by
+              # resize controller or kubelet. This is an alpha field
+              # and requires enabling RecoverVolumeExpansionFailure
+              # feature.
+              resizeStatus: string
+          # VolumeMount describes a mounting of a Volume within a
+          # container.
+          volumeMount:
+            # Path within the container at which the volume should be
+            # mounted.  Must not contain ':'.
+            mountPath: string
+            # mountPropagation determines how mounts are propagated from
+            # the host to container and the other way around. When not
+            # set, MountPropagationNone is used. This field is beta in
+            # 1.10.
+            mountPropagation: string
+            # This must match the Name of a Volume.
+            name: string
+            # Mounted read-only if true, read-write otherwise (false or
+            # unspecified). Defaults to false.
+            readOnly: true
+            # Path within the volume from which the container's volume
+            # should be mounted. Defaults to "" (volume's root).
+            subPath: string
+            # Expanded path within the volume from which the container's
+            # volume should be mounted. Behaves similarly to SubPath
+            # but environment variable references $(VAR_NAME) are
+            # expanded using the container's environment. Defaults
+            # to "" (volume's root). SubPathExpr and SubPath are
+            # mutually exclusive.
+            subPathExpr: string
+        # Enable procs (UDFs)
+        enable: true
+      # SecurityConfig
+      security:
+        # Automatically create accounts for externally-authenticated
+        # users. If 'enable_external_authentication' is "false", this
+        # setting has no effect. Note that accounts are not
+        # automatically deleted if users are removed from the external
+        # authentication provider and will be orphaned.
+        autoCreateExternalUsers: false
+        # Automatically add roles passed in via the "KINETICA_ROLES"
+        # HTTP header to externally-authenticated users. Specified
+        # roles that do not exist are ignored.
+        # If 'enable_external_authentication' is "false", this setting
+        # has no effect. IMPORTANT: DO NOT ENABLE unless the
+        # authentication proxy is configured to block "KINETICA_ROLES"
+        # HTTP headers passed in from clients.
+        autoGrantExternalRoles: false
+        # Comma-separated list of roles to revoke from
+        # externally-authenticated users prior to granting roles passed
+        # in via the "KINETICA_ROLES" HTTP header, or "*" to revoke all
+        # roles. Preceding a role name with an "!" overrides the
+        # revocation (e.g. "*,!foo" revokes all roles except "foo").
+        # Leave blank to disable. If
+        # either 'enable_external_authentication'
+        # or 'auto_grant_external_roles' is "false", this setting has
+        # no effect.
+        autoRevokeExternalRoles: false
+        # Enable authorization checks.  When disabled, all requests will
+        # be treated as the administrative user.
+        enableAuthorization: true
+        # Enable external (LDAP, Kerberos, etc.) authentication. User
+        # IDs of externally-authenticated users must be passed in via
+        # the "REMOTE_USER" HTTP header from the authentication proxy.
+        # May be used in conjuntion with the 'enable_httpd_proxy'
+        # setting above for an integrated external authentication
+        # solution. IMPORTANT: DO NOT ENABLE unless external access to
+        # GPUdb ports has been blocked via firewall AND the
+        # authentication proxy is configured to block "REMOTE_USER"
+        # HTTP headers passed in from clients. server.
+        enableExternalAuthentication: true
+        # ExternalSecurity
+        externalSecurity:
+          # Ranger
+          ranger:
+            # AuthorizerAddress - The network URI for the
+            # ranger_authorizer to start. The URI can be either TCP or
+            # IPC. TCP address is used to indicate the remote
+            # ranger_authorizer which may run at other hosts. The IPC
+            # address is for a local ranger_authorizer. Example
+            # addresses for remote or TCP servers: tcp://127.0.0.1:9293
+            # tcp://HOST_IP:9293 Example address for local IPC servers:
+            # ipc:///tmp/gpudb-ranger-0
+            # security.external.ranger_authorizer.address = ipc://$
+            # {gaia.temp_directory}/gpudb-ranger-0
+            authorizerAddress: "ipc://$
+            {gaia.temp_directory}/gpudb-ranger-0"
+            # Remote debugger port used for the ranger_authorizer.
+            # Setting the port to "0" disables remote debugging. NOTE:
+            # Recommended port to use is "5005"
+            # security.external.ranger_authorizer.remote_debug_port =
+            # 0
+            authorizerRemoteDebugPort: 0
+            # AuthorizerTimeout - Ranger Authorizer timeout in seconds
+            # security.external.ranger_authorizer.timeout = 120
+            authorizerTimeout: 120
+            # CacheMinutes- Maximum minutes to hold on to data from
+            # Ranger security.external.ranger.cache_minutes = 60
+            cacheMinutes: 60
+            # Name of the service created on the Ranger Server to manage
+            # this Kinetica instance
+            # security.external.ranger.service_name = kinetica
+            name: "kinetica"
+            # ExtURL - URL of Ranger REST API.  E.g.,
+            # https://localhost:6080/ Leave blank for no Ranger Server
+            # security.external.ranger.url =
+            url: string
+        # The minimum allowable password length.
+        minPasswordLength: 4
+        # Require all users to be authenticated.  Disable this to allow
+        # users to access the database as the 'unauthenticated' user.
+        # Useful for situations where the public needs to access the
+        # data.
+        requireAuthentication: true
+        # UnifiedSecurityNamespace - Use a single namespace for internal
+        # and external user IDs and role names. If false, external user
+        # IDs must be prefixed with "@" to differentiate them from
+        # internal user IDs and role names (except in the "REMOTE_USER"
+        # HTTP header, where the "@" is omitted).
+        # unified_security_namespace = true
+        unifiedSecurityNamespace: true
+      # SQLConfig
+      sql:
+        # SQLPlannerAddress is not included as it is just default
+        # always
+        address: "ipc://${gaia.temp_directory}/gpudb-query-engine-0"
+        # Enable the cost-based optimizer
+        costBasedOptimization: false
+        # Enable distributed joins
+        distributedJoins: true
+        # Enable distributed operations
+        distributedOperations: true
+        # Enable Query Planner
+        enablePlanner: true
+        # Perform joins between only 2 tables at a time; default is all
+        # tables involved in the operation at once
+        forceBinaryJoins: false
+        # Perform unions/intersections/exceptions between only 2 tables
+        # at a time; default is all tables involved in the operation at
+        # once
+        forceBinarySetOps: false
+        # Max parallel steps
+        maxParallelSteps: 4
+        # Max allowed view nesting levels. Valid range(1-64)
+        maxViewNestingLevels: 16
+        # TTL of the paging results table
+        pagingTableTTL: 20
+        # Enable parallel query evaluation
+        parallelExecution: true
+        # The maximum number of entries in the SQL plan cache.  The
+        # default is "4000" entries, but the configurable range
+        # is "1" - "1000000".  Plan caching will be disabled if the
+        # value is set outside of that range.
+        planCacheSize: 4000
+        # The maximum memory for the query planner to use in Megabytes.
+        plannerMaxMemory: 4096
+        # The maximum stack size for the query planner threads to use in
+        # Megabytes.
+        plannerMaxStack: 6
+        # Query planner timeout in seconds
+        plannerTimeout: 120
+        # Max Query planner threads
+        plannerWorkers: 16
+        # Remote debugger port used for the query planner. Setting the
+        # port to "0" disables remote debugging. NOTE:  Recommended
+        # port to use is "5005"
+        remoteDebugPort: 5005
+        # TTL of the query cache results table
+        resultsCacheTTL: 60
+        # Enable query results caching
+        resultsCaching: true
+        # Enable rule-based query rewrites
+        ruleBasedOptimization: true
+      # SQLEngineConfig
+      sqlEngine:
+        # Enable the cost-based optimizer
+        costBasedOptimization: false
+        # Name of default collection for user tables
+        defaultSchema: ""
+        # Enable distributed joins
+        distributedJoins: true
+        # Enable distributed operations
+        distributedOperations: true
+        # Perform joins between only 2 tables at a time; default is all
+        # tables involved in the operation at once
+        forceBinaryJoins: false
+        # Perform unions/intersections/exceptions between only 2 tables
+        # at a time; default is all tables involved in the operation at
+        # once
+        forceBinarySetOps: false
+        # Max parallel steps
+        maxParallelSteps: 4
+        # Max allowed view nesting levels. Valid range(1-64)
+        maxViewNestingLevels: 16
+        # TTL of the paging results table
+        pagingTableTTL: 20
+        # Enable parallel query evaluation
+        parallelExecution: true
+        # The maximum number of entries in the SQL plan cache.  The
+        # default is "4000" entries, but the configurable range
+        # is "1" - "1000000".  Plan caching will be disabled if the
+        # value is set outside of that range.
+        planCacheSize: 4000
+        # PlannerConfig
+        planner:
+          # Enable Query Planner
+          enablePlanner: true
+          # The maximum memory for the query planner to use in
+          # Megabytes.
+          maxMemory: 4096
+          # The maximum stack size for the query planner threads to use
+          # in Megabytes.
+          maxStack: 6
+          # The network URI for the query planner to start. The URI can
+          # be either TCP or IPC. TCP address is used to indicate the
+          # remote query planner which may run at other hosts. The IPC
+          # address is for a local query planner. Example for remote or
+          # TCP servers: 
+          #  #  sql.planner.address  = tcp://127.0.0.1:9293 #
+          #     sql.planner.address  = tcp://HOST_IP:9293 Example for
+          #     local IPC servers: 
+          #  #  sql.planner.address  = ipc:///tmp/gpudb-query-engine-0
+          plannerAddress: "ipc:///tmp/gpudb-query-engine-0"
+          # Remote debugger port used for the query planner. Setting the
+          # port to "0" disables remote debugging. NOTE:  Recommended
+          # port to use is "5005"
+          remoteDebugPort: 0
+          # Query planner timeout in seconds
+          timeout: 120
+          # Max Query planner threads
+          workers: 16 results:
+          # TTL of the query cache results table
+          cacheTTL: 60
+          # Enable query results caching
+          caching: true
+        # Enable rule-based query rewrites
+        ruleBasedOptimization: true
+        # Name of collection that will be used to store result tables
+        # generated as part of query execution
+        tempCollection: "__SQL_TEMP"
+      # StatisticsConfig
+      statistics:
+        # system_metadata.stats_aggr_rowcount = 10000
+        aggrRowCount: 10000
+        # system_metadata.stats_aggr_time = 1
+        aggrTime: 1
+        # Run a statistics server to collect information about Kinetica
+        # and the machines it runs on.
+        enable: true
+        # Statistics server IP address (run on head node) default port
+        # is "2003"
+        ipAddress: "${gaia.host0.address}"
+        # Statistics server namespace - should be a machine identifier
+        namespace: "gpudb" port: 2003
+        # System metadata catalog settings
+        # system_metadata.stats_retention_days = 21
+        retentionDays: 21
+      # TextSearchConfig
+      textSearch:
+        # Enable text search capability within the database.
+        enableTextSearch: false
+        # Number of text indices to start for each rank
+        textIndicesPerTom: 2
+        # Searcher refresh intervals - specifies the maximum delay
+        # (in seconds) between writing to the text search index and
+        # being able to search for the value just written.  A value
+        # of "0" insures that writes to the index are immediately
+        # available to be searched.  A more nominal value of "100"
+        # should improve ingest speed at the cost of some delay in
+        # being able to text search newly added values.
+        textSearcherRefreshInterval: 20
+        # Use the production capable external text server instead of a
+        # lightweight internal server which should only be used for
+        # light testing. Note: The internal text server is deprecated
+        # and may be removed in future versions.
+        useExternalTextServer: true tieredStorage:
+        # Cold Storage Tiers can be used to extend the storage capacity
+        # of the Persist Tier. Assign a tier strategy with cold storage
+        # to objects that will be infrequently accessed since they will
+        # be moved as needed from the Persist Tier. The Cold Storage
+        # Tier is typically a much larger capacity physical disk or a
+        # cloud-based storage system which may not be as performant as
+        # the Persist Tier storage. A default storage limit and
+        # eviction thresholds can be set across all ranks for a given
+        # Cold Storage Tier, while one or more ranks within a Cold
+        # Storage Tier may be configured to override those defaults.
+        # NOTE: If an object needs to be pulled out of cold storage
+        # during a query, it may need to use the local persist
+        # directory as a temporary swap space. This may trigger an
+        # eviction of other persisted items to cold storage due to low
+        # disk space condition defined by the watermark settings for
+        # the Persist Tier.
+        coldStorageTier:
+          # ColdStorageAzure
+          coldStorageAzure:
+            # 'base_path'             : A base path based on the
+            #  provider type for this tier.
+            basePath: string clientID: string clientSecret: string
+            # 'connection_timeout'    : Timeout in seconds for
+            #  connecting to this storage provider.
+            connectionTimeout: "30"
+            # 'base_path'             : A base path based on the
+            #  provider type for this tier. BasePath string
+            #  `json:"basePath,omitempty"`
+            containerName: "/gpudb/cold_storage"
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath" sasToken:
+            string storageAccountKey: string storageAccountName: string
+            tenantID: string useManagedCredentials: false
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+            # 'wait_timeout'          : Timeout in seconds for reading
+            #  from or writing to this storage provider.
+            waitTimeout: "90"
+          # ColdStorageDisk
+          coldStorageDisk:
+            # 'base_path'             : A base path based on the
+            #  provider type for this tier.
+            basePath: string
+            # 'connection_timeout'    : Timeout in seconds for
+            #  connecting to this storage provider.
+            connectionTimeout: "30"
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+            # 'wait_timeout'          : Timeout in seconds for reading
+            #  from or writing to this storage provider.
+            waitTimeout: "90"
+          # ColdStorageGCS - Google Cloud Storage-specific *parameter*
+          # names: 
+          #  * BucketName =        'gcs_bucket_name' *
+          #    ProjectID - 'gcs_project_id'
+          #    (optional) * AccountID - 'gcs_service_account_id'
+          #    (optional) *
+          #    AccountPrivateKey - 'gcs_service_account_private_key'
+          #    (optional) * AccountKeys -  'gcs_service_account_keys'
+          #    (optional) NOTE: If
+          #    the 'gcs_service_account_id', 'gcs_service_account_private_key'
+          #    and/or 'gcs_service_account_keys' values are not
+          #    specified, the Google Clould Client Libraries will
+          #    attempt to find and use service account credentials from
+          #    the GOOGLE_APPLICATION_CREDENTIALS environment
+          #    variable.
+          coldStorageGCS: accountID: string accountKeys: string
+          accountPrivateKey: string
+            # 'base_path'             : A base path based on the
+            #  provider type for this tier.
+            basePath: string bucketName: string
+            # 'connection_timeout'    : Timeout in seconds for
+            #  connecting to this storage provider.
+            connectionTimeout: "30"
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" projectID: string
+            provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+            # 'wait_timeout'          : Timeout in seconds for reading
+            #  from or writing to this storage provider.
+            waitTimeout: "90"
+          # ColdStorageHDFS
+          coldStorageHDFS:
+            # ColdStorageDisk
+            default:
+              # 'base_path'             : A base path based on the
+              #  provider type for this tier.
+              basePath: string
+              # 'connection_timeout'    : Timeout in seconds for
+              #  connecting to this storage provider.
+              connectionTimeout: "30"
+              # * 'high_watermark' : Percentage used eviction threshold.
+              #    Once usage exceeds this value, evictions from this
+              #    tier will be scheduled in the background and
+              #    continue until the 'low_watermark' percentage usage
+              #    is reached.  Default is "90", signifying a 90%
+              #    memory usage threshold.
+              highWatermark: 90
+              # * 'limit'          : The maximum (bytes) per rank that
+              #    can be allocated across all resource groups.
+              limit: "1Gi"
+              # * 'low_watermark'  : Percentage used recovery threshold.
+              #    Once usage exceeds the 'high_watermark', evictions
+              #    will continue until usage falls below this recovery
+              #    threshold. Default is "80", signifying an 80% usage
+              #    threshold.
+              lowWatermark: 80 name: string
+              # A base directory to use as a space for this tier.
+              path: "default" provisioner: "docker.io/hostpath"
+              # Kubernetes Persistent Volume Claim for this disk tier.
+              volumeClaim:
+                # APIVersion defines the versioned schema of this
+                # representation of an object. Servers should convert
+                # recognized schemas to the latest internal value, and
+                # may reject unrecognized values. More info:
+                # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+                apiVersion: app.kinetica.com/v1
+                # Kind is a string value representing the REST resource
+                # this object represents. Servers may infer this from
+                # the endpoint the client submits requests to. Cannot
+                # be updated. In CamelCase. More info:
+                # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+                kind: KineticaCluster
+                # Standard object's metadata. More info:
+                # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+                metadata: {}
+                # spec defines the desired characteristics of a volume
+                # requested by a pod author. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+                spec:
+                  # accessModes contains the desired access modes the
+                  # volume should have. More info:
+                  # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                  accessModes: ["string"]
+                  # dataSource field can be used to specify either: * An
+                  # existing VolumeSnapshot object
+                  # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                  # existing PVC (PersistentVolumeClaim) If the
+                  # provisioner or an external controller can support
+                  # the specified data source, it will create a new
+                  # volume based on the contents of the specified data
+                  # source. When the AnyVolumeDataSource feature gate
+                  # is enabled, dataSource contents will be copied to
+                  # dataSourceRef, and dataSourceRef contents will be
+                  # copied to dataSource when dataSourceRef.namespace
+                  # is not specified. If the namespace is specified,
+                  # then dataSourceRef will not be copied to
+                  # dataSource.
+                  dataSource:
+                    # APIGroup is the group for the resource being
+                    # referenced. If APIGroup is not specified, the
+                    # specified Kind must be in the core API group. For
+                    # any other third-party types, APIGroup is
+                    # required.
+                    apiGroup: string
+                    # Kind is the type of resource being referenced
+                    kind: KineticaCluster
+                    # Name is the name of resource being referenced
+                    name: string
+                  # dataSourceRef specifies the object from which to
+                  # populate the volume with data, if a non-empty
+                  # volume is desired. This may be any object from a
+                  # non-empty API group (non core object) or a
+                  # PersistentVolumeClaim object. When this field is
+                  # specified, volume binding will only succeed if the
+                  # type of the specified object matches some installed
+                  # volume populator or dynamic provisioner. This field
+                  # will replace the functionality of the dataSource
+                  # field and as such if both fields are non-empty,
+                  # they must have the same value. For backwards
+                  # compatibility, when namespace isn't specified in
+                  # dataSourceRef, both fields (dataSource and
+                  # dataSourceRef) will be set to the same value
+                  # automatically if one of them is empty and the other
+                  # is non-empty. When namespace is specified in
+                  # dataSourceRef, dataSource isn't set to the same
+                  # value and must be empty. There are three important
+                  # differences between dataSource and dataSourceRef: *
+                  # While dataSource only allows two specific types of
+                  # objects, dataSourceRef allows any non-core object,
+                  # as well as PersistentVolumeClaim objects. * While
+                  # dataSource ignores disallowed values
+                  # (dropping them), dataSourceRef preserves all
+                  # values, and generates an error if a disallowed
+                  # value is specified. * While dataSource only allows
+                  # local objects, dataSourceRef allows objects in any
+                  # namespaces. (Beta) Using this field requires the
+                  # AnyVolumeDataSource feature gate to be enabled.
+                  # (Alpha) Using the namespace field of dataSourceRef
+                  # requires the CrossNamespaceVolumeDataSource feature
+                  # gate to be enabled.
+                  dataSourceRef:
+                    # APIGroup is the group for the resource being
+                    # referenced. If APIGroup is not specified, the
+                    # specified Kind must be in the core API group. For
+                    # any other third-party types, APIGroup is
+                    # required.
+                    apiGroup: string
+                    # Kind is the type of resource being referenced
+                    kind: KineticaCluster
+                    # Name is the name of resource being referenced
+                    name: string
+                    # Namespace is the namespace of resource being
+                    # referenced Note that when a namespace is
+                    # specified, a
+                    # gateway.networking.k8s.io/ReferenceGrant object
+                    # is required in the referent namespace to allow
+                    # that namespace's owner to accept the reference.
+                    # See the ReferenceGrant documentation for
+                    # details. (Alpha) This field requires the
+                    # CrossNamespaceVolumeDataSource feature gate to be
+                    # enabled.
+                    namespace: string
+                  # resources represents the minimum resources the
+                  # volume should have. If
+                  # RecoverVolumeExpansionFailure feature is enabled
+                  # users are allowed to specify resource requirements
+                  # that are lower than previous value but must still
+                  # be higher than capacity recorded in the status
+                  # field of the claim. More info:
+                  # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                  resources:
+                    # Claims lists the names of resources, defined in
+                    # spec.resourceClaims, that are used by this
+                    # container. This is an alpha field and requires
+                    # enabling the DynamicResourceAllocation feature
+                    # gate. This field is immutable. It can only be set
+                    # for containers.
+                    claims:
+                    - name: string
+                    # Limits describes the maximum amount of compute
+                    # resources allowed. More info:
+                    # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                    limits: {}
+                    # Requests describes the minimum amount of compute
+                    # resources required. If Requests is omitted for a
+                    # container, it defaults to Limits if that is
+                    # explicitly specified, otherwise to an
+                    # implementation-defined value. Requests cannot
+                    # exceed Limits. More info:
+                    # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                    requests: {}
+                  # selector is a label query over volumes to consider
+                  # for binding.
+                  selector:
+                    # matchExpressions is a list of label selector
+                    # requirements. The requirements are ANDed.
+                    matchExpressions:
+                    - key: string
+                      # operator represents a key's relationship to a
+                      # set of values. Valid operators are In, NotIn,
+                      # Exists and DoesNotExist.
+                      operator: string
+                      # values is an array of string values. If the
+                      # operator is In or NotIn, the values array must
+                      # be non-empty. If the operator is Exists or
+                      # DoesNotExist, the values array must be empty.
+                      # This array is replaced during a strategic merge
+                      # patch.
+                      values: ["string"]
+                    # matchLabels is a map of {key,value} pairs. A
+                    # single {key,value} in the matchLabels map is
+                    # equivalent to an element of matchExpressions,
+                    # whose key field is "key", the operator is "In",
+                    # and the values array contains only "value". The
+                    # requirements are ANDed.
+                    matchLabels: {}
+                  # storageClassName is the name of the StorageClass
+                  # required by the claim. More info:
+                  # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                  storageClassName: string
+                  # volumeMode defines what type of volume is required
+                  # by the claim. Value of Filesystem is implied when
+                  # not included in claim spec.
+                  volumeMode: string
+                  # volumeName is the binding reference to the
+                  # PersistentVolume backing this claim.
+                  volumeName: string
+                # status represents the current information/status of a
+                # persistent volume claim. Read-only. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+                status:
+                  # accessModes contains the actual access modes the
+                  # volume backing the PVC has. More info:
+                  # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                  accessModes: ["string"]
+                  # allocatedResources is the storage resource within
+                  # AllocatedResources tracks the capacity allocated to
+                  # a PVC. It may be larger than the actual capacity
+                  # when a volume expansion operation is requested. For
+                  # storage quota, the larger value from
+                  # allocatedResources and PVC.spec.resources is used.
+                  # If allocatedResources is not set,
+                  # PVC.spec.resources alone is used for quota
+                  # calculation. If a volume expansion capacity request
+                  # is lowered, allocatedResources is only lowered if
+                  # there are no expansion operations in progress and
+                  # if the actual volume capacity is equal or lower
+                  # than the requested capacity. This is an alpha field
+                  # and requires enabling RecoverVolumeExpansionFailure
+                  # feature.
+                  allocatedResources: {}
+                  # capacity represents the actual resources of the
+                  # underlying volume.
+                  capacity: {}
+                  # conditions is the current Condition of persistent
+                  # volume claim. If underlying persistent volume is
+                  # being resized then the Condition will be set
+                  # to 'ResizeStarted'.
+                  conditions:
+                  - lastProbeTime: string
+                    # lastTransitionTime is the time the condition
+                    # transitioned from one status to another.
+                    lastTransitionTime: string
+                    # message is the human-readable message indicating
+                    # details about last transition.
+                    message: string
+                    # reason is a unique, this should be a short,
+                    # machine understandable string that gives the
+                    # reason for condition's last transition. If it
+                    # reports "ResizeStarted" that means the underlying
+                    # persistent volume is being resized.
+                    reason: string status: string
+                    # PersistentVolumeClaimConditionType is a valid
+                    # value of PersistentVolumeClaimCondition.Type
+                    type: string
+                  # phase represents the current phase of
+                  # PersistentVolumeClaim.
+                  phase: string
+                  # resizeStatus stores status of resize operation.
+                  # ResizeStatus is not set by default but when
+                  # expansion is complete resizeStatus is set to empty
+                  # string by resize controller or kubelet. This is an
+                  # alpha field and requires enabling
+                  # RecoverVolumeExpansionFailure feature.
+                  resizeStatus: string
+              # 'wait_timeout'          : Timeout in seconds for reading
+              #  from or writing to this storage provider.
+              waitTimeout: "90"
+            # 'hdfs_kerberos_keytab'  : The Kerberos keytab file used to
+            #  authenticate the "gpudb" Kerberos
+            kerberosKeytab: string
+            # 'hdfs_principal'        : The effective principal name to
+            #  use when connecting to the hadoop cluster.
+            principal: string
+            # 'hdfs_uri'              : The host IP address & port for
+            #  the hadoop distributed file system. For example:
+            #  hdfs://localhost:8020
+            uri: string
+            # 'hdfs_use_kerberos'     : Set to "true" to enable Kerberos
+            #  authentication to an HDFS storage server. The
+            #  credentials of the principal are in the file specified
+            #  by the 'hdfs_kerberos_keytab' parameter. Note that
+            #  Kerberos's *kinit* command will be run when the database
+            #  is started.
+            useKerberos: true
+          # ColdStorageS3
+          coldStorageS3: awsAccessKeyId: string awsRoleARN: string
+          awsSecretAccessKey: string
+            # 'base_path'             : A base path based on the
+            #  provider type for this tier.
+            basePath: string bucketName: string
+            # 'connection_timeout'    : Timeout in seconds for
+            #  connecting to this storage provider.
+            connectionTimeout: "30" encryptionCustomerAlgorithm: string
+            encryptionCustomerKey: string
+            # EncryptionType - This is optional and valid values are
+            # sse-s3 (Encryption key is managed by Amazon S3) and
+            # sse-kms (Encryption key is managed by AWS Key Management
+            # Service (kms)).
+            encryptionType: string
+            # Endpoint - s3_endpoint
+            endpoint: string
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # KMSKeyID - This is optional and must be specified when
+            # encryption type is sse-kms.
+            kmsKeyID: string
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath" region:
+            string useManagedCredentials: true
+            # UseVirtualAddressing - 's3_use_virtual_addressing'  : If
+            # true (default), S3 endpoints will be constructed using
+            # the 'virtual' style which includes the bucket name as
+            # part of the hostname. Set to false to use the 'path'
+            # style which treats the bucket name as if it is a path in
+            # the URI.
+            useVirtualAddressing: true
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+            # 'wait_timeout'          : Timeout in seconds for reading
+            #  from or writing to this storage provider.
+            waitTimeout: "90"
+          # ColdStorageType The storage provider type. Currently,
+          # supports "none", "disk"(local/network storage), "hdfs"
+          # (Hadoop distributed filesystem), "s3" (Amazon S3
+          # bucket), "azure_blob" (Microsoft Azure Blob Storage)
+          # and "gcs" (Google GCS Bucket).
+          coldStorageType: "none" name: string
+        # The DiskCacheTier are used as temporary swap space for data
+        # that doesn't fit in RAM or VRAM. The disk should be as fast
+        # or faster than the Persist Tier storage since this tier is
+        # used as an intermediary cache between the RAM and Persist
+        # Tiers.
+        diskCacheTier:
+          # DiskTierStorageLimit
+          default:
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string defaultStorePersistentObjects: true
+                ranks:
+          - highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+        # GlobalTier Parameters
+        globalTier:
+          # Co-locates all disks to a single disk i.e. persist, cache,
+          # UDF will be on a single PVC.
+          colocateDisks: true
+          # Timeout in seconds for subsequent requests to wait on a
+          # locked resource
+          concurrentWaitTimeout: 120
+          # EncryptDataAtRest - Enable disk encryption of data at rest
+          encryptDataAtRest: true
+        # The PersistTier are used as temporary swap space for data that
+        # doesn't fit in RAM or VRAM. The disk should be as fast or
+        # faster than the Persist Tier storage since this tier is used
+        # as an intermediary cache between the RAM and Persist Tiers.
+        persistTier:
+          # DiskTierStorageLimit
+          default:
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string defaultStorePersistentObjects: true
+                ranks:
+          - highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+            # A base directory to use as a space for this tier.
+            path: "default" provisioner: "docker.io/hostpath"
+            # Kubernetes Persistent Volume Claim for this disk tier.
+            volumeClaim:
+              # APIVersion defines the versioned schema of this
+              # representation of an object. Servers should convert
+              # recognized schemas to the latest internal value, and
+              # may reject unrecognized values. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              apiVersion: app.kinetica.com/v1
+              # Kind is a string value representing the REST resource
+              # this object represents. Servers may infer this from the
+              # endpoint the client submits requests to. Cannot be
+              # updated. In CamelCase. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              kind: KineticaCluster
+              # Standard object's metadata. More info:
+              # https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+              metadata: {}
+              # spec defines the desired characteristics of a volume
+              # requested by a pod author. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              spec:
+                # accessModes contains the desired access modes the
+                # volume should have. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # dataSource field can be used to specify either: * An
+                # existing VolumeSnapshot object
+                # (snapshot.storage.k8s.io/VolumeSnapshot) * An
+                # existing PVC (PersistentVolumeClaim) If the
+                # provisioner or an external controller can support the
+                # specified data source, it will create a new volume
+                # based on the contents of the specified data source.
+                # When the AnyVolumeDataSource feature gate is enabled,
+                # dataSource contents will be copied to dataSourceRef,
+                # and dataSourceRef contents will be copied to
+                # dataSource when dataSourceRef.namespace is not
+                # specified. If the namespace is specified, then
+                # dataSourceRef will not be copied to dataSource.
+                dataSource:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                # dataSourceRef specifies the object from which to
+                # populate the volume with data, if a non-empty volume
+                # is desired. This may be any object from a non-empty
+                # API group (non core object) or a
+                # PersistentVolumeClaim object. When this field is
+                # specified, volume binding will only succeed if the
+                # type of the specified object matches some installed
+                # volume populator or dynamic provisioner. This field
+                # will replace the functionality of the dataSource
+                # field and as such if both fields are non-empty, they
+                # must have the same value. For backwards
+                # compatibility, when namespace isn't specified in
+                # dataSourceRef, both fields (dataSource and
+                # dataSourceRef) will be set to the same value
+                # automatically if one of them is empty and the other
+                # is non-empty. When namespace is specified in
+                # dataSourceRef, dataSource isn't set to the same value
+                # and must be empty. There are three important
+                # differences between dataSource and dataSourceRef: *
+                # While dataSource only allows two specific types of
+                # objects, dataSourceRef allows any non-core object, as
+                # well as PersistentVolumeClaim objects. * While
+                # dataSource ignores disallowed values (dropping them),
+                # dataSourceRef preserves all values, and generates an
+                # error if a disallowed value is specified. * While
+                # dataSource only allows local objects, dataSourceRef
+                # allows objects in any namespaces. (Beta) Using this
+                # field requires the AnyVolumeDataSource feature gate
+                # to be enabled. (Alpha) Using the namespace field of
+                # dataSourceRef requires the
+                # CrossNamespaceVolumeDataSource feature gate to be
+                # enabled.
+                dataSourceRef:
+                  # APIGroup is the group for the resource being
+                  # referenced. If APIGroup is not specified, the
+                  # specified Kind must be in the core API group. For
+                  # any other third-party types, APIGroup is required.
+                  apiGroup: string
+                  # Kind is the type of resource being referenced
+                  kind: KineticaCluster
+                  # Name is the name of resource being referenced
+                  name: string
+                  # Namespace is the namespace of resource being
+                  # referenced Note that when a namespace is specified,
+                  # a gateway.networking.k8s.io/ReferenceGrant object
+                  # is required in the referent namespace to allow that
+                  # namespace's owner to accept the reference. See the
+                  # ReferenceGrant documentation for details.
+                  # (Alpha) This field requires the
+                  # CrossNamespaceVolumeDataSource feature gate to be
+                  # enabled.
+                  namespace: string
+                # resources represents the minimum resources the volume
+                # should have. If RecoverVolumeExpansionFailure feature
+                # is enabled users are allowed to specify resource
+                # requirements that are lower than previous value but
+                # must still be higher than capacity recorded in the
+                # status field of the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
+                resources:
+                  # Claims lists the names of resources, defined in
+                  # spec.resourceClaims, that are used by this
+                  # container. This is an alpha field and requires
+                  # enabling the DynamicResourceAllocation feature
+                  # gate. This field is immutable. It can only be set
+                  # for containers.
+                  claims:
+                  - name: string
+                  # Limits describes the maximum amount of compute
+                  # resources allowed. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  limits: {}
+                  # Requests describes the minimum amount of compute
+                  # resources required. If Requests is omitted for a
+                  # container, it defaults to Limits if that is
+                  # explicitly specified, otherwise to an
+                  # implementation-defined value. Requests cannot
+                  # exceed Limits. More info:
+                  # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+                  requests: {}
+                # selector is a label query over volumes to consider for
+                # binding.
+                selector:
+                  # matchExpressions is a list of label selector
+                  # requirements. The requirements are ANDed.
+                  matchExpressions:
+                  - key: string
+                    # operator represents a key's relationship to a set
+                    # of values. Valid operators are In, NotIn, Exists
+                    # and DoesNotExist.
+                    operator: string
+                    # values is an array of string values. If the
+                    # operator is In or NotIn, the values array must be
+                    # non-empty. If the operator is Exists or
+                    # DoesNotExist, the values array must be empty.
+                    # This array is replaced during a strategic merge
+                    # patch.
+                    values: ["string"]
+                  # matchLabels is a map of {key,value} pairs. A single
+                  # {key,value} in the matchLabels map is equivalent to
+                  # an element of matchExpressions, whose key field
+                  # is "key", the operator is "In", and the values
+                  # array contains only "value". The requirements are
+                  # ANDed.
+                  matchLabels: {}
+                # storageClassName is the name of the StorageClass
+                # required by the claim. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
+                storageClassName: string
+                # volumeMode defines what type of volume is required by
+                # the claim. Value of Filesystem is implied when not
+                # included in claim spec.
+                volumeMode: string
+                # volumeName is the binding reference to the
+                # PersistentVolume backing this claim.
+                volumeName: string
+              # status represents the current information/status of a
+              # persistent volume claim. Read-only. More info:
+              # https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+              status:
+                # accessModes contains the actual access modes the
+                # volume backing the PVC has. More info:
+                # https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
+                accessModes: ["string"]
+                # allocatedResources is the storage resource within
+                # AllocatedResources tracks the capacity allocated to a
+                # PVC. It may be larger than the actual capacity when a
+                # volume expansion operation is requested. For storage
+                # quota, the larger value from allocatedResources and
+                # PVC.spec.resources is used. If allocatedResources is
+                # not set, PVC.spec.resources alone is used for quota
+                # calculation. If a volume expansion capacity request
+                # is lowered, allocatedResources is only lowered if
+                # there are no expansion operations in progress and if
+                # the actual volume capacity is equal or lower than the
+                # requested capacity. This is an alpha field and
+                # requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                allocatedResources: {}
+                # capacity represents the actual resources of the
+                # underlying volume.
+                capacity: {}
+                # conditions is the current Condition of persistent
+                # volume claim. If underlying persistent volume is
+                # being resized then the Condition will be set
+                # to 'ResizeStarted'.
+                conditions:
+                - lastProbeTime: string
+                  # lastTransitionTime is the time the condition
+                  # transitioned from one status to another.
+                  lastTransitionTime: string
+                  # message is the human-readable message indicating
+                  # details about last transition.
+                  message: string
+                  # reason is a unique, this should be a short, machine
+                  # understandable string that gives the reason for
+                  # condition's last transition. If it
+                  # reports "ResizeStarted" that means the underlying
+                  # persistent volume is being resized.
+                  reason: string status: string
+                  # PersistentVolumeClaimConditionType is a valid value
+                  # of PersistentVolumeClaimCondition.Type
+                  type: string
+                # phase represents the current phase of
+                # PersistentVolumeClaim.
+                phase: string
+                # resizeStatus stores status of resize operation.
+                # ResizeStatus is not set by default but when expansion
+                # is complete resizeStatus is set to empty string by
+                # resize controller or kubelet. This is an alpha field
+                # and requires enabling RecoverVolumeExpansionFailure
+                # feature.
+                resizeStatus: string
+        # The RAMTier represents the RAM available for data storage per
+        # rank. The RAM Tier is NOT used for small, non-data objects or
+        # variables that are allocated and deallocated for program flow
+        # control or used to store metadata or other similar
+        # information; these continue to use either the stack or the
+        # regular runtime memory allocator. This tier should be sized
+        # on each machine such that there is sufficient RAM left over
+        # to handle this overhead, as well as the needs of other
+        # processes running on the same machine.
+        ramTier:
+          # The RAM Tier represents the RAM available for data storage
+          # per rank. The RAM Tier is NOT used for small, non-data
+          # objects or variables that are allocated and deallocated for
+          # program flow control or used to store metadata or other
+          # similar information; these continue to use either the stack
+          # or the regular runtime memory allocator. This tier should
+          # be sized on each machine such that there is sufficient RAM
+          # left over to handle this overhead, as well as the needs of
+          # other processes running on the same machine. A default
+          # memory limit and eviction thresholds can be set across all
+          # ranks, while one or more ranks may be configured to
+          # override those defaults. The general format for RAM
+          # settings: 
+          #  # tier.ram.[default|rank<#>].<parameter> Valid *parameter*
+          #    names include: 
+          #  * 'limit'          : The maximum RAM (bytes) per rank that
+          #     can be allocated across all resource groups.  Default
+          #     is -1, signifying no limit and ignore watermark
+          #     settings. * 'high_watermark' : RAM percentage used
+          #     eviction threshold.  Once memory usage exceeds this
+          #     value, evictions from this tier will be scheduled in
+          #     the background and continue until the 'low_watermark'
+          #     percentage usage is reached.  Default is "90",
+          #     signifying a 90% memory usage
+          #     threshold. * 'low_watermark'  : RAM percentage used
+          #     recovery threshold.  Once memory usage exceeds
+          #     the 'high_watermark', evictions will continue until
+          #     memory usage falls below this recovery threshold.
+          #     Default is "50", signifying a 50% memory usage
+          #     threshold.
+          default:
+            # * 'high_watermark' : Percentage used eviction threshold.
+            #    Once usage exceeds this value, evictions from this
+            #    tier will be scheduled in the background and continue
+            #    until the 'low_watermark' percentage usage is reached.
+            #    Default is "90", signifying a 90% memory usage
+            #    threshold.
+            highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string
+          # The maximum RAM (bytes) for processing data at rank 0.
+          # Overrides the overall default RAM tier
+          # limit. #tier.ram.rank0.limit = -1
+          ranks:
+          - highWatermark: 90
+            # * 'limit'          : The maximum (bytes) per rank that can
+            #    be allocated across all resource groups.
+            limit: "1Gi"
+            # * 'low_watermark'  : Percentage used recovery threshold.
+            #    Once usage exceeds the 'high_watermark', evictions
+            #    will continue until usage falls below this recovery
+            #    threshold. Default is "80", signifying an 80% usage
+            #    threshold.
+            lowWatermark: 80 name: string tieredStrategy:
+        # Default strategy to apply to tables or columns when one was
+        # not provided during table creation. This strategy is also
+        # applied to a resource group that does not specify one at time
+        # of creation. The strategy is formed by chaining together the
+        # tier types and their respective eviction priorities. Any
+        # given tier may appear no more than once in the chain and the
+        # priority must be in range "1" - "10", where "1" is the lowest
+        # priority (first to be evicted) and "9" is the highest
+        # priority (last to be evicted).  A priority of "10" indicates
+        # that an object is unevictable. Each tier's priority is in
+        # relation to the priority of other objects in the same tier;
+        # e.g., "RAM 9, DISK2 1" indicates that an object will be the
+        # highest evictable priority among objects in the RAM Tier
+        # (last evicted), but that it will be the lowest priority among
+        # objects in the Disk Tier named 'disk2' (first evicted).  Note
+        # that since an object can only have one Disk Tier instance in
+        # its strategy, the corresponding priority will only apply in
+        # relation to other objects in Disk Tier instance 'disk2'. See
+        # the Tiered Storage section for more information about tier
+        # type names. Format: <tier1> <priority>, <tier2> <priority>,
+        # <tier3> <priority>, ... Examples using a Disk Tier
+        # named 'disk2' and a Cold Storage Tier 'cold0': vram 3, ram 5,
+        # disk2 3, persist 10 vram 3, ram 5, disk2 3, persist 6, cold0
+        # 10 tier_strategy.default = VRAM 1, RAM 5, PERSIST 5
+        default: "VRAM 1, RAM 5, PERSIST 5"
+        # Predicate evaluation interval (in minutes) -  indicates the
+        # interval at which the tier strategy predicates are evaluated
+        predicateEvaluationInterval: 60 video:
+        # System default TTL for videos. Time-to-live (TTL) is the
+        # number of minutes before a video will expire and be removed,
+        # or -1 to disable. video_default_ttl = -1
+        defaultTTL: "-1"
+        # The maximum number of videos to allow on the system. Set to 0
+        # to disable video rendering.  Set to -1 to allow an unlimited
+        # number of videos. video_max_count = -1
+        maxCount: "-1"
+        # Directory where video files should be temporarily stored while
+        # rendering. Only accessed by rank 0. video_temp_directory = $
+        # {gaia.temp_directory}/gpudb-temp-videos
+        tmpDir: "${gaia.temp_directory}/gpudb-temp-videos"
+      # VisualizationConfig
+      visualization:
+        # Enable level-of-details rendering for fast interaction with
+        # large WKT polygon data.  Only available for the OpenGL
+        # renderer (when 'enable_opengl_renderer' is "true").
+        enableLODRendering: true
+        # If "true", enable hardware-accelerated OpenGL renderer;
+        # if "false", use the software-based Cairo renderer.
+        enableOpenGLRenderer: true
+        # If "true", enable Vector Tile Service (VTS) to support
+        # client-side visualization of geospatial data. Enabling this
+        # option increases memory usage on ingestion.
+        enableVectorTileService: false
+        # Longitude and latitude ranges of geospatial data for which
+        # level-of-details representations are being generated. The
+        # parameter order is: <min_longitude> <min_latitude>
+        # <max_longitude> <max_latitude> The default values span over
+        # the world, but the level-of-details rendering becomes more
+        # efficient when the precise extent of geospatial data is
+        # specified. kubebuilder:default:={ -180, -90, 180, 90 }
+        lodDataExtent: [integer]
+        # The extent to which shape data are pre-processed for
+        # level-of-details rendering during data insert/load or
+        # processed on-the-fly in rendering time. This is a trade-off
+        # between speed and memory. The higher the value, the faster
+        # level-of-details rendering is, but the more memory is used
+        # for storing processed shape data. The maximum level is "10"
+        # (most shape data are pre-processed) and the minimum level
+        # is "0".
+        lodPreProcessingLevel: 5
+        # The number of subregions in horizontal and vertical geospatial
+        # data extent. The default values of "12 6" divide the world
+        # into subregions of 30 degree (lon.) x 30 degree (lat.)
+        lodSubRegionNum: [12,6]
+        # A base image resolution (width and height in pixels) at which
+        # a subregion would be rendered in a global view spanning over
+        # the whole dataset. Based on this resolution level-of-details
+        # representations are generated for the polygons located in the
+        # subregion.
+        lodSubRegionResolution: [512,512]
+        # Maximum heatmap size (in pixels) that can be generated. This
+        # reserves 'max_heatmap_size' ^ 2 * 8 bytes of GPU memory
+        # at **rank0**
+        maxHeatmapSize: 3072
+        # The maximum number of levels in the level-of-details
+        # rendering. As the number increases, level-of-details
+        # rendering becomes effective at higher zoom levels, but it may
+        # increase memory usage for storing level-of-details
+        # representations.
+        maxLODLevel: 8
+        # Input geometries are pre-processed upon ingestion for faster
+        # vector tile generation. This parameter determines the
+        # zoomlevel at which the vector tile pre-processing stops. A
+        # vector tile request for a higher zoomlevel than this
+        # parameter takes additional time because the vector tile needs
+        # to be generated on the fly.
+        maxVectorTileZoomLevel: 8
+        # Input geometries are pre-processed upon ingestion for faster
+        # vector tile generation. This parameter determines the
+        # zoomlevel from which the vector tile pre-processing starts. A
+        # vector tile request for a lower zoomlevel than this parameter
+        # takes additional time because the vector tile needs to be
+        # generated on the fly.
+        minVectorTileZoomLevel: 1
+        # The number of samples to use for antialiasing. Higher numbers
+        # will improve image quality but require more GPU memory to
+        # store the samples on worker ranks.  This affects only the
+        # OpenGL renderer. Value may be "0", "4", "8" or "16". When "0"
+        # antialiasing is disabled. The default value is "0".
+        openGLAntialiasingLevel: 1
+        # Threshold number of points (per-TOM) at which point rendering
+        # switches to fast mode.
+        pointRenderThreshold: 100000
+        # Single-precision coordinates are used for usual rendering
+        # processes, but depending on the precision of geometry data
+        # and use case, double precision processing may be required at
+        # a high zoomlevel. Double precision rendering processes are
+        # used from the zoomlevel specified by this parameter, which is
+        # corresponding to a zoomlevel of TMS or Google map service.
+        renderingPrecisionThreshold: 30
+        # The image width/height (in pixels) of svg symbols cached in
+        # the OpenGL symbol cache.
+        symbolResolution: 100
+        # The width/height (in pixels) of an OpenGL texture which caches
+        # symbol images for OpenGL rendering.
+        symbolTextureSize: 4000
+        # Threshold for the number of points (per-TOM) after which
+        # symbology rendering falls back to regular rendering
+        symbologyRenderThreshold: 10000
+        # The name of map tiler used for Vector Tile Service. "google"
+        # and "tms" map tilers are supported currently. This parameter
+        # should be matched with the map tiler of clients' vector tile
+        # renderer.
+        vectorTileMapTiler: "google" workbench:
+        # Start the Workbench app on the head host when host manager is
+        # started. enable_workbench = false
+        enable: false
+        # # HTTP server port for Workbench if enabled. workbench_port =
+        #   8000
+        port:
+          # Number of port to expose on the pod's IP address. This must
+          # be a valid port number, 0 < x < 65536.
+          containerPort: 1
+          # What host IP to bind the external port to.
+          hostIP: string
+          # Number of port to expose on the host. If specified, this
+          # must be a valid port number, 0 < x < 65536. If HostNetwork
+          # is specified, this must match ContainerPort. Most
+          # containers do not need this.
+          hostPort: 1
+          # If specified, this must be an IANA_SVC_NAME and unique
+          # within the pod. Each named port in a pod must have a unique
+          # name. Name for the port that can be referred to by
+          # services.
+          name: string
+          # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+          # to "TCP".
+          protocol: "TCP"
+    # The fully qualified URL used on the Ingress records for any
+    # exposed services. Completed buy yth Operator. DO NOT POPULATE
+    # MANUALLY.
+    fqdn: ""
+    # The name of the parent HA Ring this cluster belongs to.
+    haRingName: "default"
+    # Whether to enable the separate node 'pools' for "infra", "compute"
+    # pod scheduling. Default: false
+    hasPools: true
+    # The port the HostManager will be running in each pod in the
+    # cluster. Default: 9300, TCP
+    hostManagerPort:
+      # Number of port to expose on the pod's IP address. This must be a
+      # valid port number, 0 < x < 65536.
+      containerPort: 1
+      # What host IP to bind the external port to.
+      hostIP: string
+      # Number of port to expose on the host. If specified, this must be
+      # a valid port number, 0 < x < 65536. If HostNetwork is
+      # specified, this must match ContainerPort. Most containers do
+      # not need this.
+      hostPort: 1
+      # If specified, this must be an IANA_SVC_NAME and unique within
+      # the pod. Each named port in a pod must have a unique name. Name
+      # for the port that can be referred to by services.
+      name: string
+      # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+      # to "TCP".
+      protocol: "TCP"
+    # Set the name of the container image to use.
+    image: "kinetica/kinetica-k8s-intel:v7.1.6.0"
+    # Set the policy for pulling container images.
+    imagePullPolicy: "IfNotPresent"
+    # ImagePullSecrets is an optional list of references to secrets in
+    # the same gpudb-namespace to use for pulling any of the images
+    # used by this PodSpec. If specified, these secrets will be passed
+    # to individual puller implementations for them to use. For
+    # example, in the case of docker, only DockerConfig type secrets
+    # are honored.
+    imagePullSecrets:
+    - name: string
+    # Labels - Pod labels to be applied to the Statefulset DB pods.
+    labels: {}
+    # The Ingress Endpoint that GAdmin will be running on.
+    letsEncrypt:
+      # Enable LetsEncrypt for Certificate generation.
+      enabled: false
+      # LetsEncryptEnvironment
+      environment: "staging"
+    # Set the Kinetica DB License.
+    license: string
+    # Periodic probe of container liveness. Container will be restarted
+    # if the probe fails. Cannot be updated. More info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    livenessProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+    # LoggerConfig Kinetica DB Logger Configuration Object Configure the
+    # LOG4CPLUS logger for the DB. Field takes a string containing the
+    # full configuration. If not specified a template file is used
+    # during DB configuration generation.
+    loggerConfig: configString: string
+    # Metrics - DB Metrics scrape & forward configuration for
+    # `fluent-bit`.
+    metricsRegistryRepositoryTag:
+      # Set the policy for pulling container images.
+      imagePullPolicy: "IfNotPresent"
+      # ImagePullSecrets is an optional list of references to secrets in
+      # the same gpudb-namespace to use for pulling any of the images
+      # used by this PodSpec. If specified, these secrets will be
+      # passed to individual puller implementations for them to use.
+      # For example, in the case of docker, only DockerConfig type
+      # secrets are honored.
+      imagePullSecrets:
+      - name: string
+      # The image registry & optional port containing the repository.
+      registry: "docker.io"
+      # The image repository path.
+      repository: "kineticadevcloud/"
+      # SemVer = Semantic Version for the Tag SemVer semver.Version
+      semVer: string
+      # The image sha.
+      sha: ""
+      # The image tag.
+      tag: "v7.1.5.2"
+    # Metrics - `fluent-bit` container requests/limits.
+    metricsResources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+    # NodeSelector - NodeSelector to be applied to the DB Pods
+    nodeSelector: {}
+    # Do not use internal Operator field only.
+    originalReplicas: 1
+    # podManagementPolicy controls how pods are created during initial
+    # scale up, when replacing pods on nodes, or when scaling down. The
+    # default policy is `OrderedReady`, where pods are created in
+    # increasing order (pod-0, then pod-1, etc) and the controller will
+    # wait until each pod is ready before continuing. When scaling
+    # down, the pods are removed in the opposite order. The alternative
+    # policy is `Parallel` which will create pods in parallel to match
+    # the desired scale without waiting, and on scale down will delete
+    # all pods at once.
+    podManagementPolicy: "Parallel"
+    # Number of ranks per node as a uint16 i.e. 1-65535 ranks per node.
+    # Default: 1
+    ranksPerNode: 1
+    # Periodic probe of container service readiness. Container will be
+    # removed from service endpoints if the probe fails. Cannot be
+    # updated. More info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    readinessProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+    # The number of DB ranks i.e. replicas that the cluster will spin
+    # up. Default: 3
+    replicas: 3
+    # Limit the resources a DB Pod can consume.
+    resources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+    # SecurityContext holds security configuration that will be applied
+    # to a container. Some fields are present in both SecurityContext
+    # and PodSecurityContext.  When both are set, the values in
+    # SecurityContext take precedence.
+    securityContext:
+      # AllowPrivilegeEscalation controls whether a process can gain
+      # more privileges than its parent process. This bool directly
+      # controls if the no_new_privs flag will be set on the container
+      # process. AllowPrivilegeEscalation is true always when the
+      # container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note
+      # that this field cannot be set when spec.os.name is windows.
+      allowPrivilegeEscalation: true
+      # The capabilities to add/drop when running containers. Defaults
+      # to the default set of capabilities granted by the container
+      # runtime. Note that this field cannot be set when spec.os.name
+      # is windows.
+      capabilities:
+        # Added capabilities
+        add: ["string"]
+        # Removed capabilities
+        drop: ["string"]
+      # Run container in privileged mode. Processes in privileged
+      # containers are essentially equivalent to root on the host.
+      # Defaults to false. Note that this field cannot be set when
+      # spec.os.name is windows.
+      privileged: true
+      # procMount denotes the type of proc mount to use for the
+      # containers. The default is DefaultProcMount which uses the
+      # container runtime defaults for readonly paths and masked paths.
+      # This requires the ProcMountType feature flag to be enabled.
+      # Note that this field cannot be set when spec.os.name is
+      # windows.
+      procMount: string
+      # Whether this container has a read-only root filesystem. Default
+      # is false. Note that this field cannot be set when spec.os.name
+      # is windows.
+      readOnlyRootFilesystem: true
+      # The GID to run the entrypoint of the container process. Uses
+      # runtime default if unset. May also be set in
+      # PodSecurityContext.  If set in both SecurityContext and
+      # PodSecurityContext, the value specified in SecurityContext
+      # takes precedence. Note that this field cannot be set when
+      # spec.os.name is windows.
+      runAsGroup: 1
+      # Indicates that the container must run as a non-root user. If
+      # true, the Kubelet will validate the image at runtime to ensure
+      # that it does not run as UID 0 (root) and fail to start the
+      # container if it does. If unset or false, no such validation
+      # will be performed. May also be set in PodSecurityContext.  If
+      # set in both SecurityContext and PodSecurityContext, the value
+      # specified in SecurityContext takes precedence.
+      runAsNonRoot: true
+      # The UID to run the entrypoint of the container process. Defaults
+      # to user specified in image metadata if unspecified. May also be
+      # set in PodSecurityContext.  If set in both SecurityContext and
+      # PodSecurityContext, the value specified in SecurityContext
+      # takes precedence. Note that this field cannot be set when
+      # spec.os.name is windows.
+      runAsUser: 1
+      # The SELinux context to be applied to the container. If
+      # unspecified, the container runtime will allocate a random
+      # SELinux context for each container.  May also be set in
+      # PodSecurityContext.  If set in both SecurityContext and
+      # PodSecurityContext, the value specified in SecurityContext
+      # takes precedence. Note that this field cannot be set when
+      # spec.os.name is windows.
+      seLinuxOptions:
+        # Level is SELinux level label that applies to the container.
+        level: string
+        # Role is a SELinux role label that applies to the container.
+        role: string
+        # Type is a SELinux type label that applies to the container.
+        type: string
+        # User is a SELinux user label that applies to the container.
+        user: string
+      # The seccomp options to use by this container. If seccomp options
+      # are provided at both the pod & container level, the container
+      # options override the pod options. Note that this field cannot
+      # be set when spec.os.name is windows.
+      seccompProfile:
+        # localhostProfile indicates a profile defined in a file on the
+        # node should be used. The profile must be preconfigured on the
+        # node to work. Must be a descending path, relative to the
+        # kubelet's configured seccomp profile location. Must only be
+        # set if type is "Localhost".
+        localhostProfile: string
+        # type indicates which kind of seccomp profile will be applied.
+        # Valid options are: Localhost - a profile defined in a file on
+        # the node should be used. RuntimeDefault - the container
+        # runtime default profile should be used. Unconfined - no
+        # profile should be applied.
+        type: string
+      # The Windows specific settings applied to all containers. If
+      # unspecified, the options from the PodSecurityContext will be
+      # used. If set in both SecurityContext and PodSecurityContext,
+      # the value specified in SecurityContext takes precedence. Note
+      # that this field cannot be set when spec.os.name is linux.
+      windowsOptions:
+        # GMSACredentialSpec is where the GMSA admission webhook
+        # (https://github.com/kubernetes-sigs/windows-gmsa) inlines the
+        # contents of the GMSA credential spec named by the
+        # GMSACredentialSpecName field.
+        gmsaCredentialSpec: string
+        # GMSACredentialSpecName is the name of the GMSA credential spec
+        # to use.
+        gmsaCredentialSpecName: string
+        # HostProcess determines if a container should be run as a 'Host
+        # Process' container. This field is alpha-level and will only
+        # be honored by components that enable the
+        # WindowsHostProcessContainers feature flag. Setting this field
+        # without the feature flag will result in errors when
+        # validating the Pod. All of a Pod's containers must have the
+        # same effective HostProcess value (it is not allowed to have a
+        # mix of HostProcess containers and non-HostProcess
+        # containers).  In addition, if HostProcess is true then
+        # HostNetwork must also be set to true.
+        hostProcess: true
+        # The UserName in Windows to run the entrypoint of the container
+        # process. Defaults to the user specified in image metadata if
+        # unspecified. May also be set in PodSecurityContext. If set in
+        # both SecurityContext and PodSecurityContext, the value
+        # specified in SecurityContext takes precedence.
+        runAsUserName: string
+    # StartupProbe indicates that the Pod has successfully initialized.
+    # If specified, no other probes are executed until this completes
+    # successfully. If this probe fails, the Pod will be restarted,
+    # just as if the livenessProbe failed. This can be used to provide
+    # different probe parameters at the beginning of a Pod's lifecycle,
+    # when it might take a long time to load data or warm a cache, than
+    # during steady-state operation. This cannot be updated. This is an
+    # alpha feature enabled by the StartupProbe feature flag. More
+    # info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    startupProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+  # HostManagerMonitor is used to monitor the Kinetica DB Ranks. If a
+  # rank is unavailable for the specified time(MaxRankFailureCount) the
+  # cluster will be restarted.
+  hostManagerMonitor:
+    # The HostMonitor Port for the DB StartupProbe, ReadinessProbe and
+    # Liveness probes. Default: 8888
+    db_healthz_port:
+      # Number of port to expose on the pod's IP address. This must be a
+      # valid port number, 0 < x < 65536.
+      containerPort: 1
+      # What host IP to bind the external port to.
+      hostIP: string
+      # Number of port to expose on the host. If specified, this must be
+      # a valid port number, 0 < x < 65536. If HostNetwork is
+      # specified, this must match ContainerPort. Most containers do
+      # not need this.
+      hostPort: 1
+      # If specified, this must be an IANA_SVC_NAME and unique within
+      # the pod. Each named port in a pod must have a unique name. Name
+      # for the port that can be referred to by services.
+      name: string
+      # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+      # to "TCP".
+      protocol: "TCP"
+    # The HostMonitor Port for the DB StartupProbe, ReadinessProbe and
+    # Liveness probes. Default: 8889
+    hm_healthz_port:
+      # Number of port to expose on the pod's IP address. This must be a
+      # valid port number, 0 < x < 65536.
+      containerPort: 1
+      # What host IP to bind the external port to.
+      hostIP: string
+      # Number of port to expose on the host. If specified, this must be
+      # a valid port number, 0 < x < 65536. If HostNetwork is
+      # specified, this must match ContainerPort. Most containers do
+      # not need this.
+      hostPort: 1
+      # If specified, this must be an IANA_SVC_NAME and unique within
+      # the pod. Each named port in a pod must have a unique name. Name
+      # for the port that can be referred to by services.
+      name: string
+      # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+      # to "TCP".
+      protocol: "TCP"
+    # Periodic probe of container liveness. Container will be restarted
+    # if the probe fails. Cannot be updated. More info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    livenessProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+    # Set the name of the container image to use.
+    monitorRegistryRepositoryTag:
+      # Set the policy for pulling container images.
+      imagePullPolicy: "IfNotPresent"
+      # ImagePullSecrets is an optional list of references to secrets in
+      # the same gpudb-namespace to use for pulling any of the images
+      # used by this PodSpec. If specified, these secrets will be
+      # passed to individual puller implementations for them to use.
+      # For example, in the case of docker, only DockerConfig type
+      # secrets are honored.
+      imagePullSecrets:
+      - name: string
+      # The image registry & optional port containing the repository.
+      registry: "docker.io"
+      # The image repository path.
+      repository: "kineticadevcloud/"
+      # SemVer = Semantic Version for the Tag SemVer semver.Version
+      semVer: string
+      # The image sha.
+      sha: ""
+      # The image tag.
+      tag: "v7.1.5.2"
+    # Periodic probe of container service readiness. Container will be
+    # removed from service endpoints if the probe fails. Cannot be
+    # updated. More info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    readinessProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+    # Allow for overriding resource requests/limits.
+    resources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+    # StartupProbe indicates that the Pod has successfully initialized.
+    # If specified, no other probes are executed until this completes
+    # successfully. If this probe fails, the Pod will be restarted,
+    # just as if the livenessProbe failed. This can be used to provide
+    # different probe parameters at the beginning of a Pod's lifecycle,
+    # when it might take a long time to load data or warm a cache, than
+    # during steady-state operation. This cannot be updated. This is an
+    # alpha feature enabled by the StartupProbe feature flag. More
+    # info:
+    # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+    startupProbe:
+      # Minimum consecutive failures for the probe to be considered
+      # failed after having succeeded. Defaults to 3. Minimum value is
+      # 1.
+      failureThreshold: 3
+      # Number of seconds after the container has started before
+      # liveness probes are initiated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      initialDelaySeconds: 10
+      # How often (in seconds) to perform the probe. Default to 10
+      # seconds. Minimum value is 1.
+      periodSeconds: 10
+  # The platform infrastructure provider e.g. azure, aws, gcp, on-prem
+  # etc.
+  infra: "on-prem"
+  # The Kubernetes Ingress Controller will be running on e.g.
+  # ingress-nginx, Traefik, Ambassador, Gloo, Kong etc.
+  ingressController: "nginx"
+  # The LDAP server to connect to.
+  ldap:
+    # BaseDN - The root base LDAP Distinguished Name to use as the base
+    # for the LDAP usage
+    baseDN: "dc=kinetica,dc=com"
+    # BindDN - The LDAP Distinguished Name to use for the LDAP
+    # connectivity/data connectivity/bind
+    bindDN: "cn=admin,dc=kinetica,dc=com"
+    # Host - The name of the host to connect to. If IsInLocalK8S=true
+    # then supply only the name e.g. `openldap` Default: openldap
+    host: "openldap"
+    # IsInLocalK8S - Is the LDAP server co-located in the same K8s
+    # cluster the operator is running in. Default: true
+    isInLocalK8S: true
+    # IsLDAPS - IUse LDAPS instead of LDAP Default: false
+    isLDAPS: false
+    # Namespace - The namespace the Default: openldap
+    namespace: "gpudb"
+    # Port - Defaults to LDAP Port 389 Default: 389
+    port: 389
+  # Tells the operator to use Cloud Provider Pay As You Go
+  # functionality.
+  payAsYouGo: false
+  # The Reveal Dashboard Configuration for the Kinetica Cluster.
+  reveal:
+    # The port that Reveal will be running on. It runs only on the head
+    # node pod in the cluster. Default: 8080
+    containerPort:
+      # Number of port to expose on the pod's IP address. This must be a
+      # valid port number, 0 < x < 65536.
+      containerPort: 1
+      # What host IP to bind the external port to.
+      hostIP: string
+      # Number of port to expose on the host. If specified, this must be
+      # a valid port number, 0 < x < 65536. If HostNetwork is
+      # specified, this must match ContainerPort. Most containers do
+      # not need this.
+      hostPort: 1
+      # If specified, this must be an IANA_SVC_NAME and unique within
+      # the pod. Each named port in a pod must have a unique name. Name
+      # for the port that can be referred to by services.
+      name: string
+      # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+      # to "TCP".
+      protocol: "TCP"
+    # The Ingress Endpoint that Reveal will be running on.
+    ingressPath:
+      # backend defines the referenced service endpoint to which the
+      # traffic will be forwarded to.
+      backend:
+        # resource is an ObjectRef to another Kubernetes resource in the
+        # namespace of the Ingress object. If resource is specified,
+        # serviceName and servicePort must not be specified.
+        resource:
+          # APIGroup is the group for the resource being referenced. If
+          # APIGroup is not specified, the specified Kind must be in
+          # the core API group. For any other third-party types,
+          # APIGroup is required.
+          apiGroup: string
+          # Kind is the type of resource being referenced
+          kind: KineticaCluster
+          # Name is the name of resource being referenced
+          name: string
+        # serviceName specifies the name of the referenced service.
+        serviceName: string
+        # servicePort Specifies the port of the referenced service.
+        servicePort: 
+      # path is matched against the path of an incoming request.
+      # Currently it can contain characters disallowed from the
+      # conventional "path" part of a URL as defined by RFC 3986. Paths
+      # must begin with a '/' and must be present when using PathType
+      # with value "Exact" or "Prefix".
+      path: string
+      # pathType determines the interpretation of the path matching.
+      # PathType can be one of the following values: * Exact: Matches
+      # the URL path exactly. * Prefix: Matches based on a URL path
+      # prefix split by '/'. Matching is done on a path element by
+      # element basis. A path element refers is the list of labels in
+      # the path split by the '/' separator. A request is a match for
+      # path p if every p is an element-wise prefix of p of the request
+      # path. Note that if the last element of the path is a substring
+      # of the last element in request path, it is not a match
+      # (e.g. /foo/bar matches /foo/bar/baz, but does not
+      # match /foo/barbaz). * ImplementationSpecific: Interpretation of
+      # the Path matching is up to the IngressClass. Implementations
+      # can treat this as a separate PathType or treat it identically
+      # to Prefix or Exact path types. Implementations are required to
+      # support all path types. Defaults to ImplementationSpecific.
+      pathType: string
+    # Whether to enable the Reveal Dashboard on the Cluster. Default:
+    # true
+    isEnabled: true
+  # The Stats server to deploy & connect to if required.
+  stats:
+    # AlertManager - AlertManager specific configuration.
+    alertManager:
+      # Set the arguments for the command within the container to run.
+      args:
+      ["-c","/opt/gpudb/kagent/stats/prometheus/prometheus --log.level=debug
+      --config.file=/opt/gpudb/kagent/stats/prometheus/prometheus.yml --web.listen-address=0.0.0.0:9090
+      --storage.tsdb.path=/opt/gpudb/kagent/stats/storage/prometheus-storage
+      --storage.tsdb.retention.time=7d  --web.enable-lifecycle"]
+      # Set the command within the container to run.
+      command: ["/bin/sh"]
+      # ConfigFile - Set the location of the Loki configuration file.
+      configFile: "/opt/gpudb/kagent/stats/loki/loki.yml"
+      # ConfigFileAsConfigMap - If true the ConfigFile is mounted from a
+      # ConfigMap
+      configFileAsConfigMap: true
+      # The port that Stats will be running on. It runs only on the head
+      # node pod in the cluster. Default: 9091
+      containerPort:
+        # Number of port to expose on the pod's IP address. This must be
+        # a valid port number, 0 < x < 65536.
+        containerPort: 1
+        # What host IP to bind the external port to.
+        hostIP: string
+        # Number of port to expose on the host. If specified, this must
+        # be a valid port number, 0 < x < 65536. If HostNetwork is
+        # specified, this must match ContainerPort. Most containers do
+        # not need this.
+        hostPort: 1
+        # If specified, this must be an IANA_SVC_NAME and unique within
+        # the pod. Each named port in a pod must have a unique name.
+        # Name for the port that can be referred to by services.
+        name: string
+        # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+        # to "TCP".
+        protocol: "TCP"
+      # List of environment variables to set in the container.
+      env:
+      - name: string
+        # Variable references $(VAR_NAME) are expanded using the
+        # previously defined environment variables in the container and
+        # any service environment variables. If a variable cannot be
+        # resolved, the reference in the input string will be
+        # unchanged. Double $$ are reduced to a single $, which allows
+        # for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+        # produce the string literal "$(VAR_NAME)". Escaped references
+        # will never be expanded, regardless of whether the variable
+        # exists or not. Defaults to "".
+        value: string
+        # Source for the environment variable's value. Cannot be used if
+        # value is not empty.
+        valueFrom:
+          # Selects a key of a ConfigMap.
+          configMapKeyRef:
+            # The key to select.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the ConfigMap or its key must be defined
+            optional: true
+          # Selects a field of the pod: supports metadata.name,
+          # metadata.namespace, `metadata.labels
+          # ['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
+          # spec.serviceAccountName, status.hostIP, status.podIP,
+          # status.podIPs.
+          fieldRef:
+            # Version of the schema the FieldPath is written in terms
+            # of, defaults to "v1".
+            apiVersion: app.kinetica.com/v1
+            # Path of the field to select in the specified API version.
+            fieldPath: string
+          # Selects a resource of the container: only resources limits
+          # and requests (limits.cpu, limits.memory,
+          # limits.ephemeral-storage, requests.cpu, requests.memory and
+          # requests.ephemeral-storage) are currently supported.
+          resourceFieldRef:
+            # Container name: required for volumes, optional for env
+            # vars
+            containerName: string
+            # Specifies the output format of the exposed resources,
+            # defaults to "1"
+            divisor: 
+            # Required: resource to select
+            resource: string
+          # Selects a key of a secret in the pod's namespace
+          secretKeyRef:
+            # The key of the secret to select from.  Must be a valid
+            # secret key.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the Secret or its key must be defined
+            optional: true
+      # Set the name of the container image to use.
+      image:
+        # Set the policy for pulling container images.
+        imagePullPolicy: "IfNotPresent"
+        # ImagePullSecrets is an optional list of references to secrets
+        # in the same gpudb-namespace to use for pulling any of the
+        # images used by this PodSpec. If specified, these secrets will
+        # be passed to individual puller implementations for them to
+        # use. For example, in the case of docker, only DockerConfig
+        # type secrets are honored.
+        imagePullSecrets:
+        - name: string
+        # The image registry & optional port containing the repository.
+        registry: "docker.io"
+        # The image repository path.
+        repository: "kineticadevcloud/"
+        # SemVer = Semantic Version for the Tag SemVer semver.Version
+        semVer: string
+        # The image sha.
+        sha: ""
+        # The image tag.
+        tag: "v7.1.5.2"
+      # Whether to enable the Stats Server on the Cluster. Default:
+      # true
+      isEnabled: true
+      # Periodic probe of container liveness. Container will be
+      # restarted if the probe fails. Cannot be updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      livenessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Logs - Set the location of the Loki configuration file.
+      logs: "/opt/gpudb/kagent/stats/logs" name: "stats"
+      # Periodic probe of container service readiness. Container will be
+      # removed from service endpoints if the probe fails. Cannot be
+      # updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      readinessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Resource Requests & Limits for the Stats Pod.
+      resources:
+        # Claims lists the names of resources, defined in
+        # spec.resourceClaims, that are used by this container. This is
+        # an alpha field and requires enabling the
+        # DynamicResourceAllocation feature gate. This field is
+        # immutable. It can only be set for containers.
+        claims:
+        - name: string
+        # Limits describes the maximum amount of compute resources
+        # allowed. More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        limits: {}
+        # Requests describes the minimum amount of compute resources
+        # required. If Requests is omitted for a container, it defaults
+        # to Limits if that is explicitly specified, otherwise to an
+        # implementation-defined value. Requests cannot exceed Limits.
+        # More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        requests: {}
+      # StoragePath - Set the location of the AlertManager file
+      # storage.
+      storagePath: "/opt/gpudb/kagent/stats/storage/alertmanager/alertmanager"
+      # WebConfigFile - Set the location of the AlertManager
+      # alertmanager-web-config.yml.
+      webConfigFile: "/opt/gpudb/kagent/stats/alertmanager/alertmanager-web-config.yml"
+      # WebListenAddress - Set the location of the AlertManager
+      # alertmanager-web-config.yml.
+      webListenAddress: "0.0.0.0:9089"
+    # Grafana - Grafana specific configuration.
+    grafana:
+      # Set the arguments for the command within the container to run.
+      args:
+      ["-c","/opt/gpudb/kagent/stats/prometheus/prometheus --log.level=debug
+      --config.file=/opt/gpudb/kagent/stats/prometheus/prometheus.yml --web.listen-address=0.0.0.0:9090
+      --storage.tsdb.path=/opt/gpudb/kagent/stats/storage/prometheus-storage
+      --storage.tsdb.retention.time=7d  --web.enable-lifecycle"]
+      # Set the command within the container to run.
+      command: ["/bin/sh"]
+      # ConfigFile - Set the location of the Loki configuration file.
+      configFile: "/opt/gpudb/kagent/stats/loki/loki.yml"
+      # ConfigFileAsConfigMap - If true the ConfigFile is mounted from a
+      # ConfigMap
+      configFileAsConfigMap: true
+      # The port that Stats will be running on. It runs only on the head
+      # node pod in the cluster. Default: 9091
+      containerPort:
+        # Number of port to expose on the pod's IP address. This must be
+        # a valid port number, 0 < x < 65536.
+        containerPort: 1
+        # What host IP to bind the external port to.
+        hostIP: string
+        # Number of port to expose on the host. If specified, this must
+        # be a valid port number, 0 < x < 65536. If HostNetwork is
+        # specified, this must match ContainerPort. Most containers do
+        # not need this.
+        hostPort: 1
+        # If specified, this must be an IANA_SVC_NAME and unique within
+        # the pod. Each named port in a pod must have a unique name.
+        # Name for the port that can be referred to by services.
+        name: string
+        # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+        # to "TCP".
+        protocol: "TCP"
+      # List of environment variables to set in the container.
+      env:
+      - name: string
+        # Variable references $(VAR_NAME) are expanded using the
+        # previously defined environment variables in the container and
+        # any service environment variables. If a variable cannot be
+        # resolved, the reference in the input string will be
+        # unchanged. Double $$ are reduced to a single $, which allows
+        # for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+        # produce the string literal "$(VAR_NAME)". Escaped references
+        # will never be expanded, regardless of whether the variable
+        # exists or not. Defaults to "".
+        value: string
+        # Source for the environment variable's value. Cannot be used if
+        # value is not empty.
+        valueFrom:
+          # Selects a key of a ConfigMap.
+          configMapKeyRef:
+            # The key to select.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the ConfigMap or its key must be defined
+            optional: true
+          # Selects a field of the pod: supports metadata.name,
+          # metadata.namespace, `metadata.labels
+          # ['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
+          # spec.serviceAccountName, status.hostIP, status.podIP,
+          # status.podIPs.
+          fieldRef:
+            # Version of the schema the FieldPath is written in terms
+            # of, defaults to "v1".
+            apiVersion: app.kinetica.com/v1
+            # Path of the field to select in the specified API version.
+            fieldPath: string
+          # Selects a resource of the container: only resources limits
+          # and requests (limits.cpu, limits.memory,
+          # limits.ephemeral-storage, requests.cpu, requests.memory and
+          # requests.ephemeral-storage) are currently supported.
+          resourceFieldRef:
+            # Container name: required for volumes, optional for env
+            # vars
+            containerName: string
+            # Specifies the output format of the exposed resources,
+            # defaults to "1"
+            divisor: 
+            # Required: resource to select
+            resource: string
+          # Selects a key of a secret in the pod's namespace
+          secretKeyRef:
+            # The key of the secret to select from.  Must be a valid
+            # secret key.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the Secret or its key must be defined
+            optional: true
+      # HomePath - Set the location of the Grafana home directory.
+      homePath: "/opt/gpudb/kagent/stats/grafana"
+      # GraphiteHost - Host Address
+      host: "0.0.0.0"
+      # Set the name of the container image to use.
+      image:
+        # Set the policy for pulling container images.
+        imagePullPolicy: "IfNotPresent"
+        # ImagePullSecrets is an optional list of references to secrets
+        # in the same gpudb-namespace to use for pulling any of the
+        # images used by this PodSpec. If specified, these secrets will
+        # be passed to individual puller implementations for them to
+        # use. For example, in the case of docker, only DockerConfig
+        # type secrets are honored.
+        imagePullSecrets:
+        - name: string
+        # The image registry & optional port containing the repository.
+        registry: "docker.io"
+        # The image repository path.
+        repository: "kineticadevcloud/"
+        # SemVer = Semantic Version for the Tag SemVer semver.Version
+        semVer: string
+        # The image sha.
+        sha: ""
+        # The image tag.
+        tag: "v7.1.5.2"
+      # Whether to enable the Stats Server on the Cluster. Default:
+      # true
+      isEnabled: true
+      # Periodic probe of container liveness. Container will be
+      # restarted if the probe fails. Cannot be updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      livenessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Logs - Set the location of the Loki configuration file.
+      logs: "/opt/gpudb/kagent/stats/logs" name: "stats"
+      # Periodic probe of container service readiness. Container will be
+      # removed from service endpoints if the probe fails. Cannot be
+      # updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      readinessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Resource Requests & Limits for the Stats Pod.
+      resources:
+        # Claims lists the names of resources, defined in
+        # spec.resourceClaims, that are used by this container. This is
+        # an alpha field and requires enabling the
+        # DynamicResourceAllocation feature gate. This field is
+        # immutable. It can only be set for containers.
+        claims:
+        - name: string
+        # Limits describes the maximum amount of compute resources
+        # allowed. More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        limits: {}
+        # Requests describes the minimum amount of compute resources
+        # required. If Requests is omitted for a container, it defaults
+        # to Limits if that is explicitly specified, otherwise to an
+        # implementation-defined value. Requests cannot exceed Limits.
+        # More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        requests: {}
+    # Whether to enable the Stats Server on the Cluster. Default: true
+    isEnabled: true
+    # Loki - Loki specific configuration.
+    loki:
+      # Set the arguments for the command within the container to run.
+      args:
+      ["-c","/opt/gpudb/kagent/stats/prometheus/prometheus --log.level=debug
+      --config.file=/opt/gpudb/kagent/stats/prometheus/prometheus.yml --web.listen-address=0.0.0.0:9090
+      --storage.tsdb.path=/opt/gpudb/kagent/stats/storage/prometheus-storage
+      --storage.tsdb.retention.time=7d  --web.enable-lifecycle"]
+      # Set the command within the container to run.
+      command: ["/bin/sh"]
+      # ConfigFile - Set the location of the Loki configuration file.
+      configFile: "/opt/gpudb/kagent/stats/loki/loki.yml"
+      # ConfigFileAsConfigMap - If true the ConfigFile is mounted from a
+      # ConfigMap
+      configFileAsConfigMap: true
+      # The port that Stats will be running on. It runs only on the head
+      # node pod in the cluster. Default: 9091
+      containerPort:
+        # Number of port to expose on the pod's IP address. This must be
+        # a valid port number, 0 < x < 65536.
+        containerPort: 1
+        # What host IP to bind the external port to.
+        hostIP: string
+        # Number of port to expose on the host. If specified, this must
+        # be a valid port number, 0 < x < 65536. If HostNetwork is
+        # specified, this must match ContainerPort. Most containers do
+        # not need this.
+        hostPort: 1
+        # If specified, this must be an IANA_SVC_NAME and unique within
+        # the pod. Each named port in a pod must have a unique name.
+        # Name for the port that can be referred to by services.
+        name: string
+        # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+        # to "TCP".
+        protocol: "TCP"
+      # List of environment variables to set in the container.
+      env:
+      - name: string
+        # Variable references $(VAR_NAME) are expanded using the
+        # previously defined environment variables in the container and
+        # any service environment variables. If a variable cannot be
+        # resolved, the reference in the input string will be
+        # unchanged. Double $$ are reduced to a single $, which allows
+        # for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+        # produce the string literal "$(VAR_NAME)". Escaped references
+        # will never be expanded, regardless of whether the variable
+        # exists or not. Defaults to "".
+        value: string
+        # Source for the environment variable's value. Cannot be used if
+        # value is not empty.
+        valueFrom:
+          # Selects a key of a ConfigMap.
+          configMapKeyRef:
+            # The key to select.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the ConfigMap or its key must be defined
+            optional: true
+          # Selects a field of the pod: supports metadata.name,
+          # metadata.namespace, `metadata.labels
+          # ['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
+          # spec.serviceAccountName, status.hostIP, status.podIP,
+          # status.podIPs.
+          fieldRef:
+            # Version of the schema the FieldPath is written in terms
+            # of, defaults to "v1".
+            apiVersion: app.kinetica.com/v1
+            # Path of the field to select in the specified API version.
+            fieldPath: string
+          # Selects a resource of the container: only resources limits
+          # and requests (limits.cpu, limits.memory,
+          # limits.ephemeral-storage, requests.cpu, requests.memory and
+          # requests.ephemeral-storage) are currently supported.
+          resourceFieldRef:
+            # Container name: required for volumes, optional for env
+            # vars
+            containerName: string
+            # Specifies the output format of the exposed resources,
+            # defaults to "1"
+            divisor: 
+            # Required: resource to select
+            resource: string
+          # Selects a key of a secret in the pod's namespace
+          secretKeyRef:
+            # The key of the secret to select from.  Must be a valid
+            # secret key.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the Secret or its key must be defined
+            optional: true
+      # ExpandEnv
+      expandEnv: true
+      # Set the name of the container image to use.
+      image:
+        # Set the policy for pulling container images.
+        imagePullPolicy: "IfNotPresent"
+        # ImagePullSecrets is an optional list of references to secrets
+        # in the same gpudb-namespace to use for pulling any of the
+        # images used by this PodSpec. If specified, these secrets will
+        # be passed to individual puller implementations for them to
+        # use. For example, in the case of docker, only DockerConfig
+        # type secrets are honored.
+        imagePullSecrets:
+        - name: string
+        # The image registry & optional port containing the repository.
+        registry: "docker.io"
+        # The image repository path.
+        repository: "kineticadevcloud/"
+        # SemVer = Semantic Version for the Tag SemVer semver.Version
+        semVer: string
+        # The image sha.
+        sha: ""
+        # The image tag.
+        tag: "v7.1.5.2"
+      # Whether to enable the Stats Server on the Cluster. Default:
+      # true
+      isEnabled: true
+      # Periodic probe of container liveness. Container will be
+      # restarted if the probe fails. Cannot be updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      livenessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Logs - Set the location of the Loki configuration file.
+      logs: "/opt/gpudb/kagent/stats/logs" name: "stats"
+      # Periodic probe of container service readiness. Container will be
+      # removed from service endpoints if the probe fails. Cannot be
+      # updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      readinessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Resource Requests & Limits for the Stats Pod.
+      resources:
+        # Claims lists the names of resources, defined in
+        # spec.resourceClaims, that are used by this container. This is
+        # an alpha field and requires enabling the
+        # DynamicResourceAllocation feature gate. This field is
+        # immutable. It can only be set for containers.
+        claims:
+        - name: string
+        # Limits describes the maximum amount of compute resources
+        # allowed. More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        limits: {}
+        # Requests describes the minimum amount of compute resources
+        # required. If Requests is omitted for a container, it defaults
+        # to Limits if that is explicitly specified, otherwise to an
+        # implementation-defined value. Requests cannot exceed Limits.
+        # More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        requests: {}
+      # Storage - Set the path of the Loki storage.
+      storage: "/opt/gpudb/kagent/stats/storage/loki-storage"
+    # Which vmss/node group etc. to use as the NodeSelector
+    pool: "compute"
+    # Prometheus - Prometheus specific configuration.
+    prometheus:
+      # Set the arguments for the command within the container to run.
+      args:
+      ["-c","/opt/gpudb/kagent/stats/prometheus/prometheus --log.level=debug
+      --config.file=/opt/gpudb/kagent/stats/prometheus/prometheus.yml --web.listen-address=0.0.0.0:9090
+      --storage.tsdb.path=/opt/gpudb/kagent/stats/storage/prometheus-storage
+      --storage.tsdb.retention.time=7d  --web.enable-lifecycle"]
+      # Set the command within the container to run.
+      command: ["/bin/sh"]
+      # ConfigFile - Set the location of the Loki configuration file.
+      configFile: "/opt/gpudb/kagent/stats/loki/loki.yml"
+      # ConfigFileAsConfigMap - If true the ConfigFile is mounted from a
+      # ConfigMap
+      configFileAsConfigMap: true
+      # The port that Stats will be running on. It runs only on the head
+      # node pod in the cluster. Default: 9091
+      containerPort:
+        # Number of port to expose on the pod's IP address. This must be
+        # a valid port number, 0 < x < 65536.
+        containerPort: 1
+        # What host IP to bind the external port to.
+        hostIP: string
+        # Number of port to expose on the host. If specified, this must
+        # be a valid port number, 0 < x < 65536. If HostNetwork is
+        # specified, this must match ContainerPort. Most containers do
+        # not need this.
+        hostPort: 1
+        # If specified, this must be an IANA_SVC_NAME and unique within
+        # the pod. Each named port in a pod must have a unique name.
+        # Name for the port that can be referred to by services.
+        name: string
+        # Protocol for port. Must be UDP, TCP, or SCTP. Defaults
+        # to "TCP".
+        protocol: "TCP"
+      # List of environment variables to set in the container.
+      env:
+      - name: string
+        # Variable references $(VAR_NAME) are expanded using the
+        # previously defined environment variables in the container and
+        # any service environment variables. If a variable cannot be
+        # resolved, the reference in the input string will be
+        # unchanged. Double $$ are reduced to a single $, which allows
+        # for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+        # produce the string literal "$(VAR_NAME)". Escaped references
+        # will never be expanded, regardless of whether the variable
+        # exists or not. Defaults to "".
+        value: string
+        # Source for the environment variable's value. Cannot be used if
+        # value is not empty.
+        valueFrom:
+          # Selects a key of a ConfigMap.
+          configMapKeyRef:
+            # The key to select.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the ConfigMap or its key must be defined
+            optional: true
+          # Selects a field of the pod: supports metadata.name,
+          # metadata.namespace, `metadata.labels
+          # ['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
+          # spec.serviceAccountName, status.hostIP, status.podIP,
+          # status.podIPs.
+          fieldRef:
+            # Version of the schema the FieldPath is written in terms
+            # of, defaults to "v1".
+            apiVersion: app.kinetica.com/v1
+            # Path of the field to select in the specified API version.
+            fieldPath: string
+          # Selects a resource of the container: only resources limits
+          # and requests (limits.cpu, limits.memory,
+          # limits.ephemeral-storage, requests.cpu, requests.memory and
+          # requests.ephemeral-storage) are currently supported.
+          resourceFieldRef:
+            # Container name: required for volumes, optional for env
+            # vars
+            containerName: string
+            # Specifies the output format of the exposed resources,
+            # defaults to "1"
+            divisor: 
+            # Required: resource to select
+            resource: string
+          # Selects a key of a secret in the pod's namespace
+          secretKeyRef:
+            # The key of the secret to select from.  Must be a valid
+            # secret key.
+            key: string
+            # Name of the referent. More info:
+            # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+            # TODO: Add other useful fields. apiVersion, kind, uid?
+            name: string
+            # Specify whether the Secret or its key must be defined
+            optional: true
+      # Set the name of the container image to use.
+      image:
+        # Set the policy for pulling container images.
+        imagePullPolicy: "IfNotPresent"
+        # ImagePullSecrets is an optional list of references to secrets
+        # in the same gpudb-namespace to use for pulling any of the
+        # images used by this PodSpec. If specified, these secrets will
+        # be passed to individual puller implementations for them to
+        # use. For example, in the case of docker, only DockerConfig
+        # type secrets are honored.
+        imagePullSecrets:
+        - name: string
+        # The image registry & optional port containing the repository.
+        registry: "docker.io"
+        # The image repository path.
+        repository: "kineticadevcloud/"
+        # SemVer = Semantic Version for the Tag SemVer semver.Version
+        semVer: string
+        # The image sha.
+        sha: ""
+        # The image tag.
+        tag: "v7.1.5.2"
+      # Whether to enable the Stats Server on the Cluster. Default:
+      # true
+      isEnabled: true
+      # Periodic probe of container liveness. Container will be
+      # restarted if the probe fails. Cannot be updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      livenessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Set the Prometheus logging level.
+      logLevel: "debug"
+      # Logs - Set the location of the Loki configuration file.
+      logs: "/opt/gpudb/kagent/stats/logs" name: "stats"
+      # Periodic probe of container service readiness. Container will be
+      # removed from service endpoints if the probe fails. Cannot be
+      # updated. More info:
+      # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+      readinessProbe:
+        # Exec specifies the action to take.
+        exec:
+          # Command is the command line to execute inside the container,
+          # the working directory for the command  is root ('/') in the
+          # container's filesystem. The command is simply exec'd, it is
+          # not run inside a shell, so traditional shell instructions
+          # ('|', etc) won't work. To use a shell, you need to
+          # explicitly call out to that shell. Exit status of 0 is
+          # treated as live/healthy and non-zero is unhealthy.
+          command: ["string"]
+        # Minimum consecutive failures for the probe to be considered
+        # failed after having succeeded. Defaults to 3. Minimum value
+        # is 1.
+        failureThreshold: 1
+        # GRPC specifies an action involving a GRPC port.
+        grpc:
+          # Port number of the gRPC service. Number must be in the range
+          # 1 to 65535.
+          port: 1
+          # Service is the name of the service to place in the gRPC
+          # HealthCheckRequest
+          # (see
+          # https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+          # If this is not specified, the default behavior is defined
+          # by gRPC.
+          service: string
+        # HTTPGet specifies the http request to perform.
+        httpGet:
+          # Host name to connect to, defaults to the pod IP. You
+          # probably want to set "Host" in httpHeaders instead.
+          host: string
+          # Custom headers to set in the request. HTTP allows repeated
+          # headers.
+          httpHeaders:
+          - name: string
+            # The header field value
+            value: string
+          # Path to access on the HTTP server.
+          path: string
+          # Name or number of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+          # Scheme to use for connecting to the host. Defaults to HTTP.
+          scheme: string
+        # Number of seconds after the container has started before
+        # liveness probes are initiated. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        initialDelaySeconds: 1
+        # How often (in seconds) to perform the probe. Default to 10
+        # seconds. Minimum value is 1.
+        periodSeconds: 1
+        # Minimum consecutive successes for the probe to be considered
+        # successful after having failed. Defaults to 1. Must be 1 for
+        # liveness and startup. Minimum value is 1.
+        successThreshold: 1
+        # TCPSocket specifies an action involving a TCP port.
+        tcpSocket:
+          # Optional: Host name to connect to, defaults to the pod IP.
+          host: string
+          # Number or name of the port to access on the container.
+          # Number must be in the range 1 to 65535. Name must be an
+          # IANA_SVC_NAME.
+          port: 
+        # Optional duration in seconds the pod needs to terminate
+        # gracefully upon probe failure. The grace period is the
+        # duration in seconds after the processes running in the pod
+        # are sent a termination signal and the time when the processes
+        # are forcibly halted with a kill signal. Set this value longer
+        # than the expected cleanup time for your process. If this
+        # value is nil, the pod's terminationGracePeriodSeconds will be
+        # used. Otherwise, this value overrides the value provided by
+        # the pod spec. Value must be non-negative integer. The value
+        # zero indicates stop immediately via the kill signal
+        # (no opportunity to shut down). This is a beta field and
+        # requires enabling ProbeTerminationGracePeriod feature gate.
+        # Minimum value is 1. spec.terminationGracePeriodSeconds is
+        # used if unset.
+        terminationGracePeriodSeconds: 1
+        # Number of seconds after which the probe times out. Defaults to
+        # 1 second. Minimum value is 1. More info:
+        # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
+        timeoutSeconds: 1
+      # Resource Requests & Limits for the Stats Pod.
+      resources:
+        # Claims lists the names of resources, defined in
+        # spec.resourceClaims, that are used by this container. This is
+        # an alpha field and requires enabling the
+        # DynamicResourceAllocation feature gate. This field is
+        # immutable. It can only be set for containers.
+        claims:
+        - name: string
+        # Limits describes the maximum amount of compute resources
+        # allowed. More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        limits: {}
+        # Requests describes the minimum amount of compute resources
+        # required. If Requests is omitted for a container, it defaults
+        # to Limits if that is explicitly specified, otherwise to an
+        # implementation-defined value. Requests cannot exceed Limits.
+        # More info:
+        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+        requests: {}
+      # Set the location of the TSDB database.
+      storageTSDBPath: "/opt/gpudb/kagent/stats/storage/prometheus-storage"
+      # Set the time to hold data in the TSDB database.
+      storageTSDBRetentionTime: "7d"
+      # Timings - Prometheus Intervals & Timeouts
+      timings: evaluationInterval: "30s" scrapeInterval: "30s"
+      scrapeTimeout: "10s"
+    # Whether to share a single PV for Loki, Prometheus & Grafana or
+    # have a separate PV for each. Default: true
+    sharedPV: true
+    # Resource block specifically for use with SharedPV = true to set
+    # storage `requests` & `limits`
+    sharedPVResources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+  # Supporting images like socat,busybox etc.
+  supportingImages:
+    # Set the resource requests/limits for the BusyBox Pod(s).
+    busyBoxResources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+    # Set the name of the container image to use.
+    busybox:
+      # Set the policy for pulling container images.
+      imagePullPolicy: "IfNotPresent"
+      # ImagePullSecrets is an optional list of references to secrets in
+      # the same gpudb-namespace to use for pulling any of the images
+      # used by this PodSpec. If specified, these secrets will be
+      # passed to individual puller implementations for them to use.
+      # For example, in the case of docker, only DockerConfig type
+      # secrets are honored.
+      imagePullSecrets:
+      - name: string
+      # The image registry & optional port containing the repository.
+      registry: "docker.io"
+      # The image repository path.
+      repository: "kineticadevcloud/"
+      # SemVer = Semantic Version for the Tag SemVer semver.Version
+      semVer: string
+      # The image sha.
+      sha: ""
+      # The image tag.
+      tag: "v7.1.5.2"
+    # Set the name of the container image to use.
+    socat:
+      # Set the policy for pulling container images.
+      imagePullPolicy: "IfNotPresent"
+      # ImagePullSecrets is an optional list of references to secrets in
+      # the same gpudb-namespace to use for pulling any of the images
+      # used by this PodSpec. If specified, these secrets will be
+      # passed to individual puller implementations for them to use.
+      # For example, in the case of docker, only DockerConfig type
+      # secrets are honored.
+      imagePullSecrets:
+      - name: string
+      # The image registry & optional port containing the repository.
+      registry: "docker.io"
+      # The image repository path.
+      repository: "kineticadevcloud/"
+      # SemVer = Semantic Version for the Tag SemVer semver.Version
+      semVer: string
+      # The image sha.
+      sha: ""
+      # The image tag.
+      tag: "v7.1.5.2"
+    # Set the resource requests/limits for the Socat Pod.
+    socatResources:
+      # Claims lists the names of resources, defined in
+      # spec.resourceClaims, that are used by this container. This is
+      # an alpha field and requires enabling the
+      # DynamicResourceAllocation feature gate. This field is
+      # immutable. It can only be set for containers.
+      claims:
+      - name: string
+      # Limits describes the maximum amount of compute resources
+      # allowed. More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      limits: {}
+      # Requests describes the minimum amount of compute resources
+      # required. If Requests is omitted for a container, it defaults
+      # to Limits if that is explicitly specified, otherwise to an
+      # implementation-defined value. Requests cannot exceed Limits.
+      # More info:
+      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+      requests: {}
+# KineticaClusterStatus defines the observed state of KineticaCluster
+status:
+  # CloudProvider the DB is deployed on
+  cloudProvider: string
+  # CloudRegion the DB is deployed on
+  cloudRegion: string
+  # ClusterSize the current number of ranks & type i.e. CPU or GPU of
+  # the cluster
+  clusterSize:
+    # ClusterSizeEnum - T-Shirt size of the Kinetica DB Cluster i.e. a
+    # representation of the number of nodes in a simple to understand
+    # T-Short size scheme. This indicates the size of the cluster i.e.
+    # the number of nodes. It does not identify the size of the cloud
+    # provider nodes. For node size see ClusterTypeEnum. Supported
+    # Values are: - XS S M L XL XXL XXXL
+    tshirtSize: string
+    # ClusterTypeEnum - An Enum of the node types of a KineticaCluster
+    # e.g. CPU, GPU along with the Cloud Provider node size e.g. size
+    # of the VM.
+    tshirtType: string
+  # The number of ranks (replicas) that the cluster was last run with
+  currentReplicas: 0
+  # The first start of a new cluster has completed.
+  firstStartComplete: false
+  # HostManagerStatusResponse - The contents of polling the HostManager
+  # on port 9300n are added to the BR status field. This allows clients
+  # to get the Host/Rank/Graph/ML status information.
+  hmStatus: cluster_leader: string cluster_operation: string graph:
+  status: string graph_status: string host_httpd_status: string
+  host_mode: string host_num_gpus: string host_pid: 1
+  host_stats_status: string host_status: string hostname: string hosts:
+  graph_status: string host_httpd_status: string host_mode: string
+  host_pid: 1 host_stats_status: string host_status: string ml_status:
+  string query_planner_status: string reveal_status: string
+  license_expiration: string license_status: string license_type:
+  string ml_status: string query_planner_status: string ranks: mode:
+  string
+      # Pid - The OS Process Id for the Rank.
+      pid: 1 status: string reveal_status: string system_idle_time:
+      string system_mode: string system_rebalancing: 1 system_status:
+      string text: status: string version: string
+  # The fully qualified Ingress routes.
+  ingressUrls: aaw: string dbMonitor: string files: string gadmin:
+  string postgresProxy: string ranks: {} reveal: string
+  # The fully qualified in-cluster Ingress routes.
+  internalIngressUrls: aaw: string dbMonitor: string files: string
+  gadmin: string postgresProxy: string ranks: {} reveal: string
+  # Identify FreeSaaS Cluster
+  isFreeSaaS: false
+  # HostOptions used during DB Cluster Scaling Functions
+  options: ram_limit: 1
+  # OutstandingBilling - A list of hours not yet billed for. Will only
+  # be present if the plan is Pay As You Go and the operator was unable
+  # to send the billing information due to an issue with the cloud
+  # providers billing APIs.
+  outstandingBillableHour:
+  - billable: true billed: true billedAt: string duration: string end:
+    string start: string
+  # The state or phase of the current DB installation
+  phase: stringv
+

\ No newline at end of file diff --git a/7.2/Reference/kinetica_workbench/index.html b/7.2/Reference/kinetica_workbench/index.html new file mode 100644 index 0000000..6740fb1 --- /dev/null +++ b/7.2/Reference/kinetica_workbench/index.html @@ -0,0 +1,10 @@ + Kinetica Workbench Reference - Kinetica for Kubernetes

Kinetica Workbench cRD Reference

Coming Soon

\ No newline at end of file diff --git a/7.2/Reference/workbench/index.html b/7.2/Reference/workbench/index.html new file mode 100644 index 0000000..da1dd6f --- /dev/null +++ b/7.2/Reference/workbench/index.html @@ -0,0 +1,47 @@ + Kinetica Workbench Configuration - Kinetica for Kubernetes

Kinetica Workbench Configuration

  • kubectl (yaml)
  • Helm Chart

Workbench

Using kubetctl a CustomResource of type KineticaCluster is used to define a new Kinetica DB Cluster in a yaml file.

The basic Group, Version, Kind or GVK to instantiate a Kinetica Workbench is as follows: -

Workbench GVK
1
+2
apiVersion: workbench.com.kinetica/v1
+kind: Workbench
+

Metadata

to which we add a metadata: block for the name of the DB CR along with the namespace into which we are targetting the installation of the DB cluster.

Workbench metadata
1
+2
+3
+4
+5
apiVersion: workbench.com.kinetica/v1
+kind: Workbench
+metadata:
+  name: workbench-kinetica-cluster
+  namespace: gpudb
+

The simplest valid Workbench CR looks as follows: -

workbench.yaml
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
apiVersion: workbench.com.kinetica/v1
+kind: Workbench
+metadata:
+  name: workbench-kinetica-cluster
+  namespace: gpudb
+spec:
+  executeSqlLimit: 10000
+  fqdn: kinetica-cluster.saas.kinetica.com
+  image: kineticastagingcloud/workbench:v7.1.9-8.rc1
+  letsEncrypt:
+    enabled: false
+  userIdleTimeout: 60
+  ingressController: nginx-ingress
+

1. clusterName - the user defined name of the Kinetica DB Cluster

2. clusterSize - block that defines the number of DB Ranks to run

\ No newline at end of file diff --git a/7.2/Setup/index.html b/7.2/Setup/index.html new file mode 100644 index 0000000..3facd90 --- /dev/null +++ b/7.2/Setup/index.html @@ -0,0 +1,10 @@ + Kinetica for Kubernetes Setup - Kinetica for Kubernetes

Kinetica for Kubernetes Setup

  • Prepare to Install


    What you need to know & do before beginning an installation.

    Preparation and Prerequisites

  • Set up in 15 minutes


    Install the Kinetica DB with helm and get up and running in minutes.

    Installation

  • Beyond a Simple Installation


    It is possible using the Helm Charts and Kinetica CRDs to customize your installation in a number of ways.

    Advanced Topics

\ No newline at end of file diff --git a/7.2/Support/index.html b/7.2/Support/index.html new file mode 100644 index 0000000..c95f1f4 --- /dev/null +++ b/7.2/Support/index.html @@ -0,0 +1,10 @@ + Support - Kinetica for Kubernetes

Support

  • Taking the next steps


    Further tutorials or help on configuring Kinetica in different environments.

    Help & Tutorials

  • Locating Issues


    In the unlikely event you require information on how to troubleshoot your installation, help can be found here.

    Troubleshooting

\ No newline at end of file diff --git a/7.2/Troubleshooting/troubleshooting/index.html b/7.2/Troubleshooting/troubleshooting/index.html new file mode 100644 index 0000000..53df89c --- /dev/null +++ b/7.2/Troubleshooting/troubleshooting/index.html @@ -0,0 +1,10 @@ + Troubleshooting - Kinetica for Kubernetes
\ No newline at end of file diff --git a/7.2/assets/distributed.png b/7.2/assets/distributed.png new file mode 100644 index 0000000000000000000000000000000000000000..87c4de4836c370b0de46ed66910546ee7b867513 GIT binary patch literal 67356 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 J*N7Sh{XZHI$=d(` literal 0 HcmV?d00001 diff --git a/7.2/assets/favicon.ico b/7.2/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9aa52c8a96c046bbc916a8f844f9bd9a3259e42e GIT binary patch literal 15406 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 IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/7.2/assets/javascripts/bundle.c8d2eff1.min.js b/7.2/assets/javascripts/bundle.c8d2eff1.min.js new file mode 100644 index 0000000..4b1b31f --- /dev/null +++ b/7.2/assets/javascripts/bundle.c8d2eff1.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var _i=Object.create;var br=Object.defineProperty;var Ai=Object.getOwnPropertyDescriptor;var Ci=Object.getOwnPropertyNames,Ft=Object.getOwnPropertySymbols,ki=Object.getPrototypeOf,vr=Object.prototype.hasOwnProperty,eo=Object.prototype.propertyIsEnumerable;var Zr=(e,t,r)=>t in e?br(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,F=(e,t)=>{for(var r in t||(t={}))vr.call(t,r)&&Zr(e,r,t[r]);if(Ft)for(var r of Ft(t))eo.call(t,r)&&Zr(e,r,t[r]);return e};var to=(e,t)=>{var r={};for(var o in e)vr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Ft)for(var o of Ft(e))t.indexOf(o)<0&&eo.call(e,o)&&(r[o]=e[o]);return r};var gr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Hi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ci(t))!vr.call(e,n)&&n!==r&&br(e,n,{get:()=>t[n],enumerable:!(o=Ai(t,n))||o.enumerable});return e};var jt=(e,t,r)=>(r=e!=null?_i(ki(e)):{},Hi(t||!e||!e.__esModule?br(r,"default",{value:e,enumerable:!0}):r,e));var ro=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var no=gr((xr,oo)=>{(function(e,t){typeof xr=="object"&&typeof oo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var ct=C.type,Ne=C.tagName;return!!(Ne==="INPUT"&&s[ct]&&!C.readOnly||Ne==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function h(C){a(C.target)&&(o||c(C.target))&&p(C.target)}function w(C){a(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function A(C){document.visibilityState==="hidden"&&(n&&(o=!0),Z())}function Z(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),Z(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var zr=gr((kt,Vr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof kt=="object"&&typeof Vr=="object"?Vr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof kt=="object"?kt.ClipboardJS=r():t.ClipboardJS=r()})(kt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Li}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(D){try{return document.execCommand(D)}catch(M){return!1}}var h=function(M){var O=f()(M);return u("cut"),O},w=h;function A(D){var M=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[M?"right":"left"]="-9999px";var I=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(I,"px"),O.setAttribute("readonly",""),O.value=D,O}var Z=function(M,O){var I=A(M);O.container.appendChild(I);var W=f()(I);return u("copy"),I.remove(),W},te=function(M){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},I="";return typeof M=="string"?I=Z(M,O):M instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(M==null?void 0:M.type)?I=Z(M.value,O):(I=f()(M),u("copy")),I},J=te;function C(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(O){return typeof O}:C=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},C(D)}var ct=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=M.action,I=O===void 0?"copy":O,W=M.container,K=M.target,Ce=M.text;if(I!=="copy"&&I!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(K!==void 0)if(K&&C(K)==="object"&&K.nodeType===1){if(I==="copy"&&K.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(I==="cut"&&(K.hasAttribute("readonly")||K.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ce)return J(Ce,{container:W});if(K)return I==="cut"?w(K):J(K,{container:W})},Ne=ct;function Pe(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(O){return typeof O}:Pe=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Pe(D)}function xi(D,M){if(!(D instanceof M))throw new TypeError("Cannot call a class as a function")}function Xr(D,M){for(var O=0;O0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof W.action=="function"?W.action:this.defaultAction,this.target=typeof W.target=="function"?W.target:this.defaultTarget,this.text=typeof W.text=="function"?W.text:this.defaultText,this.container=Pe(W.container)==="object"?W.container:document.body}},{key:"listenClick",value:function(W){var K=this;this.listener=p()(W,"click",function(Ce){return K.onClick(Ce)})}},{key:"onClick",value:function(W){var K=W.delegateTarget||W.currentTarget,Ce=this.action(K)||"copy",It=Ne({action:Ce,container:this.container,target:this.target(K),text:this.text(K)});this.emit(It?"success":"error",{action:Ce,text:It,trigger:K,clearSelection:function(){K&&K.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(W){return hr("action",W)}},{key:"defaultTarget",value:function(W){var K=hr("target",W);if(K)return document.querySelector(K)}},{key:"defaultText",value:function(W){return hr("text",W)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(W){var K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(W,K)}},{key:"cut",value:function(W){return w(W)}},{key:"isSupported",value:function(){var W=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],K=typeof W=="string"?[W]:W,Ce=!!document.queryCommandSupported;return K.forEach(function(It){Ce=Ce&&!!document.queryCommandSupported(It)}),Ce}}]),O}(a()),Li=Mi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,h,w){var A=p.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function c(l,f,u,h,w){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return a(A,f,u,h,w)}))}function p(l,f,u,h){return function(w){w.delegateTarget=s(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!s.string(h))throw new TypeError("Second argument must be a String");if(!s.fn(w))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,h,w);if(s.nodeList(u))return l(u,h,w);if(s.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return a(document.body,u,h,w)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function V(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function z(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,h)})})}function a(u,h){try{c(o[u](h))}catch(w){f(i[0][3],w)}}function c(u){u.value instanceof ot?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,h){u(h),i.shift(),i.length&&a(i[0][0],i[0][1])}}function so(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof ue=="function"?ue(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function k(e){return typeof e=="function"}function pt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Wt=pt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=ue(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(A){t={error:A}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof Wt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=ue(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{co(w)}catch(A){i=i!=null?i:[],A instanceof Wt?i=z(z([],V(i)),V(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Wt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)co(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Er=Ie.EMPTY;function Dt(e){return e instanceof Ie||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function co(e){k(e)?e():e.unsubscribe()}var ke={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var lt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?Er:(this.currentObservers=null,a.push(r),new Ie(function(){o.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new vo(r,o)},t}(j);var vo=function(e){se(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Er},t}(v);var St={now:function(){return(St.delegate||Date).now()},delegate:void 0};var Ot=function(e){se(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=St);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(ut.cancelAnimationFrame(o),r._scheduled=void 0)},t}(zt);var yo=function(e){se(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(qt);var de=new yo(xo);var L=new j(function(e){return e.complete()});function Kt(e){return e&&k(e.schedule)}function _r(e){return e[e.length-1]}function Je(e){return k(_r(e))?e.pop():void 0}function Ae(e){return Kt(_r(e))?e.pop():void 0}function Qt(e,t){return typeof _r(e)=="number"?e.pop():t}var dt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Yt(e){return k(e==null?void 0:e.then)}function Bt(e){return k(e[ft])}function Gt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Jt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Di(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Xt=Di();function Zt(e){return k(e==null?void 0:e[Xt])}function er(e){return ao(this,arguments,function(){var r,o,n,i;return Ut(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ot(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ot(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ot(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function tr(e){return k(e==null?void 0:e.getReader)}function N(e){if(e instanceof j)return e;if(e!=null){if(Bt(e))return Ni(e);if(dt(e))return Vi(e);if(Yt(e))return zi(e);if(Gt(e))return Eo(e);if(Zt(e))return qi(e);if(tr(e))return Ki(e)}throw Jt(e)}function Ni(e){return new j(function(t){var r=e[ft]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Vi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?g(function(n,i){return e(n,i,o)}):ce,ye(1),r?Qe(t):jo(function(){return new or}))}}function $r(e){return e<=0?function(){return L}:x(function(t,r){var o=[];t.subscribe(S(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new v}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,h=0,w=!1,A=!1,Z=function(){f==null||f.unsubscribe(),f=void 0},te=function(){Z(),l=u=void 0,w=A=!1},J=function(){var C=l;te(),C==null||C.unsubscribe()};return x(function(C,ct){h++,!A&&!w&&Z();var Ne=u=u!=null?u:r();ct.add(function(){h--,h===0&&!A&&!w&&(f=Pr(J,c))}),Ne.subscribe(ct),!l&&h>0&&(l=new it({next:function(Pe){return Ne.next(Pe)},error:function(Pe){A=!0,Z(),f=Pr(te,n,Pe),Ne.error(Pe)},complete:function(){w=!0,Z(),f=Pr(te,s),Ne.complete()}}),N(C).subscribe(l))})(p)}}function Pr(e,t){for(var r=[],o=2;oe.next(document)),e}function R(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=me(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function me(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var la=T(d(document.body,"focusin"),d(document.body,"focusout")).pipe(be(1),q(void 0),m(()=>Re()||document.body),B(1));function vt(e){return la.pipe(m(t=>e.contains(t)),Y())}function Vo(e,t){return T(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?be(t):ce,q(!1))}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function zo(e){return T(d(window,"load"),d(window,"resize")).pipe(Me(0,de),m(()=>Ue(e)),q(Ue(e)))}function ir(e){return{x:e.scrollLeft,y:e.scrollTop}}function et(e){return T(d(e,"scroll"),d(window,"resize")).pipe(Me(0,de),m(()=>ir(e)),q(ir(e)))}function qo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)qo(e,r)}function E(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)qo(o,n);return o}function ar(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function gt(e){let t=E("script",{src:e});return H(()=>(document.head.appendChild(t),T(d(t,"load"),d(t,"error").pipe(b(()=>Ar(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),ye(1))))}var Ko=new v,ma=H(()=>typeof ResizeObserver=="undefined"?gt("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Ko.next(t)})),b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function pe(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ee(e){return ma.pipe(y(t=>t.observe(e)),b(t=>Ko.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(()=>pe(e)))),q(pe(e)))}function xt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function sr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Qo=new v,fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)Qo.next(t)},{threshold:0}))).pipe(b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function yt(e){return fa.pipe(y(t=>t.observe(e)),b(t=>Qo.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Yo(e,t=16){return et(e).pipe(m(({y:r})=>{let o=pe(e),n=xt(e);return r>=n.height-o.height-t}),Y())}var cr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function Bo(e){return cr[e].checked}function Be(e,t){cr[e].checked!==t&&cr[e].click()}function We(e){let t=cr[e];return d(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ua(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function da(){return T(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(q(!1))}function Go(){let e=d(window,"keydown").pipe(g(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:Bo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),g(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!ua(o,r)}return!0}),le());return da().pipe(b(t=>t?L:e))}function ve(){return new URL(location.href)}function st(e,t=!1){if(G("navigation.instant")&&!t){let r=E("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Jo(){return new v}function Xo(){return location.hash.slice(1)}function Zo(e){let t=E("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function ha(e){return T(d(window,"hashchange"),e).pipe(m(Xo),q(Xo()),g(t=>t.length>0),B(1))}function en(e){return ha(e).pipe(m(t=>me(`[id="${t}"]`)),g(t=>typeof t!="undefined"))}function At(e){let t=matchMedia(e);return nr(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function tn(){let e=matchMedia("print");return T(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function Ur(e,t){return e.pipe(b(r=>r?t():L))}function Wr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function De(e,t){return Wr(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function rn(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function on(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function nn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function an(){return T(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(nn),q(nn()))}function sn(){return{width:innerWidth,height:innerHeight}}function cn(){return d(window,"resize",{passive:!0}).pipe(m(sn),q(sn()))}function pn(){return Q([an(),cn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function pr(e,{viewport$:t,header$:r}){let o=t.pipe(X("size")),n=Q([o,r]).pipe(m(()=>Ue(e)));return Q([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function ba(e){return d(e,"message",t=>t.data)}function va(e){let t=new v;return t.subscribe(r=>e.postMessage(r)),t}function ln(e,t=new Worker(e)){let r=ba(t),o=va(t),n=new v;n.subscribe(o);let i=o.pipe(ee(),oe(!0));return n.pipe(ee(),$e(r.pipe(U(i))),le())}var ga=P("#__config"),Et=JSON.parse(ga.textContent);Et.base=`${new URL(Et.base,ve())}`;function we(){return Et}function G(e){return Et.features.includes(e)}function ge(e,t){return typeof t!="undefined"?Et.translations[e].replace("#",t.toString()):Et.translations[e]}function Te(e,t=document){return P(`[data-md-component=${e}]`,t)}function ne(e,t=document){return R(`[data-md-component=${e}]`,t)}function xa(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function mn(e){if(!G("announce.dismiss")||!e.childElementCount)return L;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new v;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),xa(e).pipe(y(r=>t.next(r)),_(()=>t.complete()),m(r=>F({ref:e},r)))})}function ya(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function fn(e,t){let r=new v;return r.subscribe(({hidden:o})=>{e.hidden=o}),ya(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))}function Ct(e,t){return t==="inline"?E("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"})):E("div",{class:"md-tooltip",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"}))}function un(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("a",{href:r,class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}else return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("span",{class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}function dn(e){return E("button",{class:"md-clipboard md-icon",title:ge("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Dr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,E("del",null,p)," "],[]).slice(0,-1),i=we(),s=new URL(e.location,i.base);G("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=we();return E("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},E("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&E("div",{class:"md-search-result__icon md-icon"}),r>0&&E("h1",null,e.title),r<=0&&E("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return E("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&E("p",{class:"md-search-result__terms"},ge("search.result.term.missing"),": ",...n)))}function hn(e){let t=e[0].score,r=[...e],o=we(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreDr(l,1)),...c.length?[E("details",{class:"md-search-result__more"},E("summary",{tabIndex:-1},E("div",null,c.length>0&&c.length===1?ge("search.result.more.one"):ge("search.result.more.other",c.length))),...c.map(l=>Dr(l,1)))]:[]];return E("li",{class:"md-search-result__item"},p)}function bn(e){return E("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>E("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ar(r):r)))}function Nr(e){let t=`tabbed-control tabbed-control--${e}`;return E("div",{class:t,hidden:!0},E("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function vn(e){return E("div",{class:"md-typeset__scrollwrap"},E("div",{class:"md-typeset__table"},e))}function Ea(e){let t=we(),r=new URL(`../${e.version}/`,t.base);return E("li",{class:"md-version__item"},E("a",{href:`${r}`,class:"md-version__link"},e.title))}function gn(e,t){return E("div",{class:"md-version"},E("button",{class:"md-version__current","aria-label":ge("select.version")},t.title),E("ul",{class:"md-version__list"},e.map(Ea)))}var wa=0;function Ta(e,t){document.body.append(e);let{width:r}=pe(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=sr(t),n=typeof o!="undefined"?et(o):$({x:0,y:0}),i=T(vt(t),Vo(t)).pipe(Y());return Q([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Ue(t),l=pe(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function Ge(e){let t=e.title;if(!t.length)return L;let r=`__tooltip_${wa++}`,o=Ct(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new v;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),T(i.pipe(g(({active:s})=>s)),i.pipe(be(250),g(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Me(16,de)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ta(o,e).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))}).pipe(ze(ie))}function Sa(e,t){let r=H(()=>Q([zo(e),et(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=pe(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return vt(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),ye(+!o||1/0))))}function xn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),yt(e).pipe(U(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),T(i.pipe(g(({active:a})=>a)),i.pipe(be(250),g(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Me(16,de)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(s),g(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),d(n,"mousedown").pipe(U(s),ae(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Re())==null||p.blur()}}),r.pipe(U(s),g(a=>a===o),Ye(125)).subscribe(()=>e.focus()),Sa(e,t).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Oa(e){return e.tagName==="CODE"?R(".c, .c1, .cm",e):[e]}function Ma(e){let t=[];for(let r of Oa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function yn(e,t){t.append(...Array.from(e.childNodes))}function lr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Ma(t)){let[,c]=a.textContent.match(/\((\d+)\)/);me(`:scope > li:nth-child(${c})`,e)&&(s.set(c,un(c,i)),a.replaceWith(s.get(c)))}return s.size===0?L:H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=[];for(let[l,f]of s)p.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?yn(f,u):yn(u,f)}),T(...[...s].map(([,l])=>xn(l,t,{target$:r}))).pipe(_(()=>a.complete()),le())})}function En(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return En(t)}}function wn(e,t){return H(()=>{let r=En(e);return typeof r!="undefined"?lr(r,e,t):L})}var Tn=jt(zr());var La=0;function Sn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Sn(t)}}function _a(e){return Ee(e).pipe(m(({width:t})=>({scrollable:xt(e).width>t})),X("scrollable"))}function On(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new v,i=n.pipe($r(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[];if(Tn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${La++}`;let p=dn(c.id);c.insertBefore(p,e),G("content.tooltips")&&s.push(Ge(p))}let a=e.closest(".highlight");if(a instanceof HTMLElement){let c=Sn(a);if(typeof c!="undefined"&&(a.classList.contains("annotate")||G("content.code.annotate"))){let p=lr(c,e,t);s.push(Ee(a).pipe(U(i),m(({width:l,height:f})=>l&&f),Y(),b(l=>l?p:L)))}}return _a(e).pipe(y(c=>n.next(c)),_(()=>n.complete()),m(c=>F({ref:e},c)),$e(...s))});return G("content.lazy")?yt(e).pipe(g(n=>n),ye(1),b(()=>o)):o}function Aa(e,{target$:t,print$:r}){let o=!0;return T(t.pipe(m(n=>n.closest("details:not([open])")),g(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(g(n=>n||!o),y(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Mn(e,t){return H(()=>{let r=new v;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Aa(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}var Ln=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var qr,ka=0;function Ha(){return typeof mermaid=="undefined"||mermaid instanceof Element?gt("https://unpkg.com/mermaid@10.7.0/dist/mermaid.min.js"):$(void 0)}function _n(e){return e.classList.remove("mermaid"),qr||(qr=Ha().pipe(y(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Ln,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),qr.subscribe(()=>ro(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${ka++}`,r=E("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),qr.pipe(m(()=>({ref:e})))}var An=E("table");function Cn(e){return e.replaceWith(An),An.replaceWith(vn(e)),$({ref:e})}function $a(e){let t=e.find(r=>r.checked)||e[0];return T(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function kn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=R(":scope > input",e),i=Nr("prev");e.append(i);let s=Nr("next");return e.append(s),H(()=>{let a=new v,c=a.pipe(ee(),oe(!0));Q([a,Ee(e)]).pipe(U(c),Me(1,de)).subscribe({next([{active:p},l]){let f=Ue(p),{width:u}=pe(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=ir(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Q([et(o),Ee(o)]).pipe(U(c)).subscribe(([p,l])=>{let f=xt(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),T(d(i,"click").pipe(m(()=>-1)),d(s,"click").pipe(m(()=>1))).pipe(U(c)).subscribe(p=>{let{width:l}=pe(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(U(c),g(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=P(`label[for="${p.id}"]`);l.replaceChildren(E("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(c),g(f=>!(f.metaKey||f.ctrlKey)),y(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&a.pipe(Le(1),ae(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of R("[data-tabs]"))for(let A of R(":scope > input",w)){let Z=P(`label[for="${A.id}"]`);if(Z!==p&&Z.innerText.trim()===f){Z.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),a.pipe(U(c)).subscribe(()=>{for(let p of R("audio, video",e))p.pause()}),$a(n).pipe(y(p=>a.next(p)),_(()=>a.complete()),m(p=>F({ref:e},p)))}).pipe(ze(ie))}function Hn(e,{viewport$:t,target$:r,print$:o}){return T(...R(".annotate:not(.highlight)",e).map(n=>wn(n,{target$:r,print$:o})),...R("pre:not(.mermaid) > code",e).map(n=>On(n,{target$:r,print$:o})),...R("pre.mermaid",e).map(n=>_n(n)),...R("table:not([class])",e).map(n=>Cn(n)),...R("details",e).map(n=>Mn(n,{target$:r,print$:o})),...R("[data-tabs]",e).map(n=>kn(n,{viewport$:t,target$:r})),...R("[title]",e).filter(()=>G("content.tooltips")).map(n=>Ge(n)))}function Ra(e,{alert$:t}){return t.pipe(b(r=>T($(!0),$(!1).pipe(Ye(2e3))).pipe(m(o=>({message:r,active:o})))))}function $n(e,t){let r=P(".md-typeset",e);return H(()=>{let o=new v;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ra(e,t).pipe(y(n=>o.next(n)),_(()=>o.complete()),m(n=>F({ref:e},n)))})}function Pa({viewport$:e}){if(!G("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ke(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=We("search");return Q([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),q(!1))}function Rn(e,t){return H(()=>Q([Ee(e),Pa(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function Pn(e,{header$:t,main$:r}){return H(()=>{let o=new v,n=o.pipe(ee(),oe(!0));o.pipe(X("active"),je(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(R("[title]",e)).pipe(g(()=>G("content.tooltips")),re(s=>Ge(s)));return r.subscribe(o),t.pipe(U(n),m(s=>F({ref:e},s)),$e(i.pipe(U(n))))})}function Ia(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=pe(e);return{active:o>=n}}),X("active"))}function In(e,t){return H(()=>{let r=new v;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=me(".md-content h1");return typeof o=="undefined"?L:Ia(o,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))})}function Fn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Ee(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),X("bottom"))));return Q([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function Fa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(re(o=>d(o,"change").pipe(m(()=>o))),q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function jn(e){let t=R("input",e),r=E("meta",{name:"theme-color"});document.head.appendChild(r);let o=E("meta",{name:"color-scheme"});document.head.appendChild(o);let n=At("(prefers-color-scheme: light)");return H(()=>{let i=new v;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;a{let s=Te("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(Oe(ie)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Fa(t).pipe(U(n.pipe(Le(1))),at(),y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))})}function Un(e,{progress$:t}){return H(()=>{let r=new v;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(y(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Kr=jt(zr());function ja(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Wn({alert$:e}){Kr.default.isSupported()&&new j(t=>{new Kr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ja(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(y(t=>{t.trigger.focus()}),m(()=>ge("clipboard.copied"))).subscribe(e)}function Dn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ua(e,t){let r=new Map;for(let o of R("url",e)){let n=P("loc",o),i=[Dn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of R("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(Dn(new URL(a),t))}}return r}function mr(e){return on(new URL("sitemap.xml",e)).pipe(m(t=>Ua(t,new URL(e))),he(()=>$(new Map)))}function Wa(e,t){if(!(e.target instanceof Element))return L;let r=e.target.closest("a");if(r===null)return L;if(r.target||e.metaKey||e.ctrlKey)return L;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(new URL(r.href))):L}function Nn(e){let t=new Map;for(let r of R(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Vn(e){for(let t of R("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function Da(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=me(o),i=me(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Nn(document);for(let[o,n]of Nn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Te("container");return Fe(R("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),L}),ee(),oe(document))}function zn({location$:e,viewport$:t,progress$:r}){let o=we();if(location.protocol==="file:")return L;let n=mr(o.base);$(document).subscribe(Vn);let i=d(document.body,"click").pipe(je(n),b(([c,p])=>Wa(c,p)),le()),s=d(window,"popstate").pipe(m(ve),le());i.pipe(ae(t)).subscribe(([c,{offset:p}])=>{history.replaceState(p,""),history.pushState(null,"",c)}),T(i,s).subscribe(e);let a=e.pipe(X("pathname"),b(c=>rn(c,{progress$:r}).pipe(he(()=>(st(c,!0),L)))),b(Vn),b(Da),le());return T(a.pipe(ae(e,(c,p)=>p)),e.pipe(X("pathname"),b(()=>e),X("hash")),e.pipe(Y((c,p)=>c.pathname===p.pathname&&c.hash===p.hash),b(()=>i),y(()=>history.back()))).subscribe(c=>{var p,l;history.state!==null||!c.hash?window.scrollTo(0,(l=(p=history.state)==null?void 0:p.y)!=null?l:0):(history.scrollRestoration="auto",Zo(c.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(X("offset"),be(100)).subscribe(({offset:c})=>{history.replaceState(c,"")}),a}var Qn=jt(Kn());function Yn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,Qn.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Ht(e){return e.type===1}function fr(e){return e.type===3}function Bn(e,t){let r=ln(e);return T($(location.protocol!=="file:"),We("search")).pipe(He(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function Gn({document$:e}){let t=we(),r=De(new URL("../versions.json",t.base)).pipe(he(()=>L)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>d(document.body,"click").pipe(g(i=>!i.metaKey&&!i.ctrlKey),ae(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?L:(i.preventDefault(),$(c))}}return L}),b(i=>{let{version:s}=n.get(i);return mr(new URL(i)).pipe(m(a=>{let p=ve().href.replace(t.base,"");return a.has(p.split("#")[0])?new URL(`../${s}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>st(n,!0)),Q([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(gn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of ne("outdated"))a.hidden=!1})}function Ka(e,{worker$:t}){let{searchParams:r}=ve();r.has("q")&&(Be("search",!0),e.value=r.get("q"),e.focus(),We("search").pipe(He(i=>!i)).subscribe(()=>{let i=ve();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=vt(e),n=T(t.pipe(He(Ht)),d(e,"keyup"),o).pipe(m(()=>e.value),Y());return Q([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),B(1))}function Jn(e,{worker$:t}){let r=new v,o=r.pipe(ee(),oe(!0));Q([t.pipe(He(Ht)),r],(i,s)=>s).pipe(X("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(X("focus")).subscribe(({focus:i})=>{i&&Be("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),Ka(e,{worker$:t}).pipe(y(i=>r.next(i)),_(()=>r.complete()),m(i=>F({ref:e},i)),B(1))}function Xn(e,{worker$:t,query$:r}){let o=new v,n=Yo(e.parentElement).pipe(g(Boolean)),i=e.parentElement,s=P(":scope > :first-child",e),a=P(":scope > :last-child",e);We("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(ae(r),Ir(t.pipe(He(Ht)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?ge("search.result.none"):ge("search.result.placeholder");break;case 1:s.textContent=ge("search.result.one");break;default:let u=ar(l.length);s.textContent=ge("search.result.other",u)}});let c=o.pipe(y(()=>a.innerHTML=""),b(({items:l})=>T($(...l.slice(0,10)),$(...l.slice(10)).pipe(Ke(4),jr(n),b(([f])=>f)))),m(hn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(re(l=>{let f=me("details",l);return typeof f=="undefined"?L:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(g(fr),m(({data:l})=>l)).pipe(y(l=>o.next(l)),_(()=>o.complete()),m(l=>F({ref:e},l)))}function Qa(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ve();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Zn(e,t){let r=new v,o=r.pipe(ee(),oe(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),Qa(e,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))}function ei(e,{worker$:t,keyboard$:r}){let o=new v,n=Te("search-query"),i=T(d(n,"keydown"),d(n,"focus")).pipe(Oe(ie),m(()=>n.value),Y());return o.pipe(je(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(g(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(g(fr),m(({data:a})=>a)).pipe(y(a=>o.next(a)),_(()=>o.complete()),m(()=>({ref:e})))}function ti(e,{index$:t,keyboard$:r}){let o=we();try{let n=Bn(o.search,t),i=Te("search-query",e),s=Te("search-result",e);d(e,"click").pipe(g(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Be("search",!1)),r.pipe(g(({mode:c})=>c==="search")).subscribe(c=>{let p=Re();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of R(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}c.claim()}break;case"Escape":case"Tab":Be("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...R(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(g(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Jn(i,{worker$:n});return T(a,Xn(s,{worker$:n,query$:a})).pipe($e(...ne("search-share",e).map(c=>Zn(c,{query$:a})),...ne("search-suggest",e).map(c=>ei(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,qe}}function ri(e,{index$:t,location$:r}){return Q([t,r.pipe(q(ve()),g(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Yn(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=E("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ya(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return Q([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function Qr(e,o){var n=o,{header$:t}=n,r=to(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:s}=Ue(i);return H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=a.pipe(Me(0,de));return p.pipe(ae(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(He()).subscribe(()=>{for(let l of R(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2})}}}),fe(R("label[tabindex]",e)).pipe(re(l=>d(l,"click").pipe(Oe(ie),m(()=>l),U(c)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ya(e,r).pipe(y(l=>a.next(l)),_(()=>a.complete()),m(l=>F({ref:e},l)))})}function oi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Lt(De(`${r}/releases/latest`).pipe(he(()=>L),m(o=>({version:o.tag_name})),Qe({})),De(r).pipe(he(()=>L),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>F(F({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return De(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ni(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return De(r).pipe(he(()=>L),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))}function ii(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return oi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ni(r,o)}return L}var Ba;function Ga(e){return Ba||(Ba=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(ne("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return L}return ii(e.href).pipe(y(o=>__md_set("__source",o,sessionStorage)))}).pipe(he(()=>L),g(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function ai(e){let t=P(":scope > :last-child",e);return H(()=>{let r=new v;return r.subscribe(({facts:o})=>{t.appendChild(bn(o)),t.classList.add("md-source__repository--active")}),Ga(e).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Ja(e,{viewport$:t,header$:r}){return Ee(document.body).pipe(b(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),X("hidden"))}function si(e,t){return H(()=>{let r=new v;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?$({hidden:!1}):Ja(e,t)).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Xa(e,{viewport$:t,header$:r}){let o=new Map,n=R(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=me(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(X("height"),m(({height:a})=>{let c=Te("main"),p=P(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Ee(document.body).pipe(X("height"),b(a=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),je(i),b(([c,p])=>t.pipe(Rr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(a.height);for(;f.length;){let[,A]=f[0];if(A-p=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),q({prev:[],next:[]}),Ke(2,1),m(([a,c])=>a.prev.length{let i=new v,s=i.pipe(ee(),oe(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),G("toc.follow")){let a=T(t.pipe(be(1),m(()=>{})),t.pipe(be(250),m(()=>"smooth")));i.pipe(g(({prev:c})=>c.length>0),je(o.pipe(Oe(ie))),ae(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=sr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2,behavior:p})}}})}return G("navigation.tracking")&&t.pipe(U(s),X("offset"),be(250),Le(1),U(n.pipe(Le(1))),at({delay:250}),ae(i)).subscribe(([,{prev:a}])=>{let c=ve(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Xa(e,{viewport$:t,header$:r}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Za(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),Ke(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return Q([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),U(o.pipe(Le(1))),oe(!0),at({delay:250}),m(s=>({hidden:s})))}function pi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(s),X("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),d(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),Za(e,{viewport$:t,main$:o,target$:n}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))}function li({document$:e}){e.pipe(b(()=>R(".md-ellipsis")),re(t=>yt(t).pipe(U(e.pipe(Le(1))),g(r=>r),m(()=>t),ye(1))),g(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Ge(o).pipe(U(e.pipe(Le(1))),_(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>R(".md-status")),re(t=>Ge(t))).subscribe()}function mi({document$:e,tablet$:t}){e.pipe(b(()=>R(".md-toggle--indeterminate")),y(r=>{r.indeterminate=!0,r.checked=!1}),re(r=>d(r,"change").pipe(Fr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ae(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function es(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function fi({document$:e}){e.pipe(b(()=>R("[data-md-scrollfix]")),y(t=>t.removeAttribute("data-md-scrollfix")),g(es),re(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function ui({viewport$:e,tablet$:t}){Q([We("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(Ye(r?400:100))),ae(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ts(){return location.protocol==="file:"?gt(`${new URL("search/search_index.js",Yr.base)}`).pipe(m(()=>__index),B(1)):De(new URL("search/search_index.json",Yr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var rt=No(),Rt=Jo(),wt=en(Rt),Br=Go(),_e=pn(),ur=At("(min-width: 960px)"),hi=At("(min-width: 1220px)"),bi=tn(),Yr=we(),vi=document.forms.namedItem("search")?ts():qe,Gr=new v;Wn({alert$:Gr});var Jr=new v;G("navigation.instant")&&zn({location$:Rt,viewport$:_e,progress$:Jr}).subscribe(rt);var di;((di=Yr.version)==null?void 0:di.provider)==="mike"&&Gn({document$:rt});T(Rt,wt).pipe(Ye(125)).subscribe(()=>{Be("drawer",!1),Be("search",!1)});Br.pipe(g(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=me("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=me("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});li({document$:rt});mi({document$:rt,tablet$:ur});fi({document$:rt});ui({viewport$:_e,tablet$:ur});var tt=Rn(Te("header"),{viewport$:_e}),$t=rt.pipe(m(()=>Te("main")),b(e=>Fn(e,{viewport$:_e,header$:tt})),B(1)),rs=T(...ne("consent").map(e=>fn(e,{target$:wt})),...ne("dialog").map(e=>$n(e,{alert$:Gr})),...ne("header").map(e=>Pn(e,{viewport$:_e,header$:tt,main$:$t})),...ne("palette").map(e=>jn(e)),...ne("progress").map(e=>Un(e,{progress$:Jr})),...ne("search").map(e=>ti(e,{index$:vi,keyboard$:Br})),...ne("source").map(e=>ai(e))),os=H(()=>T(...ne("announce").map(e=>mn(e)),...ne("content").map(e=>Hn(e,{viewport$:_e,target$:wt,print$:bi})),...ne("content").map(e=>G("search.highlight")?ri(e,{index$:vi,location$:Rt}):L),...ne("header-title").map(e=>In(e,{viewport$:_e,header$:tt})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Ur(hi,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t})):Ur(ur,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t}))),...ne("tabs").map(e=>si(e,{viewport$:_e,header$:tt})),...ne("toc").map(e=>ci(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})),...ne("top").map(e=>pi(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})))),gi=rt.pipe(b(()=>os),$e(rs),B(1));gi.subscribe();window.document$=rt;window.location$=Rt;window.target$=wt;window.keyboard$=Br;window.viewport$=_e;window.tablet$=ur;window.screen$=hi;window.print$=bi;window.alert$=Gr;window.progress$=Jr;window.component$=gi;})(); +//# sourceMappingURL=bundle.c8d2eff1.min.js.map + diff --git a/7.2/assets/javascripts/bundle.c8d2eff1.min.js.map b/7.2/assets/javascripts/bundle.c8d2eff1.min.js.map new file mode 100644 index 0000000..fc522db --- /dev/null +++ b/7.2/assets/javascripts/bundle.c8d2eff1.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:

\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an