From d7b4ad01261a6f0b5825362751fa563263310305 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Wed, 2 Oct 2024 15:21:07 +0200
Subject: [PATCH 1/7] Add swagger-ui in docker-compose
---
.../technical/docker-compose.technical.yml | 88 +++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/docker-compose/technical/docker-compose.technical.yml b/docker-compose/technical/docker-compose.technical.yml
index 85e706ef..a9aa665e 100644
--- a/docker-compose/technical/docker-compose.technical.yml
+++ b/docker-compose/technical/docker-compose.technical.yml
@@ -187,3 +187,91 @@ services:
- GF_ANALYTICS_CHECK_FOR_UPDATES=false
ports:
- "7000:3000"
+
+ # accessible at http://localhost:9080/swagger/
+ swagger-ui:
+ #profiles: all
+ image: swaggerapi/swagger-ui:latest
+ healthcheck:
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_interval: 5s
+ start_period: 10s
+ #test: curl --fail --noproxy '*' -so /dev/null http://localhost:8080/swagger/
+ test: wget -Y off -O /dev/null http://localhost:8080/swagger/
+ restart: unless-stopped
+ deploy:
+ replicas: 1
+ #restart_policy:
+ # condition: on-failure
+ # delay: 5s
+ # max_attempts: 3
+ # window: 20s
+ resources:
+ # use ~14MB RAM when tested
+ limits:
+ # we limit the number of worker processes nginx create
+ cpus: '1'
+ memory: 50M
+ reservations:
+ memory: 20M
+ ports:
+ - 9080:8080
+ environment:
+ NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE: true
+ PORT_IPV6: 8080
+ BASE_URL: /swagger
+ DEEP_LINKING: true
+ DISPLAY_REQUEST_DURATION: true
+ FILTER: true
+ SHOW_EXTENSIONS: true
+ VALIDATOR_URL: null
+ URLS_PRIMARY_NAME: gateway
+ URLS: >
+ [
+ {"url":"https://github.com/elastic/elasticsearch-specification/raw/8.12/output/openapi/elasticsearch-serverless-openapi.json","name":"ElasticSearch API"},
+ {"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"},
+ {"url":"http://localhost:9000/v3/api-docs","name":"gateway"},
+ {"url":"http://localhost:5022/v3/api-docs","name":"actions-server"},
+ {"url":"http://localhost:5010/v3/api-docs","name":"balances-adjustment-server"},
+ {"url":"http://localhost:5039/v3/api-docs","name":"case-import-server"},
+ {"url":"http://localhost:5000/v3/api-docs","name":"case-server"},
+ {"url":"http://localhost:5011/v3/api-docs","name":"case-validation-server"},
+ {"url":"http://localhost:5021/v3/api-docs","name":"cgmes-boundary-server"},
+ {"url":"http://localhost:8095/v3/api-docs","name":"cgmes-gl-server"},
+ {"url":"http://localhost:5024/v3/api-docs","name":"config-notification-server"},
+ {"url":"http://localhost:5025/v3/api-docs","name":"config-server"},
+ {"url":"http://localhost:5004/v3/api-docs","name":"directory-notification-server"},
+ {"url":"http://localhost:5026/v3/api-docs","name":"directory-server"},
+ {"url":"http://localhost:5036/v3/api-docs","name":"dynamic-mapping-server"},
+ {"url":"http://localhost:5032/v3/api-docs","name":"dynamic-simulation-server"},
+ {"url":"http://localhost:5029/v3/api-docs","name":"explore-server"},
+ {"url":"http://localhost:5027/v3/api-docs","name":"filter-server"},
+ {"url":"http://localhost:8087/v3/api-docs","name":"geo-data-server"},
+ {"url":"http://localhost:5008/v3/api-docs","name":"loadflow-server"},
+ {"url":"http://localhost:5002/v3/api-docs","name":"merge-notification-server"},
+ {"url":"http://localhost:5020/v3/api-docs","name":"merge-orchestrator-server"},
+ {"url":"http://localhost:5003/v3/api-docs","name":"network-conversion-server"},
+ {"url":"http://localhost:5006/v3/api-docs","name":"network-map-server"},
+ {"url":"http://localhost:5007/v3/api-docs","name":"network-modification-server"},
+ {"url":"http://localhost:8080/v3/api-docs","name":"network-store-server"},
+ {"url":"http://localhost:8090/v3/api-docs","name":"odre-server"},
+ {"url":"http://localhost:5028/v3/api-docs","name":"report-server"},
+ {"url":"http://localhost:5023/v3/api-docs","name":"security-analysis-server"},
+ {"url":"http://localhost:5030/v3/api-docs","name":"sensitivity-analysis-server"},
+ {"url":"http://localhost:5031/v3/api-docs","name":"shortcircuit-server"},
+ {"url":"http://localhost:5005/v3/api-docs","name":"single-line-diagram-server"},
+ {"url":"http://localhost:5035/v3/api-docs","name":"spreadsheet-config-server"},
+ {"url":"http://localhost:5009/v3/api-docs","name":"study-notification-server"},
+ {"url":"http://localhost:5001/v3/api-docs","name":"study-server"},
+ {"url":"http://localhost:5037/v3/api-docs","name":"timeseries-server"},
+ {"url":"http://localhost:5033/v3/api-docs","name":"user-admin-server"},
+ {"url":"http://localhost:5038/v3/api-docs","name":"voltage-init-server"}
+ ]
+ # no spec found for:
+ # https://rawcdn.githack.com/rabbitmq/rabbitmq-server/v3.13.7/deps/rabbitmq_management/priv/www/api/index.html
+ # https://github.com/prometheus/prometheus/blob/main/docs/querying/api.md?plain=1
+ # https://prometheus.io/docs/prometheus/latest/querying/api/
+ # https://www.elastic.co/docs/api/doc/kibana
+ # WIP: https://github.com/elastic/kibana/issues/137240
From 059b421fc4868c81df846c19a8a0545ab3a8f182 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Wed, 2 Oct 2024 15:21:25 +0200
Subject: [PATCH 2/7] fix readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 2a676cee..5725b33b 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@ Here's the summary of the profiles and what services they includes:
| rabbitmq
postgres
elasticsearch | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| kibana
logstash
socat
logspout | | | | | | | | | ✅ | | |
| pgadmin | | | | | | | | | | ✅ | |
-| apps‑metadata‑server
mock‑user‑service
gateway
actions‑server
case‑server
config‑notification‑server
config‑server
filter‑server
loadflow‑server
network‑conversion‑server
network‑store‑server
report‑server
user‑admin‑server | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | |
+| apps‑metadata‑server
mock‑user‑service
gateway
actions‑server
case‑server
config‑notification‑server
config‑server
filter‑server
loadflow‑server
network‑conversion‑server
network‑store‑server
spreadsheet‑config‑server
report‑server
user‑admin‑server | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | |
| griddyna‑app
dynamic‑mapping‑server | | | | | ✅ | ✅ | ✅ | | | | |
| gridmerge‑app
balances‑adjustment‑server
case‑import‑job
case‑validation‑server
cgmes‑assembling‑job
cgmes‑boundary‑import‑job
cgmes‑boundary‑server
merge‑notification‑server
merge‑orchestrator‑server | | ✅ | | | | | ✅ | | | | |
| gridstudy‑app
dynamic‑simulation‑server
timeseries‑server | | | ✅ | | | ✅ | ✅ | | | | |
From c7bfeb3e00fa1bc33eab843d0a12f259fdbf93f6 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Wed, 2 Oct 2024 15:22:38 +0200
Subject: [PATCH 3/7] Update readme
Rework URLs to be clickable and add some commands that can be helpful
---
README.md | 94 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 52 insertions(+), 42 deletions(-)
diff --git a/README.md b/README.md
index 5725b33b..d6c8acdd 100644
--- a/README.md
+++ b/README.md
@@ -176,49 +176,47 @@ $ docker image prune -f
You can now access to all applications and swagger UIs of the Spring services of the chosen profile:
-Applications:
-```html
-http://localhost:80 // gridexplore
-http://localhost:81 // gridmerge
-http://localhost:82 // gridadmin
-http://localhost:83 // griddyna
-http://localhost:84 // gridstudy
-```
+- Applications:
+ - http://localhost:80 :: gridexplore
+ - http://localhost:81 :: gridmerge
+ - http://localhost:82 :: gridadmin
+ - http://localhost:83 :: griddyna
+ - http://localhost:84 :: gridstudy
+
+- Aggregated Swagger-UI: http://localhost:9080/swagger/
+- Swagger-UI per server:
+ - http://localhost:5000/swagger-ui.html :: case-server
+ - http://localhost:8095/swagger-ui.html :: cgmes-gl-server
+ - http://localhost:8087/swagger-ui.html :: geo-data-server
+ - http://localhost:5003/swagger-ui.html :: network-conversion-server
+ - http://localhost:8080/swagger-ui.html :: network-store-server
+ - http://localhost:5006/swagger-ui.html :: network-map-server
+ - http://localhost:8090/swagger-ui.html :: odre-server
+ - http://localhost:5005/swagger-ui.html :: single-line-diagram-server
+ - http://localhost:5001/swagger-ui.html :: study-server
+ - http://localhost:5007/swagger-ui.html :: network-modification-server
+ - http://localhost:5008/swagger-ui.html :: loadflow-server
+ - http://localhost:5020/swagger-ui.html :: merge-orchestrator-server
+ - http://localhost:5021/swagger-ui.html :: cgmes-boundary-server
+ - http://localhost:5022/swagger-ui.html :: actions-server
+ - http://localhost:5023/swagger-ui.html :: security-analysis-server
+ - http://localhost:5025/swagger-ui.html :: config-server
+ - http://localhost:5026/swagger-ui.html :: directory-server
+ - http://localhost:5028/swagger-ui.html :: report-server
+ - http://localhost:5029/swagger-ui.html :: explore-server
+ - http://localhost:5036/swagger-ui.html :: dynamic-mapping-server
+ - http://localhost:5032/swagger-ui.html :: dynamic-simulation-server
+ - http://localhost:5027/swagger-ui.html :: filter-server
+ - http://localhost:5010/swagger-ui.html :: balances-adjustment-server
+ - http://localhost:5011/swagger-ui.html :: case-validation-server
+ - http://localhost:5033/swagger-ui.html :: user-admin-server
+ - http://localhost:5030/swagger-ui.html :: sensitivity-analysis-server
+ - http://localhost:5031/swagger-ui.html :: shortcircuit-server
+ - http://localhost:5035/swagger-ui.html :: spreadsheet-config-server
+ - http://localhost:5037/swagger-ui.html :: timeseries-server
+ - http://localhost:5038/swagger-ui.html :: voltage-init-server
+ - http://localhost:5039/swagger-ui.html :: case-import-server
-Swagger UI:
-```html
-http://localhost:5000/swagger-ui.html // case-server
-http://localhost:8095/swagger-ui.html // cgmes-gl-server
-http://localhost:8087/swagger-ui.html // geo-data-server
-http://localhost:5003/swagger-ui.html // network-conversion-server
-http://localhost:8080/swagger-ui.html // network-store-server
-http://localhost:5006/swagger-ui.html // network-map-server
-http://localhost:8090/swagger-ui.html // odre-server
-http://localhost:5005/swagger-ui.html // single-line-diagram-server
-http://localhost:5001/swagger-ui.html // study-server
-http://localhost:5007/swagger-ui.html // network-modification-server
-http://localhost:5008/swagger-ui.html // loadflow-server
-http://localhost:5020/swagger-ui.html // merge-orchestrator-server
-http://localhost:5021/swagger-ui.html // cgmes-boundary-server
-http://localhost:5022/swagger-ui.html // actions-server
-http://localhost:5023/swagger-ui.html // security-analysis-server
-http://localhost:5025/swagger-ui.html // config-server
-http://localhost:5026/swagger-ui.html // directory-server
-http://localhost:5028/swagger-ui.html // report-server
-http://localhost:5029/swagger-ui.html // explore-server
-http://localhost:5036/swagger-ui.html // dynamic-mapping-server
-http://localhost:5032/swagger-ui.html // dynamic-simulation-server
-http://localhost:5027/swagger-ui.html // filter-server
-http://localhost:5010/swagger-ui.html // balances-adjustment-server
-http://localhost:5011/swagger-ui.html // case-validation-server
-http://localhost:5033/swagger-ui.html // user-admin-server
-http://localhost:5030/swagger-ui.html // sensitivity-analysis-server
-http://localhost:5031/swagger-ui.html // shortcircuit-server
-http://localhost:5035/swagger-ui.html // spreadsheet-config-server
-http://localhost:5037/swagger-ui.html // timeseries-server
-http://localhost:5038/swagger-ui.html // voltage-init-server
-http://localhost:5039/swagger-ui.html // case-import-server
-```
### RabbitMQ console
@@ -292,6 +290,18 @@ You must get this output from docker compose now:
> The commands shown will install the plugin user-side, so you don't need to remove your old docker-compose v1 if it is installed system-wide.
+### Tips & tricks
+
+#### Some commands that can be useful
+```shell
+# Get all services that have ports bound on host
+docker compose --profile all config --services | xargs printf -- 'grid-%s-1\n' | tr '\n' ' ' | xargs docker inspect | jq 'map( { (.Name|tostring): .HostConfig.PortBindings } ) | add'
+
+# Get the list of all ports bound on host
+docker compose --profile all config --services | xargs printf -- 'grid-%s-1\n' | tr '\n' ' ' | xargs docker inspect | jq 'map(.HostConfig.PortBindings[] | add | .HostPort | tonumber) | . + [3000,3001,3002,3003,3004,5035,5041] | sort'
+```
+
+
## k8s deployment with Minikube
### Minikube and kubectl setup
From 3ebe7f47d367dcad2080e5358fcb7cb26e7b1dd4 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Thu, 3 Oct 2024 03:31:46 +0200
Subject: [PATCH 4/7] Add k8s version
---
k8s/live/local/kustomization.yaml | 1 +
k8s/live/local/swagger-ui.yaml | 123 ++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+)
create mode 100644 k8s/live/local/swagger-ui.yaml
diff --git a/k8s/live/local/kustomization.yaml b/k8s/live/local/kustomization.yaml
index 976207c5..f63511ef 100644
--- a/k8s/live/local/kustomization.yaml
+++ b/k8s/live/local/kustomization.yaml
@@ -49,6 +49,7 @@ resources:
- timeseries-server-ingress.yaml
- voltage-init-server-ingress.yaml
- spreadsheet-config-server-ingress.yaml
+ - swagger-ui.yaml
configMapGenerator:
- name: gridapps-env-configmap
diff --git a/k8s/live/local/swagger-ui.yaml b/k8s/live/local/swagger-ui.yaml
new file mode 100644
index 00000000..0393e4b4
--- /dev/null
+++ b/k8s/live/local/swagger-ui.yaml
@@ -0,0 +1,123 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: swagger-ui
+ labels:
+ name: swagger-ui
+ app.kubernetes.io/component: gridsuite-swaggerui
+spec:
+ selector:
+ matchLabels:
+ name: swagger-ui
+ template:
+ metadata:
+ labels:
+ name: swagger-ui
+ spec:
+ containers:
+ - name: main
+ image: swaggerapi/swagger-ui:latest
+ restartPolicy: Always
+ env:
+ - name: NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE
+ value: 'true'
+ - name: PORT_IPV6
+ value: 8080
+ - name: BASE_URL
+ value: /swagger
+ - name: DEEP_LINKING
+ value: 'true'
+ - name: DISPLAY_REQUEST_DURATION
+ value: 'true'
+ - name: FILTER
+ value: 'true'
+ - name: SHOW_EXTENSIONS
+ value: 'true'
+ - name: VALIDATOR_URL
+ value: 'null'
+ - name: URLS_PRIMARY_NAME
+ value: gateway
+ - name: URLS
+ value: >
+ [
+ {"url":"https://github.com/elastic/elasticsearch-specification/raw/8.12/output/openapi/elasticsearch-serverless-openapi.json","name":"ElasticSearch API"},
+ {"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"},
+ {"url":"/gateway/v3/api-docs","name":"gateway"},
+ {"url":"/actions-server/v3/api-docs","name":"actions-server"},
+ {"url":"/balances-adjustment-server/v3/api-docs","name":"balances-adjustment-server"},
+ {"url":"/case-import-server/v3/api-docs","name":"case-import-server"},
+ {"url":"/case-server/v3/api-docs","name":"case-server"},
+ {"url":"/case-validation-server/v3/api-docs","name":"case-validation-server"},
+ {"url":"/cgmes-boundary-server/v3/api-docs","name":"cgmes-boundary-server"},
+ {"url":"/cgmes-gl-server/v3/api-docs","name":"cgmes-gl-server"},
+ {"url":"/config-notification-server/v3/api-docs","name":"config-notification-server"},
+ {"url":"/config-server/v3/api-docs","name":"config-server"},
+ {"url":"/directory-notification-server/v3/api-docs","name":"directory-notification-server"},
+ {"url":"/directory-server/v3/api-docs","name":"directory-server"},
+ {"url":"/dynamic-mapping-server/v3/api-docs","name":"dynamic-mapping-server"},
+ {"url":"/dynamic-simulation-server/v3/api-docs","name":"dynamic-simulation-server"},
+ {"url":"/explore-server/v3/api-docs","name":"explore-server"},
+ {"url":"/filter-server/v3/api-docs","name":"filter-server"},
+ {"url":"/geo-data-server/v3/api-docs","name":"geo-data-server"},
+ {"url":"/loadflow-server/v3/api-docs","name":"loadflow-server"},
+ {"url":"/merge-notification-server/v3/api-docs","name":"merge-notification-server"},
+ {"url":"/merge-orchestrator-server/v3/api-docs","name":"merge-orchestrator-server"},
+ {"url":"/network-conversion-server/v3/api-docs","name":"network-conversion-server"},
+ {"url":"/network-map-server/v3/api-docs","name":"network-map-server"},
+ {"url":"/network-modification-server/v3/api-docs","name":"network-modification-server"},
+ {"url":"/network-store-server/v3/api-docs","name":"network-store-server"},
+ {"url":"/odre-server/v3/api-docs","name":"odre-server"},
+ {"url":"/report-server/v3/api-docs","name":"report-server"},
+ {"url":"/security-analysis-server/v3/api-docs","name":"security-analysis-server"},
+ {"url":"/sensitivity-analysis-server/v3/api-docs","name":"sensitivity-analysis-server"},
+ {"url":"/shortcircuit-server/v3/api-docs","name":"shortcircuit-server"},
+ {"url":"/single-line-diagram-server/v3/api-docs","name":"single-line-diagram-server"},
+ {"url":"/spreadsheet-config-server/v3/api-docs","name":"spreadsheet-config-server"},
+ {"url":"/study-notification-server/v3/api-docs","name":"study-notification-server"},
+ {"url":"/study-server/v3/api-docs","name":"study-server"},
+ {"url":"/timeseries-server/v3/api-docs","name":"timeseries-server"},
+ {"url":"/user-admin-server/v3/api-docs","name":"user-admin-server"},
+ {"url":"/voltage-init-server/v3/api-docs","name":"voltage-init-server"}
+ ]
+ resources:
+ limits:
+ cpi: '1'
+ memory: 50Mi
+ requests: 20Mi
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ name: swagger-ui
+ app.kubernetes.io/component: gridsuite-swaggerui
+ name: swagger-ui
+spec:
+ selector:
+ name: swagger-ui
+
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: swagger-ui-ingress
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /$2
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ # our containers host at '/' so can't possibly make a difference between
+ # '/XXX/' and '/XXX' (trailing slash) (which would respectively become
+ # '/' and '' inside the container but an empty path doesn't exist in http)
+ # so always redirect '/XXX' to '/XXX/' in the client outside the container
+ rewrite ^/swagger$ /swagger/ permanent;
+spec:
+ rules:
+ - http:
+ paths:
+ - path: /swagger(/|$)(.*)
+ pathType: Prefix
+ backend:
+ service:
+ name: swagger-ui
+ port:
+ number: 8080
From 70f606f2c6664eadc2e9c427f88c81e6d91b7853 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Tue, 8 Oct 2024 15:56:09 +0200
Subject: [PATCH 5/7] review
Add pot number in show dropdown
---
.../technical/docker-compose.technical.yml | 72 +++++++++----------
1 file changed, 36 insertions(+), 36 deletions(-)
diff --git a/docker-compose/technical/docker-compose.technical.yml b/docker-compose/technical/docker-compose.technical.yml
index a9aa665e..7bf16c15 100644
--- a/docker-compose/technical/docker-compose.technical.yml
+++ b/docker-compose/technical/docker-compose.technical.yml
@@ -232,42 +232,42 @@ services:
[
{"url":"https://github.com/elastic/elasticsearch-specification/raw/8.12/output/openapi/elasticsearch-serverless-openapi.json","name":"ElasticSearch API"},
{"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"},
- {"url":"http://localhost:9000/v3/api-docs","name":"gateway"},
- {"url":"http://localhost:5022/v3/api-docs","name":"actions-server"},
- {"url":"http://localhost:5010/v3/api-docs","name":"balances-adjustment-server"},
- {"url":"http://localhost:5039/v3/api-docs","name":"case-import-server"},
- {"url":"http://localhost:5000/v3/api-docs","name":"case-server"},
- {"url":"http://localhost:5011/v3/api-docs","name":"case-validation-server"},
- {"url":"http://localhost:5021/v3/api-docs","name":"cgmes-boundary-server"},
- {"url":"http://localhost:8095/v3/api-docs","name":"cgmes-gl-server"},
- {"url":"http://localhost:5024/v3/api-docs","name":"config-notification-server"},
- {"url":"http://localhost:5025/v3/api-docs","name":"config-server"},
- {"url":"http://localhost:5004/v3/api-docs","name":"directory-notification-server"},
- {"url":"http://localhost:5026/v3/api-docs","name":"directory-server"},
- {"url":"http://localhost:5036/v3/api-docs","name":"dynamic-mapping-server"},
- {"url":"http://localhost:5032/v3/api-docs","name":"dynamic-simulation-server"},
- {"url":"http://localhost:5029/v3/api-docs","name":"explore-server"},
- {"url":"http://localhost:5027/v3/api-docs","name":"filter-server"},
- {"url":"http://localhost:8087/v3/api-docs","name":"geo-data-server"},
- {"url":"http://localhost:5008/v3/api-docs","name":"loadflow-server"},
- {"url":"http://localhost:5002/v3/api-docs","name":"merge-notification-server"},
- {"url":"http://localhost:5020/v3/api-docs","name":"merge-orchestrator-server"},
- {"url":"http://localhost:5003/v3/api-docs","name":"network-conversion-server"},
- {"url":"http://localhost:5006/v3/api-docs","name":"network-map-server"},
- {"url":"http://localhost:5007/v3/api-docs","name":"network-modification-server"},
- {"url":"http://localhost:8080/v3/api-docs","name":"network-store-server"},
- {"url":"http://localhost:8090/v3/api-docs","name":"odre-server"},
- {"url":"http://localhost:5028/v3/api-docs","name":"report-server"},
- {"url":"http://localhost:5023/v3/api-docs","name":"security-analysis-server"},
- {"url":"http://localhost:5030/v3/api-docs","name":"sensitivity-analysis-server"},
- {"url":"http://localhost:5031/v3/api-docs","name":"shortcircuit-server"},
- {"url":"http://localhost:5005/v3/api-docs","name":"single-line-diagram-server"},
- {"url":"http://localhost:5035/v3/api-docs","name":"spreadsheet-config-server"},
- {"url":"http://localhost:5009/v3/api-docs","name":"study-notification-server"},
- {"url":"http://localhost:5001/v3/api-docs","name":"study-server"},
- {"url":"http://localhost:5037/v3/api-docs","name":"timeseries-server"},
- {"url":"http://localhost:5033/v3/api-docs","name":"user-admin-server"},
- {"url":"http://localhost:5038/v3/api-docs","name":"voltage-init-server"}
+ {"url":"http://localhost:9000/v3/api-docs","name":"[9000] gateway"},
+ {"url":"http://localhost:5022/v3/api-docs","name":"[5022] actions-server"},
+ {"url":"http://localhost:5010/v3/api-docs","name":"[5010] balances-adjustment-server"},
+ {"url":"http://localhost:5039/v3/api-docs","name":"[5039] case-import-server"},
+ {"url":"http://localhost:5000/v3/api-docs","name":"[5000] case-server"},
+ {"url":"http://localhost:5011/v3/api-docs","name":"[5011] case-validation-server"},
+ {"url":"http://localhost:5021/v3/api-docs","name":"[5021] cgmes-boundary-server"},
+ {"url":"http://localhost:8095/v3/api-docs","name":"[8095] cgmes-gl-server"},
+ {"url":"http://localhost:5024/v3/api-docs","name":"[5024] config-notification-server"},
+ {"url":"http://localhost:5025/v3/api-docs","name":"[5025] config-server"},
+ {"url":"http://localhost:5004/v3/api-docs","name":"[5004] directory-notification-server"},
+ {"url":"http://localhost:5026/v3/api-docs","name":"[5026] directory-server"},
+ {"url":"http://localhost:5036/v3/api-docs","name":"[5036] dynamic-mapping-server"},
+ {"url":"http://localhost:5032/v3/api-docs","name":"[5032] dynamic-simulation-server"},
+ {"url":"http://localhost:5029/v3/api-docs","name":"[5029] explore-server"},
+ {"url":"http://localhost:5027/v3/api-docs","name":"[5027] filter-server"},
+ {"url":"http://localhost:8087/v3/api-docs","name":"[8087] geo-data-server"},
+ {"url":"http://localhost:5008/v3/api-docs","name":"[5008] loadflow-server"},
+ {"url":"http://localhost:5002/v3/api-docs","name":"[5002] merge-notification-server"},
+ {"url":"http://localhost:5020/v3/api-docs","name":"[5020] merge-orchestrator-server"},
+ {"url":"http://localhost:5003/v3/api-docs","name":"[5003] network-conversion-server"},
+ {"url":"http://localhost:5006/v3/api-docs","name":"[5006] network-map-server"},
+ {"url":"http://localhost:5007/v3/api-docs","name":"[5007] network-modification-server"},
+ {"url":"http://localhost:8080/v3/api-docs","name":"[8080] network-store-server"},
+ {"url":"http://localhost:8090/v3/api-docs","name":"[8090] odre-server"},
+ {"url":"http://localhost:5028/v3/api-docs","name":"[5028] report-server"},
+ {"url":"http://localhost:5023/v3/api-docs","name":"[5023] security-analysis-server"},
+ {"url":"http://localhost:5030/v3/api-docs","name":"[5030] sensitivity-analysis-server"},
+ {"url":"http://localhost:5031/v3/api-docs","name":"[5031] shortcircuit-server"},
+ {"url":"http://localhost:5005/v3/api-docs","name":"[5005] single-line-diagram-server"},
+ {"url":"http://localhost:5035/v3/api-docs","name":"[5035] spreadsheet-config-server"},
+ {"url":"http://localhost:5009/v3/api-docs","name":"[5009] study-notification-server"},
+ {"url":"http://localhost:5001/v3/api-docs","name":"[5001] study-server"},
+ {"url":"http://localhost:5037/v3/api-docs","name":"[5037] timeseries-server"},
+ {"url":"http://localhost:5033/v3/api-docs","name":"[5033] user-admin-server"},
+ {"url":"http://localhost:5038/v3/api-docs","name":"[5038] voltage-init-server"}
]
# no spec found for:
# https://rawcdn.githack.com/rabbitmq/rabbitmq-server/v3.13.7/deps/rabbitmq_management/priv/www/api/index.html
From ab205ec9542862acb988a3def5f3a314256ee998 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Tue, 8 Oct 2024 18:50:59 +0200
Subject: [PATCH 6/7] Solve CORS problem
But loose the server url in the ui
---
.../technical/docker-compose.technical.yml | 78 ++++++++++---------
.../technical/swagger-proxy-cors.conf | 48 ++++++++++++
2 files changed, 90 insertions(+), 36 deletions(-)
create mode 100644 docker-compose/technical/swagger-proxy-cors.conf
diff --git a/docker-compose/technical/docker-compose.technical.yml b/docker-compose/technical/docker-compose.technical.yml
index 7bf16c15..6934dda7 100644
--- a/docker-compose/technical/docker-compose.technical.yml
+++ b/docker-compose/technical/docker-compose.technical.yml
@@ -218,10 +218,16 @@ services:
memory: 20M
ports:
- 9080:8080
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+ volumes:
+ - $PWD/../technical/swagger-proxy-cors.conf:/etc/nginx/templates/embedding.conf:ro
+ #- $PWD/../technical/nginx-docker.conf:/etc/nginx/conf.d/docker.conf:ro
environment:
NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE: true
PORT_IPV6: 8080
BASE_URL: /swagger
+ EMBEDDING: false #hack for cors
DEEP_LINKING: true
DISPLAY_REQUEST_DURATION: true
FILTER: true
@@ -232,42 +238,42 @@ services:
[
{"url":"https://github.com/elastic/elasticsearch-specification/raw/8.12/output/openapi/elasticsearch-serverless-openapi.json","name":"ElasticSearch API"},
{"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"},
- {"url":"http://localhost:9000/v3/api-docs","name":"[9000] gateway"},
- {"url":"http://localhost:5022/v3/api-docs","name":"[5022] actions-server"},
- {"url":"http://localhost:5010/v3/api-docs","name":"[5010] balances-adjustment-server"},
- {"url":"http://localhost:5039/v3/api-docs","name":"[5039] case-import-server"},
- {"url":"http://localhost:5000/v3/api-docs","name":"[5000] case-server"},
- {"url":"http://localhost:5011/v3/api-docs","name":"[5011] case-validation-server"},
- {"url":"http://localhost:5021/v3/api-docs","name":"[5021] cgmes-boundary-server"},
- {"url":"http://localhost:8095/v3/api-docs","name":"[8095] cgmes-gl-server"},
- {"url":"http://localhost:5024/v3/api-docs","name":"[5024] config-notification-server"},
- {"url":"http://localhost:5025/v3/api-docs","name":"[5025] config-server"},
- {"url":"http://localhost:5004/v3/api-docs","name":"[5004] directory-notification-server"},
- {"url":"http://localhost:5026/v3/api-docs","name":"[5026] directory-server"},
- {"url":"http://localhost:5036/v3/api-docs","name":"[5036] dynamic-mapping-server"},
- {"url":"http://localhost:5032/v3/api-docs","name":"[5032] dynamic-simulation-server"},
- {"url":"http://localhost:5029/v3/api-docs","name":"[5029] explore-server"},
- {"url":"http://localhost:5027/v3/api-docs","name":"[5027] filter-server"},
- {"url":"http://localhost:8087/v3/api-docs","name":"[8087] geo-data-server"},
- {"url":"http://localhost:5008/v3/api-docs","name":"[5008] loadflow-server"},
- {"url":"http://localhost:5002/v3/api-docs","name":"[5002] merge-notification-server"},
- {"url":"http://localhost:5020/v3/api-docs","name":"[5020] merge-orchestrator-server"},
- {"url":"http://localhost:5003/v3/api-docs","name":"[5003] network-conversion-server"},
- {"url":"http://localhost:5006/v3/api-docs","name":"[5006] network-map-server"},
- {"url":"http://localhost:5007/v3/api-docs","name":"[5007] network-modification-server"},
- {"url":"http://localhost:8080/v3/api-docs","name":"[8080] network-store-server"},
- {"url":"http://localhost:8090/v3/api-docs","name":"[8090] odre-server"},
- {"url":"http://localhost:5028/v3/api-docs","name":"[5028] report-server"},
- {"url":"http://localhost:5023/v3/api-docs","name":"[5023] security-analysis-server"},
- {"url":"http://localhost:5030/v3/api-docs","name":"[5030] sensitivity-analysis-server"},
- {"url":"http://localhost:5031/v3/api-docs","name":"[5031] shortcircuit-server"},
- {"url":"http://localhost:5005/v3/api-docs","name":"[5005] single-line-diagram-server"},
- {"url":"http://localhost:5035/v3/api-docs","name":"[5035] spreadsheet-config-server"},
- {"url":"http://localhost:5009/v3/api-docs","name":"[5009] study-notification-server"},
- {"url":"http://localhost:5001/v3/api-docs","name":"[5001] study-server"},
- {"url":"http://localhost:5037/v3/api-docs","name":"[5037] timeseries-server"},
- {"url":"http://localhost:5033/v3/api-docs","name":"[5033] user-admin-server"},
- {"url":"http://localhost:5038/v3/api-docs","name":"[5038] voltage-init-server"}
+ {"url":"http://localhost:9080/swagger/proxy-cors/9000","name":"[9000] gateway"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5022","name":"[5022] actions"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5010","name":"[5010] balances-adjustment"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5039","name":"[5039] case-import"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5000","name":"[5000] case"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5011","name":"[5011] case-validation"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5021","name":"[5021] cgmes-boundary"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/8095","name":"[8095] cgmes-gl"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5024","name":"[5024] config-notification"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5025","name":"[5025] config"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5004","name":"[5004] directory-notification"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5026","name":"[5026] directory"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5036","name":"[5036] dynamic-mapping"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5032","name":"[5032] dynamic-simulation"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5029","name":"[5029] explore"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5027","name":"[5027] filter"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/8087","name":"[8087] geo-data"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5008","name":"[5008] loadflow"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5002","name":"[5002] merge-notification"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5020","name":"[5020] merge-orchestrator"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5003","name":"[5003] network-conversion"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5006","name":"[5006] network-map"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5007","name":"[5007] network-modification"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/8080","name":"[8080] network-store"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/8090","name":"[8090] odre"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5028","name":"[5028] report"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5023","name":"[5023] security-analysis"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5030","name":"[5030] sensitivity-analysis"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5031","name":"[5031] shortcircuit"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5005","name":"[5005] single-line-diagram"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5035","name":"[5035] spreadsheet-config"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5009","name":"[5009] study-notification"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5001","name":"[5001] study"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5037","name":"[5037] timeseries"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5033","name":"[5033] user-admin"},
+ {"url":"http://localhost:9080/swagger/proxy-cors/5038","name":"[5038] voltage-init"}
]
# no spec found for:
# https://rawcdn.githack.com/rabbitmq/rabbitmq-server/v3.13.7/deps/rabbitmq_management/priv/www/api/index.html
diff --git a/docker-compose/technical/swagger-proxy-cors.conf b/docker-compose/technical/swagger-proxy-cors.conf
new file mode 100644
index 00000000..e1e4c956
--- /dev/null
+++ b/docker-compose/technical/swagger-proxy-cors.conf
@@ -0,0 +1,48 @@
+# Little hack with docker to replace unused embedding.conf to inject additionnal config
+# https://github.com/swagger-api/swagger-ui/blob/master/docker/docker-entrypoint.d/40-swagger-ui.sh
+
+# We add a proxy just to add the missing CORS headers to the servers reponse
+location ~ ^/swagger/proxy-cors/([0-9]+)/?$ {
+ set $dest_port $1;
+
+ #[error] 0#0: *1 host.docker.internal could not be resolved (3: Host not found)
+ # set DNS resolver as Docker internal DNS
+ resolver 127.0.0.11 ipv6=off valid=10s;
+ resolver_timeout 5s;
+
+ # prevent dns caching and force nginx to make a dns lookup on each request.
+ #set $target http://host.docker.internal:$dest_port/v3/api-docs;
+ set $target http://172.17.0.1:$dest_port/v3/api-docs;
+ #TODO: why the resolver not work?!
+
+ # Prevent loop requests
+ if ($dest_port = 80) { return 508; }
+ if ($dest_port = 8080) { return 508; }
+ if ($dest_port = 9080) { return 508; }
+
+ # Proxy to the external JSON server
+ # Build the proxy target dynamically based on the extracted port and path
+ proxy_pass $target;
+ #proxy_http_version 1.1;
+ proxy_redirect off;
+
+ # Additional proxy settings (if necessary)
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-Host $server_name;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ # Optionally handle timeouts or larger client requests
+ client_max_body_size 10M;
+ proxy_read_timeout 90;
+
+ # Add CORS headers
+ # Note: no need as we are include in a block that already add the headers
+ # https://github.com/swagger-api/swagger-ui/blob/master/docker/default.conf.template
+
+ # Handle preflight OPTIONS requests
+ if ($request_method = OPTIONS) {
+ return 204; # No Content for preflight
+ }
+}
From e370e83954a822f3011432eaf5e80bcca49cbe98 Mon Sep 17 00:00:00 2001
From: Tristan Chuine
Date: Fri, 18 Oct 2024 01:57:30 +0200
Subject: [PATCH 7/7] Fix CORS problem
use nginx as a a proxy to add missing CORS headers
---
.../technical/docker-compose.technical.yml | 60 +---
docker-compose/technical/swagger/Dockerfile | 12 +
.../proxy-cors.conf} | 7 +-
.../technical/swagger/swagger-initializer.js | 332 ++++++++++++++++++
4 files changed, 352 insertions(+), 59 deletions(-)
create mode 100644 docker-compose/technical/swagger/Dockerfile
rename docker-compose/technical/{swagger-proxy-cors.conf => swagger/proxy-cors.conf} (90%)
create mode 100644 docker-compose/technical/swagger/swagger-initializer.js
diff --git a/docker-compose/technical/docker-compose.technical.yml b/docker-compose/technical/docker-compose.technical.yml
index 6934dda7..e9a31e7d 100644
--- a/docker-compose/technical/docker-compose.technical.yml
+++ b/docker-compose/technical/docker-compose.technical.yml
@@ -192,14 +192,7 @@ services:
swagger-ui:
#profiles: all
image: swaggerapi/swagger-ui:latest
- healthcheck:
- interval: 30s
- timeout: 10s
- retries: 3
- start_interval: 5s
- start_period: 10s
- #test: curl --fail --noproxy '*' -so /dev/null http://localhost:8080/swagger/
- test: wget -Y off -O /dev/null http://localhost:8080/swagger/
+ build: ./technical/swagger
restart: unless-stopped
deploy:
replicas: 1
@@ -220,60 +213,15 @@ services:
- 9080:8080
extra_hosts:
- "host.docker.internal:host-gateway"
- volumes:
- - $PWD/../technical/swagger-proxy-cors.conf:/etc/nginx/templates/embedding.conf:ro
- #- $PWD/../technical/nginx-docker.conf:/etc/nginx/conf.d/docker.conf:ro
environment:
- NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE: true
- PORT_IPV6: 8080
+ NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE: true # with deploy limits, will redduce the number of wrokers
BASE_URL: /swagger
- EMBEDDING: false #hack for cors
- DEEP_LINKING: true
- DISPLAY_REQUEST_DURATION: true
- FILTER: true
- SHOW_EXTENSIONS: true
- VALIDATOR_URL: null
+ #TRY_IT_OUT_ENABLED: true #enable "Try it out" by default
URLS_PRIMARY_NAME: gateway
URLS: >
[
{"url":"https://github.com/elastic/elasticsearch-specification/raw/8.12/output/openapi/elasticsearch-serverless-openapi.json","name":"ElasticSearch API"},
- {"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"},
- {"url":"http://localhost:9080/swagger/proxy-cors/9000","name":"[9000] gateway"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5022","name":"[5022] actions"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5010","name":"[5010] balances-adjustment"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5039","name":"[5039] case-import"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5000","name":"[5000] case"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5011","name":"[5011] case-validation"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5021","name":"[5021] cgmes-boundary"},
- {"url":"http://localhost:9080/swagger/proxy-cors/8095","name":"[8095] cgmes-gl"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5024","name":"[5024] config-notification"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5025","name":"[5025] config"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5004","name":"[5004] directory-notification"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5026","name":"[5026] directory"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5036","name":"[5036] dynamic-mapping"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5032","name":"[5032] dynamic-simulation"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5029","name":"[5029] explore"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5027","name":"[5027] filter"},
- {"url":"http://localhost:9080/swagger/proxy-cors/8087","name":"[8087] geo-data"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5008","name":"[5008] loadflow"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5002","name":"[5002] merge-notification"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5020","name":"[5020] merge-orchestrator"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5003","name":"[5003] network-conversion"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5006","name":"[5006] network-map"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5007","name":"[5007] network-modification"},
- {"url":"http://localhost:9080/swagger/proxy-cors/8080","name":"[8080] network-store"},
- {"url":"http://localhost:9080/swagger/proxy-cors/8090","name":"[8090] odre"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5028","name":"[5028] report"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5023","name":"[5023] security-analysis"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5030","name":"[5030] sensitivity-analysis"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5031","name":"[5031] shortcircuit"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5005","name":"[5005] single-line-diagram"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5035","name":"[5035] spreadsheet-config"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5009","name":"[5009] study-notification"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5001","name":"[5001] study"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5037","name":"[5037] timeseries"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5033","name":"[5033] user-admin"},
- {"url":"http://localhost:9080/swagger/proxy-cors/5038","name":"[5038] voltage-init"}
+ {"url":"https://github.com/elastic/kibana/raw/refs/tags/v8.7.1/x-pack/plugins/fleet/common/openapi/bundled.json","name":"Kibana plugin Fleet API"}
]
# no spec found for:
# https://rawcdn.githack.com/rabbitmq/rabbitmq-server/v3.13.7/deps/rabbitmq_management/priv/www/api/index.html
diff --git a/docker-compose/technical/swagger/Dockerfile b/docker-compose/technical/swagger/Dockerfile
new file mode 100644
index 00000000..de941387
--- /dev/null
+++ b/docker-compose/technical/swagger/Dockerfile
@@ -0,0 +1,12 @@
+FROM swaggerapi/swagger-ui:latest
+#--start-period=10s --start-interval=5s
+HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
+ CMD wget -Y off -O /dev/null http://localhost:8080/swagger/
+ #CMD curl --fail --noproxy '*' -so /dev/null http://localhost:8080/swagger/
+ENV PORT_IPV6: 8080
+
+#hack for cors
+ENV EMBEDDING: false
+COPY --chmod=0666 ./proxy-cors.conf /etc/nginx/templates/embedding.conf
+
+COPY --chmod=0666 ./swagger-initializer.js /usr/share/nginx/html/swagger-initializer.js
diff --git a/docker-compose/technical/swagger-proxy-cors.conf b/docker-compose/technical/swagger/proxy-cors.conf
similarity index 90%
rename from docker-compose/technical/swagger-proxy-cors.conf
rename to docker-compose/technical/swagger/proxy-cors.conf
index e1e4c956..c85a89d3 100644
--- a/docker-compose/technical/swagger-proxy-cors.conf
+++ b/docker-compose/technical/swagger/proxy-cors.conf
@@ -2,8 +2,9 @@
# https://github.com/swagger-api/swagger-ui/blob/master/docker/docker-entrypoint.d/40-swagger-ui.sh
# We add a proxy just to add the missing CORS headers to the servers reponse
-location ~ ^/swagger/proxy-cors/([0-9]+)/?$ {
+location ~ ^/swagger/proxy-cors/([0-9]+)(.*)$ {
set $dest_port $1;
+ set $path $2;
#[error] 0#0: *1 host.docker.internal could not be resolved (3: Host not found)
# set DNS resolver as Docker internal DNS
@@ -11,8 +12,8 @@ location ~ ^/swagger/proxy-cors/([0-9]+)/?$ {
resolver_timeout 5s;
# prevent dns caching and force nginx to make a dns lookup on each request.
- #set $target http://host.docker.internal:$dest_port/v3/api-docs;
- set $target http://172.17.0.1:$dest_port/v3/api-docs;
+ #set $target http://host.docker.internal:$dest_port$path;
+ set $target http://172.17.0.1:$dest_port$path;
#TODO: why the resolver not work?!
# Prevent loop requests
diff --git a/docker-compose/technical/swagger/swagger-initializer.js b/docker-compose/technical/swagger/swagger-initializer.js
new file mode 100644
index 00000000..05568f8f
--- /dev/null
+++ b/docker-compose/technical/swagger/swagger-initializer.js
@@ -0,0 +1,332 @@
+'use strict';
+const USE_PROXY = true; // pass by nginx proxy route
+const USE_DOCKER = false; // use container name for url instead of "localhost"
+const proxy_cors_url = 'http://localhost:9080/swagger/proxy-cors/';
+const proxy_url_transform = /^(http:\/\/)localhost:\d+\/swagger\/proxy-cors\/(\d+)(.*)$/;
+
+const RTE_LOGO = "%3Csvg width='70' height='70' viewBox='0 0 70 70' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3C!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch --%3E%3Ctitle%3ELogo RTE%3C/title%3E%3Cdesc%3ECreated with Sketch.%3C/desc%3E%3Cdefs%3E%3Cpolygon id='path-1' points='0.000122807018 0.377385965 69.6229825 0.377385965 69.6229825 70 0.000122807018 70'%3E%3C/polygon%3E%3Cpolygon id='path-1' points='0.000122807018 0.377385965 69.6229825 0.377385965 69.6229825 70 0.000122807018 70'%3E%3C/polygon%3E%3C/defs%3E%3Cg id='Symbols' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg id='HEADER/D/FILTRE' transform='translate(-101.000000, -16.000000)' fill='none'%3E%3Cg id='Logo-RTE' transform='translate(101.000000, 16.000000)' fill='none'%3E%3Cg fill='none'%3E%3Cg id='Grouper' fill='none'%3E%3Cmask id='mask-2' fill='%23FFFFFF'%3E%3Cuse xlink:href='%23path-1' fill='%23FFFFFF'%3E%3C/use%3E%3C/mask%3E%3Cg id='Clip-2' fill='none'%3E%3C/g%3E%3Cpath d='M69.6231053,35.1882632 C69.6231053,54.4137018 54.0376667,70.0003684 34.811,70.0003684 C15.5855614,70.0003684 0.000122807018,54.4137018 0.000122807018,35.1882632 C0.000122807018,15.9628246 15.5855614,0.377385965 34.811,0.377385965 C54.0376667,0.377385965 69.6231053,15.9628246 69.6231053,35.1882632' id='Fill-1' fill='%2300ADDF'%3E%3C/path%3E%3C/g%3E%3Cpath d='M45.5114541,33.5014463 C45.8647997,31.5726931 47.7579886,29.9540483 49.9549307,29.9540483 C52.150633,29.9540483 54.1678027,31.4656752 54.4864337,33.5014463 L45.5114541,33.5014463 Z M21.8248971,33.5014463 L17.3839002,33.5014463 L17.3839002,25.9335829 L21.8248971,25.9335829 C23.9561294,25.9335829 25.6807041,27.6264105 25.6807041,29.7144743 C25.6807041,31.8061865 23.9561294,33.5014463 21.8248971,33.5014463 Z M49.9623695,27.0159224 C46.116481,27.0159224 42.8446243,29.8579755 42.3660579,33.5002302 L36.6183019,33.5002302 L36.6183019,28.4691759 C36.6183019,27.665326 35.9190494,27.0110579 35.1007753,27.0110579 C34.2750623,27.0110579 33.5844885,27.665326 33.5844885,28.4691759 L33.5844885,33.5014463 L27.3023747,33.5002302 C28.1367664,32.5419341 28.6475678,31.1202995 28.6475678,29.721771 C28.6475678,26.0187107 25.5877184,23.0136986 21.8100194,23.0136986 L15.8713328,23.0136986 C15.0530587,23.0136986 14.3835616,23.659454 14.3835616,24.4754649 L14.3835616,42.6526872 C14.3835616,43.4601854 15.0480994,44.109589 15.8713328,44.109589 C16.6945662,44.109589 17.359104,43.4601854 17.359104,42.6526872 L17.359104,36.4176823 L22.9208886,36.4176823 L28.145445,43.5063976 C28.43804,43.9004178 28.8918102,44.109589 29.3554989,44.109589 C29.6580124,44.109589 29.9605259,44.0195968 30.2221256,43.8335317 C30.8866634,43.3616803 31.0379202,42.4483804 30.5556343,41.7977606 L26.5932038,36.4176823 L33.5844885,36.4176823 C33.5795293,36.7837319 33.5844885,39.8410368 33.5844885,39.8410368 C33.5844885,42.3644687 35.4553607,44.087699 37.9089434,44.087699 L38.7991265,44.087699 C39.6310385,44.087699 40.2980559,43.423702 40.2980559,42.6101233 C40.2980559,41.801409 39.6310385,41.1325475 38.7991265,41.1325475 L37.9089434,41.1325475 C37.1923336,41.1325475 36.6207815,40.539085 36.6207815,39.7765829 L36.6207815,36.4176823 L42.3164655,36.4176823 C42.3164655,40.7652817 45.8028093,44.087699 50.0156813,44.087699 L55.5824252,44.087699 C56.4081382,44.087699 57.1185489,43.4188376 57.1185489,42.6101233 C57.1185489,41.7989767 56.4540111,41.1325475 55.6245787,41.1325475 L50.0466766,41.1325475 C47.4591945,41.1325475 45.4122693,39.1733915 45.4122693,36.4176823 L55.9320514,36.4176823 C56.8023975,36.4176823 57.533885,35.619913 57.533885,34.7430964 C57.5747987,30.2544279 54.1380473,27.0159224 49.9623695,27.0159224 Z' id='Fill-3' fill='%23FEFEFE'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E";
+
+const GRIDSUITE_LOGO = "%3Csvg width='47.279259' height='54.585152' viewBox='0 0 86.531912 99.999998' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M86.6156 75.0103V24.9897L43.2975 0L0 24.9897V75.0103L43.2975 100L86.6156 75.0103Z' fill='%233DABE2'/%3E%3Cpath d='M86.533 75.0103L43.2975 100L0.0828247 75.0103L43.2975 50.3103L86.533 75.0103Z' fill='%231D1D1B'/%3E%3Cpath d='M72.6313 42.7389L53.041 24.7828H33.6367L14.0877 42.7389H30.9268L25.693 73.1071L28.734 73.6243L33.9677 42.7389H52.8134L58.0058 73.6243L61.0674 73.1071L55.9578 42.7389H72.6313ZM55.4613 39.6566L53.7857 29.6855L64.6462 39.6566H55.4613ZM21.9901 39.6566L33.0575 29.5407L31.3405 39.6566H21.9901ZM34.4021 39.6566L36.4708 27.9272H50.331L52.2962 39.6566H34.4021Z' fill='white'/%3E%3Cpath d='M17.2941 43.794C16.7827 43.794 16.2827 43.6423 15.8575 43.3582C15.4322 43.074 15.1008 42.6702 14.9051 42.1977C14.7094 41.7252 14.6582 41.2052 14.7579 40.7036C14.8577 40.202 15.104 39.7413 15.4656 39.3796C15.8273 39.018 16.288 38.7717 16.7896 38.6719C17.2912 38.5722 17.8112 38.6234 18.2837 38.8191C18.7562 39.0148 19.16 39.3462 19.4442 39.7715C19.7283 40.1967 19.88 40.6967 19.88 41.2081C19.88 41.8939 19.6075 42.5516 19.1226 43.0366C18.6376 43.5215 17.9799 43.794 17.2941 43.794V43.794Z' fill='%233DABE2'/%3E%3Cpath d='M17.2941 39.6566C17.6774 39.7008 18.031 39.8843 18.2877 40.1723C18.5444 40.4603 18.6863 40.8326 18.6863 41.2184C18.6863 41.6042 18.5444 41.9766 18.2877 42.2646C18.031 42.5526 17.6774 42.7361 17.2941 42.7803C16.9109 42.7361 16.5572 42.5526 16.3005 42.2646C16.0438 41.9766 15.902 41.6042 15.902 41.2184C15.902 40.8326 16.0438 40.4603 16.3005 40.1723C16.5572 39.8843 16.9109 39.7008 17.2941 39.6566V39.6566ZM17.2941 37.5879C16.5723 37.5838 15.8655 37.7944 15.2636 38.1929C14.6617 38.5914 14.1919 39.1598 13.9137 39.8259C13.6356 40.492 13.5618 41.2258 13.7016 41.934C13.8414 42.6421 14.1886 43.2928 14.699 43.8032C15.2094 44.3136 15.8601 44.6608 16.5683 44.8006C17.2764 44.9405 18.0102 44.8666 18.6763 44.5885C19.3425 44.3104 19.9109 43.8405 20.3094 43.2386C20.7078 42.6367 20.9184 41.9299 20.9143 41.2081C20.9143 40.248 20.5329 39.3272 19.854 38.6482C19.1751 37.9693 18.2543 37.5879 17.2941 37.5879V37.5879Z' fill='white'/%3E%3Cpath d='M69.3216 43.7939C68.8133 43.7735 68.3223 43.6037 67.9101 43.3056C67.4979 43.0075 67.1828 42.5945 67.0041 42.1182C66.8255 41.6419 66.7913 41.1235 66.9059 40.6279C67.0204 40.1323 67.2786 39.6814 67.6481 39.3318C68.0176 38.9822 68.482 38.7494 68.9832 38.6624C69.4844 38.5754 70.0002 38.6382 70.4658 38.8429C70.9315 39.0476 71.3265 39.3851 71.6013 39.8132C71.8762 40.2412 72.0186 40.7408 72.0109 41.2495C72.0056 41.5944 71.9314 41.9349 71.7926 42.2507C71.6538 42.5665 71.4531 42.8514 71.2025 43.0885C70.9519 43.3256 70.6564 43.5102 70.3334 43.6314C70.0103 43.7525 69.6663 43.8078 69.3216 43.7939V43.7939Z' fill='%233DABE2'/%3E%3Cpath d='M69.3216 39.6566C69.6343 39.6525 69.9411 39.7417 70.2028 39.9129C70.4645 40.0841 70.6692 40.3294 70.7907 40.6175C70.9123 40.9056 70.9451 41.2234 70.8851 41.5303C70.8251 41.8372 70.675 42.1192 70.4539 42.3404C70.2328 42.5615 69.9507 42.7116 69.6438 42.7716C69.3369 42.8316 69.0191 42.7988 68.731 42.6772C68.4429 42.5557 68.1976 42.3509 68.0264 42.0893C67.8553 41.8276 67.766 41.5208 67.7701 41.2081C67.7755 40.7983 67.9406 40.4067 68.2304 40.1169C68.5203 39.8271 68.9118 39.6619 69.3216 39.6566V39.6566ZM69.3216 37.5879C68.6006 37.5879 67.8959 37.802 67.2967 38.203C66.6975 38.604 66.2309 39.1738 65.9559 39.8403C65.681 40.5068 65.6101 41.2399 65.7523 41.9467C65.8944 42.6535 66.2433 43.3022 66.7545 43.8106C67.2658 44.3189 67.9165 44.6641 68.6241 44.8022C69.3317 44.9403 70.0644 44.8653 70.7293 44.5865C71.3942 44.3078 71.9614 43.8379 72.359 43.2365C72.7565 42.635 72.9666 41.9291 72.9625 41.2081C72.957 40.2461 72.571 39.3253 71.8888 38.647C71.2066 37.9686 70.2837 37.5879 69.3216 37.5879V37.5879Z' fill='white'/%3E%3Cpath d='M43.2974 43.8353C44.7255 43.8353 45.8832 42.6776 45.8832 41.2495C45.8832 39.8214 44.7255 38.6636 43.2974 38.6636C41.8693 38.6636 40.7115 39.8214 40.7115 41.2495C40.7115 42.6776 41.8693 43.8353 43.2974 43.8353Z' fill='%233DABE2'/%3E%3Cpath d='M43.2975 39.6566C43.6102 39.6525 43.917 39.7417 44.1787 39.9129C44.4403 40.0841 44.6451 40.3294 44.7666 40.6175C44.8882 40.9056 44.921 41.2234 44.861 41.5303C44.801 41.8372 44.6509 42.1192 44.4298 42.3404C44.2086 42.5615 43.9266 42.7116 43.6197 42.7716C43.3128 42.8316 42.995 42.7988 42.7069 42.6772C42.4188 42.5557 42.1735 42.3509 42.0023 42.0893C41.8311 41.8276 41.7419 41.5208 41.746 41.2081C41.7513 40.7983 41.9165 40.4067 42.2063 40.1169C42.4961 39.8271 42.8877 39.6619 43.2975 39.6566V39.6566ZM43.2975 37.5879C42.5765 37.5879 41.8718 37.802 41.2726 38.203C40.6734 38.604 40.2068 39.1738 39.9318 39.8403C39.6569 40.5068 39.586 41.2399 39.7282 41.9467C39.8703 42.6535 40.2192 43.3022 40.7304 43.8106C41.2417 44.3189 41.8923 44.6641 42.6 44.8022C43.3076 44.9403 44.0403 44.8653 44.7052 44.5865C45.3701 44.3078 45.9373 43.8379 46.3349 43.2365C46.7324 42.635 46.9425 41.9291 46.9384 41.2081C46.9329 40.2461 46.5469 39.3253 45.8647 38.647C45.1825 37.9686 44.2595 37.5879 43.2975 37.5879V37.5879Z' fill='white'/%3E%3Cpath d='M27.2239 75.9619C28.652 75.9619 29.8097 74.8042 29.8097 73.3761C29.8097 71.948 28.652 70.7902 27.2239 70.7902C25.7957 70.7902 24.638 71.948 24.638 73.3761C24.638 74.8042 25.7957 75.9619 27.2239 75.9619Z' fill='white'/%3E%3Cpath d='M27.2239 71.8246C27.6354 71.8246 28.03 71.988 28.321 72.279C28.6119 72.57 28.7754 72.9646 28.7754 73.3761C28.7754 73.7876 28.6119 74.1822 28.321 74.4732C28.03 74.7641 27.6354 74.9276 27.2239 74.9276C26.8124 74.9276 26.4178 74.7641 26.1268 74.4732C25.8358 74.1822 25.6724 73.7876 25.6724 73.3761C25.6724 72.9646 25.8358 72.57 26.1268 72.279C26.4178 71.988 26.8124 71.8246 27.2239 71.8246V71.8246ZM27.2239 69.7559C26.5079 69.7559 25.808 69.9682 25.2126 70.366C24.6173 70.7638 24.1533 71.3292 23.8793 71.9907C23.6053 72.6522 23.5336 73.3801 23.6733 74.0823C23.8129 74.7846 24.1577 75.4296 24.664 75.9359C25.1703 76.4422 25.8154 76.787 26.5176 76.9267C27.2199 77.0664 27.9478 76.9947 28.6093 76.7207C29.2708 76.4467 29.8362 75.9827 30.234 75.3873C30.6318 74.792 30.8441 74.0921 30.8441 73.3761C30.8441 72.4159 30.4627 71.4951 29.7838 70.8162C29.1048 70.1373 28.184 69.7559 27.2239 69.7559V69.7559Z' fill='white'/%3E%3Cpath d='M59.5367 75.9619C60.9648 75.9619 62.1225 74.8042 62.1225 73.3761C62.1225 71.948 60.9648 70.7902 59.5367 70.7902C58.1085 70.7902 56.9508 71.948 56.9508 73.3761C56.9508 74.8042 58.1085 75.9619 59.5367 75.9619Z' fill='white'/%3E%3Cpath d='M59.5987 71.8246C60.0102 71.8246 60.4048 71.988 60.6958 72.279C60.9868 72.57 61.1502 72.9646 61.1502 73.3761C61.1502 73.7876 60.9868 74.1822 60.6958 74.4732C60.4048 74.7641 60.0102 74.9276 59.5987 74.9276C59.1872 74.9276 58.7926 74.7641 58.5016 74.4732C58.2107 74.1822 58.0472 73.7876 58.0472 73.3761C58.0472 72.9646 58.2107 72.57 58.5016 72.279C58.7926 71.988 59.1872 71.8246 59.5987 71.8246ZM59.5987 69.7559C58.8827 69.7559 58.1828 69.9682 57.5874 70.366C56.9921 70.7638 56.5281 71.3292 56.2541 71.9907C55.9801 72.6522 55.9084 73.3801 56.0481 74.0823C56.1878 74.7846 56.5326 75.4296 57.0388 75.9359C57.5451 76.4422 58.1902 76.787 58.8924 76.9267C59.5947 77.0664 60.3226 76.9947 60.9841 76.7207C61.6456 76.4467 62.211 75.9827 62.6088 75.3873C63.0066 74.792 63.2189 74.0921 63.2189 73.3761C63.2189 72.4159 62.8375 71.4951 62.1586 70.8162C61.4797 70.1373 60.5588 69.7559 59.5987 69.7559V69.7559Z' fill='white'/%3E%3C/svg%3E";
+
+const SWAGGERUI_DARK_CSS = '@media only screen and (prefers-color-scheme:dark){a{color:#8c8cfa}embed[type="application/pdf"]{filter:invert(90%)}html{background:#1f1f1f!important;box-sizing:border-box;filter:contrast(100%) brightness(100%) saturate(100%);overflow-y:scroll}body{background:#1f1f1f;background-image:none!important}.swagger-ui input[disabled],.swagger-ui select[disabled],button,input,select,textarea{background-color:#1f1f1f;color:#bfbfbf}font,html{color:#bfbfbf}.swagger-ui,.swagger-ui .checkbox p,.swagger-ui .dialog-ux .modal-ux-content h4,.swagger-ui .dialog-ux .modal-ux-content p,.swagger-ui .dialog-ux .modal-ux-header h3,.swagger-ui .errors-wrapper .errors h4,.swagger-ui .errors-wrapper hgroup h4,.swagger-ui .info .base-url,.swagger-ui .info .title,.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5,.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table,.swagger-ui .loading-container .loading::after,.swagger-ui .model,.swagger-ui .opblock .opblock-section-header h4,.swagger-ui .opblock .opblock-section-header>label,.swagger-ui .opblock .opblock-summary-description,.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated,.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-tag small,.swagger-ui .opblock-title_normal,.swagger-ui .opblock-title_normal h4,.swagger-ui .opblock-title_normal p,.swagger-ui .parameter__name,.swagger-ui .parameter__type,.swagger-ui .response-col_links,.swagger-ui .response-col_status,.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5,.swagger-ui .scheme-container .schemes>label,.swagger-ui .scopes h2,.swagger-ui .servers>label,.swagger-ui .tab li,.swagger-ui label,.swagger-ui section h3,.swagger-ui select,.swagger-ui table.headers td{color:#b5bac9}.swagger-ui a{background-color:transparent}.swagger-ui mark{background-color:#664b00;color:#bfbfbf}.swagger-ui .color-inherit,.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover,.swagger-ui legend{color:inherit}.swagger-ui .debug *{outline:#e6da99 solid 1px}.swagger-ui .debug-white *{outline:#fff solid 1px}.swagger-ui .debug-black *{outline:#bfbfbf solid 1px}.swagger-ui .debug-grid{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==)}.swagger-ui .debug-grid-16{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC)}.swagger-ui .debug-grid-8-solid{background:url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) #1c1c21}.swagger-ui .debug-grid-16-solid{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) #1c1c21}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#121212}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#545454}.swagger-ui .b--gray{border-color:#787878}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#6e6e6e}.swagger-ui .b--moon-gray{border-color:#4d4d4d}.swagger-ui .b--light-gray{border-color:#2b2b2b}.swagger-ui .b--near-white{border-color:#242424}.swagger-ui .b--white{border-color:#1c1c21}.swagger-ui .b--white-90{border-color:rgba(28,28,33,.9)}.swagger-ui .b--white-80{border-color:rgba(28,28,33,.8)}.swagger-ui .b--white-70{border-color:rgba(28,28,33,.7)}.swagger-ui .b--white-60{border-color:rgba(28,28,33,.6)}.swagger-ui .b--white-50{border-color:rgba(28,28,33,.5)}.swagger-ui .b--white-40{border-color:rgba(28,28,33,.4)}.swagger-ui .b--white-30{border-color:rgba(28,28,33,.3)}.swagger-ui .b--white-20{border-color:rgba(28,28,33,.2)}.swagger-ui .b--white-10{border-color:rgba(28,28,33,.1)}.swagger-ui .b--white-05{border-color:rgba(28,28,33,.05)}.swagger-ui .b--white-025{border-color:rgba(28,28,33,.024)}.swagger-ui .b--white-0125{border-color:rgba(28,28,33,.01)}.swagger-ui .b--black-90{border-color:rgba(0,0,0,.9)}.swagger-ui .b--black-80{border-color:rgba(0,0,0,.8)}.swagger-ui .b--black-70{border-color:rgba(0,0,0,.7)}.swagger-ui .b--black-60{border-color:rgba(0,0,0,.6)}.swagger-ui .b--black-50{border-color:rgba(0,0,0,.5)}.swagger-ui .b--black-40{border-color:rgba(0,0,0,.4)}.swagger-ui .b--black-30{border-color:rgba(0,0,0,.3)}.swagger-ui .b--black-20{border-color:rgba(0,0,0,.2)}.swagger-ui .b--black-10{border-color:rgba(0,0,0,.1)}.swagger-ui .b--black-05{border-color:rgba(0,0,0,.05)}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.024)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.01)}.swagger-ui .b--dark-red{border-color:#bc2f36}.swagger-ui .b--red{border-color:#c83932}.swagger-ui .b--light-red{border-color:#ab3c2b}.swagger-ui .b--orange{border-color:#cc6e33}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#672caf}.swagger-ui .b--dark-pink{border-color:#ab2b81}.swagger-ui .b--hot-pink{border-color:#c03086}.swagger-ui .b--pink{border-color:#8f2464}.swagger-ui .b--light-pink{border-color:#721d4d}.swagger-ui .b--dark-green{border-color:#1c6e50}.swagger-ui .b--green{border-color:#279b70}.swagger-ui .b--light-green{border-color:#228762}.swagger-ui .b--navy{border-color:#0d1d35}.swagger-ui .b--dark-blue{border-color:#20497e}.swagger-ui .b--blue{border-color:#4380d0}.swagger-ui .b--light-blue{border-color:#20517e}.swagger-ui .b--lightest-blue{border-color:#143a52}.swagger-ui .b--washed-blue{border-color:#0c312d}.swagger-ui .b--washed-green{border-color:#0f3d2c}.swagger-ui .b--washed-red{border-color:#411010}.swagger-ui .b--transparent{border-color:transparent}.swagger-ui .b--gold,.swagger-ui .b--light-yellow,.swagger-ui .b--washed-yellow,.swagger-ui .b--yellow{border-color:#664b00}.swagger-ui .shadow-1{box-shadow:rgba(0,0,0,.2) 0 0 4px 2px}.swagger-ui .shadow-2{box-shadow:rgba(0,0,0,.2) 0 0 8px 2px}.swagger-ui .shadow-3{box-shadow:rgba(0,0,0,.2) 2px 2px 4px 2px}.swagger-ui .shadow-4{box-shadow:rgba(0,0,0,.2) 2px 2px 8px 0}.swagger-ui .shadow-5{box-shadow:rgba(0,0,0,.2) 4px 4px 8px 0}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:rgba(0,0,0,.2) 0 0 4px 2px}.swagger-ui .shadow-2-ns{box-shadow:rgba(0,0,0,.2) 0 0 8px 2px}.swagger-ui .shadow-3-ns{box-shadow:rgba(0,0,0,.2) 2px 2px 4px 2px}.swagger-ui .shadow-4-ns{box-shadow:rgba(0,0,0,.2) 2px 2px 8px 0}.swagger-ui .shadow-5-ns{box-shadow:rgba(0,0,0,.2) 4px 4px 8px 0}}@media screen and (max-width:60em) and (min-width:30em){.swagger-ui .shadow-1-m{box-shadow:rgba(0,0,0,.2) 0 0 4px 2px}.swagger-ui .shadow-2-m{box-shadow:rgba(0,0,0,.2) 0 0 8px 2px}.swagger-ui .shadow-3-m{box-shadow:rgba(0,0,0,.2) 2px 2px 4px 2px}.swagger-ui .shadow-4-m{box-shadow:rgba(0,0,0,.2) 2px 2px 8px 0}.swagger-ui .shadow-5-m{box-shadow:rgba(0,0,0,.2) 4px 4px 8px 0}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:rgba(0,0,0,.2) 0 0 4px 2px}.swagger-ui .shadow-2-l{box-shadow:rgba(0,0,0,.2) 0 0 8px 2px}.swagger-ui .shadow-3-l{box-shadow:rgba(0,0,0,.2) 2px 2px 4px 2px}.swagger-ui .shadow-4-l{box-shadow:rgba(0,0,0,.2) 2px 2px 8px 0}.swagger-ui .shadow-5-l{box-shadow:rgba(0,0,0,.2) 4px 4px 8px 0}}.swagger-ui .black-05{color:rgba(191,191,191,.05)}.swagger-ui .bg-black-05{background-color:rgba(0,0,0,.05)}.swagger-ui .black-90,.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:rgba(191,191,191,.9)}.swagger-ui .black-80,.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:rgba(191,191,191,.8)}.swagger-ui .black-70,.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:rgba(191,191,191,.7)}.swagger-ui .black-60,.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:rgba(191,191,191,.6)}.swagger-ui .black-50,.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:rgba(191,191,191,.5)}.swagger-ui .black-40,.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:rgba(191,191,191,.4)}.swagger-ui .black-30,.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:rgba(191,191,191,.3)}.swagger-ui .black-20,.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:rgba(191,191,191,.2)}.swagger-ui .black-10,.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:rgba(191,191,191,.1)}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover,.swagger-ui .white-90{color:rgba(255,255,255,.9)}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover,.swagger-ui .white-80{color:rgba(255,255,255,.8)}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover,.swagger-ui .white-70{color:rgba(255,255,255,.7)}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover,.swagger-ui .white-60{color:rgba(255,255,255,.6)}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover,.swagger-ui .white-50{color:rgba(255,255,255,.5)}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover,.swagger-ui .white-40{color:rgba(255,255,255,.4)}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover,.swagger-ui .white-30{color:rgba(255,255,255,.3)}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover,.swagger-ui .white-20{color:rgba(255,255,255,.2)}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover,.swagger-ui .white-10{color:rgba(255,255,255,.1)}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover,.swagger-ui .moon-gray{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover,.swagger-ui .light-gray{color:#ededed}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover,.swagger-ui .near-white{color:#f5f5f5}.swagger-ui .dark-red,.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e6999d}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover,.swagger-ui .red{color:#e69d99}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover,.swagger-ui .light-red{color:#e6a399}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover,.swagger-ui .orange{color:#e6b699}.swagger-ui .gold,.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#e6d099}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover,.swagger-ui .yellow{color:#e6da99}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover,.swagger-ui .light-yellow{color:#ede6b6}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover,.swagger-ui .purple{color:#b99ae4}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover,.swagger-ui .light-purple{color:#bb99e6}.swagger-ui .dark-pink,.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#e699cc}.swagger-ui .hot-pink,.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover,.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover,.swagger-ui .pink{color:#e699c7}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover,.swagger-ui .light-pink{color:#edb6d5}.swagger-ui .dark-green,.swagger-ui .green,.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover,.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#99e6c9}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover,.swagger-ui .light-green{color:#a1e8ce}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover,.swagger-ui .navy{color:#99b8e6}.swagger-ui .blue,.swagger-ui .dark-blue,.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover,.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#99bae6}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover,.swagger-ui .light-blue{color:#a9cbea}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover,.swagger-ui .lightest-blue{color:#d6e9f5}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover,.swagger-ui .washed-blue{color:#f7fdfc}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover,.swagger-ui .washed-green{color:#ebfaf4}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover,.swagger-ui .washed-yellow{color:#fbf9ef}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover,.swagger-ui .washed-red{color:#f9e7e7}.swagger-ui .bg-black-90,.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.swagger-ui .bg-black-80,.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.swagger-ui .bg-black-70,.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.swagger-ui .bg-black-60,.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.swagger-ui .bg-black-50,.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.swagger-ui .bg-black-40,.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.swagger-ui .bg-black-30,.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.swagger-ui .bg-black-20,.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.swagger-ui .bg-white-90,.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:rgba(28,28,33,.9)}.swagger-ui .bg-white-80,.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:rgba(28,28,33,.8)}.swagger-ui .bg-white-70,.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:rgba(28,28,33,.7)}.swagger-ui .bg-white-60,.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:rgba(28,28,33,.6)}.swagger-ui .bg-white-50,.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:rgba(28,28,33,.5)}.swagger-ui .bg-white-40,.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:rgba(28,28,33,.4)}.swagger-ui .bg-white-30,.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:rgba(28,28,33,.3)}.swagger-ui .bg-white-20,.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:rgba(28,28,33,.2)}.swagger-ui .bg-black,.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .bg-near-black,.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#121212}.swagger-ui .bg-dark-gray,.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .bg-mid-gray,.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#545454}.swagger-ui .bg-gray,.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#787878}.swagger-ui .bg-silver,.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .bg-white,.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#1c1c21}.swagger-ui .bg-transparent,.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:transparent}.swagger-ui .bg-dark-red,.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#bc2f36}.swagger-ui .bg-red,.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#c83932}.swagger-ui .bg-light-red,.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ab3c2b}.swagger-ui .bg-orange,.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#cc6e33}.swagger-ui .bg-gold,.swagger-ui .bg-light-yellow,.swagger-ui .bg-washed-yellow,.swagger-ui .bg-yellow,.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover,.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover,.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover,.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:#664b00}.swagger-ui .bg-purple,.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .bg-light-purple,.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#672caf}.swagger-ui .bg-dark-pink,.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#ab2b81}.swagger-ui .bg-hot-pink,.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#c03086}.swagger-ui .bg-pink,.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#8f2464}.swagger-ui .bg-light-pink,.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#721d4d}.swagger-ui .bg-dark-green,.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#1c6e50}.swagger-ui .bg-green,.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#279b70}.swagger-ui .bg-light-green,.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#228762}.swagger-ui .bg-navy,.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#0d1d35}.swagger-ui .bg-dark-blue,.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#20497e}.swagger-ui .bg-blue,.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#4380d0}.swagger-ui .bg-light-blue,.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#20517e}.swagger-ui .bg-lightest-blue,.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#143a52}.swagger-ui .bg-washed-blue,.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#0c312d}.swagger-ui .bg-washed-green,.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#0f3d2c}.swagger-ui .bg-washed-red,.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#411010}.swagger-ui .bg-inherit,.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .shadow-hover{transition:.5s cubic-bezier(.165, .84, .44, 1)}.swagger-ui .shadow-hover::after{border-radius:inherit;box-shadow:rgba(0,0,0,.2) 0 0 16px 2px;content:"";height:100%;left:0;opacity:0;position:absolute;top:0;transition:opacity .5s cubic-bezier(.165, .84, .44, 1);width:100%;z-index:-1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .nested-links a{color:#99bae6;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#a9cbea;transition:color .15s ease-in}.swagger-ui .opblock-tag{border-bottom:1px solid rgba(58,64,80,.3);color:#b5bac9;transition:.2s}.swagger-ui .opblock-tag svg,.swagger-ui section.models h4 svg{transition:.4s}.swagger-ui .opblock{border:1px solid #000;border-radius:4px;box-shadow:rgba(0,0,0,.19) 0 0 3px;margin:0 0 15px}.swagger-ui .opblock .tab-header .tab-item.active h4 span::after{background:gray}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{background:rgba(28,28,33,.8);box-shadow:rgba(0,0,0,.1) 0 1px 2px}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-summary-method{background:#000;color:#fff;text-shadow:rgba(0,0,0,.1) 0 1px 0}.swagger-ui .opblock.opblock-post{background:rgba(72,203,144,.1);border-color:#48cb90}.swagger-ui .opblock.opblock-post .opblock-summary-method,.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span::after{background:#48cb90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#48cb90}.swagger-ui .opblock.opblock-put{background:rgba(213,157,88,.1);border-color:#d59d58}.swagger-ui .opblock.opblock-put .opblock-summary-method,.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span::after{background:#d59d58}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#d59d58}.swagger-ui .opblock.opblock-delete{background:rgba(200,50,50,.1);border-color:#c83232}.swagger-ui .opblock.opblock-delete .opblock-summary-method,.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span::after{background:#c83232}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#c83232}.swagger-ui .opblock.opblock-get{background:rgba(42,105,167,.1);border-color:#2a69a7}.swagger-ui .opblock.opblock-get .opblock-summary-method,.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span::after{background:#2a69a7}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#2a69a7}.swagger-ui .opblock.opblock-patch{background:rgba(92,214,188,.1);border-color:#5cd6bc}.swagger-ui .opblock.opblock-patch .opblock-summary-method,.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span::after{background:#5cd6bc}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#5cd6bc}.swagger-ui .opblock.opblock-head{background:rgba(140,63,207,.1);border-color:#8c3fcf}.swagger-ui .opblock.opblock-head .opblock-summary-method,.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span::after{background:#8c3fcf}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#8c3fcf}.swagger-ui .opblock.opblock-options{background:rgba(36,89,143,.1);border-color:#24598f}.swagger-ui .opblock.opblock-options .opblock-summary-method,.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span::after{background:#24598f}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#24598f}.swagger-ui .opblock.opblock-deprecated{background:rgba(46,46,46,.1);border-color:#2e2e2e;opacity:.6}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method,.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span::after{background:#2e2e2e}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#2e2e2e}.swagger-ui .filter .operation-filter-input{border:2px solid #2b3446}.swagger-ui .tab li:first-of-type::after{background:rgba(0,0,0,.2)}.swagger-ui .download-contents{background:#7c8192;color:#fff}.swagger-ui .scheme-container{background:#1c1c21;box-shadow:rgba(0,0,0,.15) 0 1px 2px 0}.swagger-ui .loading-container .loading::before{animation:1s linear infinite rotation,.5s opacity;border-color:rgba(0,0,0,.6) rgba(84,84,84,.1) rgba(84,84,84,.1)}.swagger-ui .response-control-media-type--accept-controller select{border-color:#196619}.swagger-ui .response-control-media-type__accept-message{color:#99e699}.swagger-ui .version-pragma__message code{background-color:#3b3b3b}.swagger-ui .btn{background:0 0;border:2px solid gray;box-shadow:rgba(0,0,0,.1) 0 1px 2px;color:#b5bac9}.swagger-ui .btn:hover{box-shadow:rgba(0,0,0,.3) 0 0 5px}.swagger-ui .btn.authorize,.swagger-ui .btn.cancel{background-color:transparent;border-color:#a72a2a;color:#e69999}.swagger-ui .btn.cancel:hover{background-color:#a72a2a;color:#fff}.swagger-ui .btn.authorize{border-color:#48cb90;color:#9ce3c3}.swagger-ui .btn.authorize svg{fill:#9ce3c3}.btn.authorize.unlocked:hover{background-color:#48cb90;color:#fff}.btn.authorize.unlocked:hover svg{fill:#fbfbfb}.swagger-ui .btn.execute{background-color:#5892d5;border-color:#5892d5;color:#fff}.swagger-ui .copy-to-clipboard{background:#7c8192}.swagger-ui .copy-to-clipboard button{background:url("data:image/svg+xml;charset=utf-8,") 50% center no-repeat}.swagger-ui select{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMS4wICg0MDM1YTRmYjQ5LCAyMDIwLTA1LTAxKSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZG93bmxvYWQuc3ZnIgogICBpZD0ic3ZnNCIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMjAgMjAiPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTEwIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzOCIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItOSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTkiCiAgICAgaW5rc2NhcGU6Y3k9IjEwIgogICAgIGlua3NjYXBlOmN4PSIxMCIKICAgICBpbmtzY2FwZTp6b29tPSI0MS41IgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3NiIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDAxIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIKICAgICBpZD0icGF0aDIiCiAgICAgZD0iTTEzLjQxOCA3Ljg1OWEuNjk1LjY5NSAwIDAxLjk3OCAwIC42OC42OCAwIDAxMCAuOTY5bC0zLjkwOCAzLjgzYS42OTcuNjk3IDAgMDEtLjk3OSAwbC0zLjkwOC0zLjgzYS42OC42OCAwIDAxMC0uOTY5LjY5NS42OTUgMCAwMS45NzggMEwxMCAxMWwzLjQxOC0zLjE0MXoiIC8+Cjwvc3ZnPgo=) right 10px center/20px no-repeat #1c1c21;border:2px solid #41444e}.swagger-ui select[multiple]{background:#212121}.swagger-ui button.invalid,.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui select.invalid,.swagger-ui textarea.invalid{background:#390e0e;border-color:#c83232}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{background:#1c1c21;border:1px solid #404040}.swagger-ui textarea{background:rgba(28,28,33,.8);color:#b5bac9}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}.swagger-ui select[disabled]{border-color:#878787}.swagger-ui textarea:focus{border:2px solid #2a69a7}.swagger-ui .checkbox input[type=checkbox]+label>.item{background:#303030;box-shadow:#303030 0 0 0 2px}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:url("data:image/svg+xml;charset=utf-8,") 50% center no-repeat #303030}.swagger-ui .dialog-ux .backdrop-ux{background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{background:#1c1c21;border:1px solid #2e2e2e;box-shadow:rgba(0,0,0,.2) 0 10px 30px 0}.swagger-ui .dialog-ux .modal-ux-header .close-modal{background:0 0}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#bfbfbf!important}.swagger-ui .model-toggle::after{background:url("data:image/svg+xml;charset=utf-8,") 50% center/100% no-repeat}.swagger-ui .model-hint{background:rgba(0,0,0,.7);color:#ebebeb}.swagger-ui section.models{border:1px solid rgba(58,64,80,.3)}.swagger-ui section.models.is-open h4{border-bottom:1px solid rgba(58,64,80,.3)}.swagger-ui section.models .model-container{background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui .model-box{background:rgba(0,0,0,.1)}.swagger-ui .prop-type{color:#aaaad4}.swagger-ui table thead tr td,.swagger-ui table thead tr th{border-bottom:1px solid rgba(58,64,80,.2);color:#b5bac9}.swagger-ui .parameter__name.required::after{color:rgba(230,153,153,.6)}.swagger-ui .topbar .download-url-wrapper .select-label{color:#f0f0f0}.swagger-ui .topbar .download-url-wrapper .download-url-button{background:#63a040;color:#fff}.swagger-ui .info .title small{background:#7c8492}.swagger-ui .info .title small.version-stamp{background-color:#7a9b27}.swagger-ui .auth-container .errors{background-color:#350d0d;color:#b5bac9}.swagger-ui .errors-wrapper{background:rgba(200,50,50,.1);border:2px solid #c83232}.swagger-ui .markdown code,.swagger-ui .renderedmarkdown code{background:rgba(0,0,0,.05);color:#c299e6}.swagger-ui .model-toggle:after{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMS4wICg0MDM1YTRmYjQ5LCAyMDIwLTA1LTAxKSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZG93bmxvYWQyLnN2ZyIKICAgaWQ9InN2ZzQiCiAgIHZlcnNpb249IjEuMSIKICAgaGVpZ2h0PSIyNCIKICAgd2lkdGg9IjI0Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzQiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTkiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii05IgogICAgIGlua3NjYXBlOmN5PSIxMiIKICAgICBpbmtzY2FwZTpjeD0iMTIiCiAgICAgaW5rc2NhcGU6em9vbT0iMzQuNTgzMzMzIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3NiIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDAxIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIKICAgICBpZD0icGF0aDIiCiAgICAgZD0iTTEwIDZMOC41OSA3LjQxIDEzLjE3IDEybC00LjU4IDQuNTlMMTAgMThsNi02eiIgLz4KPC9zdmc+Cg==) 50% no-repeat}#large-arrow-up,#unlocked,.arrow{fill:#fff}::-webkit-scrollbar-button,::-webkit-scrollbar-track-piece{background-color:#3e4346!important}.swagger-ui .black,.swagger-ui .checkbox,.swagger-ui .dark-gray,.swagger-ui .download-url-wrapper .loading,.swagger-ui .errors-wrapper .errors small,.swagger-ui .fallback,.swagger-ui .filter .loading,.swagger-ui .gray,.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover,.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover,.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover,.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover,.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover,.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover,.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover,.swagger-ui .light-silver,.swagger-ui .markdown pre,.swagger-ui .mid-gray,.swagger-ui .model .property,.swagger-ui .model .property.primitive,.swagger-ui .model-title,.swagger-ui .near-black,.swagger-ui .parameter__extension,.swagger-ui .parameter__in,.swagger-ui .prop-format,.swagger-ui .renderedmarkdown pre,.swagger-ui .response-col_links .response-undocumented,.swagger-ui .response-col_status .response-undocumented,.swagger-ui .silver,.swagger-ui section.models h4,.swagger-ui section.models h5,.swagger-ui span.token-not-formatted,.swagger-ui span.token-string,.swagger-ui table.headers .header-example,.swagger-ui table.model tr.description,.swagger-ui table.model tr.extension{color:#bfbfbf}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover,.swagger-ui .info .title small pre,.swagger-ui .topbar a,.swagger-ui .white{color:#fff}.swagger-ui .bg-black-10,.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover,.swagger-ui .stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.swagger-ui .bg-white-10,.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover,.swagger-ui .stripe-light:nth-child(odd){background-color:rgba(28,28,33,.1)}.swagger-ui .bg-light-silver,.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover,.swagger-ui .striped--light-silver:nth-child(odd){background-color:#6e6e6e}.swagger-ui .bg-moon-gray,.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover,.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#4d4d4d}.swagger-ui .bg-light-gray,.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover,.swagger-ui .striped--light-gray:nth-child(odd){background-color:#2b2b2b}.swagger-ui .bg-near-white,.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover,.swagger-ui .striped--near-white:nth-child(odd){background-color:#242424}.swagger-ui .opblock-tag:hover,.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui .download-url-wrapper .failed,.swagger-ui .filter .failed,.swagger-ui .model-deprecated-warning,.swagger-ui .parameter__deprecated,.swagger-ui .parameter__name.required span,.swagger-ui table.model tr.property-row .star{color:#e69999}.swagger-ui .opblock-body pre.microlight,.swagger-ui textarea.curl{background:#41444e;border-radius:4px;color:#fff}.swagger-ui .expand-methods svg,.swagger-ui .expand-methods:hover svg{fill:#bfbfbf}.swagger-ui .auth-container,.swagger-ui .dialog-ux .modal-ux-header{border-bottom:1px solid #2e2e2e}.swagger-ui .topbar .download-url-wrapper .select-label select,.swagger-ui .topbar .download-url-wrapper input[type=text]{border:2px solid #63a040}.swagger-ui .info a,.swagger-ui .info a:hover,.swagger-ui .scopes h2 a{color:#99bde6}::-webkit-scrollbar{width:14px;height:14px}::-webkit-scrollbar-button{background-color:#3e4346!important}::-webkit-scrollbar-track{background-color:#646464!important}::-webkit-scrollbar-track-piece{background-color:#3e4346!important}::-webkit-scrollbar-thumb{height:50px;background-color:#242424!important;border:2px solid #3e4346!important}::-webkit-scrollbar-button:vertical:start:decrement{background:linear-gradient(130deg,#696969 40%,rgba(255,0,0,0) 41%),linear-gradient(230deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(0deg,#696969 40%,rgba(0,0,0,0) 31%);background-color:#b6b6b6}::-webkit-scrollbar-button:vertical:end:increment{background:linear-gradient(310deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(50deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(180deg,#696969 40%,rgba(0,0,0,0) 31%);background-color:#b6b6b6}::-webkit-scrollbar-button:horizontal:end:increment{background:linear-gradient(210deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(330deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(90deg,#696969 30%,rgba(0,0,0,0) 31%);background-color:#b6b6b6}::-webkit-scrollbar-button:horizontal:start:decrement{background:linear-gradient(30deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(150deg,#696969 40%,rgba(0,0,0,0) 41%),linear-gradient(270deg,#696969 30%,rgba(0,0,0,0) 31%);background-color:#b6b6b6}}';
+
+/* src: https://github.com/Amoenus/SwaggerDark
+ * alt: https://github.com/oqo0/swagger-themes
+ */
+//window.addEventListener('load', function() {
+ let darkStyle = document.createElement('style');
+ darkStyle.setAttribute('type', 'text/css');
+ darkStyle.textContent = SWAGGERUI_DARK_CSS;
+ document.head.appendChild(darkStyle);
+ console.info('SwaggerDark CSS injected.');
+//});
+
+/** Modify URL shown in header */
+function transformServerUrlApi(url) {
+ if(USE_PROXY) {
+ console.debug('[info component] URL =', url);
+ return url?.replace(proxy_url_transform, '$1localhost:$2$3');
+ } else return url;
+}
+
+/** Modify server url in spec, for components like ServersContainer, request_snippets, etc... */
+function transformServerUrlSpec(servers = [], specUrl) {
+ if(USE_PROXY) {
+ //console.debug('[redux(spec)] servers:', servers);
+ return servers.map(server => {
+ if (server.url === 'http://localhost') {
+ return {
+ url: specUrl?.replace(proxy_url_transform, '$1localhost:$2'),
+ description: server.description,
+ };
+ } else return server;
+ });
+ } else return servers;
+}
+
+/** Revert back the URL for the "Try it out" requests */
+function transformRequestUrl(reqParams = {}) {
+ if(USE_PROXY) {
+ return {
+ ...reqParams,
+ spec: {
+ ...reqParams.spec,
+ servers: reqParams.spec.servers.map(server => ({
+ url: server.url.replace(/^https?:\/\/localhost:(\d+)/, `${proxy_cors_url}$1`),
+ description: server.description,
+ })),
+ },
+ };
+ } else return reqParams;
+}
+
+/* Ref:
+ * https://github.com/swagger-api/swagger-ui/blob/master/Dockerfile
+ * https://github.com/swagger-api/swagger-ui/blob/master/docker/docker-entrypoint.d/40-swagger-ui.sh
+ * https://github.com/swagger-api/swagger-ui/blob/master/dist/swagger-initializer.js
+ */
+// Doc: https://swagger.io/docs/open-source-tools/swagger-ui/customization/overview/
+/**
+ * Centralize GridSuite servers OpenApi specs in one UI
+ * Customization of Swagger-UI for GridSuite servers:
+ * - Add logo
+ * - Wrap around core actions/selectors to modify URL when passing through the proxy for CORS with navigators,
+ * but not showing it in the UI to users
+ *
+ */
+const GridSuitePlugin = (system) => ({
+ //TODO: rewrite "server" sections url
+ statePlugins: {
+ // return type of actions: https://github.com/redux-utilities/flux-standard-action
+ /*[stateKey]: {
+ actions, //then system.stateKeyActions.myAction("blue")
+ reducers,
+ selectors, //then system.stateKeySelectors.mySelector()
+ wrapActions,
+ wrapSelectors
+ }*/
+ /*auth: {
+ actions: {
+ authPopup: f(i), authorize: f(i), authorizeAccessCodeWithBasicAuthentication: f(i), authorizeAccessCodeWithFormParams: f(i), authorizeApplication: f(i),
+ authorizeOauth2: f(i), authorizeOauth2WithPersistOption: f(i), authorizePassword: f(i), authorizeRequest: f(i), authorizeWithPersistOption: f(i), configureAuth: f(i),
+ logout: f(i), logoutWithPersistOption: f(i), persistAuthorizationIfNeeded: f(i), preAuthorizeImplicit: f(i), restoreAuthorization: f(i), showDefinitions: f(i)
+ },
+ selectors: {
+ authorized: f(u), definitionsForRequirements: f(u), definitionsToAuthorize: f(_), getConfigs: f(u), getDefinitionsByNames: f(u), isAuthorized: f(u), shownDefinitions: f(u)
+ }
+ },
+ config: {
+ actions: {
+ downloadConfig: f(i), getConfigByUrl: f(i), loaded: f(i), toggle: f(i), update: f(i)
+ },
+ selectors: {
+ get: f(u)
+ }
+ },
+ err: {
+ actions: {
+ clear: f(i), clearBy: f(i), newAuthErr: f(i), newSpecErr: f(i), newSpecErrBatch: f(i), newThrownErr: f(i), newThrownErrBatch: f(i)
+ },
+ selectors: {
+ allErrors: f(u), lastError: f(u)
+ }
+ },
+ example: {
+ actions: {
+ updateFavoriteColor: f(i)
+ }
+ },
+ layout: {
+ actions: {
+ changeMode: f(i), clearScrollTo: f(i), parseDeepLinkHash: f(i), readyToScroll: f(i), scrollTo: f(i), scrollToElement: f(i), show: f(i), updateFilter: f(i), updateLayout: f(i)
+ },
+ selectors: {
+ current: f(u), currentFilter: f(u), getScrollToKey: f(u), isShown: f(u), isShownKeyFromUrlHashArray: f(u), showSummary: f(u), urlHashArrayFromIsShownKey: f(u), whatMode: f(u)
+ }
+ },
+ oas3: {
+ actions: {
+ clearRequestBodyValidateError: f(i), clearRequestBodyValue: f(i), initRequestBodyValidateError: f(i), setActiveExamplesMember: f(i), setRequestBodyInclusion: f(i),
+ setRequestBodyValidateError: f(i), setRequestBodyValue: f(i), setRequestContentType: f(i), setResponseContentType: f(i), setRetainRequestBodyValueFlag: f(i),
+ setSelectedServer: f(i), setServerVariableValue: f(i)
+ },
+ selectors: {
+ activeExamplesMember: f(u), hasUserEditedBody: f(u), requestBodyErrors: f(u), requestBodyInclusionSetting: f(u), requestBodyValue: f(u), requestContentType: f(u),
+ responseContentType: f(u), selectDefaultRequestBodyValue: f(u), selectedServer: f(u), serverEffectiveValue: f(u), serverVariableValue: f(u), serverVariables: f(u),
+ shouldRetainRequestBodyValue: f(u), validOperationMethods: f(u), validateBeforeExecute: f(u), validateShallowRequired: f(u)
+ }
+ },
+ oas31: {
+ selectors: {
+ selectLicenseUrl: f(u)
+ }
+ },
+ requestSnippets: {
+ selectors: {
+ getActiveLanguage: f(u), getDefaultExpanded: f(u), getGenerators: f(u), getSnippetGenerators: f(u)
+ }
+ },
+ spec: {
+ actions: {
+ changeConsumesValue: f(i), changeParam: f(i), changeParamByIdentity: f(i), changeProducesValue: f(i), clearRequest: f(i), clearResponse: f(i), clearValidateParams: f(i),
+ download: f(i), execute: f(i), executeRequest: f(i), invalidateResolvedSubtreeCache: f(i), logRequest: f(i), parseToJson: f(i), requestResolvedSubtree: f(i), resolveSpec: f(i),
+ setMutatedRequest: f(i), setRequest: f(i), setResponse: f(i), setScheme: f(i), updateEmptyParamInclusion: f(i), updateJsonSpec: f(i), updateLoadingStatus: f(i), updateResolved: f(i),
+ updateResolvedSubtree: f(i), updateSpec: f(i), updateUrl: f(i), validateParams: f(i)
+ },
+ selectors: {
+ allowTryItOutFor: f(u), basePath: f(_), callbacksOperations: f(u), canExecuteScheme: f(u), consumes: f(_), consumesOptionsFor: f(u), contact: f(u), contentTypeValues: f(u),
+ currentProducesFor: f(u), definitions: f(_), externalDocs: f(u), findDefinition: f(_), findSchema: f(u), getOAS3RequiredRequestBodyContentType: f(u), getParameter: f(u),
+ hasHost: f(_), host: f(_), info: f(u), isMediaTypeSchemaPropertiesEqual: f(u), isOAS3: f(_), isOAS30: f(u), isOAS31: f(u), isSwagger2: f(u), lastError: f(u), license: f(u),
+ loadingStatus: f(u), mutatedRequestFor: f(u), mutatedRequests: f(u), operationScheme: f(u), operationWithMeta: f(u), operations: f(u), operationsWithRootInherited: f(u),
+ operationsWithTags: f(u), parameterInclusionSettingFor: f(u), parameterValues: f(u), parameterWithMeta: f(u), parameterWithMetaByIdentity: f(u), parametersIncludeIn: f(u),
+ parametersIncludeType: f(u), paths: f(u), produces: f(_), producesOptionsFor: f(u), requestFor: f(u), requests: f(u), responseFor: f(u), responses: f(u), schemes: f(_),
+ security: f(u), securityDefinitions: f(_), selectContactEmailField: f(u), selectContactNameField: f(u), selectContactUrl: f(u), selectContactUrlField: f(u),
+ selectExternalDocsDescriptionField: f(u), selectExternalDocsUrl: f(u), selectExternalDocsUrlField: f(u), selectInfoDescriptionField: f(u), selectInfoSummaryField: f(u),
+ selectInfoTermsOfServiceField: f(u), selectInfoTermsOfServiceUrl: f(u), selectInfoTitleField: f(u), selectJsonSchemaDialectDefault: f(u), selectJsonSchemaDialectField: f(u),
+ selectLicenseIdentifierField: f(u), selectLicenseNameField: f(u), selectLicenseUrl: f(_), selectLicenseUrlField: f(u), selectSchemas: f(u), selectWebhooksOperations: f(u), semver: f(u),
+ servers: f(u), spec: f(u), specJS: f(u), specJson: f(u), specJsonWithResolvedSubtrees: f(u), specResolved: f(u), specResolvedSubtree: f(u), specSource: f(u), specStr: f(u),
+ tagDetails: f(u), taggedOperations: f(_), tags: f(u), url: f(u), validOperationMethods: f(_), validateBeforeExecute: f(u), validationErrors: f(u), version: f(u), webhooks: f(u)
+ }
+ },*/
+ spec: {
+ wrapActions: {
+ updateJsonSpec: (oriAction, system) => (spec) => {
+ // here, you can hand the value to some function that exists outside of Swagger UI
+ console.debug('[redux(spec)] updateJsonSpec:', spec);
+ return oriAction({...spec, servers: transformServerUrlSpec(spec.servers, system.specSelectors.url())}); // don't forget! otherwise, Swagger UI won't update
+ },
+ executeRequest: (oriAction, system) => (params) => {
+ // here, you can hand the value to some function that exists outside of Swagger UI
+ console.debug('[redux(spec)] executeRequest:', params);
+ return oriAction(transformRequestUrl(params)); // don't forget! otherwise, Swagger UI won't update
+ },
+ },
+ }
+ },
+ //components: {},
+ wrapComponents: {
+ Logo: (Original, system) => (props) => {
+ let rte_logo = system.React.createElement('img', {
+ alt: 'RTE logo',
+ height: '40',
+ src: 'data:image/svg+xml,' + RTE_LOGO, //data:image/svg+xml;base64,...
+ }, null);
+ let grd_logo = system.React.createElement('img', {
+ alt: 'GridSuite logo',
+ height: '40',
+ src: 'data:image/svg+xml,' + GRIDSUITE_LOGO,
+ }, null);
+ return system.React.createElement('span', {
+ //style: 'padding: 0;',
+ style: {
+ padding: 0,
+ display: 'inline-grid',
+ 'grid-auto-flow': 'column',
+ 'grid-column-gap': '.5em',
+ },
+ }, rte_logo, grd_logo, system.React.createElement(Original, props, null));
+ },
+ info: (Original, system) => (props) => system.React.createElement(Original, {...props, url: transformServerUrlApi(props.url)}, null),
+ },
+ //rootInjects: {},
+ //afterLoad: (system) => {},
+ //fn: {},
+ //TODO later: https://swagger.io/docs/open-source-tools/swagger-ui/customization/plug-points/#request-snippets
+});
+
+// keep trace of original class
+const OriginalSwaggerUIBundle = window.SwaggerUIBundle;
+/** We do a wrapper to override the config comming from the conatiner and injectig our plugin. */
+window.SwaggerUIBundle = (props) => OriginalSwaggerUIBundle({
+ ...props,
+ urls: [
+ ...props.urls,
+ ...([
+ { local_port: 9000, name: 'gateway', docker_host: 'gateway' },
+ { local_port: 5022, name: 'actions' },
+ { local_port: 5010, name: 'balances-adjustment' },
+ { local_port: 5039, name: 'case-import' },
+ { local_port: 5000, name: 'case' },
+ { local_port: 5011, name: 'case-validation' },
+ { local_port: 5021, name: 'cgmes-boundary' },
+ { local_port: 8095, name: 'cgmes-gl' },
+ { local_port: 5024, name: 'config-notification' },
+ { local_port: 5025, name: 'config' },
+ { local_port: 5004, name: 'directory-notification' },
+ { local_port: 5026, name: 'directory' },
+ { local_port: 5036, name: 'dynamic-mapping' },
+ { local_port: 5032, name: 'dynamic-simulation' },
+ { local_port: 5029, name: 'explore' },
+ { local_port: 5027, name: 'filter' },
+ { local_port: 8087, name: 'geo-data' },
+ { local_port: 5008, name: 'loadflow' },
+ { local_port: 5002, name: 'merge-notification' },
+ { local_port: 5020, name: 'merge-orchestrator' },
+ { local_port: 5003, name: 'network-conversion' },
+ { local_port: 5006, name: 'network-map' },
+ { local_port: 5007, name: 'network-modification' },
+ { local_port: 8080, name: 'network-store' },
+ { local_port: 8090, name: 'odre' },
+ { local_port: 5028, name: 'report' },
+ { local_port: 5023, name: 'security-analysis' },
+ { local_port: 5030, name: 'sensitivity-analysis' },
+ { local_port: 5031, name: 'shortcircuit' },
+ { local_port: 5005, name: 'single-line-diagram' },
+ { local_port: 5035, name: 'spreadsheet-config' },
+ { local_port: 5009, name: 'study-notification' },
+ { local_port: 5001, name: 'study' },
+ { local_port: 5037, name: 'timeseries' },
+ { local_port: 5033, name: 'user-admin' },
+ { local_port: 5038, name: 'voltage-init' },
+ ]
+ .map(def => ({name: `[${def.local_port}] ${def.name}`, url: (USE_PROXY ? `${proxy_cors_url}${def.local_port}` : `http://${USE_DOCKER ? `${name}-server` : `localhost:${def.local_port}`}`) + '/v3/api-docs'}))),
+ ],
+ //Doc: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
+ url: null, //reset because use "urls"
+ spec: null, //reset because use "urls"
+ configUrl: null, //reset because override config here
+ queryConfigEnabled: true,
+ validatorUrl: null,
+ filter: true,
+ displayRequestDuration: true,
+ deepLinking: true,
+ displayOperationId: false,
+ displayRequestDuration: true,
+ showExtensions: true,
+ showCommonExtensions: true,
+ showMutatedRequest: true,
+ requestSnippetsEnabled: true,
+ docExpansion: 'list',
+ //tryItOutEnabled: true,
+ supportedSubmitMethods: ["get", "put", "post", "delete", "options", "head", "patch", "trace"],
+ //TODO requestInterceptor instead of wrapActions in plugin maybe?
+ //oauth2: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/#instance-methods
+ //persistAuthorization: true,
+ //TODO oauth2RedirectUrl on oidc-mock-server url?
+ /*syntaxHighlight: {
+ activated: true,
+ // Only these 7 styles are available: "agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night", "idea"
+ theme: , // https://highlightjs.org/static/demo/ //TODO depending of navigator theme?
+ }*/
+ // TODO later: requestSnippets:{...requestSnippets, ...} with generator for react fronts
+ plugins: [
+ ...props.plugins,
+ GridSuitePlugin,
+ /*OriginalSwaggerUIBundle.plugins.SafeRender({
+ fullOverride: true, // only the component list defined here will apply (not the default list)
+ componentList: [
+ "Logo",
+ ],
+ }),*/
+ // others: https://github.com/swagger-api/swagger-ui/wiki/Plugins
+ // others: https://github.com/kael-shipman/swagger-ui-plugins
+ ],
+});
+window.SwaggerUIBundle.presets = OriginalSwaggerUIBundle.presets;
+window.SwaggerUIBundle.plugins = OriginalSwaggerUIBundle.plugins;
+window.SwaggerUIBundle.config = OriginalSwaggerUIBundle.config;
+window.SwaggerUIBundle.System = OriginalSwaggerUIBundle.System;
+
+/**
+ * This part will be rewrite by scripts in swagger-ui container.
+ */
+window.onload = function() {
+ //
+
+ // the following lines will be replaced by docker/configurator, when it runs in a docker-container
+ window.ui = SwaggerUIBundle({
+ url: "https://petstore.swagger.io/v2/swagger.json",
+ dom_id: '#swagger-ui',
+ deepLinking: true,
+ presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIStandalonePreset
+ ],
+ plugins: [
+ SwaggerUIBundle.plugins.DownloadUrl
+ ],
+ layout: "StandaloneLayout"
+ });
+
+ //
+};