diff --git a/about/index.md b/about/index.md index f20c24060..610024189 100644 --- a/about/index.md +++ b/about/index.md @@ -36,7 +36,7 @@ CAP-based projects benefit from a **[primary focus on domain](#domain-modeling)* The CAP framework features a mix of proven and broadly adopted open-source and SAP technologies, as highlighted in the figure below. -The graphic is explained in the accompanying text. +![The graphic is explained in the accompanying text.](../assets/overview.drawio.svg){style="width:480px; margin: auto"}
Node.js logo @@ -310,7 +310,7 @@ All behavioral aspects in CAP are based on ubiquitous notions of [Services](#ser Services in CAP are **stateless** and with a **minimal footprint**, which allows you to modularize solutions into single-purposed (nano) services or functions-as-a-service.
- +
Hexagonal Architecture à la CAP
diff --git a/cds/index.md b/cds/index.md index 9ccefe088..406e2ea1f 100644 --- a/cds/index.md +++ b/cds/index.md @@ -8,7 +8,7 @@ Language Reference Documentation CDL is the backbone of the SAP Cloud Application Programming Model (CAP). It provides the means to declaratively capture service definitions and data models, queries, and expressions in plain (JavaScript) object notations. CDL features to parse from a variety of source languages and to compile them into various target languages. Though the language used within `.cds` files is CDL, we usually use the terms _CDS_ or _CDS Models_ as synonyms to keep it simple where we don't need to care about technical details too much. -The graphic is explained in the accompanying text. +!["The graphic is explained in the accompanying text."](./assets/csn.drawio.svg) CDS models are plain JavaScript objects complying to the _[Core Schema Notation (CSN)](./csn)_, an open specification derived from [JSON Schema](https://json-schema.org/). You can easily create or interpret these models, which foster extensions by 3rd-party contributions. Models are processed dynamically at runtime and can also be created dynamically. diff --git a/get-started/in-a-nutshell.md b/get-started/in-a-nutshell.md index 1ea88b286..15aa81da8 100644 --- a/get-started/in-a-nutshell.md +++ b/get-started/in-a-nutshell.md @@ -377,7 +377,7 @@ Open __ / __ in your browser and s
-Generic welcome page generated by CAP that list all endpoints. Eases jumpstarting development and is not meant for productive use. +![Generic welcome page generated by CAP that list all endpoints. Eases jumpstarting development and is not meant for productive use.](./assets/in-a-nutshell/welcome_java.png) > Note: User `authenticated` is a [prepared mock user](../java/security#mock-users) which will be authenticated by default. Use it to access the _/admin_ service. You don't need to enter a password. diff --git a/get-started/jumpstart.md b/get-started/jumpstart.md index 4099382d5..ea3adf4d8 100644 --- a/get-started/jumpstart.md +++ b/get-started/jumpstart.md @@ -29,7 +29,7 @@ Follow the steps below to set up a local development environment. If you are a d Choose the **LTS** version, via the left-hand side button: -Screenshot showing exemplary buttons from the nodejs.org download page. The term LTS is magnified on the left-hand button. +![Screenshot showing exemplary buttons from the nodejs.org download page. The term LTS is magnified on the left-hand button.](./assets/jumpstart/image-20230310202845639.png){style="zoom: 33%;" } diff --git a/get-started/samples.md b/get-started/samples.md index 355f0253e..d18176784 100644 --- a/get-started/samples.md +++ b/get-started/samples.md @@ -53,8 +53,8 @@ It is available in both Node.js and Java. The Node.js variant contains additiona Available for: -[Node.js logo](https://github.com/sap-samples/cloud-cap-samples) -[Java logo](https://github.com/sap-samples/cloud-cap-samples-java) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the cloud-cap-samples repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/sap-samples/cloud-cap-samples) +[![Java logo](../assets/logos/java.svg 'link to the cloud-cap-samples-java repository.'){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/sap-samples/cloud-cap-samples-java) @@ -64,7 +64,7 @@ A reference sample application for CAP and the SAP BTP Developer Guide. Available for: -[Node.js logo](https://github.com/cap-js/incidents-app) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the incident-app repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/incidents-app) @@ -74,8 +74,8 @@ This sample is a CAP adaptation of the popular [SFLIGHT](https://blog.sap-press. Available for: -[Node.js logo](https://github.com/sap-samples/cap-sflight) -[Java logo](https://github.com/sap-samples/cap-sflight) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the cap-sflight repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/sap-samples/cap-sflight) +[![Java logo](../assets/logos/java.svg 'Link to the cap-sflight repository.'){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/sap-samples/cap-sflight) @@ -87,7 +87,7 @@ The projects described above have fallen out of maintenance but still offered th Available for: -[Node.js logo](https://github.com/SAP-samples/cloud-cap-hana-swapi) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the Star Wars app repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/SAP-samples/cloud-cap-hana-swapi) @@ -97,4 +97,4 @@ The Sustainable SaaS (SusaaS) sample application has been built in a partner col Available for: -[Node.js logo](https://github.com/SAP-samples/btp-cap-multitenant-saas) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the Sustainable SaaS (SusaaS) repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/SAP-samples/btp-cap-multitenant-saas) diff --git a/guides/data-privacy/annotations.md b/guides/data-privacy/annotations.md index 904cdedea..aa20579e2 100644 --- a/guides/data-privacy/annotations.md +++ b/guides/data-privacy/annotations.md @@ -23,7 +23,7 @@ In order to automate audit logging, personal data management, and data retention In the remainder of this guide, we use the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app) as the base to add data privacy and audit logging to. -Shows the connections between the entities in the sample app. +![Shows the connections between the entities in the sample app.](./assets/Incidents-App.drawio.svg){style="zoom:111%;"} So, let's annotate the data model to identify personal data. In essence, in all our entities we search for elements which carry personal data, such as person names, birth dates, etc., and tag them accordingly. @@ -82,7 +82,7 @@ Learn more about these annotations in the [@PersonalData OData vocabulary](https The entity-level annotation `@PersonalData.EntitySemantics` signifies relevant entities as *Data Subject*, *Data Subject Details*, or *Other* in data privacy terms, as depicted in the following graphic. -Shows the connections between the entities in the sample app. In addition via color coding it makes clear how entities are annotated: customers are data subject, addresses are data subject details and incidents are other. +![Shows the connections between the entities in the sample app. In addition via color coding it makes clear how entities are annotated: customers are data subject, addresses are data subject details and incidents are other.](./assets/Data-Subjects.drawio.svg){style="zoom:111%;"} The following table provides some further details. diff --git a/guides/data-privacy/index.md b/guides/data-privacy/index.md index 8e33041ab..e165cc917 100644 --- a/guides/data-privacy/index.md +++ b/guides/data-privacy/index.md @@ -29,7 +29,7 @@ Data protection is associated with numerous legal requirements and privacy conce CAP supports applications in their obligations to comply to data privacy regulations, by automating tedious tasks as much as possible based on annotated models. That is, CAP provides easy ways to designate personal data, as well as out-of-the-box integration with SAP BTP services, which enable you to fulfill specific data privacy requirements in your application. This relieves application developers of these tedious tasks and related efforts. -Shows with which solutions CAP annotations can be used out of the box, as described in the following table. +![Shows with which solutions CAP annotations can be used out of the box, as described in the following table.](./assets/Data-Privacy.drawio.svg){style="zoom:111%;"} diff --git a/guides/messaging/s4.md b/guides/messaging/s4.md index 6bd420e65..f1614ff16 100644 --- a/guides/messaging/s4.md +++ b/guides/messaging/s4.md @@ -23,7 +23,7 @@ As documented in the [Service Consumption guide](../using-services#external-serv 1. Find / open [Business Partner (A2X) API](https://api.sap.com/api/API_BUSINESS_PARTNER). 2. Choose button *"API Specification"*. 3. Download the EDMX spec from this list: -Showing all available specifications on the SAP Business Accelerator Hub. +![Showing all available specifications on the SAP Business Accelerator Hub.](./assets/api-specification.png){style="zoom: 33%;" } 1. Import it as a CDS model: ```sh diff --git a/guides/security/overview.md b/guides/security/overview.md index dea450f64..fc40b799a 100644 --- a/guides/security/overview.md +++ b/guides/security/overview.md @@ -133,7 +133,7 @@ CAP requires a dedicated [platform environment](#platform-environment) to integr The following diagram provides a high-level overview about the security-relevant aspects of a deployed CAP application in a cloud environment: -This TAM graphic is explained in the accompanying text. +![This TAM graphic is explained in the accompanying text.](./assets/cap-security-architecture-overview.png){width="600px"} To serve a business request, different runtime components are involved: a request, issued by a UI or technical client ([public zone](#public-zone)), is forwarded by a gateway or ingress router to the CAP application. In case of an UI request, an [Application Router](https://help.sap.com/docs/btp/sap-business-technology-platform/application-router) instance acts as a proxy. The CAP application might make use of a CAP sidecar. All application components ([application zone](#application-zone)) might make use of platform services such as database or identity service ([platform zone](#platform-zone)). diff --git a/java/cqn-services/remote-services.md b/java/cqn-services/remote-services.md index ba5928c5d..3ca1b4774 100644 --- a/java/cqn-services/remote-services.md +++ b/java/cqn-services/remote-services.md @@ -24,7 +24,7 @@ Destinations in the Cloud SDK are the means to express and define connectivity t On top of that CAP integrates nicely with Cloud SDK, for example, ensuring automatic propagation of tenant and user information from the _Request Context_ to the Cloud SDK. -This graphic depicts the integration of SAP Cloud SDK into SAP CAP Java. +![This graphic depicts the integration of SAP Cloud SDK into SAP CAP Java.](../assets/remote%20services.drawio.svg){width="700px" class="mute-dark"} CAP's clear recommendation is to use _Remote Services_ over directly using the SAP Cloud SDK. However, if you can't leverage CQN-based _Remote Services_, refer to [native consumption with Cloud SDK](#native-consumption) for details. diff --git a/java/developing-applications/building.md b/java/developing-applications/building.md index 362cee486..2fa850b27 100644 --- a/java/developing-applications/building.md +++ b/java/developing-applications/building.md @@ -46,7 +46,7 @@ A common example for this is to run the application locally on H2 instead of SAP The following diagram illustrates the modular stack architecture and highlights the generic components: -This screenshot is explained in the accompanying text. +![This screenshot is explained in the accompanying text.](./assets/modularized-architecture.png){width="600px"} You can recognize five different areas of the stack, which comprise components according to different tasks: diff --git a/java/event-handlers/request-contexts.md b/java/event-handlers/request-contexts.md index 45f625d40..1a0d27951 100644 --- a/java/event-handlers/request-contexts.md +++ b/java/event-handlers/request-contexts.md @@ -119,7 +119,7 @@ The CAP Java SDK allows you to create new Request Contexts and define their scop There are a few typical use cases in a CAP-based, multitenant application on SAP BTP in which creation of new Request Contexts is necessary. These scenarios are identified by a combination of the user (technical or named) and the tenant (provider or subscribed). -A named user can switch to a technical user in the same/subscriber tenant using the systemUser() method. Also, a named user can switch to a technical user in the provider tenant using the systemUserProvider() method. In addition technical users provider/subscriber tenants can switch to technical users on provider/subscriber tenants using the methods systemUserProvider() or systemUser(tenant). +![A named user can switch to a technical user in the same/subscriber tenant using the systemUser() method. Also, a named user can switch to a technical user in the provider tenant using the systemUserProvider() method. In addition technical users provider/subscriber tenants can switch to technical users on provider/subscriber tenants using the methods systemUserProvider() or systemUser(tenant).](./assets/requestcontext.drawio.svg) When calling CAP Services, it's important to call them in an appropriate Request Context. Services might, for example, trigger HTTP requests to external services by deriving the target tenant from the current Request Context. @@ -144,7 +144,7 @@ In the following a few concrete examples are given: ### Switching to Technical User -The graphic is explained in the accompanying text. +![The graphic is explained in the accompanying text.](./assets/nameduser.drawio.svg) The incoming JWT token triggers the creation of an initial RequestContext with a named user. Accesses to the database in the OData Adapter as well as the custom `On` handler are executed within tenant1 and authorization checks are performed for user JohnDoe. An additionally defined `After` handler wants to call out to an external service using a technical user without propagating the named user JohnDoe. Therefore, the `After` handler needs to create a new Request Context. To achieve this, it's required to call `requestContext()` on the current `CdsRuntime` and use the `systemUser()` method to remove the named user from the new Request Context: @@ -160,7 +160,7 @@ public void afterHandler(EventContext context){ ``` ### Switching to Technical Provider Tenant {#switching-to-provider-tenant} -The graphic is explained in the accompanying text. +![The graphic is explained in the accompanying text.](./assets/switchprovidertenant.drawio.svg) The application offers an action for one of its CDS entities. Within the action, a communication happens with a remote CAP service using an internal technical user from the provider account. The corresponding `on` handler of the action needs to create a new Request Context by calling `requestContext()`. Using the `systemUserProvider()` method, the existing user information is removed and the tenant is automatically set to the provider tenant. This allows the application to perform an HTTP call to the remote CAP service, which is secured using the pseudo-role `internal-user`. @@ -175,7 +175,7 @@ public void onAction(AddToOrderContext context){ ``` ### Switching to a Specific Technical Tenant -The graphic is explained in the accompanying text. +![The graphic is explained in the accompanying text.](./assets/switchtenant.drawio.svg) The application is using a job scheduler that needs to regularly perform tasks on behalf of a certain tenant. By default, background executions (for example in a dedicated thread pool) aren't associated to any subscriber tenant and user. In this case, it's necessary to explicitly define a new Request Context based on the subscribed tenant by calling `systemUser(tenantId)`. This ensures that the Persistence Service performs the query for the specified tenant. diff --git a/java/messaging.md b/java/messaging.md index 299861650..098b2e99b 100644 --- a/java/messaging.md +++ b/java/messaging.md @@ -36,7 +36,7 @@ In the following, we provide a basic introduction to publish-subscribe-based mes In a publish-subscribe-based messaging scenario (pub-sub messaging), senders send a message tagged with a topic to a message broker. Receivers can create queues at the message broker and subscribe these queues to the topics they're interested in. The message broker will then copy incoming messages matching the subscribed topics to the corresponding queues. Receivers can now consume these messages from their queues. If the receiver is offline, no messages will be lost as the message broker safely stores messages in the queue until a receiver consumes the messages. After the receiver acknowledges the successful processing of a message, the message broker will delete the acknowledged message from the queue. -The graphic is explained in the accompanying text. +![The graphic is explained in the accompanying text.](./assets/messaging_foundation.png){width="700px"} CAP makes sending and receiving messages easy by providing an API agnostic from specific message brokers, and taking care of broker-specific mechanics like connection handling, protocols to use, creating queues, subscriptions, etc. The API seamlessly blends into the common event API of CAP services, so that event messages can be sent using `emit` and handlers to execute when receiving event messages can be declared with the `@On` annotation. diff --git a/java/operating-applications/observability.md b/java/operating-applications/observability.md index b703e316e..5a77cca54 100644 --- a/java/operating-applications/observability.md +++ b/java/operating-applications/observability.md @@ -29,7 +29,7 @@ Various logging frameworks for Java have evolved and are widely used in Open Sou CAP Java SDK seamlessly integrates with Simple Logging Façade for Java ([SLF4J](https://www.slf4j.org)), which provides an abstraction layer for logging APIs. Applications compiled against SLF4J are free to choose a logging framework implementation at deployment time. Most famous libraries have a native integration to SLF4J, but it also can bridge legacy logging API calls: - +![](./assets/slf4j.png){width="500px"} ### Logger API { #logging-api} @@ -252,7 +252,7 @@ Spans and traces that are produced out of the box, include HTTP requests as well In addition, it's possible to add manual instrumentations using the [Open Telemetry Java API](https://opentelemetry.io/docs/instrumentation/java/manual/), for example, in a custom event handler. -This graphic shows several spans, which conclude a trace of a single HTTP request, including the time they're opened and closed. +![This graphic shows several spans, which conclude a trace of a single HTTP request, including the time they're opened and closed.](./assets/screenshot_otel_trace.png){width="500px" class="mute-dark"} #### Configure Java Agent and Extension Library { #agent-extension } diff --git a/java/operating-applications/optimizing.md b/java/operating-applications/optimizing.md index d49abd43d..3a7f2ee26 100644 --- a/java/operating-applications/optimizing.md +++ b/java/operating-applications/optimizing.md @@ -26,7 +26,7 @@ Typically, such tools are capable of focusing on a specific aspect of an applica How can dedicated Java tools access the running services in a secure manner? The depicted diagram shows recommended options that **do not require exposed HTTP endpoints**: -This screenshot is explained in the accompanying text. +![This screenshot is explained in the accompanying text.](./assets/remote-tracing.png){width="600px"} As an authorized operator, you can access the container and start tools [locally](#profiling-local) in a CLI session running with the same user as the target process. Depending on the protocol, the JVM supports on-demand connections, for example, JVM diagnostic tools such as `jcmd`. Alternatively, additional JVM configuration is required as a prerequisite (JMX). A bunch of tools also support [remote](#profiling-remote) connections in a secure way. Instead of running the tool locally, a remote daemon is started as a proxy in the container, which connects the JVM with a remote profiling tool via an ssh tunnel. diff --git a/plugins/index.md b/plugins/index.md index ce86aee16..11c6de449 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -122,8 +122,8 @@ The OData v2 Proxy is a protocol adapter that allows you to expose your services Available for: -[Node.js](https://github.com/cap-js-community/odata-v2-adapter#readme) -[Java](../java/migration#v2adapter) +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js-community/odata-v2-adapter#readme) +[![Java](../assets/logos/java.svg 'Link to the documentation of the OData feature.'){style="height:3em; display:inline; margin:0 0.2em;"}](../java/migration#v2adapter) See also [Cookbook > Protocols/APIs > OData APIs > V2 Support](../advanced/odata#v2-support) {.learn-more} @@ -134,7 +134,7 @@ The UI5 Dev Server is a CDS server plugin that enables the integration of UI5 (U Available for: -[Node.js](https://github.com/ui5-community/ui5-ecosystem-showcase/tree/main/packages/cds-plugin-ui5#cds-plugin-ui5) +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/ui5-community/ui5-ecosystem-showcase/tree/main/packages/cds-plugin-ui5#cds-plugin-ui5) ## GraphQL Adapter @@ -146,7 +146,7 @@ The GraphQL Adapter is a protocol adapter that generically generates a GraphQL s Available for: -[Node.js](https://github.com/cap-js/graphql#readme) +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/graphql#readme) @@ -181,8 +181,8 @@ Outlook: Available for: -[Node.js logo](https://github.com/cap-js/attachments#readme) -[Java](https://github.com/cap-java/cds-feature-attachments#readme) +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the repository for cap-js attachments.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/attachments#readme) +[![Java](../assets/logos/java.svg 'Link to the repository for cap-java-attachments.'){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-attachments#readme) ## Audit Logging @@ -209,8 +209,8 @@ Features: Available for: -[Node.js](https://github.com/cap-js/audit-logging#readme) -Java +[![Node.js logo](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/audit-logging#readme) +![Java](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"} Learn more about audit logging in [Node.js](../guides/data-privacy/audit-logging) and in [Java](../java/auditlog) {.learn-more} @@ -232,9 +232,8 @@ annotate my.Incidents { Available for: -[Node.js](https://github.com/cap-js/change-tracking#readme) -[Java](../java/change-tracking) - +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/change-tracking#readme) +[![Java](../assets/logos/java.svg 'Link to the documentation of the change-tracking feature.'){style="height:3em; display:inline; margin:0 0.2em;"}](../java/change-tracking) ## Notifications @@ -262,7 +261,7 @@ Features: Available for: -[Node.js](https://github.com/cap-js/notifications#readme) +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/notifications#readme) ## Telemetry @@ -289,9 +288,8 @@ Telemetry data can be exported to [SAP Cloud Logging](https://help.sap.com/docs/ Available for: -[Node.js](https://github.com/cap-js/telemetry#readme) -[Java](../java/operating-applications/observability#open-telemetry) - +[![Node.js](../assets/logos/nodejs.svg 'Link to the plugins repository.'){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/telemetry#readme) +[![Java](../assets/logos/java.svg 'Link to the documentation of the telemetry feature.'){style="height:3em; display:inline; margin:0 0.2em;"}](../java/operating-applications/observability#open-telemetry) ## CAP Operator for Kubernetes {#cap-operator-plugin} @@ -302,8 +300,8 @@ This is where the CAP Operator **plugin** is very useful, as it provides an easy Available for: -[Node.js logo](https://github.com/cap-js/cap-operator-plugin#readme) -Java logo +[![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/cap-operator-plugin#readme) +![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}
diff --git a/tools/cds-editors.md b/tools/cds-editors.md index c653f9f7f..ca5632e54 100644 --- a/tools/cds-editors.md +++ b/tools/cds-editors.md @@ -384,8 +384,7 @@ A **CAP Notebook** is a [Custom Notebook in Visual Studio Code](https://code.vis The cell inputs/outputs are especially useful at later points in time when the project's details have long been forgotten. In addition, notebooks are a good way to share, compare, and also reproduce projects. * If you are new to CAP Notebooks, try out the notebooks based on our documentation. When available for a given page, these are accessible via the "Download Notebook" button on the top of the screen and enable you to try things out on your local machine, for example the [Getting Started in a Nutshell](../get-started/in-a-nutshell) guide. - - The screenshot is explained in the accompanying text. + ![The screenshot is explained in the accompanying text.](./assets/cap-notebook-button.png){width="800px" style="width:800px; box-shadow: 1px 1px 5px #888888"} * To see which features are available in a CAP Notebook, open our [CAP Notebook page](#cap-notebooks-page): F1 → *CDS: Open CAP Notebooks Page* diff --git a/tools/cds-lint/index.md b/tools/cds-lint/index.md index 98dd68670..89e97bfa6 100644 --- a/tools/cds-lint/index.md +++ b/tools/cds-lint/index.md @@ -37,7 +37,7 @@ To catch issues in CDS models and the CDS environment early, CAP provides an [ES
-ESLint plugin for CDS logo +![ESLint plugin for CDS logo](../assets/cdslint.svg){width="130px" class="ignore-dark"}