From f0d8cf044e3a94e63fbe75fb3d242d2e0e259dd6 Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mail@dustinkaiser.eu>
Date: Thu, 19 Sep 2024 16:49:57 +0200
Subject: [PATCH 1/7] wip

---
 charts/Makefile  | 33 +++++++++++++++++++++------------
 charts/README.md |  8 ++++++++
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/charts/Makefile b/charts/Makefile
index 8bf61fee..f33c5391 100644
--- a/charts/Makefile
+++ b/charts/Makefile
@@ -7,33 +7,32 @@ CONFIG_DIR := $(shell dirname $(REPO_CONFIG_LOCATION))
 CHART_DIRS := $(wildcard $(REPO_BASE_DIR)/charts/*/)
 
 .PHONY: .check-helmfile-installed
-.check-helmfile-installed:
+.check-helmfile-installed: ## Checks if helmfile is installed
 	@if ! command -v helmfile >/dev/null 2>&1; then \
 			echo "'helmfile' is not installed. Install it to continue ...";\
 	fi
 
-helmfile.yaml: simcore-charts/helmfile.yaml
+helmfile.yaml: simcore-charts/helmfile.yaml ## Copies the helmfile.yaml to the charts directory
 	cp $(CONFIG_DIR)/$@ $(REPO_BASE_DIR)/charts/helmfile.yaml
 
-simcore-charts/helmfile.yaml:
+simcore-charts/helmfile.yaml: ## Copies the simcore helmfile to the charts directory
 	cp $(CONFIG_DIR)/helmfile.simcore.yaml $(REPO_BASE_DIR)/charts/$@
 
 .PHONY: helmfile-lint
-helmfile-lint: .check-helmfile-installed helmfile.yaml
+helmfile-lint: .check-helmfile-installed helmfile.yaml ## Lints the helmfile
 	set -a; source $(REPO_CONFIG_LOCATION); set +a; \
 	helmfile lint
 
 .PHONY: .helmfile-local-post-install
-.helmfile-local-post-install:
+.helmfile-local-post-install: ## Post install steps for local helmfile deployment
 	@$(MAKE) -s configure-local-hosts
 	@echo "";
 	@echo "Cluster has been deployed locally: http://$(MACHINE_FQDN)";
 	@echo "    For secure connections self-signed certificates are used.";
-	@echo "    Install their root-ca certificate in your system for smooth experience.";
-	@echo "    For insecure connections make sure to disable automatic https redirects in your browser.";
+	@echo "
 
 .PHONY: helmfile-apply
-helmfile-apply: .check-helmfile-installed helmfile.yaml
+helmfile-apply: .check-helmfile-installed helmfile.yaml ## Applies the helmfile configuration
 	set -a; source $(REPO_CONFIG_LOCATION); set +a; \
 	helmfile -f $(REPO_BASE_DIR)/charts/helmfile.yaml apply
 
@@ -41,17 +40,27 @@ helmfile-apply: .check-helmfile-installed helmfile.yaml
 		$(MAKE) -s .helmfile-local-post-install; \
 	fi
 
+.PHONY: helmfile-sync
+helmfile-sync: .check-helmfile-installed helmfile.yaml ## Syncs the helmfile configuration
+	set -a; source $(REPO_CONFIG_LOCATION); set +a; \
+	helmfile -f $(REPO_BASE_DIR)/charts/helmfile.yaml sync
+
+	@if [ "$(MACHINE_FQDN)" = "osparc.local" ]; then \
+		$(MAKE) -s .helmfile-local-post-install; \
+	fi
+
+
 .PHONY: configure-local-hosts
-configure-local-hosts:
-	@echo "Addings $(MACHINE_FQDN) hosts to /etc/hosts ..."
+configure-local-hosts: ## Adds local hosts entries for the machine
+	@echo "Adding $(MACHINE_FQDN) hosts to /etc/hosts ..."
 	@grep -q '127.0.0.1 k8s.monitoring.$(MACHINE_FQDN)' /etc/hosts || echo '127.0.0.1 k8s.monitoring.$(MACHINE_FQDN)' | sudo tee -a /etc/hosts
 
 .PHONY: helmfile-diff
-helmfile-diff: .check-helmfile-installed helmfile.yaml
+helmfile-diff: .check-helmfile-installed helmfile.yaml ## Shows the differences that would be applied by helmfile
 	@set -a; source $(REPO_CONFIG_LOCATION); set +a; \
 	helmfile -f $(REPO_BASE_DIR)/charts/helmfile.yaml diff
 
 .PHONY: helmfile-delete
-helmfile-delete: .check-helmfile-installed helmfile.yaml
+helmfile-delete: .check-helmfile-installed helmfile.yaml ## Deletes the helmfile configuration
 	@set -a; source $(REPO_CONFIG_LOCATION); set +a; \
 	helmfile -f $(REPO_BASE_DIR)/charts/helmfile.yaml delete
diff --git a/charts/README.md b/charts/README.md
index 13767e80..45d83630 100644
--- a/charts/README.md
+++ b/charts/README.md
@@ -23,6 +23,14 @@ source: https://kind.sigs.k8s.io/docs/user/quick-start
 
 Follow the instructions here: https://helm.sh/docs/intro/install/
 
+Install the helm-diff plugin: `helm plugin install https://github.com/databus23/helm-diff`
+
+`via https://doc.traefik.io/traefik/user-guides/crd-acme/#ingressroute-definition`
+Install traefik-v3 CRDs: `kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml`
+
+`via https://doc.traefik.io/traefik/user-guides/crd-acme/#ingressroute-definition`
+Install traefik-v3 RBAC: `kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml`
+
 #### helmfile
 
 If you have a different OS / architecture, pick a different link from [release artifacts](https://github.com/helmfile/helmfile/releases)

From 293f63c8c7971afeb0de64af16d01153bf76eed4 Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mail@dustinkaiser.eu>
Date: Thu, 24 Oct 2024 10:13:28 +0200
Subject: [PATCH 2/7] Add csi-s3 and have portainer use it

---
 .gitignore                          | 3 +++
 charts/csi-s3/values.yaml.gotmpl    | 7 +++++++
 charts/portainer/values.yaml.gotmpl | 6 ++++++
 3 files changed, 16 insertions(+)
 create mode 100644 charts/csi-s3/values.yaml.gotmpl

diff --git a/.gitignore b/.gitignore
index 0c825bcd..24edb7f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -149,3 +149,6 @@ docker-compose.simcore.yml
 repo.config
 .temp
 .temp/**
+
+# By convention: `.secret` files are gitignored
+**/*.secret
diff --git a/charts/csi-s3/values.yaml.gotmpl b/charts/csi-s3/values.yaml.gotmpl
new file mode 100644
index 00000000..7e6ff4c9
--- /dev/null
+++ b/charts/csi-s3/values.yaml.gotmpl
@@ -0,0 +1,7 @@
+secret:
+  accessKey: {{ requiredEnv "S3_ACCESS_KEY" }}
+  secretKey: {{ requiredEnv "S3_SECRET_KEY" }}
+  region: {{ requiredEnv "S3_REGION" }}
+  endpoint: {{ requiredEnv "S3_ENDPOINT" }}
+storageClass:
+  singleBucket:  {{ requiredEnv "S3_K8S_CSI_BUCKET_NAME" }}
diff --git a/charts/portainer/values.yaml.gotmpl b/charts/portainer/values.yaml.gotmpl
index e89f2457..edc56479 100644
--- a/charts/portainer/values.yaml.gotmpl
+++ b/charts/portainer/values.yaml.gotmpl
@@ -18,6 +18,12 @@ serviceAccount:
   # The name of the service account to use.
   # If not set and create is true, a name is generated using the fullname template
   name: portainer-sa-clusteradmin
+persistence:
+  enabled: true
+  size: "10Gi"
+  annotations: {}
+  storageClass: "csi-s3"
+  existingClaim:
 
 podAnnotations: {}
 podLabels: {}

From f7f72ec27e13232dababef209c92e2a3a1b983d4 Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mail@dustinkaiser.eu>
Date: Fri, 25 Oct 2024 08:37:18 +0200
Subject: [PATCH 3/7] Change request @hrytsuk 1GB max portainer volume size

---
 charts/portainer/values.yaml.gotmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/charts/portainer/values.yaml.gotmpl b/charts/portainer/values.yaml.gotmpl
index edc56479..1f5f5c44 100644
--- a/charts/portainer/values.yaml.gotmpl
+++ b/charts/portainer/values.yaml.gotmpl
@@ -20,7 +20,7 @@ serviceAccount:
   name: portainer-sa-clusteradmin
 persistence:
   enabled: true
-  size: "10Gi"
+  size: "1Gi"
   annotations: {}
   storageClass: "csi-s3"
   existingClaim:

From c9c70d642e632e920a25cc76395cc56f1be8f134 Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mail@dustinkaiser.eu>
Date: Tue, 3 Dec 2024 16:08:00 +0100
Subject: [PATCH 4/7] Arch Linux Certificates Customization

---
 certificates/Makefile | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/certificates/Makefile b/certificates/Makefile
index a9326900..9af700df 100644
--- a/certificates/Makefile
+++ b/certificates/Makefile
@@ -66,16 +66,10 @@ install-root-certificate: rootca.crt ## installs a certificate in the host syste
 		echo "Is the DOCKER service ready? press when ready" && read -n 1; \
 	    fi;\
 		echo "======================================";,\
-		$(if $(IS_OSX),                                             \
-			sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain $<; \
-			echo "Please restart the DOCKER service now..." && read -n 1; \
-			echo "Is the DOCKER service ready? press when ready" && read -n 1; \
-		,                                                           \
-		sudo cp $< /usr/local/share/ca-certificates/osparc.crt; \
-		sudo update-ca-certificates -f;                            \
-		echo "# restarting docker daemon";                      \
+		sudo cp $< /etc/ca-certificates/trust-source/anchors/osparc.crt; \
+		sudo trust extract-compat &&                            \
+		echo "# restarting docker daemon" &&                      \
 		sudo systemctl restart docker                           \
-		) \
 	)
 
 

From e0955e80ce5dd234f857c847d131941653467906 Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mrnicegyu11@users.noreply.github.com>
Date: Tue, 4 Feb 2025 13:55:04 +0100
Subject: [PATCH 5/7] wip

---
 services/admin-panels/docker-compose.yml.j2      | 2 +-
 services/appmotion_gateway/docker-compose.yml.j2 | 6 +++---
 services/maintenance-page/docker-compose.yml.j2  | 4 ++--
 services/minio/docker-compose.yaml               | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/services/admin-panels/docker-compose.yml.j2 b/services/admin-panels/docker-compose.yml.j2
index 4861e2ee..dbdccea9 100644
--- a/services/admin-panels/docker-compose.yml.j2
+++ b/services/admin-panels/docker-compose.yml.j2
@@ -7,7 +7,7 @@ configs:
     file: ./data/{{ item.name }}{% endfor %}
 services:
   adminpanels:
-    image: jupyter/base-notebook:18b10e7f732d
+    image: jupyter/base-notebook:18b10e7f732d ## no arm iamge
     user: root
     networks:
       - public
diff --git a/services/appmotion_gateway/docker-compose.yml.j2 b/services/appmotion_gateway/docker-compose.yml.j2
index b2c82484..1fd8bb83 100644
--- a/services/appmotion_gateway/docker-compose.yml.j2
+++ b/services/appmotion_gateway/docker-compose.yml.j2
@@ -3,7 +3,7 @@ version: '3.7'
 services:
 
     adminer:
-        image: adminer:4.8.1
+        image: adminer:4.8.1 ## has arm
         init: true
         environment:
             - ADMINER_DEFAULT_SERVER=db
@@ -35,7 +35,7 @@ services:
             - public
 
     db:
-        image: mariadb:10.11
+        image: mariadb:10.11 ## has arm
         environment:
             - MYSQL_USER=${APPMOTION_GATEWAY_DB_USER}
             - MYSQL_PASSWORD=${APPMOTION_GATEWAY_DB_PASSWORD}
@@ -68,7 +68,7 @@ services:
             - internal
 
     api:
-        image: itisfoundation/appmotion-gateway-php-apache-8.2:1.2-2024-03-26-11-40.2a6228f@sha256:378587d0fe401b8453bddd65714ed505bd08fc1eb9f9da9fc0b566b98ed72bf6
+        image: itisfoundation/appmotion-gateway-php-apache-8.2:1.2-2024-03-26-11-40.2a6228f@sha256:378587d0fe401b8453bddd65714ed505bd08fc1eb9f9da9fc0b566b98ed72bf6 ## Todo arm
         environment:
             - WEB_DOCUMENT_ROOT=/app/public
         deploy:
diff --git a/services/maintenance-page/docker-compose.yml.j2 b/services/maintenance-page/docker-compose.yml.j2
index a119e5fc..fc6f4eae 100644
--- a/services/maintenance-page/docker-compose.yml.j2
+++ b/services/maintenance-page/docker-compose.yml.j2
@@ -16,7 +16,7 @@ services:
       - source: nginx_config
         target: /etc/nginx/conf.d/default.conf
     # nginx config
-    image: nginx:1.25.1
+    image: nginx:1.25.1  # has arm
     networks:
       - public
       - monitored
@@ -35,7 +35,7 @@ services:
 {% endfor %}
   maintenance_api:
     # nginx config
-    image: nginx:1.25.1
+    image: nginx:1.25.1  # has arm
     configs:
       - source: maintenance_api_html
         target: /usr/share/nginx/html/index.html
diff --git a/services/minio/docker-compose.yaml b/services/minio/docker-compose.yaml
index 92456040..63419aa6 100644
--- a/services/minio/docker-compose.yaml
+++ b/services/minio/docker-compose.yaml
@@ -1,7 +1,7 @@
 version: '3.7'
 services:
   minio:
-    image: minio/minio:RELEASE.2024-10-29T16-01-48Z
+    image: minio/minio:RELEASE.2024-10-29T16-01-48Z ## has arm
     init: true
     hostname: minio
     volumes:

From 79692677a25dce17ca6bf5e690306479f43828bf Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mrnicegyu11@users.noreply.github.com>
Date: Wed, 5 Feb 2025 16:36:05 +0100
Subject: [PATCH 6/7] Comment which images have arm available

---
 .../templates/tests/test-connection.yaml      |  2 +-
 services/admin-panels/docker-compose.yml.j2   |  2 +-
 services/monitoring/docker-compose.yml.j2     | 24 +++++++++----------
 services/registry/docker-compose.yml.j2       |  4 ++--
 services/traefik/docker-compose.yml.j2        |  4 ++--
 5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/charts/simcore-charts/resource-usage-tracker/templates/tests/test-connection.yaml b/charts/simcore-charts/resource-usage-tracker/templates/tests/test-connection.yaml
index a7046a09..0701472f 100644
--- a/charts/simcore-charts/resource-usage-tracker/templates/tests/test-connection.yaml
+++ b/charts/simcore-charts/resource-usage-tracker/templates/tests/test-connection.yaml
@@ -9,7 +9,7 @@ metadata:
 spec:
   containers:
     - name: wget
-      image: busybox
+      image: busybox # has arm
       command: ['wget']
       args: ['{{ include "resource-usage-tracker.fullname" . }}:{{ .Values.service.port }}']
   restartPolicy: Never
diff --git a/services/admin-panels/docker-compose.yml.j2 b/services/admin-panels/docker-compose.yml.j2
index dbdccea9..888d82a7 100644
--- a/services/admin-panels/docker-compose.yml.j2
+++ b/services/admin-panels/docker-compose.yml.j2
@@ -7,7 +7,7 @@ configs:
     file: ./data/{{ item.name }}{% endfor %}
 services:
   adminpanels:
-    image: jupyter/base-notebook:18b10e7f732d ## no arm iamge
+    image: jupyter/base-notebook:18b10e7f732d ## no arm iamge, but latest jupyter base has arm
     user: root
     networks:
       - public
diff --git a/services/monitoring/docker-compose.yml.j2 b/services/monitoring/docker-compose.yml.j2
index d1bdffd0..e7310287 100644
--- a/services/monitoring/docker-compose.yml.j2
+++ b/services/monitoring/docker-compose.yml.j2
@@ -54,7 +54,7 @@ services:
           cpus: "0.1"
   prometheuscatchall:
     hostname: "{% raw %}{{.Service.Name}}{% endraw %}"
-    image: prom/prometheus:v2.54.0
+    image: prom/prometheus:v2.54.0 ## arm64 available
     volumes:
       - prometheus_data:/prometheus
       - /var/run/docker.sock:/var/run/docker.sock:ro
@@ -100,7 +100,7 @@ services:
           cpus: "0.2"
   prometheusfederation:
     hostname: "{% raw %}{{.Service.Name}}{% endraw %}"
-    image: prom/prometheus:v2.54.0
+    image: prom/prometheus:v2.54.0 ## arm64 available
     volumes:
       - prometheus_data_federation:/prometheus
       - /var/run/docker.sock:/var/run/docker.sock:ro
@@ -145,7 +145,7 @@ services:
           memory: 64M
           cpus: "0.2"
   node-exporter:
-    image: prom/node-exporter:v1.8.2
+    image: prom/node-exporter:v1.8.2  ## arm64 available
     volumes:
       - /sys:/host/sys:ro
       - /:/rootfs:ro
@@ -183,7 +183,7 @@ services:
           cpus: "0.1"
 
   nvidia-exporter:
-    image: mindprince/nvidia_gpu_prometheus_exporter:0.1
+    image: mindprince/nvidia_gpu_prometheus_exporter:0.1 ## No arm support
     networks:
       - monitored
     deploy:
@@ -203,7 +203,7 @@ services:
           cpus: "0.1"
 
   alertmanager:
-    image: prom/alertmanager:v0.27.0
+    image: prom/alertmanager:v0.27.0 ## arm support
     volumes:
       - alertmanager_data:/alertmanager
     command:
@@ -227,7 +227,7 @@ services:
           cpus: "0.1"
 
   docker-events-exporter:
-    image: itisfoundation/docker-events-exporter:latest
+    image: itisfoundation/docker-events-exporter:latest ## no arm support yet
     volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
     user: root # only user root can use the docker socket
@@ -247,7 +247,7 @@ services:
           cpus: "0.1"
 
   grafana:
-    image: grafana/grafana-oss:11.2.4
+    image: grafana/grafana-oss:11.2.4 ## arm support
     volumes:
       - grafana_data:/var/lib/grafana
     env_file:
@@ -279,7 +279,7 @@ services:
           cpus: "0.1"
 
   smokeping-prober-exporter:
-    image: quay.io/superq/smokeping-prober:v0.8.1
+    image: quay.io/superq/smokeping-prober:v0.8.1 ## arm available
     networks:
       - monitored
     volumes: []
@@ -307,7 +307,7 @@ services:
   dcgm-exporter:
     cap_add:
       - SYS_ADMIN
-    image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.7-3.5.0-ubuntu22.04
+    image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.7-3.5.0-ubuntu22.04 ## arm64 available
     hostname: '{{'{{.Node.Hostname}}'}}'
     networks:
       - monitored
@@ -328,7 +328,7 @@ services:
       - prometheus-port=9400
 
   pgsql-query-exporter:
-    image: adonato/query-exporter:2.10.0
+    image: adonato/query-exporter:2.10.0 # no arm available
     volumes: []
     dns: 9.9.9.9
     configs:
@@ -353,7 +353,7 @@ services:
           memory: 64M
           cpus: "0.1"{% for _stack in MONITORED_STACK_NAMES.split(",") if _stack != "" %}
   {{_stack}}-postgres-exporter:
-    image: bitnami/postgres-exporter:0.15.0
+    image: bitnami/postgres-exporter:0.15.0 ## arm64 available
     networks:
       - monitored
     environment:
@@ -373,7 +373,7 @@ services:
           memory: 32M
           cpus: "0.1"
   {{_stack}}-redis-exporter:
-    image: oliver006/redis_exporter:v1.62.0-alpine
+    image: oliver006/redis_exporter:v1.62.0-alpine # no arm available
     networks:
       - monitored
     environment:
diff --git a/services/registry/docker-compose.yml.j2 b/services/registry/docker-compose.yml.j2
index 3df5f697..9da3dda1 100644
--- a/services/registry/docker-compose.yml.j2
+++ b/services/registry/docker-compose.yml.j2
@@ -1,7 +1,7 @@
 version: "3.7"
 services:
   registry:
-    image: registry:2.8.3
+    image: registry:2.8.3 ## arm64
     command: ["/bin/sh", "/etc/docker/registry/init"]
     environment:
       REGISTRY_HTTP_HOST: "https://${REGISTRY_DOMAIN}"
@@ -72,7 +72,7 @@ services:
     {%- raw %}
     hostname: "registry-ptc-{{.Node.Hostname}}-{{.Task.Slot}}"
     {%- endraw %}
-    image: registry:2.8.3
+    image: registry:2.8.3 ## arm64
     environment:
       REGISTRY_HTTP_SECRET: ${REGISTRY_PULL_THROUGH_CACHE_HTTP_SECRET}
       # S3
diff --git a/services/traefik/docker-compose.yml.j2 b/services/traefik/docker-compose.yml.j2
index 13ae322b..f8233aca 100644
--- a/services/traefik/docker-compose.yml.j2
+++ b/services/traefik/docker-compose.yml.j2
@@ -2,7 +2,7 @@ version: "3.7"
 
 services:
   traefik:
-    image: "traefik:v3.1.2@sha256:ec1a82940b8e00eaeef33fb4113aa1d1573b2ebb6440e10c023743fe96f08475"
+    image: "traefik:v3.1.2@sha256:ec1a82940b8e00eaeef33fb4113aa1d1573b2ebb6440e10c023743fe96f08475" ## arm64 available
     init: true
     command:
       - "--api=true"
@@ -179,7 +179,7 @@ services:
       public: null
       monitored: null
   whoami:
-    image: "containous/whoami"
+    image: "containous/whoami" ## arm 64 available
     deploy:
       placement:
         constraints:

From 5854f1daf763f668c55bbcb2ef3291ea41c5f86e Mon Sep 17 00:00:00 2001
From: Dustin Kaiser <mrnicegyu11@users.noreply.github.com>
Date: Wed, 5 Feb 2025 17:02:07 +0100
Subject: [PATCH 7/7] Revert accidental commit

---
 certificates/Makefile | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/certificates/Makefile b/certificates/Makefile
index 9af700df..a9326900 100644
--- a/certificates/Makefile
+++ b/certificates/Makefile
@@ -66,10 +66,16 @@ install-root-certificate: rootca.crt ## installs a certificate in the host syste
 		echo "Is the DOCKER service ready? press when ready" && read -n 1; \
 	    fi;\
 		echo "======================================";,\
-		sudo cp $< /etc/ca-certificates/trust-source/anchors/osparc.crt; \
-		sudo trust extract-compat &&                            \
-		echo "# restarting docker daemon" &&                      \
+		$(if $(IS_OSX),                                             \
+			sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain $<; \
+			echo "Please restart the DOCKER service now..." && read -n 1; \
+			echo "Is the DOCKER service ready? press when ready" && read -n 1; \
+		,                                                           \
+		sudo cp $< /usr/local/share/ca-certificates/osparc.crt; \
+		sudo update-ca-certificates -f;                            \
+		echo "# restarting docker daemon";                      \
 		sudo systemctl restart docker                           \
+		) \
 	)