From e465c93ed44103351a273583a6e762dbede54c88 Mon Sep 17 00:00:00 2001 From: alicekb Date: Thu, 27 Jun 2024 13:34:33 -0400 Subject: [PATCH] Deploy bundle --- hugo_stats.json | 1 + public/404.html | 2 +- public/blog/example-post/index.html | 2 +- public/blog/index.html | 2 +- public/categories/index.html | 2 +- public/contributors/index.html | 2 +- public/docs/about/changelog/index.html | 4 ++-- public/docs/about/faq/index.html | 2 +- public/docs/about/glossary/index.html | 4 ++-- public/docs/about/how-to-contribute/index.html | 2 +- public/docs/about/index.html | 2 +- public/docs/about/index.xml | 6 +++--- public/docs/about/sitemap.xml | 2 +- public/docs/components/actions/index.html | 2 +- public/docs/components/computed/index.html | 2 +- public/docs/components/dispatch/index.html | 2 +- public/docs/components/handlers/index.html | 4 ++-- public/docs/components/handling-legacy-methods/index.html | 4 ++-- public/docs/components/index.html | 2 +- public/docs/components/initrelay/index.html | 4 ++-- public/docs/components/rolls/index.html | 4 ++-- .../docs/gettingstarted/example-patterns-sheet/index.html | 2 +- public/docs/gettingstarted/index.html | 2 +- public/docs/gettingstarted/installing-beacon/index.html | 4 ++-- public/docs/gettingstarted/introduction/index.html | 2 +- .../gettingstarted/quick-start-sheet-template/index.html | 4 ++-- public/docs/gettingstarted/releasing-a-sheet/index.html | 4 ++-- public/docs/index.html | 2 +- public/docs/index.xml | 2 +- public/docs/sitemap.xml | 2 +- public/index.html | 2 +- public/index.xml | 8 +++++--- ...ef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css | 1 + public/privacy/index.html | 2 +- public/search-index.json | 2 +- public/sitemap.xml | 2 +- public/tags/index.html | 2 +- .../app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.content | 2 +- .../scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.json | 2 +- 39 files changed, 54 insertions(+), 50 deletions(-) create mode 100644 public/main.bdaa5498903a6087c6d7e8fac6133113e5fa6b01e7c78680535b430bf606cfeae8afc6aec4d97aef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css diff --git a/hugo_stats.json b/hugo_stats.json index 6523c65..9d6f05b 100644 --- a/hugo_stats.json +++ b/hugo_stats.json @@ -159,6 +159,7 @@ "mt-n3", "mx-2", "mx-auto", + "mx-xl-auto", "my-0", "my-3", "nav", diff --git a/public/404.html b/public/404.html index a0b9120..d17681b 100644 --- a/public/404.html +++ b/public/404.html @@ -1 +1 @@ -404 Page not found |

Page not found :(

The page you are looking for doesn't exist or has been moved.

\ No newline at end of file +404 Page not found |

Page not found :(

The page you are looking for doesn't exist or has been moved.

\ No newline at end of file diff --git a/public/blog/example-post/index.html b/public/blog/example-post/index.html index 4d092b1..57b08f4 100644 --- a/public/blog/example-post/index.html +++ b/public/blog/example-post/index.html @@ -1 +1 @@ -Example Post |

Example Post

September 7, 20231 minute

You can use blog posts for announcing product updates and features.

Well-thought-through product announcements will help increase feature awareness and engage users with new functionality. Just like sharing your public roadmap, it’s also a great way to let potential customers see that you’re constantly improving.

Further reading

\ No newline at end of file +Example Post |

Example Post

September 7, 20231 minute

You can use blog posts for announcing product updates and features.

Well-thought-through product announcements will help increase feature awareness and engage users with new functionality. Just like sharing your public roadmap, it’s also a great way to let potential customers see that you’re constantly improving.

Further reading

\ No newline at end of file diff --git a/public/blog/index.html b/public/blog/index.html index 1e5d549..b871494 100644 --- a/public/blog/index.html +++ b/public/blog/index.html @@ -1 +1 @@ -Blog |

Blog

Example Post

You can use blog posts for announcing product updates and features.

September 7, 20231 minute

\ No newline at end of file +Blog |

Blog

Example Post

You can use blog posts for announcing product updates and features.

September 7, 20231 minute

\ No newline at end of file diff --git a/public/categories/index.html b/public/categories/index.html index 3700179..38be321 100644 --- a/public/categories/index.html +++ b/public/categories/index.html @@ -1 +1 @@ -Categories |

Categories

\ No newline at end of file +Categories |

Categories

\ No newline at end of file diff --git a/public/contributors/index.html b/public/contributors/index.html index ceefaf1..c850359 100644 --- a/public/contributors/index.html +++ b/public/contributors/index.html @@ -1 +1 @@ -Contributors |

Contributors

\ No newline at end of file +Contributors |

Contributors

\ No newline at end of file diff --git a/public/docs/about/changelog/index.html b/public/docs/about/changelog/index.html index 31ac600..98f3326 100644 --- a/public/docs/about/changelog/index.html +++ b/public/docs/about/changelog/index.html @@ -1,3 +1,3 @@ -Changelog | Changelog |

Changelog

Release Date: 2022-03-17

New Features

  • Initial release of the Beacon SDK.
  • Support for Vue.js framework.
  • Setup with Vite for rapid development.
  • Basic and advanced sheet examples.

Improvements

  • Detailed comments added to example files for better understanding.
  • Support for complex roll templates and rich sheet actions.

Bug Fixes

  • N/A (initial release).

Version 2.0.0

Release Date: 2023-03-17

New Features

  • SCSS support for styling.
  • Integration with Roll20 and VTT.
  • Mock Relay for offline development.

Improvements

  • TypeScript integration for type checking and improved development experience.
  • Unit testing with Vitest.
  • End-to-End testing with Cypress.

Bug Fixes

  • N/A (initial release).
\ No newline at end of file +New Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development.">

Changelog

Release Date: 2022-03-17

New Features

  • Initial release of the Beacon SDK.
  • Support for Vue.js framework.
  • Setup with Vite for rapid development.
  • Basic and advanced sheet examples.

Improvements

  • Detailed comments added to example files for better understanding.
  • Support for complex roll templates and rich sheet actions.

Bug Fixes

  • N/A (initial release).

Version 2.0.0

Release Date: 2023-03-17

New Features

  • SCSS support for styling.
  • Integration with Roll20 and VTT.
  • Mock Relay for offline development.

Improvements

  • TypeScript integration for type checking and improved development experience.
  • Unit testing with Vitest.
  • End-to-End testing with Cypress.

Bug Fixes

  • N/A (initial release).
\ No newline at end of file diff --git a/public/docs/about/faq/index.html b/public/docs/about/faq/index.html index 32b9164..f1c5051 100644 --- a/public/docs/about/faq/index.html +++ b/public/docs/about/faq/index.html @@ -1 +1 @@ -FAQ |

FAQ

Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)?

It depends on your web development skill level. There are a number of benefits to the Beacon SDK if you know how to build web applications. If you don’t know how to set up your own local environment, than the Beacon SDK might now be the first place you should start. Learn more about sheet development using the custom sheet.

If you have the skill to take advantage of the Beacon SDK, there are a number of improvements that will make it much easier to build characters sheets.

First, the Beacon SDK allows you to develop locally and preview your changes automatically in the Roll20 Tabletop and Roll20 Character sandboxes. This means that you don’t have to keep uploading your HTML and CSS into the custom sheet to see your changes.

Next, it allows you to develop your character sheet with all the power of JavaScript frameworks and modern web development libraries. In our example sheets, we use Vue.js, but you are free to use whatever you are most comfortable with. Also, you could use something like Cypress to create automated testing. That’s what we use in our Beacon sheets.

Lastly, the Beacon SDK makes it much easier for a web developer who knows JSON and Javascript to access character data and manage attributes on the character. If you’re familiar with the custom sheet, you no longer have to deal with sheet workers to get the data you need for a character. Also, the Beacon SDK introduces nested and computed attributes that make complex data models for your character sheet easier to create and maintain.

Q: I’m not really a web developer, should I use Beacon or the custom sheet to make a my own character sheet?

That is up to you and your comfort level. If you’re looking to learn more about web development, building a character sheet with the Beacon SDK is a great way to level up your skills. What you learn during this process can be taken with you into any other web development project you work on in the future.

If setting up your own development environment is too intimidating for you, than it might be easier for you to start with the custom sheet and to go from there.

Q: I’m interested in using Beacon, but I don’t know the basics of setting up a local environment. Where can I go to learn more about web development?

You can start learning how to build a local development environment by reading or watching the following tutorials. Note: these are not tutorials that we’ve produced, but we have found them helpful in getting started with web development.

Q: Now that Roll20 has acquired Demiplane, will you continue to support character sheets built on Beacon?

The recent acquisition of Demiplane brings exciting new opportunities for character sheets and compendiums on Roll20. At the same time, we are fully committed to supporting the Beacon SDK and character sheets that are built in our new advanced sheets ecosystem on Roll20. In fact, we believe that the Beacon SDK will be a key component of our future plans for Demiplane integration. In addition, our new D&D 2024 sheet is built on top of the Beacon SDK, and we will continue to utilize it to build first-class experiences on Roll20.

In short, you can rest assured that the Beacon SDK is an important tool in our toolbox moving forward.

Q: What are actions in the context of Beacon?Actions are methods executed in the chat log of Roll20 Tabletop or Roll20 Characters, often used for rolls triggered from macros or chat buttons. They are defined in the sheet’s configuration and can interact with character data.
Q: How are computed properties used in Roll20?Computed properties are attributes which are accessible by users of your character sheet. They are usable in macros to create custom rolls or common actions for each character. Computed properties can represent derived values or complex calculations based on character data.
Q: What is the dispatch function used for?The dispatch function provides methods for sending commands from the character sheet back to Roll20, including updating character data, performing actions, and interacting with the interface.
Q: What are roll buttons, and how do they work?Roll buttons are HTML elements with specific attributes that execute designated sheet actions when clicked. They can pass arguments to the action method and are commonly used for triggering rolls from the character sheet.
Q: How are legacy attributes handled in Beacon?Beacon gives you the ability to transition your legacy attributes to new attributes you create in Beacon. This means that when a user updates their sheet to the new Beacon sheet, their legacy attribute can be mapped to Beacon attributes using the convertLegacyMacroAttributes function. Sheet developers can define how to handle legacy attribute values to ensure compatibility with existing macros.
Q: What is the purpose of the query function?The query function displays a SweetAlert2 prompt to users and returns the results along with any errors. It is commonly used for interactive prompts or confirmations within the VTT interface.
Q: How are tokens managed in the VTT?Tokens represent characters or objects on Roll20 Tabletop (VTT). Functions like getTokens, updateTokensByCharacter, and addToTracker are used to retrieve token information, update token data, and manage tokens in the turn tracker.
Q: What is the role of the convertLegacyMacroAttributesArgs type?The convertLegacyMacroAttributesArgs type defines the arguments used for handling legacy macro attributes. It includes the attribute name, character ID, and character data needed for mapping legacy attributes to the new sheet structure.
\ No newline at end of file +FAQ |

FAQ

Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)?

It depends on your web development skill level. There are a number of benefits to the Beacon SDK if you know how to build web applications. If you don’t know how to set up your own local environment, than the Beacon SDK might now be the first place you should start. Learn more about sheet development using the custom sheet.

If you have the skill to take advantage of the Beacon SDK, there are a number of improvements that will make it much easier to build characters sheets.

First, the Beacon SDK allows you to develop locally and preview your changes automatically in the Roll20 Tabletop and Roll20 Character sandboxes. This means that you don’t have to keep uploading your HTML and CSS into the custom sheet to see your changes.

Next, it allows you to develop your character sheet with all the power of JavaScript frameworks and modern web development libraries. In our example sheets, we use Vue.js, but you are free to use whatever you are most comfortable with. Also, you could use something like Cypress to create automated testing. That’s what we use in our Beacon sheets.

Lastly, the Beacon SDK makes it much easier for a web developer who knows JSON and Javascript to access character data and manage attributes on the character. If you’re familiar with the custom sheet, you no longer have to deal with sheet workers to get the data you need for a character. Also, the Beacon SDK introduces nested and computed attributes that make complex data models for your character sheet easier to create and maintain.

Q: I’m not really a web developer, should I use Beacon or the custom sheet to make a my own character sheet?

That is up to you and your comfort level. If you’re looking to learn more about web development, building a character sheet with the Beacon SDK is a great way to level up your skills. What you learn during this process can be taken with you into any other web development project you work on in the future.

If setting up your own development environment is too intimidating for you, than it might be easier for you to start with the custom sheet and to go from there.

Q: I’m interested in using Beacon, but I don’t know the basics of setting up a local environment. Where can I go to learn more about web development?

You can start learning how to build a local development environment by reading or watching the following tutorials. Note: these are not tutorials that we’ve produced, but we have found them helpful in getting started with web development.

Q: Now that Roll20 has acquired Demiplane, will you continue to support character sheets built on Beacon?

The recent acquisition of Demiplane brings exciting new opportunities for character sheets and compendiums on Roll20. At the same time, we are fully committed to supporting the Beacon SDK and character sheets that are built in our new advanced sheets ecosystem on Roll20. In fact, we believe that the Beacon SDK will be a key component of our future plans for Demiplane integration. In addition, our new D&D 2024 sheet is built on top of the Beacon SDK, and we will continue to utilize it to build first-class experiences on Roll20.

In short, you can rest assured that the Beacon SDK is an important tool in our toolbox moving forward.

Q: What are actions in the context of Beacon?Actions are methods executed in the chat log of Roll20 Tabletop or Roll20 Characters, often used for rolls triggered from macros or chat buttons. They are defined in the sheet’s configuration and can interact with character data.
Q: How are computed properties used in Roll20?Computed properties are attributes which are accessible by users of your character sheet. They are usable in macros to create custom rolls or common actions for each character. Computed properties can represent derived values or complex calculations based on character data.
Q: What is the dispatch function used for?The dispatch function provides methods for sending commands from the character sheet back to Roll20, including updating character data, performing actions, and interacting with the interface.
Q: What are roll buttons, and how do they work?Roll buttons are HTML elements with specific attributes that execute designated sheet actions when clicked. They can pass arguments to the action method and are commonly used for triggering rolls from the character sheet.
Q: How are legacy attributes handled in Beacon?Beacon gives you the ability to transition your legacy attributes to new attributes you create in Beacon. This means that when a user updates their sheet to the new Beacon sheet, their legacy attribute can be mapped to Beacon attributes using the convertLegacyMacroAttributes function. Sheet developers can define how to handle legacy attribute values to ensure compatibility with existing macros.
Q: What is the purpose of the query function?The query function displays a SweetAlert2 prompt to users and returns the results along with any errors. It is commonly used for interactive prompts or confirmations within the VTT interface.
Q: How are tokens managed in the VTT?Tokens represent characters or objects on Roll20 Tabletop (VTT). Functions like getTokens, updateTokensByCharacter, and addToTracker are used to retrieve token information, update token data, and manage tokens in the turn tracker.
Q: What is the role of the convertLegacyMacroAttributesArgs type?The convertLegacyMacroAttributesArgs type defines the arguments used for handling legacy macro attributes. It includes the attribute name, character ID, and character data needed for mapping legacy attributes to the new sheet structure.
\ No newline at end of file diff --git a/public/docs/about/glossary/index.html b/public/docs/about/glossary/index.html index 0fbfdcd..89acd40 100644 --- a/public/docs/about/glossary/index.html +++ b/public/docs/about/glossary/index.html @@ -1,3 +1,3 @@ -Glossary | Glossary |

Glossary

Background:

The background color of the alert box.

Character:

An entity in the game with attributes, bio, GM notes, and a token representation.

Character sheet:

A digital or printed page used to track a character’s attributes, abilities, and other relevant information in a role-playing game.

Computed Property:

Properties that have both get and set methods, which can be dynamically calculated.

ConvertLegacyMacroAttributes:

A function to handle mapping legacy macro attributes to the new Beacon Sheet format.

Dispatch:

A set of functions enabling the sheet to send commands back to the VTT.

GM (Game Master):

The person who runs the game, controls the NPCs & the story, and provides challenges for the players.

Handler:

Methods that act as event handlers to process messages from the host.

InitRelay:

Function to initialize the SDK relay, setting up communication between the host and the character sheet.

Macro:

A script that automates repetitive tasks in the VTT.

Roll Template:

A predefined format for displaying the results of a dice roll.

Token:

A visual representation of a character or object on the virtual tabletop, with various properties like position, size, and attributes.

VTT (Virtual Tabletop):

An online platform that allows players to play tabletop role-playing games over the internet.

ValidationMessage:

A message displayed when an input value does not meet specific criteria.

Quantum Roll:

A system that ensures the fairness and authenticity of dice rolls in the VTT by using cryptographic methods.

\ No newline at end of file +Character: An entity in the game with attributes, bio, GM notes, and a token representation.">

Glossary

Background:

The background color of the alert box.

Character:

An entity in the game with attributes, bio, GM notes, and a token representation.

Character sheet:

A digital or printed page used to track a character’s attributes, abilities, and other relevant information in a role-playing game.

Computed Property:

Properties that have both get and set methods, which can be dynamically calculated.

ConvertLegacyMacroAttributes:

A function to handle mapping legacy macro attributes to the new Beacon Sheet format.

Dispatch:

A set of functions enabling the sheet to send commands back to the VTT.

GM (Game Master):

The person who runs the game, controls the NPCs & the story, and provides challenges for the players.

Handler:

Methods that act as event handlers to process messages from the host.

InitRelay:

Function to initialize the SDK relay, setting up communication between the host and the character sheet.

Macro:

A script that automates repetitive tasks in the VTT.

Roll Template:

A predefined format for displaying the results of a dice roll.

Token:

A visual representation of a character or object on the virtual tabletop, with various properties like position, size, and attributes.

VTT (Virtual Tabletop):

An online platform that allows players to play tabletop role-playing games over the internet.

ValidationMessage:

A message displayed when an input value does not meet specific criteria.

Quantum Roll:

A system that ensures the fairness and authenticity of dice rolls in the VTT by using cryptographic methods.

\ No newline at end of file diff --git a/public/docs/about/how-to-contribute/index.html b/public/docs/about/how-to-contribute/index.html index beb79bd..6710fec 100644 --- a/public/docs/about/how-to-contribute/index.html +++ b/public/docs/about/how-to-contribute/index.html @@ -1 +1 @@ -How to Contribute |

How to Contribute

We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:

How to Contribute

Reporting Bugs

If you find a bug, please report it by opening an issue in the GitHub repository. Provide as much detail as possible to help us understand and reproduce the issue.

Suggesting Features

We welcome suggestions for new features. Please open an issue in the GitHub repository with a detailed description of the feature you would like to see and why you think it would be useful.

Code Contributions

  1. Fork the Repository: Create a personal fork of the project on GitHub.

  2. Clone the Fork: Clone your fork to your local machine.

    git clone 
  3. Create a Branch: Create a new branch for your work.

    git checkout -b feature-or-bugfix-description
  4. Make Changes: Make your changes to the codebase. Follow the existing code style and conventions.

  5. Run Tests: Ensure that all tests pass before submitting your changes.

    npm run ci-check
  6. Commit Changes: Commit your changes with a descriptive commit message.

    git commit -m "Description of your changes"
  7. Push Changes: Push your changes to your fork.

    git push origin feature-or-bugfix-description
  8. Create a Pull Request: Open a pull request from your fork to the main repository. Provide a detailed description of your changes and why they should be merged.

Running Tests

  • Unit Tests: Run unit tests with Vitest.

    npm run test:unit
  • End-to-End Tests: Run End-to-End tests with Cypress.

    npm run test:e2e

Code Style

  • Follow the existing code style and conventions.

  • Use ESLint for linting.

    npm run lint
  • Format code with Prettier.

    npm run format

Communication

  • GitHub Issues: Use GitHub issues for bug reports, feature requests, and questions.
  • Pull Requests: Use GitHub pull requests to submit your code contributions.

Thank you for contributing to the Beacon SDK project!

\ No newline at end of file +How to Contribute |

How to Contribute

We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:

How to Contribute

Reporting Bugs

If you find a bug, please report it by opening an issue in the GitHub repository. Provide as much detail as possible to help us understand and reproduce the issue.

Suggesting Features

We welcome suggestions for new features. Please open an issue in the GitHub repository with a detailed description of the feature you would like to see and why you think it would be useful.

Code Contributions

  1. Fork the Repository: Create a personal fork of the project on GitHub.

  2. Clone the Fork: Clone your fork to your local machine.

    git clone 
  3. Create a Branch: Create a new branch for your work.

    git checkout -b feature-or-bugfix-description
  4. Make Changes: Make your changes to the codebase. Follow the existing code style and conventions.

  5. Run Tests: Ensure that all tests pass before submitting your changes.

    npm run ci-check
  6. Commit Changes: Commit your changes with a descriptive commit message.

    git commit -m "Description of your changes"
  7. Push Changes: Push your changes to your fork.

    git push origin feature-or-bugfix-description
  8. Create a Pull Request: Open a pull request from your fork to the main repository. Provide a detailed description of your changes and why they should be merged.

Running Tests

  • Unit Tests: Run unit tests with Vitest.

    npm run test:unit
  • End-to-End Tests: Run End-to-End tests with Cypress.

    npm run test:e2e

Code Style

  • Follow the existing code style and conventions.

  • Use ESLint for linting.

    npm run lint
  • Format code with Prettier.

    npm run format

Communication

  • GitHub Issues: Use GitHub issues for bug reports, feature requests, and questions.
  • Pull Requests: Use GitHub pull requests to submit your code contributions.

Thank you for contributing to the Beacon SDK project!

\ No newline at end of file diff --git a/public/docs/about/index.html b/public/docs/about/index.html index 6762131..2b9ed2c 100644 --- a/public/docs/about/index.html +++ b/public/docs/about/index.html @@ -1 +1 @@ -About |
\ No newline at end of file +About |
\ No newline at end of file diff --git a/public/docs/about/index.xml b/public/docs/about/index.xml index 9611f7b..af9b234 100644 --- a/public/docs/about/index.xml +++ b/public/docs/about/index.xml @@ -1,3 +1,3 @@ -About onhttps://roll20.github.io/beacon-docs/docs/about/Recent content in About onHugoenCopyright (c) 2020-2024 Beacon SDKSat, 07 Sep 2024 16:13:18 +0200Glossaryhttps://roll20.github.io/beacon-docs/docs/about/glossary/Thu, 07 Mar 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/glossary/Background: The background color of the alert box. -Character: An entity in the game with attributes, bio, GM notes, and a token representation.FAQhttps://roll20.github.io/beacon-docs/docs/about/faq/Sun, 07 Jan 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/faq/Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)? It depends on your web development skill level.Changeloghttps://roll20.github.io/beacon-docs/docs/about/changelog/Sun, 07 Jan 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/about/changelog/Release Date: 2022-03-17 -New Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development.How to Contributehttps://roll20.github.io/beacon-docs/docs/about/how-to-contribute/Wed, 07 Feb 2024 16:13:18 +0200https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started: \ No newline at end of file +About onhttps://roll20.github.io/beacon-docs/docs/about/Recent content in About onHugoenCopyright (c) 2020-2024 Beacon SDKSat, 07 Sep 2024 16:13:18 +0200FAQhttps://roll20.github.io/beacon-docs/docs/about/faq/Sun, 07 Jan 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/faq/Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)? It depends on your web development skill level.Glossaryhttps://roll20.github.io/beacon-docs/docs/about/glossary/Thu, 07 Mar 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/glossary/Background: The background color of the alert box. +Character: An entity in the game with attributes, bio, GM notes, and a token representation.How to Contributehttps://roll20.github.io/beacon-docs/docs/about/how-to-contribute/Wed, 07 Feb 2024 16:13:18 +0200https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:Changeloghttps://roll20.github.io/beacon-docs/docs/about/changelog/Sun, 07 Jan 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/about/changelog/Release Date: 2022-03-17 +New Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development. \ No newline at end of file diff --git a/public/docs/about/sitemap.xml b/public/docs/about/sitemap.xml index 2cc6348..abf0771 100644 --- a/public/docs/about/sitemap.xml +++ b/public/docs/about/sitemap.xml @@ -1 +1 @@ -https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5 \ No newline at end of file +https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5 \ No newline at end of file diff --git a/public/docs/components/actions/index.html b/public/docs/components/actions/index.html index 6fc2c49..95d5034 100644 --- a/public/docs/components/actions/index.html +++ b/public/docs/components/actions/index.html @@ -1,4 +1,4 @@ -Actions |

Actions

initRelay({
+Actions | 

Actions

initRelay({
   //...other methods
     actions: {},
 }): Promise<Dispatch>

Actions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters. These actions are used for any rolls that may need to be triggered outside of the sheet itself, such as from a macro or a chat button. Generally, most or all of a sheet’s rolls should be defined as actions.

actions: {
diff --git a/public/docs/components/computed/index.html b/public/docs/components/computed/index.html
index e1c20cd..04aa9bc 100644
--- a/public/docs/components/computed/index.html
+++ b/public/docs/components/computed/index.html
@@ -1,4 +1,4 @@
-Computed | 

Computed

Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.

initRelay({
+Computed | 

Computed

Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.

initRelay({
   //...other methods
   computed: {
     [name: string]: {
diff --git a/public/docs/components/dispatch/index.html b/public/docs/components/dispatch/index.html
index f34a16f..8120fbe 100644
--- a/public/docs/components/dispatch/index.html
+++ b/public/docs/components/dispatch/index.html
@@ -1,4 +1,4 @@
-Dispatch | 

Dispatch

The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host. Except when specified every method below will return a promise.

update

dispatch.update({
+Dispatch | 

Dispatch

The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host. Except when specified every method below will return a promise.

update

dispatch.update({
   options: { overwrite?: boolean }
   character: Partial<Character>
 }): Promise<void>

The update method sends character changes to the host (Roll20 Tabletop or Roll20 Characters) to be persisted.

The partial character passed in here must contain the character’s id, and can contain any combination of the attributes, bio, and gmNotes properties. When updating a character’s attributes, only include those attributes that have changed.

updateCharacter

dispatch.updateCharacter({
diff --git a/public/docs/components/handlers/index.html b/public/docs/components/handlers/index.html
index 3a04531..32d1ab2 100644
--- a/public/docs/components/handlers/index.html
+++ b/public/docs/components/handlers/index.html
@@ -1,4 +1,4 @@
-Handlers | 

Handlers

Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. It is the main agrument that must be passed into initRelay or the sheet will never fully load.

initRelay({
+Handlers | 

Handlers

Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. It is the main agrument that must be passed into initRelay or the sheet will never fully load.

initRelay({
     handlers: {
         onInit,
         onChange,
@@ -49,4 +49,4 @@
     categoryName: string
     expansionId: number
   }
-}, dispatch: Dispatch) => void
\ No newline at end of file +
}, dispatch: Dispatch) => void
\ No newline at end of file diff --git a/public/docs/components/handling-legacy-methods/index.html b/public/docs/components/handling-legacy-methods/index.html index 670f037..beb032a 100644 --- a/public/docs/components/handling-legacy-methods/index.html +++ b/public/docs/components/handling-legacy-methods/index.html @@ -1,4 +1,4 @@ -Handling Legacy methods |

Handling Legacy methods

When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.

This scenario commonly arises when transitioning from an existing legacy sheet to a Beacon sheet. During such transitions, it’s possible that the attributes or roll templates called from the legacy macro may not align with the structure of attributes or the lack of roll templates in the Beacon Sheet.

convertLegacyMacroAttributes

The convertLegacyMacroAttributes method allows us to determine the mapping strategy for legacy attributes to the new Beacon Sheet.

initRelay({
+Handling Legacy methods | 

Handling Legacy methods

When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.

This scenario commonly arises when transitioning from an existing legacy sheet to a Beacon sheet. During such transitions, it’s possible that the attributes or roll templates called from the legacy macro may not align with the structure of attributes or the lack of roll templates in the Beacon Sheet.

convertLegacyMacroAttributes

The convertLegacyMacroAttributes method allows us to determine the mapping strategy for legacy attributes to the new Beacon Sheet.

initRelay({
   convertLegacyMacroAttributes: (messages:  {
     attribute: string,
     characterId: string,
@@ -29,4 +29,4 @@
     },
     ............
   }
-}
\ No newline at end of file +
}
\ No newline at end of file diff --git a/public/docs/components/index.html b/public/docs/components/index.html index 4dc9da2..5903d3b 100644 --- a/public/docs/components/index.html +++ b/public/docs/components/index.html @@ -1 +1 @@ -Components |
\ No newline at end of file +Components |
\ No newline at end of file diff --git a/public/docs/components/initrelay/index.html b/public/docs/components/initrelay/index.html index 5adae24..5052ae1 100644 --- a/public/docs/components/initrelay/index.html +++ b/public/docs/components/initrelay/index.html @@ -1,4 +1,4 @@ -InitRelay |

InitRelay

The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games. initRelay is the main method that initializes the Beacon SDK communication channel with the host (Either the Roll20 tabletop or in Roll20 Characters). It should be initialized as soon as the sheet loads, as its onInit handler will be the earliest we can get access to that character’s data.

initRelay({
+InitRelay | 

InitRelay

The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games. initRelay is the main method that initializes the Beacon SDK communication channel with the host (Either the Roll20 tabletop or in Roll20 Characters). It should be initialized as soon as the sheet loads, as its onInit handler will be the earliest we can get access to that character’s data.

initRelay({
     handlers: {
         onInit,
         onChange,
@@ -12,4 +12,4 @@
     computed: {},
     convertLegacyMacroAttributes,
     handleLegacyRollTemplates
-}): Promise<Dispatch>

These components are crucial for handling actions, computations, macros, and rolls. This overview provides a high-level summary of each section, helping you understand their roles and how they integrate within the SDK.

Actions

Actions define specific operations that can be performed by characters within the Roll20 Tabletop. These operations can range from simple tasks like rolling a dice to more complex interactions such as casting spells or activating abilities.

Handlers

Handlers are event listeners that manage communication between the Roll20 Tabletop and the character sheet. They respond to various events, such as changes in character attributes or settings, and trigger appropriate actions or updates.

Computed

Computed properties are dynamic values derived from other character attributes. They allow for the creation of complex, calculated attributes that automatically update when their dependencies change.

Macro Attributes

Macro attributes handle the conversion of legacy macro attributes to the new format used in the Beacon SDK. This ensures compatibility with older character sheets and macros, allowing for a smooth transition to the new system.

Rolls

The Rolls component allows for advanced dice-rolling mechanics within the Roll20 Tabletop. It supports both simple and complex rolls, providing flexibility in how roll results are displayed and computed.

Dispatch

The dispatch object provides methods for sending commands from the character sheet back to the host. Except when specified every method returns a promise.

\ No newline at end of file +
}): Promise<Dispatch>

These components are crucial for handling actions, computations, macros, and rolls. This overview provides a high-level summary of each section, helping you understand their roles and how they integrate within the SDK.

Actions

Actions define specific operations that can be performed by characters within the Roll20 Tabletop. These operations can range from simple tasks like rolling a dice to more complex interactions such as casting spells or activating abilities.

Handlers

Handlers are event listeners that manage communication between the Roll20 Tabletop and the character sheet. They respond to various events, such as changes in character attributes or settings, and trigger appropriate actions or updates.

Computed

Computed properties are dynamic values derived from other character attributes. They allow for the creation of complex, calculated attributes that automatically update when their dependencies change.

Macro Attributes

Macro attributes handle the conversion of legacy macro attributes to the new format used in the Beacon SDK. This ensures compatibility with older character sheets and macros, allowing for a smooth transition to the new system.

Rolls

The Rolls component allows for advanced dice-rolling mechanics within the Roll20 Tabletop. It supports both simple and complex rolls, providing flexibility in how roll results are displayed and computed.

Dispatch

The dispatch object provides methods for sending commands from the character sheet back to the host. Except when specified every method returns a promise.

\ No newline at end of file diff --git a/public/docs/components/rolls/index.html b/public/docs/components/rolls/index.html index 0a38fcc..72e7d01 100644 --- a/public/docs/components/rolls/index.html +++ b/public/docs/components/rolls/index.html @@ -1,4 +1,4 @@ -Rolls |

Rolls

The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed. These features include attributes and elements that allow for dynamic roll results and interactivity within the host. +Rolls |

Rolls

The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed. These features include attributes and elements that allow for dynamic roll results and interactivity within the host. Vist the Roll20 help center to learn more about Roll20’s Dice Rolling system

The most command way to trigger a dice roll is through the dispatch object returned from the initRelay, but it could also be called from actions:

dispatch.roll({
   rolls: { [rollName: string]: string } // Ex. {attack: '1d20+4', damage: `3d6+2`}
   messageId?: string
@@ -22,4 +22,4 @@
       }[]
     }
   }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/public/docs/gettingstarted/example-patterns-sheet/index.html b/public/docs/gettingstarted/example-patterns-sheet/index.html index ccfee9d..89a8eca 100644 --- a/public/docs/gettingstarted/example-patterns-sheet/index.html +++ b/public/docs/gettingstarted/example-patterns-sheet/index.html @@ -1 +1 @@ -Example Patterns Sheet |

Example Patterns Sheet

Prerequisites

To set this sheet up properly, make sure that you have the following:

  • Vue framework & Routing
  • Multiple Data Stores
  • Complex Roll Templates
  • Rich Sheet Actions
  • TypeScript
  • Vite
  • SCSS
  • Ability to run Unit & End-to-End Tests

To download the community quick start sheet, refer to these repositories:

Figure 1: Advanced sheet

This sheet uses the same steps listed in the . Immediately after implementing those three steps, you’ll add the following step:

  • Run a CI check: This will run several checks to ensure your code is as optimal as possible, including formatting, linting, type checking, unit tests, and end-to-end tests.
npm run ci-check

You can think of this command as a sanity check you can leverage when pushing a big release for your sheet!

Useful Commands

The following set of commands can come in handy when working with this sheet:

  • For Hot reloading and building CSS files, use the following command:
npm run watch-scss
  • For linting, use the following command:
npm run lint
  • For formatting with Prettier, use the following command:
npm run format
  • For type checking with TypeScript, use the following command:
npm run type-check
  • For running unit tests with Vitest, use the following command:
npm run test:unit
  • To open up and develop local end-to-end tests with Cypress, use the following command:
npm run test:e2e:open:local
  • For running local end-to-end tests with Cypress, use the following command:
npm run test:e2e:local
  • To run CDN-hosted end-to-end tests with Cypress, use the following command:
npm run test:e2e
\ No newline at end of file +Example Patterns Sheet |

Example Patterns Sheet

Prerequisites

To set this sheet up properly, make sure that you have the following:

  • Vue framework & Routing
  • Multiple Data Stores
  • Complex Roll Templates
  • Rich Sheet Actions
  • TypeScript
  • Vite
  • SCSS
  • Ability to run Unit & End-to-End Tests

To download the community quick start sheet, refer to these repositories:

Figure 1: Advanced sheet

This sheet uses the same steps listed in the . Immediately after implementing those three steps, you’ll add the following step:

  • Run a CI check: This will run several checks to ensure your code is as optimal as possible, including formatting, linting, type checking, unit tests, and end-to-end tests.
npm run ci-check

You can think of this command as a sanity check you can leverage when pushing a big release for your sheet!

Useful Commands

The following set of commands can come in handy when working with this sheet:

  • For Hot reloading and building CSS files, use the following command:
npm run watch-scss
  • For linting, use the following command:
npm run lint
  • For formatting with Prettier, use the following command:
npm run format
  • For type checking with TypeScript, use the following command:
npm run type-check
  • For running unit tests with Vitest, use the following command:
npm run test:unit
  • To open up and develop local end-to-end tests with Cypress, use the following command:
npm run test:e2e:open:local
  • For running local end-to-end tests with Cypress, use the following command:
npm run test:e2e:local
  • To run CDN-hosted end-to-end tests with Cypress, use the following command:
npm run test:e2e
\ No newline at end of file diff --git a/public/docs/gettingstarted/index.html b/public/docs/gettingstarted/index.html index 4a33dae..0f78fa1 100644 --- a/public/docs/gettingstarted/index.html +++ b/public/docs/gettingstarted/index.html @@ -1 +1 @@ -Getting Started |
\ No newline at end of file +Getting Started |
\ No newline at end of file diff --git a/public/docs/gettingstarted/installing-beacon/index.html b/public/docs/gettingstarted/installing-beacon/index.html index 651b844..3b6eb9a 100644 --- a/public/docs/gettingstarted/installing-beacon/index.html +++ b/public/docs/gettingstarted/installing-beacon/index.html @@ -1,4 +1,4 @@ -Installing Beacon |

Installing Beacon

This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.

To get started quickly with a boilerplate, you can download and start editing the Quick Start Example Sheet which already has the Beacon SDK installed, along with several recommanded patterns implemented in a Vue.js project.

Prerequisites

Before you can install the Beacon SDK, you’ll need to have the following:

  • A local web development environment with a code editor.
  • Node.js installed on your machine. If you don’t have Node.js installed, use the following steps in the official Node.js documentation.
  • A javascript project, we recommand Vue.js but you can choose whichever you are more comfortable with.

These steps use npm but you are free to use any package manager and framework you prefer.

The following steps will guide you in installing the Beacon SDK in your application:

Step 1: Add the package to your project

You can find the latest version of the package on the NPM registry.

In your project’s directory, run the following:

  npm i @roll20-official/beacon-sdk

This will install the Beacon SDK package to your project’s package.json file.

Step 2: Use the Beacon package in your project

The Beacon package exports various utilities you can use in your application. The main one that needs to be setup to enable the connection between Beacon SDK and Roll20 is initRelay.

Ideally you would want to call this when your sheet is initalizing, and it is the function where you will define sheet actions, computed values, and how the sheet will response to or send character data changes. visit the initRelay page for a more detailed breakdown.

Add the following to your project:

import { initRelay } from '@roll20/beacon-sdk';
+Installing Beacon | 

Installing Beacon

This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.

To get started quickly with a boilerplate, you can download and start editing the Quick Start Example Sheet which already has the Beacon SDK installed, along with several recommanded patterns implemented in a Vue.js project.

Prerequisites

Before you can install the Beacon SDK, you’ll need to have the following:

  • A local web development environment with a code editor.
  • Node.js installed on your machine. If you don’t have Node.js installed, use the following steps in the official Node.js documentation.
  • A javascript project, we recommand Vue.js but you can choose whichever you are more comfortable with.

These steps use npm but you are free to use any package manager and framework you prefer.

The following steps will guide you in installing the Beacon SDK in your application:

Step 1: Add the package to your project

You can find the latest version of the package on the NPM registry.

In your project’s directory, run the following:

  npm i @roll20-official/beacon-sdk

This will install the Beacon SDK package to your project’s package.json file.

Step 2: Use the Beacon package in your project

The Beacon package exports various utilities you can use in your application. The main one that needs to be setup to enable the connection between Beacon SDK and Roll20 is initRelay.

Ideally you would want to call this when your sheet is initalizing, and it is the function where you will define sheet actions, computed values, and how the sheet will response to or send character data changes. visit the initRelay page for a more detailed breakdown.

Add the following to your project:

import { initRelay } from '@roll20/beacon-sdk';
 
 const dispatch = initRelay({
     handlers: {
@@ -15,4 +15,4 @@
 })

initRelay returns a dispatch function that allows you to call methods or send changes from the sheet to Roll20. Check out the page on dispatch to learn more about the different methods.

Step 3: Settings up the Roll20 tabletop sandbox

On the Roll20 website visit the custom sheet sandbox and create a new sandbox, we’ll use this sandbox to develop our sheet but we must set it up to listen to our local project’s web server.

After creating a new sandbox, we’ll be taken to the sandbox details page, here you will find a collapseable section called Sheet.json Editor, opening this we can add the settings we need to connect to our project:

{
 	"advanced": true,
 	"advancedPort": 7620 // or the port of your webserver
-}

After adding these changes make sure to click Save Changes at the bottom of the page. After which you can click Launch Game on the page to go into the game and start testing your sheet.

Character sheet and dev tools open showing character data results

\ No newline at end of file +
}

After adding these changes make sure to click Save Changes at the bottom of the page. After which you can click Launch Game on the page to go into the game and start testing your sheet.

Character sheet and dev tools open showing character data results

\ No newline at end of file diff --git a/public/docs/gettingstarted/introduction/index.html b/public/docs/gettingstarted/introduction/index.html index 6c426d5..496121d 100644 --- a/public/docs/gettingstarted/introduction/index.html +++ b/public/docs/gettingstarted/introduction/index.html @@ -1 +1 @@ -Introduction |

Introduction

This project is currently in closed beta.

Please complete the form to request access to the closed beta.

For more info about the release of the closed beta, refer to this document

The Beacon SDK is a toolset designed to enhance and streamline the development of virtual tabletop (VTT) character sheets and other interactive elements.

Whether you’re a game master (GM), a developer, or a player, the Beacon SDK provides a framework to create dynamic, responsive, and fully integrated Roll20 Tabletop experiences.

What is the Beacon SDK?

The Beacon SDK is a specialized software development kit for virtual tabletops.

It facilitates creating and managing interactive character sheets, roll templates, macros, and other Roll20 Tabletop functionalities.

The SDK ensures easy communication between the Roll20 Tabletop platform and the character sheets, allowing real-time updates and interactions.

Key Features

  • Character Sheets: Design and implement detailed character sheets with dynamic attributes and real-time updates.
  • Roll Mechanics: Integrate complex roll formulas and display roll results directly within the Roll20 Tabletop.
  • Macros: Create and manage macros for automated actions and roll calculations.
  • Event Handling: Utilize a comprehensive set of handlers to manage various events and interactions within the Roll20 Tabletop.
  • Legacy Support: Convert and integrate legacy macros and roll templates with the new Beacon architecture.
  • Customization: Define custom actions computed properties and handle specific roll templates tailored to your game’s needs.

Components Overview

The Beacon SDK is composed of several key components:

  • Actions: Define and manage custom actions that can be triggered within the Roll20 Tabletop.
  • Handlers: Event handlers that process and respond to various Roll20 Tabletop events and messages.
  • Computed Properties: Define dynamically computed properties based on other attributes.
  • Macro Attributes: Convert and manage legacy macro attributes for compatibility with the Beacon SDK.
  • Rolls: Implement advanced roll mechanics and display results dynamically within the Roll20 Tabletop.

For a comprehensive overview of these components, view the components section.

Getting Started

To get started with the Beacon SDK, you must initialize the relay, set up your character sheets, and define the necessary actions, handlers, and computed properties.

This documentation provides detailed guides and examples to help you through each step of the process.

By leveraging the Beacon SDK, you can create rich, interactive, fully integrated Roll20 Tabletop experiences that enhance gameplay and streamline game management.

Whether adapting existing character sheets or building new ones from scratch, the Beacon SDK offers the tools and flexibility to bring your virtual tabletop to life.

\ No newline at end of file +Introduction |

Introduction

This project is currently in closed beta.

Please complete the form to request access to the closed beta.

For more info about the release of the closed beta, refer to this document

The Beacon SDK is a toolset designed to enhance and streamline the development of virtual tabletop (VTT) character sheets and other interactive elements.

Whether you’re a game master (GM), a developer, or a player, the Beacon SDK provides a framework to create dynamic, responsive, and fully integrated Roll20 Tabletop experiences.

What is the Beacon SDK?

The Beacon SDK is a specialized software development kit for virtual tabletops.

It facilitates creating and managing interactive character sheets, roll templates, macros, and other Roll20 Tabletop functionalities.

The SDK ensures easy communication between the Roll20 Tabletop platform and the character sheets, allowing real-time updates and interactions.

Key Features

  • Character Sheets: Design and implement detailed character sheets with dynamic attributes and real-time updates.
  • Roll Mechanics: Integrate complex roll formulas and display roll results directly within the Roll20 Tabletop.
  • Macros: Create and manage macros for automated actions and roll calculations.
  • Event Handling: Utilize a comprehensive set of handlers to manage various events and interactions within the Roll20 Tabletop.
  • Legacy Support: Convert and integrate legacy macros and roll templates with the new Beacon architecture.
  • Customization: Define custom actions computed properties and handle specific roll templates tailored to your game’s needs.

Components Overview

The Beacon SDK is composed of several key components:

  • Actions: Define and manage custom actions that can be triggered within the Roll20 Tabletop.
  • Handlers: Event handlers that process and respond to various Roll20 Tabletop events and messages.
  • Computed Properties: Define dynamically computed properties based on other attributes.
  • Macro Attributes: Convert and manage legacy macro attributes for compatibility with the Beacon SDK.
  • Rolls: Implement advanced roll mechanics and display results dynamically within the Roll20 Tabletop.

For a comprehensive overview of these components, view the components section.

Getting Started

To get started with the Beacon SDK, you must initialize the relay, set up your character sheets, and define the necessary actions, handlers, and computed properties.

This documentation provides detailed guides and examples to help you through each step of the process.

By leveraging the Beacon SDK, you can create rich, interactive, fully integrated Roll20 Tabletop experiences that enhance gameplay and streamline game management.

Whether adapting existing character sheets or building new ones from scratch, the Beacon SDK offers the tools and flexibility to bring your virtual tabletop to life.

\ No newline at end of file diff --git a/public/docs/gettingstarted/quick-start-sheet-template/index.html b/public/docs/gettingstarted/quick-start-sheet-template/index.html index 7e031ee..dd5d718 100644 --- a/public/docs/gettingstarted/quick-start-sheet-template/index.html +++ b/public/docs/gettingstarted/quick-start-sheet-template/index.html @@ -1,4 +1,4 @@ -Quick Start Sheet Template |

Quick Start Sheet Template

Prerequisites

To set this sheet up properly, make sure that you have the following tools installed:

  • Vue.js
  • Vite
  • SCSS

To download the community quick start sheet, refer to these repositories:

Figure 1: Quickstart sheet

Use the following steps to get started:

  1. Install the Beacon SDK: Run the following command.
npm i @roll20-official/beacon-sdk
  1. Install dependencies: Install the dependencies for the project.
npm install
  1. Start the Vite server: After installing the project’s dependencies, you’ll need to start the Vite server. There are two ways to do this:

a. Offline Development: This method will run the Vite server with the default port and environment set to development.

npm run dev

Once this code executes successfully, you can access the Vite server at http://localhost:5173.

This method is useful when you do not have access to the Roll20 website or would like to work on parts of your project that do not depend on a connection to the Roll20 Tabletop or Roll20 Characters, such as working on styling, mocking up the environment, building Vue components, testing functionality, etc.

In development mode, you cannot save or access existing character data or use the Beacon SDK functions that depend on Roll20 Tabletop or Roll20 Characters functionality, such as dice rolling and token manipulation.

b. Sandbox Development: This method will run the Vite server with the port set to 7620 and the environment set to staging mode.

npm run sandbox

This command will build the SCSS files and then run the Vite server. This will set the server up for connecting to a Roll20 Tabletop custom sheet sandbox as well as through the sandbox in Roll20 Characters.

To test your changes in the Roll20 Tabletop custom sheet sandbox, you will need to add the following to the sheet.json editor in the game settings:

{
+Quick Start Sheet Template | 

Quick Start Sheet Template

Prerequisites

To set this sheet up properly, make sure that you have the following tools installed:

  • Vue.js
  • Vite
  • SCSS

To download the community quick start sheet, refer to these repositories:

Figure 1: Quickstart sheet

Use the following steps to get started:

  1. Install the Beacon SDK: Run the following command.
npm i @roll20-official/beacon-sdk
  1. Install dependencies: Install the dependencies for the project.
npm install
  1. Start the Vite server: After installing the project’s dependencies, you’ll need to start the Vite server. There are two ways to do this:

a. Offline Development: This method will run the Vite server with the default port and environment set to development.

npm run dev

Once this code executes successfully, you can access the Vite server at http://localhost:5173.

This method is useful when you do not have access to the Roll20 website or would like to work on parts of your project that do not depend on a connection to the Roll20 Tabletop or Roll20 Characters, such as working on styling, mocking up the environment, building Vue components, testing functionality, etc.

In development mode, you cannot save or access existing character data or use the Beacon SDK functions that depend on Roll20 Tabletop or Roll20 Characters functionality, such as dice rolling and token manipulation.

b. Sandbox Development: This method will run the Vite server with the port set to 7620 and the environment set to staging mode.

npm run sandbox

This command will build the SCSS files and then run the Vite server. This will set the server up for connecting to a Roll20 Tabletop custom sheet sandbox as well as through the sandbox in Roll20 Characters.

To test your changes in the Roll20 Tabletop custom sheet sandbox, you will need to add the following to the sheet.json editor in the game settings:

{
        "advanced": true,
        "advancedPort": 7620
-}

Useful Commands

The following set of commands can come in handy when working with this sheet:

  • For Hot reloading and building CSS files, use the following command:
npm run watch-scss
  • For linting, use the following command:
npm run lint
  • For formatting with Prettier, use the following command:
npm run format
\ No newline at end of file +
}

Useful Commands

The following set of commands can come in handy when working with this sheet:

  • For Hot reloading and building CSS files, use the following command:
npm run watch-scss
  • For linting, use the following command:
npm run lint
  • For formatting with Prettier, use the following command:
npm run format
\ No newline at end of file diff --git a/public/docs/gettingstarted/releasing-a-sheet/index.html b/public/docs/gettingstarted/releasing-a-sheet/index.html index f8621da..1514699 100644 --- a/public/docs/gettingstarted/releasing-a-sheet/index.html +++ b/public/docs/gettingstarted/releasing-a-sheet/index.html @@ -1,5 +1,5 @@ -Releasing a Sheet |

Releasing a Sheet

There are two ways you can publish a Beacon sheet.

  1. You can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or
  2. You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access.

When publishing a sheet, you will need to includes all the necessary code, assets, and metadata packaged together to be easily deployed and tested on the Roll20 platform. When a sheet is published, either publicly or privately for testing purposes, the sheet will run on Roll20 and will no longer require a local development environment to use it.

Releasing a Test Sheet

The following steps will aid you while releasing your sheet:

  1. Create a Build Command:

    You must have a build command that will produce the minified production-ready code. You can find more information in our Quickstart Package JSON. The build command must be able to create these exact files:

    • sheet.js
    • sheet.css
    • host.css (optional) - This is the styling for any sheet rolls made to the chat.
    • Add a local folder that contains fonts and images used in the sheet (optional).
  2. Add a sheet.json file:

    Add a sheet.json file to your sheet folder to ensure the metadata for your sheet is up-to-date. You can find more information about the sheet.json options on the Roll20 Wiki as well as on the Quickstart sheet.

  3. Create a Pull Request in the Beacon Community Sheet Repo:

    In the Beacon Community Sheet Repo, create a pull request that must include the submission checklist listed for reference below.

    The name of the pull request should…

    • Contain the short name of the sheet being submitted, and
    • State the type of change being submitted (New/Update/Bugfix/etc.). +Releasing a Sheet |

      Releasing a Sheet

      There are two ways you can publish a Beacon sheet.

      1. You can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or
      2. You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access.

      When publishing a sheet, you will need to includes all the necessary code, assets, and metadata packaged together to be easily deployed and tested on the Roll20 platform. When a sheet is published, either publicly or privately for testing purposes, the sheet will run on Roll20 and will no longer require a local development environment to use it.

      Releasing a Test Sheet

      The following steps will aid you while releasing your sheet:

      1. Create a Build Command:

        You must have a build command that will produce the minified production-ready code. You can find more information in our Quickstart Package JSON. The build command must be able to create these exact files:

        • sheet.js
        • sheet.css
        • host.css (optional) - This is the styling for any sheet rolls made to the chat.
        • Add a local folder that contains fonts and images used in the sheet (optional).
      2. Add a sheet.json file:

        Add a sheet.json file to your sheet folder to ensure the metadata for your sheet is up-to-date. You can find more information about the sheet.json options on the Roll20 Wiki as well as on the Quickstart sheet.

      3. Create a Pull Request in the Beacon Community Sheet Repo:

        In the Beacon Community Sheet Repo, create a pull request that must include the submission checklist listed for reference below.

        The name of the pull request should…

        • Contain the short name of the sheet being submitted, and
        • State the type of change being submitted (New/Update/Bugfix/etc.). Pull Request Title Example: Sheet/<TYPE_OF_CHANGE>/<SHEET_SHORT_NAME>

        If this is the first time you are submitting this sheet to the repository, please make sure to have the following information ready.

        • The full name of the game associated with the sheet (i.e. Dungeons & Dragons 5th Edition, The Dresden Files RPG).
        • The name of this game system/family associated with the shee (i.e. Dungeons & Dragons, FATE).
        • The publisher of the game associated with the sheet (i.e. Wizards of the Coast, Evil Hat).

        The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you’d like them to be displayed. To see example of how this information will show up, create a new game on Roll20. The name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.

      Pull requests that contain changes to files outside the sheet sub-folder on which you’re working will be rejected.

      1. Give Specific Roll20 Users Access:

        Before your testing sheet is finally approved, you want choose to give specific Roll20 Users access to the testing sheet. This will allow only those users to see the sheet in Roll20 Tabletop and Roll20 Characters. These users will be able to use it just like the final users will when the sheet is public. You can give access to friends, group members, or even clients and publishers you’re working with.

        To give access to one ore more specific user’s, fill out the Beacon Sheet Access Form. You will need the email associated with the Roll20 Account that will have access to the sheet for each person you’d like to give access.

      We can always grant more people access to the sheet after it is released. Resubmit the Beacon Sheet Access Form to the new people for which you’d like to give access.

      1. Wait for Approval and Access:

        After you create a pull request, our team will approve it and add your sheet to the sheet selection in Roll20 Tabletop and Roll20 Characters. We will then give only your Roll20 user and any others you’ve listed in the pull request comments access to the sheet in Roll20. This sheet will then be available for you and others with access to test it.

      Submission Checklist

      • The Pull Request title contains the short name of the sheet being submitted.
      • The Pull Request title states the type of change being submitted (New/Update/Bugfix/etc.).
      • I have authorization from the game’s publisher to make this an official sheet on Roll20 with their name attached.
      • This game is not a traditionally published game, but a copy of the game rules can be purchased/downloaded/found at: < >
      • This sheet is for an unofficial fan game, modification to an existing game, or a homebrew system.

      New Sheet Checklist

      If you are submitting a new sheet to the repository, please fill in any empty spaces indicated by < >.

      • The full name of the game associated with the sheet is: < >
        • (i.e. Dungeons & Dragons 5th Edition, The Dresden Files RPG)
      • The name of this game system/family associated with the sheet is: < >
        • (i.e. Dungeons & Dragons, FATE)
      • The publisher of the game associated with the sheet is: < >
        • (i.e. Wizards of the Coast, Evil Hat)

      The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you’d like them to be displayed. To see example of where this information will show up, create a new game on Roll20. The Name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.

      Please check any that apply:

      Changes / Description (optional)

      Provide any notes relevant to this pull request here. This can include a description of the code changes, references to related pull requests, etc.

      More Help

      Additional information for the beacon sdk can be found at the Beacon SDK Documentation Site. You can also post additional questions using the -Beacon Community GitHub Issues Tab.

      Releasing a Final Version

      After you have released a test version of your sheet, you can follow the same steps as releasing a test version to make your sheet available to everyone. This time, the pull request comments state that it is a final release version.

      Once you have created the pull request, our team will review the sheet functionality, code, and metadata for consistency, best practices, and overall system security. We reserve the right to reject any sheet that does not meet our terms of use or conflicts with our partnerships.

      \ No newline at end of file +Beacon Community GitHub Issues Tab.

Releasing a Final Version

After you have released a test version of your sheet, you can follow the same steps as releasing a test version to make your sheet available to everyone. This time, the pull request comments state that it is a final release version.

Once you have created the pull request, our team will review the sheet functionality, code, and metadata for consistency, best practices, and overall system security. We reserve the right to reject any sheet that does not meet our terms of use or conflicts with our partnerships.

\ No newline at end of file diff --git a/public/docs/index.html b/public/docs/index.html index 0becf69..3dff9fc 100644 --- a/public/docs/index.html +++ b/public/docs/index.html @@ -1 +1 @@ -Docs |
\ No newline at end of file +Docs |
\ No newline at end of file diff --git a/public/docs/index.xml b/public/docs/index.xml index 93dc3b1..912b938 100644 --- a/public/docs/index.xml +++ b/public/docs/index.xml @@ -1 +1 @@ -Docs onhttps://roll20.github.io/beacon-docs/docs/Recent content in Docs onHugoenCopyright (c) 2020-2024 Beacon SDKTue, 27 Feb 2024 09:30:56 +0100FAQhttps://roll20.github.io/beacon-docs/docs/faq/Sun, 07 Jan 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/faq/Q1: What are actions in the context of the VTT? Actions are methods executed from the VTT, often used for rolls triggered from macros or chat buttons.Resourceshttps://roll20.github.io/beacon-docs/docs/resources/Tue, 27 Feb 2024 09:30:56 +0100https://roll20.github.io/beacon-docs/docs/resources/Link to valuable, relevant resources. \ No newline at end of file +Docs onhttps://roll20.github.io/beacon-docs/docs/Recent content in Docs onHugoenCopyright (c) 2020-2024 Beacon SDK \ No newline at end of file diff --git a/public/docs/sitemap.xml b/public/docs/sitemap.xml index d542c34..9a6ea79 100644 --- a/public/docs/sitemap.xml +++ b/public/docs/sitemap.xml @@ -1 +1 @@ -https://roll20.github.io/beacon-docs/docs/gettingstarted/2023-09-07T16:06:50+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/resources/2024-02-27T09:30:56+01:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/2024-01-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/2024-05-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/initrelay/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/actions/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/computed/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handlers/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/rolls/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/dispatch/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handling-legacy-methods/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5 \ No newline at end of file +https://roll20.github.io/beacon-docs/docs/gettingstarted/2023-09-07T16:06:50+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/2024-01-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/2024-05-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/initrelay/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/actions/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/computed/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handlers/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/rolls/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/dispatch/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handling-legacy-methods/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5 \ No newline at end of file diff --git a/public/index.html b/public/index.html index 7876a52..2c83e7f 100644 --- a/public/index.html +++ b/public/index.html @@ -1,2 +1,2 @@ -Welcome to Beacon SDK +Welcome to Beacon SDK

Welcome to Beacon SDK

Congrats on setting up a new Doks project!

Update content

Edit content/_index.md to see this page change.

Add new content

Add Markdown files to content to create new pages.

Configure your site

Edit your config in config/_default/hyas/doks.toml.

Read the docs

Learn more in the Docs.

\ No newline at end of file diff --git a/public/index.xml b/public/index.xml index 5616b9b..4e7b0e4 100644 --- a/public/index.xml +++ b/public/index.xml @@ -1,4 +1,6 @@ -Welcome to Beacon SDK onhttps://roll20.github.io/beacon-docs/Recent content in Welcome to Beacon SDK onHugoenCopyright (c) 2020-2024 Beacon SDKWed, 07 Feb 2024 16:04:48 +0200Example Posthttps://roll20.github.io/beacon-docs/blog/example-post/Thu, 07 Sep 2023 16:27:22 +0200https://roll20.github.io/beacon-docs/blog/example-post/You can use blog posts for announcing product updates and features.Introductionhttps://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/Tue, 07 May 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/This project is currently in closed beta. +Welcome to Beacon SDK onhttps://roll20.github.io/beacon-docs/Recent content in Welcome to Beacon SDK onHugoenCopyright (c) 2020-2024 Beacon SDKSat, 07 Sep 2024 16:13:18 +0200Introductionhttps://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/Tue, 07 May 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/This project is currently in closed beta. Please complete the form to request access to the closed beta. -For more info about the release of the closed beta, refer to this documentInstalling Beaconhttps://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/Sun, 07 Apr 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.Glossaryhttps://roll20.github.io/beacon-docs/docs/about/glossary/Thu, 07 Mar 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/glossary/Background: The background color of the alert box. -Character: An entity in the game with attributes, bio, GM notes, and a token representation.FAQhttps://roll20.github.io/beacon-docs/docs/about/faq/Sun, 07 Jan 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/about/faq/Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)? It depends on your web development skill level.FAQhttps://roll20.github.io/beacon-docs/docs/faq/Sun, 07 Jan 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/faq/Q1: What are actions in the context of the VTT? Actions are methods executed from the VTT, often used for rolls triggered from macros or chat buttons.InitRelayhttps://roll20.github.io/beacon-docs/docs/components/initrelay/Fri, 07 Jun 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/initrelay/The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games.Actionshttps://roll20.github.io/beacon-docs/docs/components/actions/Tue, 07 May 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/actions/initRelay({ //...other methods actions: {}, }): Promise&lt;Dispatch&gt; Actions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters.Computedhttps://roll20.github.io/beacon-docs/docs/components/computed/Sun, 07 Apr 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/computed/Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.Handlershttps://roll20.github.io/beacon-docs/docs/components/handlers/Thu, 07 Mar 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/handlers/Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. \ No newline at end of file +For more info about the release of the closed beta, refer to this documentInstalling Beaconhttps://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/Sun, 07 Apr 2024 16:04:48 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.Quick Start Sheet Templatehttps://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/Sun, 07 Apr 2024 16:13:18 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/Prerequisites To set this sheet up properly, make sure that you have the following tools installed: +Vue.js Vite SCSS To download the community quick start sheet, refer to these repositories:Example Patterns Sheethttps://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/Thu, 07 Mar 2024 16:13:18 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/Prerequisites To set this sheet up properly, make sure that you have the following: +Vue framework &amp; Routing Multiple Data Stores Complex Roll Templates Rich Sheet Actions TypeScript Vite SCSS Ability to run Unit &amp; End-to-End Tests To download the community quick start sheet, refer to these repositories:Releasing a Sheethttps://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/Wed, 07 Feb 2024 16:13:18 +0200https://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/There are two ways you can publish a Beacon sheet. +You can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access.Example Posthttps://roll20.github.io/beacon-docs/blog/example-post/Thu, 07 Sep 2023 16:27:22 +0200https://roll20.github.io/beacon-docs/blog/example-post/You can use blog posts for announcing product updates and features.InitRelayhttps://roll20.github.io/beacon-docs/docs/components/initrelay/Fri, 07 Jun 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/initrelay/The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games.Actionshttps://roll20.github.io/beacon-docs/docs/components/actions/Tue, 07 May 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/actions/initRelay({ //...other methods actions: {}, }): Promise&lt;Dispatch&gt; Actions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters.Computedhttps://roll20.github.io/beacon-docs/docs/components/computed/Sun, 07 Apr 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/computed/Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.Handlershttps://roll20.github.io/beacon-docs/docs/components/handlers/Thu, 07 Mar 2024 16:12:37 +0200https://roll20.github.io/beacon-docs/docs/components/handlers/Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. \ No newline at end of file diff --git a/public/main.bdaa5498903a6087c6d7e8fac6133113e5fa6b01e7c78680535b430bf606cfeae8afc6aec4d97aef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css b/public/main.bdaa5498903a6087c6d7e8fac6133113e5fa6b01e7c78680535b430bf606cfeae8afc6aec4d97aef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css new file mode 100644 index 0000000..cb2a8fc --- /dev/null +++ b/public/main.bdaa5498903a6087c6d7e8fac6133113e5fa6b01e7c78680535b430bf606cfeae8afc6aec4d97aef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css @@ -0,0 +1 @@ +:root[data-bs-theme="light"],[data-bs-theme="light"] ::backdrop{--sl-color-white: hsl(224, 10%, 10%);--sl-color-gray-1: hsl(224, 14%, 16%);--sl-color-gray-2: hsl(224, 10%, 23%);--sl-color-gray-3: hsl(224, 7%, 36%);--sl-color-gray-4: hsl(224, 6%, 56%);--sl-color-gray-5: hsl(224, 6%, 77%);--sl-color-gray-6: hsl(224, 20%, 94%);--sl-color-gray-7: hsl(224, 19%, 97%);--sl-color-black: hsl(0, 0%, 100%)}:root,::backdrop{--sl-color-white: hsl(0, 0%, 100%);--sl-color-gray-1: hsl(224, 20%, 94%);--sl-color-gray-2: hsl(224, 6%, 77%);--sl-color-gray-3: hsl(224, 6%, 56%);--sl-color-gray-4: hsl(224, 7%, 36%);--sl-color-gray-5: hsl(224, 10%, 23%);--sl-color-gray-6: hsl(224, 14%, 16%);--sl-color-black: hsl(224, 10%, 10%);--sl-hue-orange: 41;--sl-color-orange-low: hsl(var(--sl-hue-orange), 39%, 22%);--sl-color-orange: hsl(var(--sl-hue-orange), 82%, 63%);--sl-color-orange-high: hsl(var(--sl-hue-orange), 82%, 87%);--sl-hue-green: 101;--sl-color-green-low: hsl(var(--sl-hue-green), 39%, 22%);--sl-color-green: hsl(var(--sl-hue-green), 82%, 63%);--sl-color-green-high: hsl(var(--sl-hue-green), 82%, 80%);--sl-hue-blue: 234;--sl-color-blue-low: hsl(var(--sl-hue-blue), 54%, 20%);--sl-color-blue: hsl(var(--sl-hue-blue), 100%, 60%);--sl-color-blue-high: hsl(var(--sl-hue-blue), 100%, 87%);--sl-hue-purple: 281;--sl-color-purple-low: hsl(var(--sl-hue-purple), 39%, 22%);--sl-color-purple: hsl(var(--sl-hue-purple), 82%, 63%);--sl-color-purple-high: hsl(var(--sl-hue-purple), 82%, 89%);--sl-hue-red: 339;--sl-color-red-low: hsl(var(--sl-hue-red), 39%, 22%);--sl-color-red: hsl(var(--sl-hue-red), 82%, 63%);--sl-color-red-high: hsl(var(--sl-hue-red), 82%, 87%);--sl-color-accent-low: hsl(224, 54%, 20%);--sl-color-accent: hsl(224, 100%, 60%);--sl-color-accent-high: hsl(224, 100%, 85%);--sl-color-text: var(--sl-color-gray-2);--sl-color-text-accent: var(--sl-color-accent-high);--sl-color-text-invert: var(--sl-color-accent-low);--sl-color-bg: var(--sl-color-black);--sl-color-bg-nav: var(--sl-color-gray-6);--sl-color-bg-sidebar: var(--sl-color-gray-6);--sl-color-bg-inline-code: var(--sl-color-gray-5);--sl-color-hairline-light: var(--sl-color-gray-5);--sl-color-hairline: var(--sl-color-gray-6);--sl-color-hairline-shade: var(--sl-color-black);--sl-color-backdrop-overlay: hsla(223, 13%, 10%, 0.66);--sl-shadow-sm: 0px 1px 1px hsla(0, 0%, 0%, 0.12), 0px 2px 1px hsla(0, 0%, 0%, 0.24);--sl-shadow-md: 0px 8px 4px hsla(0, 0%, 0%, 0.08), 0px 5px 2px hsla(0, 0%, 0%, 0.08), 0px 3px 2px hsla(0, 0%, 0%, 0.12), 0px 1px 1px hsla(0, 0%, 0%, 0.15);--sl-shadow-lg: 0px 25px 7px hsla(0, 0%, 0%, 0.03), 0px 16px 6px hsla(0, 0%, 0%, 0.1), 0px 9px 5px hsla(223, 13%, 10%, 0.33), 0px 4px 4px hsla(0, 0%, 0%, 0.75), 0px 4px 2px hsla(0, 0%, 0%, 0.25);--sl-text-xs: 0.8125rem;--sl-text-sm: 0.875rem;--sl-text-base: 1rem;--sl-text-lg: 1.125rem;--sl-text-xl: 1.25rem;--sl-text-2xl: 1.5rem;--sl-text-3xl: 1.8125rem;--sl-text-4xl: 2.1875rem;--sl-text-5xl: 2.625rem;--sl-text-6xl: 4rem;--sl-text-body: var(--sl-text-base);--sl-text-body-sm: var(--sl-text-xs);--sl-text-code: var(--sl-text-sm);--sl-text-code-sm: var(--sl-text-xs);--sl-text-h1: var(--sl-text-4xl);--sl-text-h2: var(--sl-text-3xl);--sl-text-h3: var(--sl-text-2xl);--sl-text-h4: var(--sl-text-xl);--sl-text-h5: var(--sl-text-lg);--sl-line-height: 1.8;--sl-line-height-headings: 1.2;--sl-font-system: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--sl-font-system-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--__sl-font: var(--sl-font, ""), var(--sl-font-system);--__sl-font-mono: var(--sl-font-mono, ""), var(--sl-font-system-mono);--sl-nav-height: 3.5rem;--sl-nav-pad-x: 1rem;--sl-nav-pad-y: 0.75rem;--sl-mobile-toc-height: 3rem;--sl-sidebar-width: 18.75rem;--sl-sidebar-pad-x: 1rem;--sl-content-width: 45rem;--sl-content-pad-x: 1rem;--sl-menu-button-size: 2rem;--sl-nav-gap: var(--sl-content-pad-x);--sl-outline-offset-inside: -0.1875rem;--sl-z-index-toc: 4;--sl-z-index-menu: 5;--sl-z-index-navbar: 10;--sl-z-index-skiplink: 20}:root{--purple-hsl: 255, 60%, 60%;--overlay-blurple: hsla(var(--purple-hsl), 0.2)}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0.75rem;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}:root,[data-bs-theme="light"]{--bs-blue: #3347ff;--bs-indigo: #6610f2;--bs-purple: #bd53ee;--bs-pink: #d63384;--bs-red: #ee5389;--bs-orange: #fd7e14;--bs-yellow: #eebd53;--bs-green: #84ee53;--bs-teal: #20c997;--bs-cyan: #0dcaf0;--bs-black: #000;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #5d2f86;--bs-secondary: #6c757d;--bs-success: #84ee53;--bs-info: #3347ff;--bs-warning: #eebd53;--bs-danger: #ee5389;--bs-light: #f8f9fa;--bs-dark: #212529;--bs-primary-rgb: 93,47,134;--bs-secondary-rgb: 108,117,125;--bs-success-rgb: 132.2821,238.017,83.283;--bs-info-rgb: 51,71.4,255;--bs-warning-rgb: 238.017,189.0179,83.283;--bs-danger-rgb: 238.017,83.283,137.4399;--bs-light-rgb: 248,249,250;--bs-dark-rgb: 33,37,41;--bs-primary-text-emphasis: #251336;--bs-secondary-text-emphasis: #2b2f32;--bs-success-text-emphasis: #355f21;--bs-info-text-emphasis: #141d66;--bs-warning-text-emphasis: #5f4c21;--bs-danger-text-emphasis: #5f2137;--bs-light-text-emphasis: #495057;--bs-dark-text-emphasis: #495057;--bs-primary-bg-subtle: #dfd5e7;--bs-secondary-bg-subtle: #e2e3e5;--bs-success-bg-subtle: #e6fcdd;--bs-info-bg-subtle: #d6daff;--bs-warning-bg-subtle: #fcf2dd;--bs-danger-bg-subtle: #fcdde7;--bs-light-bg-subtle: #fcfcfd;--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: #beaccf;--bs-secondary-border-subtle: #c4c8cb;--bs-success-border-subtle: #cef8ba;--bs-info-border-subtle: #adb6ff;--bs-warning-border-subtle: #f8e5ba;--bs-danger-border-subtle: #f8bad0;--bs-light-border-subtle: #e9ecef;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-font-sans-serif: "Jost", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #1d2d35;--bs-body-color-rgb: 29,45,53;--bs-body-bg: #fff;--bs-body-bg-rgb: 255,255,255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0,0,0;--bs-secondary-color: rgba(29,45,53,0.75);--bs-secondary-color-rgb: 29,45,53;--bs-secondary-bg: #e9ecef;--bs-secondary-bg-rgb: 233,236,239;--bs-tertiary-color: rgba(29,45,53,0.5);--bs-tertiary-color-rgb: 29,45,53;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248,249,250;--bs-heading-color: inherit;--bs-link-color: #5d2f86;--bs-link-color-rgb: 93,47,134;--bs-link-decoration: none;--bs-link-hover-color: #4a266b;--bs-link-hover-color-rgb: 74,38,107;--bs-link-hover-decoration: underline;--bs-code-color: #d63384;--bs-highlight-color: #1d2d35;--bs-highlight-bg: #fcf2dd;--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0,0,0,0.175);--bs-border-radius: .375rem;--bs-border-radius-sm: .25rem;--bs-border-radius-lg: .5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0,0,0,0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0,0,0,0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0,0,0,0.075);--bs-focus-ring-width: .25rem;--bs-focus-ring-opacity: .25;--bs-focus-ring-color: rgba(93,47,134,0.25);--bs-form-valid-color: #84ee53;--bs-form-valid-border-color: #84ee53;--bs-form-invalid-color: #ee5389;--bs-form-invalid-border-color: #ee5389}[data-bs-theme="dark"]{color-scheme:dark;--bs-body-color: #c1c3c8;--bs-body-color-rgb: 192.831,194.7078,199.869;--bs-body-bg: #17181c;--bs-body-bg-rgb: 22.95,24.31,28.05;--bs-emphasis-color: #fff;--bs-emphasis-color-rgb: 255,255,255;--bs-secondary-color: rgba(193,195,200,0.75);--bs-secondary-color-rgb: 192.831,194.7078,199.869;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52,58,64;--bs-tertiary-color: rgba(193,195,200,0.5);--bs-tertiary-color-rgb: 192.831,194.7078,199.869;--bs-tertiary-bg: #2b3035;--bs-tertiary-bg-rgb: 43,48,53;--bs-primary-text-emphasis: #9e82b6;--bs-secondary-text-emphasis: #a7acb1;--bs-success-text-emphasis: #b5f598;--bs-info-text-emphasis: #8591ff;--bs-warning-text-emphasis: #f5d798;--bs-danger-text-emphasis: #f598b8;--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: #13091b;--bs-secondary-bg-subtle: #161719;--bs-success-bg-subtle: #1a3011;--bs-info-bg-subtle: #0a0e33;--bs-warning-bg-subtle: #302611;--bs-danger-bg-subtle: #30111b;--bs-light-bg-subtle: #23262f;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: #381c50;--bs-secondary-border-subtle: #41464b;--bs-success-border-subtle: #4f8f32;--bs-info-border-subtle: #1f2b99;--bs-warning-border-subtle: #8f7132;--bs-danger-border-subtle: #8f3252;--bs-light-border-subtle: #353841;--bs-dark-border-subtle: #343a40;--bs-heading-color: #fff;--bs-link-color: #b3c7ff;--bs-link-hover-color: #c2d2ff;--bs-link-color-rgb: 178.5,198.9,255;--bs-link-hover-color-rgb: 194,210,255;--bs-code-color: #e685b5;--bs-highlight-color: #c1c3c8;--bs-highlight-bg: #5f4c21;--bs-border-color: #495057;--bs-border-color-translucent: rgba(255,255,255,0.15);--bs-form-valid-color: #b5f598;--bs-form-valid-border-color: #b5f598;--bs-form-invalid-color: #f598b8;--bs-form-invalid-border-color: #f598b8}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:700;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width: 1200px){h1,.h1{font-size:2.5rem}}h2,.h2{font-size:calc(1.325rem + .9vw)}@media (min-width: 1200px){h2,.h2{font-size:2rem}}h3,.h3{font-size:calc(1.3rem + .6vw)}@media (min-width: 1200px){h3,.h3{font-size:1.75rem}}h4,.h4{font-size:calc(1.275rem + .3vw)}@media (min-width: 1200px){h4,.h4{font-size:1.5rem}}h5,.h5{font-size:1.25rem}p{margin-top:0;margin-bottom:1rem}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}strong{font-weight:bolder}small,.small{font-size:.875em}mark,.mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:none}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb);text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator{display:none !important}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}summary{display:list-item;cursor:pointer}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:400}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.img-fluid{max-width:100%;height:auto}.figure{display:inline-block}.container,.container-fluid,.container-lg{--bs-gutter-x: 3rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container-lg,.container{max-width:960px}}@media (min-width: 1200px){.container-lg,.container{max-width:1240px}}@media (min-width: 1400px){.container-lg,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.row{--bs-gutter-x: 3rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width: 768px){.col-md-12{flex:0 0 auto;width:75%}}@media (min-width: 992px){.col-lg-5{flex:0 0 auto;width:31.25%}.col-lg-8{flex:0 0 auto;width:50%}.col-lg-9{flex:0 0 auto;width:56.25%}.col-lg-10{flex:0 0 auto;width:62.5%}.col-lg-11{flex:0 0 auto;width:68.75%}.col-lg-12{flex:0 0 auto;width:75%}}@media (min-width: 1200px){.col-xl-3{flex:0 0 auto;width:18.75%}.col-xl-4{flex:0 0 auto;width:25%}.col-xl-8{flex:0 0 auto;width:50%}.col-xl-9{flex:0 0 auto;width:56.25%}}.sticky-top{position:sticky;top:0;z-index:1020}.visually-hidden{width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}li input[type="checkbox"]{--bs-form-check-bg: var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;print-color-adjust:exact}li input[type="checkbox"]{border-radius:.25em}li input[type="radio"][type="checkbox"]{border-radius:50%}li input[type="checkbox"]:active{filter:brightness(90%)}li input[type="checkbox"]:focus{border-color:#ae97c3;outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}li input:checked[type="checkbox"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}li input[type="checkbox"]:checked[type="radio"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}li input[type="checkbox"]:indeterminate{background-color:#5d2f86;border-color:#5d2f86;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:.5}.btn{--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 0 rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);text-decoration:none;background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #5d2f86;--bs-btn-border-color: #5d2f86;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #4f2872;--bs-btn-hover-border-color: #4a266b;--bs-btn-focus-shadow-rgb: 117,78,152;--bs-btn-active-color: #fff;--bs-btn-active-bg: #4a266b;--bs-btn-active-border-color: #462365;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #5d2f86;--bs-btn-disabled-border-color: #5d2f86}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: var(--bs-link-color);--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: var(--bs-link-hover-color);--bs-btn-hover-border-color: transparent;--bs-btn-active-color: var(--bs-link-hover-color);--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 117,78,152;text-decoration:none}.btn-link:hover,.btn-link:focus-visible{text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.nav{--bs-nav-link-padding-x: 1rem;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-link-color);--bs-nav-link-hover-color: var(--bs-link-hover-color);--bs-nav-link-disabled-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);background:none;border:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color);text-decoration:none}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: .5rem;--bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y: .3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x: .5rem;--bs-navbar-toggler-padding-y: .25rem;--bs-navbar-toggler-padding-x: .75rem;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2829,45,53,0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius: var(--bs-border-radius);--bs-navbar-toggler-focus-width: 0;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color);text-decoration:none}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:transparent !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar[data-bs-theme="dark"]{--bs-navbar-color: #c1c3c8;--bs-navbar-hover-color: #b3c7ff;--bs-navbar-disabled-color: rgba(255,255,255,0.25);--bs-navbar-active-color: #b3c7ff;--bs-navbar-brand-color: #b3c7ff;--bs-navbar-brand-hover-color: #b3c7ff;--bs-navbar-toggler-border-color: rgba(255,255,255,0.1);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23c1c3c8' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: .5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: var(--bs-border-width);--bs-card-border-color: #e9ecef;--bs-card-border-radius: var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y: .5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: var(--bs-body-bg);--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 1.5rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-text:last-child{margin-bottom:0}.breadcrumb{--bs-breadcrumb-padding-x: 0;--bs-breadcrumb-padding-y: 0;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color: var(--bs-secondary-color);--bs-breadcrumb-item-padding-x: .5rem;--bs-breadcrumb-item-active-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);text-decoration:none;background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: .5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.offcanvas{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 332px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: var(--bs-body-color);--bs-offcanvas-bg: var(--bs-body-bg);--bs-offcanvas-border-width: var(--bs-border-width);--bs-offcanvas-border-color: var(--bs-border-color-translucent);--bs-offcanvas-box-shadow: var(--bs-box-shadow-sm);--bs-offcanvas-transition: transform .3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.position-relative{position:relative !important}.w-100{width:100% !important}.h-auto{height:auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-grow-1{flex-grow:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.order-3{order:3 !important}.m-2{margin:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.mt-1{margin-top:.25rem !important}.mt-4{margin-top:1.5rem !important}.me-2{margin-right:.5rem !important}.me-auto{margin-right:auto !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.ms-2{margin-left:.5rem !important}.ms-auto{margin-left:auto !important}.mt-n3{margin-top:-1rem !important}.p-0{padding:0 !important}.p-2{padding:.5rem !important}.pt-4{padding-top:1.5rem !important}.pe-4{padding-right:1.5rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.ps-3{padding-left:1rem !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-nowrap{white-space:nowrap !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.rounded-circle{border-radius:50% !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}}@media (min-width: 992px){.d-lg-block{display:block !important}.d-lg-none{display:none !important}.flex-lg-row{flex-direction:row !important}.order-lg-4{order:4 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-3{margin-right:1rem !important}.ms-lg-2{margin-left:.5rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}}@media (min-width: 1200px){.d-xl-block{display:block !important}.d-xl-none{display:none !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}}@font-face{font-family:Jost;font-style:normal;font-weight:400;font-display:swap;src:local("Jost Regular Regular"),local("Jost-Regular"),local("Jost* Book"),local("Jost-Book"),url("fonts/vendor/jost/jost-v4-latin-regular.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-regular.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:500;font-display:swap;src:local("Jost Regular Medium"),local("JostRoman-Medium"),local("Jost* Medium"),local("Jost-Medium"),url("fonts/vendor/jost/jost-v4-latin-500.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:700;font-display:swap;src:local("Jost Regular Bold"),local("JostRoman-Bold"),local("Jost* Bold"),local("Jost-Bold"),url("fonts/vendor/jost/jost-v4-latin-700.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:400;font-display:swap;src:local("Jost Italic Italic"),local("Jost-Italic"),local("Jost* BookItalic"),local("Jost-BookItalic"),url("fonts/vendor/jost/jost-v4-latin-italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:500;font-display:swap;src:local("Jost Italic Medium Italic"),local("JostItalic-Medium"),local("Jost* Medium Italic"),local("Jost-MediumItalic"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:700;font-display:swap;src:local("Jost Italic Bold Italic"),local("JostItalic-Bold"),local("Jost* Bold Italic"),local("Jost-BoldItalic"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff") format("woff")}html[data-bs-theme="dark"] .icon-tabler-sun{display:block}html[data-bs-theme="dark"] .icon-tabler-moon{display:none}html[data-bs-theme="light"] .icon-tabler-sun{display:none}html[data-bs-theme="light"] .icon-tabler-moon{display:block}.privacy .content,.contributors .content,.blog .content,.error404 .content,.docs.list .content,.categories.list .content,.tags.list .content,.list.section .content{padding-top:1rem;padding-bottom:3rem}.content img{max-width:100%}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:2rem;margin-bottom:1rem}@media (min-width: 768px){body{font-size:1.125rem}h1,h2,h3,h4,h5,.h1,.h2,.h3,.h4,.h5{margin-bottom:1.125rem}}.home h1,.home .h1{font-size:calc(1.875rem + 1.5vw);margin-top:-1rem}a:hover,a:focus{text-decoration:underline}a.btn:hover,a.btn:focus{text-decoration:none}.section{padding-top:5rem;padding-bottom:5rem}body.section{padding-top:0;padding-bottom:0}.section-md{padding-top:3rem;padding-bottom:3rem}.docs-sidebar{order:2}@media (min-width: 992px){.docs-sidebar{order:0;border-right:1px solid #e9ecef}@supports (position: sticky){.docs-sidebar{position:sticky;top:4.25rem;z-index:1000;height:calc(100vh - 4.25rem)}}}@media (min-width: 1200px){.docs-sidebar{flex:0 1 320px}}.docs-links{padding-bottom:5rem}@media (min-width: 992px){@supports (position: sticky){.docs-links{max-height:calc(100vh - 4rem);overflow-y:scroll}}}@media (min-width: 992px){.docs-links{display:block;width:auto;margin-right:-1.5rem;padding-bottom:4rem}}.docs-toc{order:2}@supports (position: sticky){.docs-toc{position:sticky;top:4.25rem;height:calc(100vh - 4.25rem);overflow-y:auto}}.docs-content{padding-bottom:3rem;order:1}.navbar a:hover,.navbar a:focus{text-decoration:none}#TableOfContents ul,#toc ul{padding-left:0;list-style:none}#toc a.active{color:#5d2f86;font-weight:500}.section-features{padding-top:2rem}.bg-dots{background-image:radial-gradient(#dee2e6 15%, transparent 15%);background-position:0 0;background-size:1rem 1rem;-webkit-mask:linear-gradient(to top, #fff, transparent);mask:linear-gradient(to top, #fff, transparent);width:100%;height:11rem;margin-top:-10rem;z-index:-1}.modal-backdrop{background-color:#fff}.modal-backdrop.show{opacity:0.7}@media (min-width: 768px){.modal-backdrop.show{opacity:0}}li input[type="checkbox"]{margin:0.25rem;border:1px solid #ced4da}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:1}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}[data-bs-theme="dark"] li input[type="checkbox"]{border:1px solid #6c757d}[data-bs-theme="dark"] li input[type="checkbox"]:checked{background-color:#b3c7ff;border-color:#b3c7ff;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%231d2d35' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.content .svg-inline{margin-bottom:1.5rem}.content .svg-inline:not(.svg-inline-custom){height:1.875rem;width:1.875rem;stroke-width:1.5}.card-nav{-moz-column-gap:1rem;column-gap:1rem}.card-nav .card{margin:0.5rem 0}.card-nav .card:hover{border:1px solid #d9d9d9;background-color:var(--sl-color-gray-7)}[data-bs-theme="dark"] .card-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .card-nav .card:hover{border:1px solid #888c96;background-color:var(--sl-color-gray-6)}.highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.bg{background-color:var(--sl-color-gray-7)}.chroma{background-color:var(--sl-color-gray-7)}.chroma .err{color:inherit}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{background-color:#0000001a}.chroma .hl{border-inline-start:0.15rem solid #00000055;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .line{display:flex}.chroma .k{color:#000000;font-weight:bold}.chroma .kc{color:#000000;font-weight:bold}.chroma .kd{color:#000000;font-weight:bold}.chroma .kn{color:#000000;font-weight:bold}.chroma .kp{color:#000000;font-weight:bold}.chroma .kr{color:#000000;font-weight:bold}.chroma .kt{color:#445588;font-weight:bold}.chroma .na{color:#008080}.chroma .nb{color:#0086b3}.chroma .bp{color:#999999}.chroma .nc{color:#445588;font-weight:bold}.chroma .no{color:#008080}.chroma .nd{color:#3c5d5d;font-weight:bold}.chroma .ni{color:#800080}.chroma .ne{color:#990000;font-weight:bold}.chroma .nf{color:#990000;font-weight:bold}.chroma .nl{color:#990000;font-weight:bold}.chroma .nn{color:#555555}.chroma .nt{color:#000080}.chroma .nv{color:#008080}.chroma .vc{color:#008080}.chroma .vg{color:#008080}.chroma .vi{color:#008080}.chroma .s{color:#dd1144}.chroma .sa{color:#dd1144}.chroma .sb{color:#dd1144}.chroma .sc{color:#dd1144}.chroma .dl{color:#dd1144}.chroma .sd{color:#dd1144}.chroma .s2{color:#dd1144}.chroma .se{color:#dd1144}.chroma .sh{color:#dd1144}.chroma .si{color:#dd1144}.chroma .sx{color:#dd1144}.chroma .sr{color:#009926}.chroma .s1{color:#dd1144}.chroma .ss{color:#990073}.chroma .m{color:#009999}.chroma .mb{color:#009999}.chroma .mf{color:#009999}.chroma .mh{color:#009999}.chroma .mi{color:#009999}.chroma .il{color:#009999}.chroma .mo{color:#009999}.chroma .o{color:#000000;font-weight:bold}.chroma .ow{color:#000000;font-weight:bold}.chroma .c{color:#999988;font-style:italic}.chroma .ch{color:#999988;font-style:italic}.chroma .cm{color:#999988;font-style:italic}.chroma .c1{color:#999988;font-style:italic}.chroma .cs{color:#999999;font-weight:bold;font-style:italic}.chroma .cp{color:#999999;font-weight:bold;font-style:italic}.chroma .cpf{color:#999999;font-weight:bold;font-style:italic}.chroma .gd{color:#000000;background-color:#ffdddd}.chroma .ge{color:inherit;font-style:italic}.chroma .gr{color:#aa0000}.chroma .gh{color:#999999}.chroma .gi{color:#000000;background-color:#ddffdd}.chroma .go{color:#888888}.chroma .gp{color:#555555}.chroma .gs{font-weight:bold}.chroma .gu{color:#aaaaaa}.chroma .gt{color:#aa0000}.chroma .gl{text-decoration:underline}.chroma .w{color:#bbbbbb}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .bg{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma .err{color:inherit}[data-bs-theme="dark"] .chroma .lnlinks{outline:none;text-decoration:none;color:inherit}[data-bs-theme="dark"] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .hl{background-color:#ffffff17}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}[data-bs-theme="dark"] .chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#64686c}[data-bs-theme="dark"] .chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681}[data-bs-theme="dark"] .chroma .line{display:flex}[data-bs-theme="dark"] .chroma .k{color:#ff7b72}[data-bs-theme="dark"] .chroma .kc{color:#79c0ff}[data-bs-theme="dark"] .chroma .kd{color:#ff7b72}[data-bs-theme="dark"] .chroma .kn{color:#ff7b72}[data-bs-theme="dark"] .chroma .kp{color:#79c0ff}[data-bs-theme="dark"] .chroma .kr{color:#ff7b72}[data-bs-theme="dark"] .chroma .kt{color:#ff7b72}[data-bs-theme="dark"] .chroma .na{color:#d2a8ff}[data-bs-theme="dark"] .chroma .nc{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .no{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nd{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .ni{color:#ffa657}[data-bs-theme="dark"] .chroma .ne{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .nf{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nl{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nn{color:#ff7b72}[data-bs-theme="dark"] .chroma .py{color:#79c0ff}[data-bs-theme="dark"] .chroma .nt{color:#7ee787}[data-bs-theme="dark"] .chroma .nv{color:#79c0ff}[data-bs-theme="dark"] .chroma .l{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ld{color:#79c0ff}[data-bs-theme="dark"] .chroma .s{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sa{color:#79c0ff}[data-bs-theme="dark"] .chroma .sb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sc{color:#a5d6ff}[data-bs-theme="dark"] .chroma .dl{color:#79c0ff}[data-bs-theme="dark"] .chroma .sd{color:#a5d6ff}[data-bs-theme="dark"] .chroma .s2{color:#a5d6ff}[data-bs-theme="dark"] .chroma .se{color:#79c0ff}[data-bs-theme="dark"] .chroma .sh{color:#79c0ff}[data-bs-theme="dark"] .chroma .si{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sx{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sr{color:#79c0ff}[data-bs-theme="dark"] .chroma .s1{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ss{color:#a5d6ff}[data-bs-theme="dark"] .chroma .m{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mf{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mh{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mi{color:#a5d6ff}[data-bs-theme="dark"] .chroma .il{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mo{color:#a5d6ff}[data-bs-theme="dark"] .chroma .o{color:inherit;font-weight:bold}[data-bs-theme="dark"] .chroma .ow{color:#ff7b72;font-weight:bold}[data-bs-theme="dark"] .chroma .c{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .ch{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cm{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .c1{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cs{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cp{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cpf{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .gd{color:#ffa198;background-color:#490202}[data-bs-theme="dark"] .chroma .ge{font-style:italic}[data-bs-theme="dark"] .chroma .gr{color:#ffa198}[data-bs-theme="dark"] .chroma .gh{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .gi{color:#56d364;background-color:#0f5323}[data-bs-theme="dark"] .chroma .go{color:#8b949e}[data-bs-theme="dark"] .chroma .gp{color:#8b949e}[data-bs-theme="dark"] .chroma .gs{font-weight:bold}[data-bs-theme="dark"] .chroma .gu{color:#79c0ff}[data-bs-theme="dark"] .chroma .gt{color:#ff7b72}[data-bs-theme="dark"] .chroma .gl{text-decoration:underline}[data-bs-theme="dark"] .chroma .w{color:#6e7681}[data-bs-theme="dark"] h1,[data-bs-theme="dark"] .h1,[data-bs-theme="dark"] h2,[data-bs-theme="dark"] .h2,[data-bs-theme="dark"] h3,[data-bs-theme="dark"] .h3,[data-bs-theme="dark"] h4,[data-bs-theme="dark"] .h4{color:#fff}[data-bs-theme="dark"] body{background:#17181c;color:#c1c3c8}[data-bs-theme="dark"] a{color:#b3c7ff}[data-bs-theme="dark"] .callout a{color:inherit}[data-bs-theme="dark"] .btn-primary{--bs-btn-color: #000;--bs-btn-bg: #b3c7ff;--bs-btn-border-color: #b3c7ff;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #becfff;--bs-btn-hover-border-color: #bacdff;--bs-btn-focus-shadow-rgb: 152,169,217;--bs-btn-active-color: #000;--bs-btn-active-bg: #c2d2ff;--bs-btn-active-border-color: #bacdff;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #b3c7ff;--bs-btn-disabled-border-color: #b3c7ff;color:#17181c}[data-bs-theme="dark"] .navbar{background-color:rgba(23,24,28,0.95);border-bottom:1px solid #23262f}[data-bs-theme="dark"] body.home .navbar{border-bottom:0}[data-bs-theme="dark"] .offcanvas-header{border-bottom:1px solid #343a40}[data-bs-theme="dark"] .offcanvas .nav-link{color:#c1c3c8}[data-bs-theme="dark"] .offcanvas .nav-link:hover,[data-bs-theme="dark"] .offcanvas .nav-link:focus{color:#b3c7ff}[data-bs-theme="dark"] .offcanvas .nav-link.active{color:#b3c7ff}[data-bs-theme="dark"] .page-links a{color:#c1c3c8}[data-bs-theme="dark"] .page-links a:hover{text-decoration:none;color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link{color:#c1c3c8}[data-bs-theme="dark"] .content .btn-link{color:#b3c7ff}[data-bs-theme="dark"] .content .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:active{color:#b3c7ff}@media (min-width: 992px){[data-bs-theme="dark"] .docs-sidebar{order:0;border-right:1px solid #23262f}}[data-bs-theme="dark"] .footer{border-top:1px solid #23262f}[data-bs-theme="dark"] .docs-links,[data-bs-theme="dark"] .docs-toc{scrollbar-width:thin;scrollbar-color:#17181c #17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar{width:5px}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-track,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-track{background:#17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb{background:#17181c}[data-bs-theme="dark"] .docs-links:hover,[data-bs-theme="dark"] .docs-toc:hover{scrollbar-width:thin;scrollbar-color:#23262f #17181c}[data-bs-theme="dark"] .docs-links:hover::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc:hover::-webkit-scrollbar-thumb{background:#23262f}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb:hover,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb:hover{background:#23262f}[data-bs-theme="dark"] .docs-links h3:not(:first-child),[data-bs-theme="dark"] .docs-links .h3:not(:first-child){border-top:1px solid #23262f}[data-bs-theme="dark"] .page-links li:not(:first-child){border-top:1px dashed #23262f}[data-bs-theme="dark"] .card{background:#17181c;border:1px solid #23262f}[data-bs-theme="dark"] .bg-dots{background-image:radial-gradient(#414349 15%, transparent 15%)}[data-bs-theme="dark"] .text-muted{color:#adafb6 !important}[data-bs-theme="dark"] .offcanvas{background-color:#17181c}[data-bs-theme="dark"] .page-link{color:#b3c7ff;background-color:transparent;border:var(--bs-border-width) solid #23262f}[data-bs-theme="dark"] .page-link:hover{color:#17181c;background-color:#c1c3c8;border-color:#c1c3c8}[data-bs-theme="dark"] .page-link:focus{color:#17181c;background-color:#c1c3c8}[data-bs-theme="dark"] .page-item.active .page-link{color:#17181c;background-color:#b3c7ff;border-color:#b3c7ff}[data-bs-theme="dark"] .page-item.disabled .page-link{color:var(--bs-secondary-color);background-color:#23262f;border-color:#23262f}[data-bs-theme="dark"] details{border:1px solid #23262f}[data-bs-theme="dark"] summary:hover{background:#23262f}[data-bs-theme="dark"] details[open]>summary{border-bottom:1px solid #23262f}[data-bs-theme="dark"] details summary::after{content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e")}[data-bs-theme="dark"] #toc a.active{color:#b3c7ff}.navbar .btn-link{color:rgba(var(--bs-emphasis-color-rgb), 0.65);padding:0.4375rem 0}.btn-link:focus{outline:0;box-shadow:none}@media (min-width: 992px){.navbar .btn-link{padding:0.5625em 0.25rem 0.5rem 0.125rem}}.navbar .btn-link:hover{color:rgba(var(--bs-emphasis-color-rgb), 0.8)}.navbar .btn-link:active{color:rgba(var(--bs-emphasis-color-rgb), 1)}.clipboard{position:relative;float:right}.btn-clipboard{transition:opacity 0.25s ease-in-out;opacity:0;position:absolute;right:0.5rem;top:0.5rem;line-height:1;padding:0.3125rem 0.3125rem 0.1875rem;background-color:transparent;border-color:transparent}@media (max-width: 767.98px){.btn-clipboard{position:absolute;right:-0.5rem;top:0.5rem}}.btn-clipboard::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#495057}.btn-clipboard:hover{border-color:transparent}.btn-clipboard:hover::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}.btn-clipboard:focus,.btn-clipboard:active{border-color:transparent !important}.btn-clipboard:focus::after,.btn-clipboard:active::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}[data-bs-theme="dark"] .btn-clipboard{background-color:transparent;border-color:transparent}[data-bs-theme="dark"] .btn-clipboard::after{background-color:#ced4da}[data-bs-theme="dark"] .btn-clipboard:hover{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:hover::after{background-color:#e9ecef}[data-bs-theme="dark"] .btn-clipboard:focus,[data-bs-theme="dark"] .btn-clipboard:active{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:focus::after,[data-bs-theme="dark"] .btn-clipboard:active::after{background-color:#e9ecef}.highlight{position:relative}@media (min-width: 768px){.highlight:hover .btn-clipboard{opacity:1}}#toTop{opacity:0;transition:opacity 0.3s ease-in-out}.callout{--bs-link-color-rgb: var(--callout-link);--bs-code-color: var(--callout-code-color);color:var(--callout-color, inherit);background-color:var(--callout-bg, var(--bs-gray-100));border-left:0.25rem solid var(--callout-border, var(--bs-gray-300));border-radius:0}.callout a{text-decoration:underline}.callout .highlight{background-color:rgba(0,0,0,0.05)}.callout .callout-icon.svg-inline{flex-shrink:0;height:calc(1.5 * 1.125rem)}.callout .callout-title{font-weight:700}.callout-content{min-width:0}.callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-high)}.callout.callout-note .callout-icon,.callout.callout-note .callout-title,.callout.callout-note .callout-body a{color:var(--sl-color-blue-low)}.callout.callout-note .callout-body,.callout.callout-note .callout-body a:hover,.callout.callout-note .callout-body a:active{color:var(--sl-color-white)}.callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-high)}.callout.callout-tip .callout-icon,.callout.callout-tip .callout-title,.callout.callout-tip .callout-body a{color:var(--sl-color-purple-low)}.callout.callout-tip .callout-body,.callout.callout-tip .callout-body a:hover,.callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}.callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-high)}.callout.callout-caution .callout-icon,.callout.callout-caution .callout-title,.callout.callout-caution .callout-body a{color:var(--sl-color-orange-low)}.callout.callout-caution .callout-body,.callout.callout-caution .callout-body a:hover,.callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}.callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-high)}.callout.callout-danger .callout-icon,.callout.callout-danger .callout-title,.callout.callout-danger .callout-body a{color:var(--sl-color-red-low)}.callout.callout-danger .callout-body,.callout.callout-danger .callout-body a:hover,.callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout{color:var(--sl-color-gray-1)}[data-bs-theme="dark"] .callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-low)}[data-bs-theme="dark"] .callout.callout-note .callout-icon,[data-bs-theme="dark"] .callout.callout-note .callout-title,[data-bs-theme="dark"] .callout.callout-note .callout-body a{color:var(--sl-color-blue-high)}[data-bs-theme="dark"] .callout.callout-note .callout-body,[data-bs-theme="dark"] .callout.callout-note .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-note .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-note code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-low)}[data-bs-theme="dark"] .callout.callout-tip .callout-icon,[data-bs-theme="dark"] .callout.callout-tip .callout-title,[data-bs-theme="dark"] .callout.callout-tip .callout-body a{color:var(--sl-color-purple-high)}[data-bs-theme="dark"] .callout.callout-tip .callout-body,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-tip code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-low)}[data-bs-theme="dark"] .callout.callout-caution .callout-icon,[data-bs-theme="dark"] .callout.callout-caution .callout-title,[data-bs-theme="dark"] .callout.callout-caution .callout-body a{color:var(--sl-color-orange-high)}[data-bs-theme="dark"] .callout.callout-caution .callout-body,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-caution code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-low)}[data-bs-theme="dark"] .callout.callout-danger .callout-icon,[data-bs-theme="dark"] .callout.callout-danger .callout-title,[data-bs-theme="dark"] .callout.callout-danger .callout-body a{color:var(--sl-color-red-high)}[data-bs-theme="dark"] .callout.callout-danger .callout-body,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-danger code:not(:where(.not-content *)){color:var(--ec-codeFg)}.expressive-code{font-family:var(--ec-uiFontFml);font-size:var(--ec-uiFontSize);line-height:var(--ec-uiLineHt);-moz-text-size-adjust:none;text-size-adjust:none;-webkit-text-size-adjust:none;margin:1.5rem 0}.expressive-code *:not(path){all:revert;box-sizing:border-box}.expressive-code pre{display:flex;margin:0;padding:0;border:var(--ec-brdWd) solid var(--ec-brdCol);border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));background:var(--ec-codeBg)}.expressive-code pre:focus-visible{outline:3px solid var(--ec-focusBrd);outline-offset:-3px}.expressive-code pre>code{all:unset;display:block;flex:1 0 100%;padding:var(--ec-codePadBlk) 0;color:var(--ec-codeFg);font-family:var(--ec-codeFontFml);font-size:var(--ec-codeFontSize);line-height:var(--ec-codeLineHt)}.expressive-code pre{overflow-x:auto}.expressive-code pre::-webkit-scrollbar,.expressive-code pre::-webkit-scrollbar-track{background-color:inherit;border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));border-top-left-radius:0;border-top-right-radius:0}.expressive-code pre::-webkit-scrollbar-thumb{background-color:var(--ec-sbThumbCol);border:4px solid transparent;background-clip:content-box;border-radius:10px}.expressive-code pre::-webkit-scrollbar-thumb:hover{background-color:var(--ec-sbThumbHoverCol)}.expressive-code .ec-line{padding-inline:var(--ec-codePadInl);padding-inline-end:calc(2rem + var(--ec-codePadInl));direction:ltr;unicode-bidi:isolate}.expressive-code .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.expressive-code .ec-line.mark{--tmLineBgCol: var(--ec-tm-markBg);--tmLineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line.ins{--tmLineBgCol: var(--ec-tm-insBg);--tmLineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line.ins::before{content:var(--ec-tm-insDiffIndContent);color:var(--ec-tm-insDiffIndCol)}.expressive-code .ec-line.del{--tmLineBgCol: var(--ec-tm-delBg);--tmLineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line.del::before{content:var(--ec-tm-delDiffIndContent);color:var(--ec-tm-delDiffIndCol)}.expressive-code .ec-line.mark,.expressive-code .ec-line.ins,.expressive-code .ec-line.del{position:relative;background:var(--tmLineBgCol);min-width:calc(100% - var(--ec-tm-lineMarkerAccentMarg));margin-inline-start:var(--ec-tm-lineMarkerAccentMarg);border-inline-start:var(--ec-tm-lineMarkerAccentWd) solid var(--tmLineBrdCol);padding-inline-start:calc(var(--ec-codePadInl) - var(--ec-tm-lineMarkerAccentMarg) - var(--ec-tm-lineMarkerAccentWd)) !important}.expressive-code .ec-line.mark::before,.expressive-code .ec-line.ins::before,.expressive-code .ec-line.del::before{position:absolute;left:var(--ec-tm-lineDiffIndMargLeft)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark{--tmInlineBgCol: var(--ec-tm-markBg);--tmInlineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line ins{--tmInlineBgCol: var(--ec-tm-insBg);--tmInlineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line del{--tmInlineBgCol: var(--ec-tm-delBg);--tmInlineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark,.expressive-code .ec-line ins,.expressive-code .ec-line del{all:unset;display:inline-block;position:relative;--tmBrdL: var(--ec-tm-inlMarkerBrdWd);--tmBrdR: var(--ec-tm-inlMarkerBrdWd);--tmRadL: var(--ec-tm-inlMarkerBrdRad);--tmRadR: var(--ec-tm-inlMarkerBrdRad);margin-inline:0.025rem;padding-inline:var(--ec-tm-inlMarkerPad);border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);background:var(--tmInlineBgCol);background-clip:padding-box}.expressive-code .ec-line mark.open-start,.expressive-code .ec-line .open-start.mark,.expressive-code .ec-line ins.open-start,.expressive-code .ec-line del.open-start{margin-inline-start:0;padding-inline-start:0;--tmBrdL: 0px;--tmRadL: 0}.expressive-code .ec-line mark.open-end,.expressive-code .ec-line .open-end.mark,.expressive-code .ec-line ins.open-end,.expressive-code .ec-line del.open-end{margin-inline-end:0;padding-inline-end:0;--tmBrdR: 0px;--tmRadR: 0}.expressive-code .ec-line mark::before,.expressive-code .ec-line .mark::before,.expressive-code .ec-line ins::before,.expressive-code .ec-line del::before{content:"";position:absolute;pointer-events:none;display:inline-block;inset:0;border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);border:var(--ec-tm-inlMarkerBrdWd) solid var(--tmInlineBrdCol);border-inline-width:var(--tmBrdL) var(--tmBrdR)}.expressive-code .frame{all:unset;position:relative;display:block;--header-border-radius: calc(var(--ec-brdRad) + var(--ec-brdWd));--tab-border-radius: calc(var(--ec-frm-edTabBrdRad) + var(--ec-brdWd));--button-spacing: 0.4rem;--code-background: var(--ec-frm-edBg);border-radius:var(--header-border-radius);box-shadow:var(--ec-frm-frameBoxShdCssVal)}.expressive-code .frame .header{display:none;z-index:1;position:relative;border-radius:var(--header-border-radius) var(--header-border-radius) 0 0}.expressive-code .frame.has-title pre,.expressive-code .frame.has-title code,.expressive-code .frame.is-terminal pre,.expressive-code .frame.is-terminal code{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.expressive-code .frame .title:empty:before{content:"\a0"}.expressive-code .frame.has-title:not(.is-terminal){--button-spacing: calc(1.9rem + 2 * (var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)))}.expressive-code .frame.has-title:not(.is-terminal) .title{position:relative;color:var(--ec-frm-edActTabFg);background:var(--ec-frm-edActTabBg);background-clip:padding-box;margin-block-start:var(--ec-frm-edTabsMargBlkStart);padding:calc(var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)) var(--ec-uiPadInl);border:var(--ec-brdWd) solid var(--ec-frm-edActTabBrdCol);border-radius:var(--tab-border-radius) var(--tab-border-radius) 0 0;border-bottom:none;overflow:hidden}.expressive-code .frame.has-title:not(.is-terminal) .title::after{content:"";position:absolute;pointer-events:none;inset:0;border-top:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndTopCol);border-bottom:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndBtmCol)}.expressive-code .frame.has-title:not(.is-terminal) .header{display:flex;background:linear-gradient(to top, var(--ec-frm-edTabBarBrdBtmCol) var(--ec-brdWd), transparent var(--ec-brdWd)),linear-gradient(var(--ec-frm-edTabBarBg), var(--ec-frm-edTabBarBg));background-repeat:no-repeat;padding-inline-start:var(--ec-frm-edTabsMargInlStart)}.expressive-code .frame.has-title:not(.is-terminal) .header::before{content:"";position:absolute;pointer-events:none;inset:0;border:var(--ec-brdWd) solid var(--ec-frm-edTabBarBrdCol);border-radius:inherit;border-bottom:none}.expressive-code .frame.is-terminal{--button-spacing: calc(1.9rem + var(--ec-brdWd) + 2 * var(--ec-uiPadBlk));--code-background: var(--ec-frm-trmBg)}.expressive-code .frame.is-terminal .header{display:flex;align-items:center;justify-content:center;padding-block:var(--ec-uiPadBlk);padding-block-end:calc(var(--ec-uiPadBlk) + var(--ec-brdWd));position:relative;font-weight:500;letter-spacing:0.025ch;color:var(--ec-frm-trmTtbFg);background:var(--ec-frm-trmTtbBg);border:var(--ec-brdWd) solid var(--ec-brdCol);border-bottom:none}.expressive-code .frame.is-terminal .header::before{content:"";position:absolute;pointer-events:none;left:var(--ec-uiPadInl);width:2.1rem;height:0.56rem;line-height:0;background-color:var(--ec-frm-trmTtbDotsFg);opacity:var(--ec-frm-trmTtbDotsOpa);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");mask-repeat:no-repeat}.expressive-code .frame.is-terminal .header::after{content:"";position:absolute;pointer-events:none;inset:0;border-bottom:var(--ec-brdWd) solid var(--ec-frm-trmTtbBrdBtmCol)}.expressive-code .frame pre{background:var(--code-background)}.expressive-code .copy{display:flex;gap:0.25rem;flex-direction:row;position:absolute;inset-block-start:calc(var(--ec-brdWd) + var(--button-spacing));inset-inline-end:calc(var(--ec-brdWd) + var(--ec-uiPadInl) / 2);direction:ltr;unicode-bidi:isolate}.expressive-code .copy button{position:relative;align-self:flex-end;margin:0;padding:0;border:none;border-radius:0.2rem;z-index:1;cursor:pointer;transition-property:opacity, background, border-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.25, 0.46, 0.45, 0.94);width:2.5rem;height:2.5rem;background:var(--code-background);opacity:0.75}.expressive-code .copy button div{position:absolute;inset:0;border-radius:inherit;background:var(--ec-frm-inlBtnBg);opacity:var(--ec-frm-inlBtnBgIdleOpa);transition-property:inherit;transition-duration:inherit;transition-timing-function:inherit}.expressive-code .copy button::before{content:"";position:absolute;pointer-events:none;inset:0;border-radius:inherit;border:var(--ec-brdWd) solid var(--ec-frm-inlBtnBrd);opacity:var(--ec-frm-inlBtnBrdOpa)}.expressive-code .copy button::after{content:"";position:absolute;pointer-events:none;inset:0;background-color:var(--ec-frm-inlBtnFg);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");mask-repeat:no-repeat;margin:0.475rem;line-height:0}.expressive-code .copy button:focus::after,.expressive-code .copy button:active::after{display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;margin:0.2375rem}.expressive-code .copy button:hover,.expressive-code .copy button:focus:focus-visible{opacity:1}.expressive-code .copy button:hover div,.expressive-code .copy button:focus:focus-visible div{opacity:var(--ec-frm-inlBtnBgHoverOrFocusOpa)}.expressive-code .copy button:active{opacity:1}.expressive-code .copy button:active div{opacity:var(--ec-frm-inlBtnBgActOpa)}.expressive-code .copy .feedback{--tooltip-arrow-size: 0.35rem;--tooltip-bg: var(--ec-frm-tooltipSuccessBg);color:var(--ec-frm-tooltipSuccessFg);pointer-events:none;-moz-user-select:none;user-select:none;-webkit-user-select:none;position:relative;align-self:center;background-color:var(--tooltip-bg);z-index:99;padding:0.125rem 0.75rem;border-radius:0.2rem;margin-inline-end:var(--tooltip-arrow-size);opacity:0;transition-property:opacity, transform;transition-duration:0.2s;transition-timing-function:ease-in-out;transform:translate3d(0, 0.25rem, 0)}.expressive-code .copy .feedback::after{content:"";position:absolute;pointer-events:none;top:calc(50% - var(--tooltip-arrow-size));inset-inline-end:calc(-2 * (var(--tooltip-arrow-size) - 0.5px));border:var(--tooltip-arrow-size) solid transparent;border-inline-start-color:var(--tooltip-bg)}.expressive-code .copy .feedback.show{opacity:1;transform:translate3d(0, 0, 0)}@media (hover: hover){.expressive-code .copy button{opacity:0;width:2rem;height:2rem}.expressive-code .frame:hover .copy button:not(:hover),.expressive-code .frame:focus-within :focus-visible~.copy button:not(:hover),.expressive-code .frame .copy .feedback.show~button:not(:hover){opacity:0.75}}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}.expressive-code .ec-line span[style^="--"]:not([class]){color:var(0, inherit);font-style:var(0fs, inherit);font-weight:var(0fw, inherit);-webkit-text-decoration:var(0td, inherit);text-decoration:var(0td, inherit)}@media (prefers-color-scheme: light){:root:not([data-bs-theme="dark"]){--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root:not([data-bs-theme="dark"]) .expressive-code .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}}:root[data-bs-theme="light"] .expressive-code,.expressive-code[data-bs-theme="light"]{--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root[data-bs-theme="light"] .expressive-code .ec-line span[style^="--"]:not([class]),.expressive-code[data-bs-theme="light"] .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875rem}code:not(:where(.not-content *)){background-color:var(--sl-color-gray-6);margin-block:-0.125rem;padding:0.125rem 0.375rem;color:inherit}[data-bs-theme="dark"] code:not(:where(.not-content *)){background-color:var(--sl-color-gray-5)}.math-block{display:block;margin:2rem 0;overflow-x:auto}.math-inline{display:inline}[data-bs-theme="dark"] .math-inline img,[data-bs-theme="dark"] .math-block img{filter:invert(1)}img.diagram{height:auto;width:100%;margin:1rem 0 2rem}img.diagram-kroki-mermaid{background:#fff}.highlight>pre{padding:0.875rem 1rem}.highlight div{padding:0}.highlight>.chroma{overflow-x:auto;border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.chroma .ln{padding:0 0.5rem 0 0}.chroma .hl{border-inline-start:0.15rem solid #0005;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.highlight .chroma .lntable .lnt,.highlight .chroma .lntable .hl{display:flex}.chroma .lntd:first-child{padding:0}.chroma .lntd:first-child .lnt{padding-left:1rem}.chroma .lntd:nth-child(2){padding:0}.highlight .chroma .lntable .lntd+.lntd{width:100%}[data-bs-theme="dark"] .chroma .ln{padding:0 0.5em 0 0}.chroma .lntd pre{padding:1rem 0;margin-bottom:0}.highlight>.chroma::-webkit-scrollbar,.highlight>.chroma::-webkit-scrollbar-track{background-color:inherit;border-radius:1px;border-top-left-radius:0;border-top-right-radius:0}.highlight>.chroma::-webkit-scrollbar-thumb{background-color:#dddee0;border:4px solid transparent;background-clip:content-box;border-radius:10px}.highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#9d9e9f}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb{background-color:#ffffff17}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#ffffff49}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}details{display:block;position:relative;border:1px solid #e9ecef;border-radius:0.25rem;padding:0.5rem 1rem 0;margin:0.5rem 0}summary{list-style:none;display:inline-block;width:calc(100% + 2rem);margin:-0.5rem -1rem 0;padding:0.5rem 1rem}summary::-webkit-details-marker{display:none}summary:hover{background:#f8f9fa}details summary::after{display:inline-block;content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");transition:transform 0.35s ease;transform-origin:center center;position:absolute;right:1rem}details[open]>summary::after{transform:rotate(90deg)}details[open]{padding:0.5rem 1rem}details[open]>summary{border-bottom:1px solid #dee2e6;margin-bottom:0.5rem}details h2,details .h2,details h3,details .h3,details h4,details .h4{margin:1rem 0 0.5rem}details p:last-child{margin-bottom:0}details ul,details ol{margin-bottom:0}details pre{margin:0 0 1rem}img{max-width:100%;height:auto}img[data-sizes="auto"]{display:block}img{font-size:0}figcaption{font-size:1rem;margin-top:0.5rem;font-style:italic}.blur-up{filter:blur(5px);transition:filter 400ms}.blur-up.lazyloaded{filter:unset}.section-nav{padding-top:2rem}.section-nav details{border:0;padding:0;margin:0.5rem 0}.section-nav details[open]{padding:0}.section-nav summary{width:100%;padding:0;margin:0;font-weight:700}.section-nav summary:hover{background:none}.section-nav details[open]>summary{border-bottom:0;margin-bottom:0}.section-nav ul.list-nested details{padding-left:1rem;margin-top:0.5rem}.section-nav ul.list-nested li{margin:0}.section-nav a{display:block;margin:0.5rem 0;color:#1d2d35;font-size:1rem;text-decoration:none}.section-nav a:hover,.section-nav a:active{color:#5d2f86}.section-nav li.active a{color:#5d2f86;font-weight:500}.section-nav ul.list-nested li a{padding-left:1rem}.section-nav ul.list-nested{border-left:1px solid #e9ecef}[data-bs-theme="dark"] .section-nav ul.list-nested{border-left:1px solid #23262f}[data-bs-theme="dark"] .section-nav a{color:#c1c3c8}[data-bs-theme="dark"] .section-nav a:hover,[data-bs-theme="dark"] .section-nav a:active{color:var(--sl-color-text-accent)}[data-bs-theme="dark"] .section-nav li.active a{color:var(--sl-color-text-accent);font-weight:500}[data-bs-theme="dark"] .section-nav summary{color:#fff}.footer{border-top:1px solid #e9ecef;padding-top:1.125rem;padding-bottom:1.125rem}.footer ul{margin-bottom:0}.footer li{font-size:.875rem;margin-bottom:0}.footer .list-inline-item:not(:last-child){margin-right:1rem}@media (max-width: 991.98px){.footer .col-lg-8{margin-top:0.25rem;margin-bottom:0.25rem}}@media (min-width: 768px){.footer li{font-size:1rem}}.fixed-bottom-right{position:fixed;right:0;bottom:0;z-index:1000}.navbar-brand{font-weight:700}.navbar-brand svg{margin-right:0.25rem}[data-bs-theme="dark"] .navbar-brand{color:inherit}.navbar{z-index:1000;background-color:rgba(255,255,255,0.95);border-bottom:1px solid #e9ecef}@media (min-width: 992px){.navbar{z-index:1025}}@media (min-width: 768px){.navbar-brand{font-size:1.375rem}}.nav-item{margin-left:0}@media (max-width: 991.98px){.navbar-nav .nav-link{font-weight:400}}@media (min-width: 768px){.nav-item{margin-left:0.5rem}}@media (max-width: 575.98px){.navbar .offcanvas.offcanvas-start,.navbar .offcanvas.offcanvas-end{width:80vw}}.offcanvas-header{border-bottom:1px solid #dee2e6;padding-top:1.0625rem;padding-bottom:0.8125rem}h5.offcanvas-title,.offcanvas-title.h5{margin:0;color:inherit}.offcanvas .nav-link{color:#1d2d35}.offcanvas .nav-link:hover,.offcanvas .nav-link:focus{color:#5d2f86}.offcanvas .nav-link.active{color:#5d2f86}.home .navbar{border-bottom:0}@media (min-width: 992px){.navbar-brand{margin-right:0.75rem !important}}.social-link{padding-right:0.375rem;padding-left:0.375rem}@media (max-width: 991.98px){#buttonColorMode{margin:0.5rem 0}#socialMenu{margin:0.5rem 0 0.5rem -0.25rem}.navbar-nav{margin-top:1rem}.nav-item .nav-link{font-weight:400;font-size:1.125rem}}.modal-backdrop,.offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}[data-bs-theme="dark"] .modal-backdrop,[data-bs-theme="dark"] .offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}.modal-backdrop.show,.offcanvas-backdrop.show{visibility:visible;opacity:1;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.showing,.hiding{transition:none;display:none}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{padding-right:0.75rem}.docs-content>h2[id]::before,.docs-content>[id].h2::before,.docs-content>h3[id]::before,.docs-content>[id].h3::before,.docs-content>h4[id]::before,.docs-content>[id].h4::before{display:block;height:6rem;margin-top:-6rem;content:""}.docs-content ul,.docs-content ol{margin-bottom:1rem}.anchor{visibility:hidden;margin-left:0.375rem}h1:hover a,.h1:hover a,h2:hover a,.h2:hover a,h3:hover a,.h3:hover a,h4:hover a,.h4:hover a{visibility:visible;text-decoration:none}.card-list{margin-top:2.25rem}.page-footer-meta{margin-top:2rem;margin-bottom:2rem}p.meta{margin-top:0.5rem;font-size:1rem}.breadcrumb{margin-top:2.25rem;font-size:1rem}.toc-mobile{margin-top:2rem;margin-bottom:2rem}.page-link:hover{text-decoration:none}ul li{margin:0.25rem 0}.page-nav .card .icon-tabler-arrow-left{margin-right:0.75rem}.page-nav .card .icon-tabler-arrow-right{margin-left:0.75rem}.page-nav .card:hover{border:1px solid #d9d9d9}[data-bs-theme="dark"] .page-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .page-nav .card:hover{border:1px solid #888c96}.home .card,.contributors.list .card,.blog.list .card,.blog.single .card,.categories.list .card,.tags.list .card{margin-top:2rem;margin-bottom:2rem;transition:transform 0.3s}.home .content .card:hover,.contributors.list .content .card:hover,.blog.list .content .card:hover,.blog.single .content .card:hover,.categories.list .content .card:hover,.tags.list .content .card:hover{transform:scale(1.025)}.home .content .card-body,.contributors.list .content .card-body,.blog.list .content .card-body,.blog.single .content .card-body,.categories.list .content .card-body,.tags.list .content .card-body{padding:0 2rem 1rem}.blog-header{text-align:center;margin-bottom:2rem}.page-item:first-child,.page-item:last-child,.page-item.disabled{display:none}.page-item a{margin-left:0.5rem;margin-right:0.5rem;padding-left:0.875rem;padding-right:0.875rem}span.reading-time{margin-left:2rem}span.reading-time svg{margin-right:0.3rem;vertical-align:-0.4rem}.docs-links,.docs-toc{scrollbar-width:thin;scrollbar-color:#fff #fff}.docs-links::-webkit-scrollbar,.docs-toc::-webkit-scrollbar{width:5px}.docs-links::-webkit-scrollbar-track,.docs-toc::-webkit-scrollbar-track{background:#fff}.docs-links::-webkit-scrollbar-thumb,.docs-toc::-webkit-scrollbar-thumb{background:#fff}.docs-links:hover,.docs-toc:hover{scrollbar-width:thin;scrollbar-color:#e9ecef #fff}.docs-links:hover::-webkit-scrollbar-thumb,.docs-toc:hover::-webkit-scrollbar-thumb{background:#e9ecef}.docs-links::-webkit-scrollbar-thumb:hover,.docs-toc::-webkit-scrollbar-thumb:hover{background:#e9ecef}.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{font-size:1.125rem;margin:1.25rem 0 0.5rem;padding:1.5rem 0 0}@media (min-width: 992px){.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{margin:1.125rem 1.5rem 0.75rem 0;padding:1.375rem 0 0}}.docs-links h3:not(:first-child),.docs-links .h3:not(:first-child){border-top:1px solid #e9ecef}.page-links li{margin-top:0.375rem;padding-top:0.375rem}.page-links li ul li{border-top:none;padding-left:1rem;margin-top:0.125rem;padding-top:0.125rem}.page-links li:not(:first-child){border-top:1px dashed #e9ecef}.page-links a{color:#1d2d35;display:block;padding:0.125rem 0;font-size:.9375rem;text-decoration:none}.page-links a:hover,.page-links a.active{text-decoration:none;color:#5d2f86}.nav-link.active{font-weight:500} diff --git a/public/privacy/index.html b/public/privacy/index.html index faf5ff7..c014afc 100644 --- a/public/privacy/index.html +++ b/public/privacy/index.html @@ -1 +1 @@ -Privacy Policy |

Privacy Policy

Last updated on September 7, 2023

\ No newline at end of file +Privacy Policy |

Privacy Policy

Last updated on September 7, 2023

\ No newline at end of file diff --git a/public/search-index.json b/public/search-index.json index 31a4769..535c3cb 100644 --- a/public/search-index.json +++ b/public/search-index.json @@ -1 +1 @@ -[{"content":"Well-thought-through product announcements will help increase feature awareness and engage users with new functionality. Just like sharing your public roadmap, it\u0026rsquo;s also a great way to let potential customers see that you\u0026rsquo;re constantly improving.\nFurther reading Read How to announce product updates and features ","date":"2023-09-07","id":0,"permalink":"/beacon-docs/blog/example-post/","summary":"You can use blog posts for announcing product updates and features.","tags":[],"title":"Example Post"},{"content":"","date":"2023-09-07","id":1,"permalink":"/beacon-docs/blog/","summary":"","tags":[],"title":"Blog"},{"content":"","date":"2024-06-07","id":2,"permalink":"/beacon-docs/docs/gettingstarted/","summary":"","tags":[],"title":"Getting Started"},{"content":"\rThis project is currently in closed beta.\nPlease complete the form to request access to the closed beta.\nFor more info about the release of the closed beta, refer to this document\nThe Beacon SDK is a toolset designed to enhance and streamline the development of virtual tabletop (VTT) character sheets and other interactive elements.\nWhether you\u0026rsquo;re a game master (GM), a developer, or a player, the Beacon SDK provides a framework to create dynamic, responsive, and fully integrated Roll20 Tabletop experiences.\nWhat is the Beacon SDK? The Beacon SDK is a specialized software development kit for virtual tabletops.\nIt facilitates creating and managing interactive character sheets, roll templates, macros, and other Roll20 Tabletop functionalities.\nThe SDK ensures easy communication between the Roll20 Tabletop platform and the character sheets, allowing real-time updates and interactions.\nKey Features Character Sheets: Design and implement detailed character sheets with dynamic attributes and real-time updates. Roll Mechanics: Integrate complex roll formulas and display roll results directly within the Roll20 Tabletop. Macros: Create and manage macros for automated actions and roll calculations. Event Handling: Utilize a comprehensive set of handlers to manage various events and interactions within the Roll20 Tabletop. Legacy Support: Convert and integrate legacy macros and roll templates with the new Beacon architecture. Customization: Define custom actions computed properties and handle specific roll templates tailored to your game\u0026rsquo;s needs. Components Overview The Beacon SDK is composed of several key components:\nActions: Define and manage custom actions that can be triggered within the Roll20 Tabletop. Handlers: Event handlers that process and respond to various Roll20 Tabletop events and messages. Computed Properties: Define dynamically computed properties based on other attributes. Macro Attributes: Convert and manage legacy macro attributes for compatibility with the Beacon SDK. Rolls: Implement advanced roll mechanics and display results dynamically within the Roll20 Tabletop. For a comprehensive overview of these components, view the components section.\nGetting Started To get started with the Beacon SDK, you must initialize the relay, set up your character sheets, and define the necessary actions, handlers, and computed properties.\nThis documentation provides detailed guides and examples to help you through each step of the process.\nBy leveraging the Beacon SDK, you can create rich, interactive, fully integrated Roll20 Tabletop experiences that enhance gameplay and streamline game management.\nWhether adapting existing character sheets or building new ones from scratch, the Beacon SDK offers the tools and flexibility to bring your virtual tabletop to life.\n","date":"2024-05-07","id":3,"permalink":"/beacon-docs/docs/gettingstarted/introduction/","summary":"This project is currently in closed beta.\nPlease complete the form to request access to the closed beta.\nFor more info about the release of the closed beta, refer to this document","tags":[],"title":"Introduction"},{"content":"This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.\nTo get started quickly with a boilerplate, you can download and start editing the Quick Start Example Sheet which already has the Beacon SDK installed, along with several recommanded patterns implemented in a Vue.js project.\nPrerequisites Before you can install the Beacon SDK, you\u0026rsquo;ll need to have the following:\nA local web development environment with a code editor. Node.js installed on your machine. If you don\u0026rsquo;t have Node.js installed, use the following steps in the official Node.js documentation. A javascript project, we recommand Vue.js but you can choose whichever you are more comfortable with. These steps use npm but you are free to use any package manager and framework you prefer.\nThe following steps will guide you in installing the Beacon SDK in your application:\nStep 1: Add the package to your project You can find the latest version of the package on the NPM registry.\nIn your project\u0026rsquo;s directory, run the following:\nnpm i @roll20-official/beacon-sdk\rThis will install the Beacon SDK package to your project\u0026rsquo;s package.json file.\nStep 2: Use the Beacon package in your project The Beacon package exports various utilities you can use in your application. The main one that needs to be setup to enable the connection between Beacon SDK and Roll20 is initRelay.\nIdeally you would want to call this when your sheet is initalizing, and it is the function where you will define sheet actions, computed values, and how the sheet will response to or send character data changes. visit the initRelay page for a more detailed breakdown.\nAdd the following to your project:\nimport { initRelay } from \u0026#39;@roll20/beacon-sdk\u0026#39;; const dispatch = initRelay({ handlers: { onInit: ({ character } ) =\u0026gt; { console.log(\u0026#39;sheet character\u0026#39;, character) }, onChange: () =\u0026gt; {}, onSettingsChange: () =\u0026gt; {}, onSharedSettingsChange: () =\u0026gt; {}, onTranslationsRequest: () =\u0026gt; {}, onDragOver: () =\u0026gt; {} }, // Refer to our advanced example sheet on how to setup actions and computed properties. actions: {}, computed: {} })\rinitRelay returns a dispatch function that allows you to call methods or send changes from the sheet to Roll20. Check out the page on dispatch to learn more about the different methods.\nStep 3: Settings up the Roll20 tabletop sandbox On the Roll20 website visit the custom sheet sandbox and create a new sandbox, we\u0026rsquo;ll use this sandbox to develop our sheet but we must set it up to listen to our local project\u0026rsquo;s web server.\nAfter creating a new sandbox, we\u0026rsquo;ll be taken to the sandbox details page, here you will find a collapseable section called Sheet.json Editor, opening this we can add the settings we need to connect to our project:\n{ \u0026#34;advanced\u0026#34;: true, \u0026#34;advancedPort\u0026#34;: 7620 // or the port of your webserver }\rAfter adding these changes make sure to click Save Changes at the bottom of the page. After which you can click Launch Game on the page to go into the game and start testing your sheet.\n","date":"2024-04-07","id":4,"permalink":"/beacon-docs/docs/gettingstarted/installing-beacon/","summary":"This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.","tags":[],"title":"Installing Beacon"},{"content":"Background: The background color of the alert box.\nCharacter: An entity in the game with attributes, bio, GM notes, and a token representation.\nCharacter sheet: A digital or printed page used to track a character\u0026rsquo;s attributes, abilities, and other relevant information in a role-playing game.\nComputed Property: Properties that have both get and set methods, which can be dynamically calculated.\nConvertLegacyMacroAttributes: A function to handle mapping legacy macro attributes to the new Beacon Sheet format.\nDispatch: A set of functions enabling the sheet to send commands back to the VTT.\nGM (Game Master): The person who runs the game, controls the NPCs \u0026amp; the story, and provides challenges for the players.\nHandler: Methods that act as event handlers to process messages from the host.\nInitRelay: Function to initialize the SDK relay, setting up communication between the host and the character sheet.\nMacro: A script that automates repetitive tasks in the VTT.\nRoll Template: A predefined format for displaying the results of a dice roll.\nToken: A visual representation of a character or object on the virtual tabletop, with various properties like position, size, and attributes.\nVTT (Virtual Tabletop): An online platform that allows players to play tabletop role-playing games over the internet.\nValidationMessage: A message displayed when an input value does not meet specific criteria.\nQuantum Roll: A system that ensures the fairness and authenticity of dice rolls in the VTT by using cryptographic methods.\n","date":"2024-03-07","id":5,"permalink":"/beacon-docs/docs/about/glossary/","summary":"Background: The background color of the alert box.\nCharacter: An entity in the game with attributes, bio, GM notes, and a token representation.","tags":[],"title":"Glossary"},{"content":"\rQ: How is Beacon better than the old way of building sheets (known as Custom Sheets)?\rIt depends on your web development skill level. There are a number of benefits to the Beacon SDK if you know how to build web applications. If you don\u0026rsquo;t know how to set up your own local environment, than the Beacon SDK might now be the first place you should start. Learn more about sheet development using the custom sheet.\nIf you have the skill to take advantage of the Beacon SDK, there are a number of improvements that will make it much easier to build characters sheets.\nFirst, the Beacon SDK allows you to develop locally and preview your changes automatically in the Roll20 Tabletop and Roll20 Character sandboxes. This means that you don\u0026rsquo;t have to keep uploading your HTML and CSS into the custom sheet to see your changes.\nNext, it allows you to develop your character sheet with all the power of JavaScript frameworks and modern web development libraries. In our example sheets, we use Vue.js, but you are free to use whatever you are most comfortable with. Also, you could use something like Cypress to create automated testing. That\u0026rsquo;s what we use in our Beacon sheets.\nLastly, the Beacon SDK makes it much easier for a web developer who knows JSON and Javascript to access character data and manage attributes on the character. If you\u0026rsquo;re familiar with the custom sheet, you no longer have to deal with sheet workers to get the data you need for a character. Also, the Beacon SDK introduces nested and computed attributes that make complex data models for your character sheet easier to create and maintain.\nQ: I\u0026rsquo;m not really a web developer, should I use Beacon or the custom sheet to make a my own character sheet?\rThat is up to you and your comfort level. If you\u0026rsquo;re looking to learn more about web development, building a character sheet with the Beacon SDK is a great way to level up your skills. What you learn during this process can be taken with you into any other web development project you work on in the future.\nIf setting up your own development environment is too intimidating for you, than it might be easier for you to start with the custom sheet and to go from there.\nQ: I\u0026rsquo;m interested in using Beacon, but I don\u0026rsquo;t know the basics of setting up a local environment. Where can I go to learn more about web development?\rYou can start learning how to build a local development environment by reading or watching the following tutorials. Note: these are not tutorials that we\u0026rsquo;ve produced, but we have found them helpful in getting started with web development.\nhttps://learn.microsoft.com/en-us/windows/dev-environment/javascript/vue-on-wsl https://www.youtube.com/watch?v=WPqXP_kLzpo Q: Now that Roll20 has acquired Demiplane, will you continue to support character sheets built on Beacon?\rThe recent acquisition of Demiplane brings exciting new opportunities for character sheets and compendiums on Roll20. At the same time, we are fully committed to supporting the Beacon SDK and character sheets that are built in our new advanced sheets ecosystem on Roll20. In fact, we believe that the Beacon SDK will be a key component of our future plans for Demiplane integration. In addition, our new D\u0026amp;D 2024 sheet is built on top of the Beacon SDK, and we will continue to utilize it to build first-class experiences on Roll20.\nIn short, you can rest assured that the Beacon SDK is an important tool in our toolbox moving forward.\nQ: What are actions in the context of Beacon?\rActions are methods executed in the chat log of Roll20 Tabletop or Roll20 Characters, often used for rolls triggered from macros or chat buttons. They are defined in the sheet\u0026rsquo;s configuration and can interact with character data. Q: How are computed properties used in Roll20?\rComputed properties are attributes which are accessible by users of your character sheet. They are usable in macros to create custom rolls or common actions for each character. Computed properties can represent derived values or complex calculations based on character data. Q: What is the dispatch function used for?\rThe dispatch function provides methods for sending commands from the character sheet back to Roll20, including updating character data, performing actions, and interacting with the interface. Q: What are roll buttons, and how do they work?\rRoll buttons are HTML elements with specific attributes that execute designated sheet actions when clicked. They can pass arguments to the action method and are commonly used for triggering rolls from the character sheet. Q: How are legacy attributes handled in Beacon?\rBeacon gives you the ability to transition your legacy attributes to new attributes you create in Beacon. This means that when a user updates their sheet to the new Beacon sheet, their legacy attribute can be mapped to Beacon attributes using the convertLegacyMacroAttributes function. Sheet developers can define how to handle legacy attribute values to ensure compatibility with existing macros. Q: What is the purpose of the query function?\rThe query function displays a SweetAlert2 prompt to users and returns the results along with any errors. It is commonly used for interactive prompts or confirmations within the VTT interface. Q: How are tokens managed in the VTT?\rTokens represent characters or objects on Roll20 Tabletop (VTT). Functions like getTokens, updateTokensByCharacter, and addToTracker are used to retrieve token information, update token data, and manage tokens in the turn tracker. Q: What is the role of the convertLegacyMacroAttributesArgs type?\rThe convertLegacyMacroAttributesArgs type defines the arguments used for handling legacy macro attributes. It includes the attribute name, character ID, and character data needed for mapping legacy attributes to the new sheet structure. ","date":"2024-01-07","id":6,"permalink":"/beacon-docs/docs/about/faq/","summary":"Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)?\rIt depends on your web development skill level.","tags":[],"title":"FAQ"},{"content":"\rQ1: What are actions in the context of the VTT?\rActions are methods executed from the VTT, often used for rolls triggered from macros or chat buttons. They are defined in the sheet\u0026rsquo;s configuration and can interact with character data. Q2: How are computed properties used in the VTT?\rComputed properties are defined attributes accessible by the host, usable in macros, and assignable to token bars. They can represent derived values or complex calculations based on character data. Q3: What is the dispatch function used for?\rThe dispatch function provides methods for sending commands from the character sheet back to the host, including updating character data, performing actions, and interacting with the VTT interface. Q4: What are roll buttons, and how do they work?\rRoll buttons are HTML elements with specific attributes that execute designated sheet actions when clicked. They can pass arguments to the action method and are commonly used for triggering rolls from the character sheet. Q5: How are legacy macro attributes handled in the VTT?\rLegacy macro attributes can be mapped to the new sheet structure using the convertLegacyMacroAttributes function. Sheet developers can define how to handle legacy attribute values to ensure compatibility with existing macros. Q6: What is the purpose of the query function?\rThe query function displays a SweetAlert prompt to users and returns the results along with any errors. It is commonly used for interactive prompts or confirmations within the VTT interface. Q7: How are tokens managed in the VTT?\rTokens represent characters or objects on the virtual tabletop. Functions like getTokens, updateTokensByCharacter, and addToTracker are used to retrieve token information, update token data, and manage tokens in the turn tracker. Q8: What is the role of the convertLegacyMacroAttributesArgs type?\rThe convertLegacyMacroAttributesArgs type defines the arguments used for handling legacy macro attributes. It includes the attribute name, character ID, and character data needed for mapping legacy attributes to the new sheet structure. Q9:Now that Roll20 has acquired Demiplane, will you continue to support character sheets built on Beacon?\rThe recent acquisition of Demiplane brings exciting new opportunities for character sheets and compendiums on Roll20. At the same time, we are fully committed to supporting the Beacon SDK and character sheets that are built in our new advanced sheets ecosystem on Roll20. In fact, we believe that the Beacon SDK will be a key component of our future plans for Demiplane integration. In addition, our new D\u0026amp;D 2024 sheet is built on top of the Beacon SDK, and we will continue to utilize it to build first-class experiences on Roll20.\nIn short, you can rest assured that the Beacon SDK is an important tool in our toolbox moving forward.\n","date":"2024-01-07","id":7,"permalink":"/beacon-docs/docs/faq/","summary":"Q1: What are actions in the context of the VTT?\rActions are methods executed from the VTT, often used for rolls triggered from macros or chat buttons.","tags":[],"title":"FAQ"},{"content":"The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games. initRelay is the main method that initializes the Beacon SDK communication channel with the host (Either the Roll20 tabletop or in Roll20 Characters). It should be initialized as soon as the sheet loads, as its onInit handler will be the earliest we can get access to that character\u0026rsquo;s data.\ninitRelay({ handlers: { onInit, onChange, onSettingsChange, onSharedSettingsChange, onTranslationsRequest, onDragOver, onDropOver, }, actions: {}, computed: {}, convertLegacyMacroAttributes, handleLegacyRollTemplates }): Promise\u0026lt;Dispatch\u0026gt;\rThese components are crucial for handling actions, computations, macros, and rolls. This overview provides a high-level summary of each section, helping you understand their roles and how they integrate within the SDK.\nActions\rActions define specific operations that can be performed by characters within the Roll20 Tabletop. These operations can range from simple tasks like rolling a dice to more complex interactions such as casting spells or activating abilities.\nHandlers\rHandlers are event listeners that manage communication between the Roll20 Tabletop and the character sheet. They respond to various events, such as changes in character attributes or settings, and trigger appropriate actions or updates.\nComputed\rComputed properties are dynamic values derived from other character attributes. They allow for the creation of complex, calculated attributes that automatically update when their dependencies change.\nMacro Attributes\rMacro attributes handle the conversion of legacy macro attributes to the new format used in the Beacon SDK. This ensures compatibility with older character sheets and macros, allowing for a smooth transition to the new system.\nRolls\rThe Rolls component allows for advanced dice-rolling mechanics within the Roll20 Tabletop. It supports both simple and complex rolls, providing flexibility in how roll results are displayed and computed.\nDispatch\rThe dispatch object provides methods for sending commands from the character sheet back to the host. Except when specified every method returns a promise.\n","date":"2024-06-07","id":8,"permalink":"/beacon-docs/docs/components/initrelay/","summary":"The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games.","tags":[],"title":"InitRelay"},{"content":"\rinitRelay({ //...other methods actions: {}, }): Promise\u0026lt;Dispatch\u0026gt;\rActions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters. These actions are used for any rolls that may need to be triggered outside of the sheet itself, such as from a macro or a chat button. Generally, most or all of a sheet’s rolls should be defined as actions.\nactions: { [name: string]: { method: (props: { dispatch: Dispatch, character: Character, messageId?: string, rolls?: RollResults }, ...args: string[]): void | Promise\u0026lt;void\u0026gt; } }\rActions are passed into the initRelay function in an object, where the keys are the unique names of the actions, and the values are objects containing a method property (additional metadata fields may be added to this object in the future).\nThe action\u0026rsquo;s method receives a props object from the host containing the following properties:\ndispatch: A Dispatch object. character: The data of the character performing the action. Currently, the action will not receive the character’s bio or GM notes, regardless of whether the player has access to those fields. messageId (optional): A unique ID for an existing chat message. It\u0026rsquo;s included in actions triggered from chat buttons to provide context for the original roll. rolls (optional): Included when action is triggered from a chat button. Contains the roll results of the original roll. These methods can also receive an unlimited number of additional arguments. This is because these actions can be triggered by plain text via a macro. However, all additional arguments must be strings. Additionally, these methods can be synchronous or asynchronous and do not return a value.\n","date":"2024-05-07","id":9,"permalink":"/beacon-docs/docs/components/actions/","summary":"initRelay({ //...other methods actions: {}, }): Promise\u0026lt;Dispatch\u0026gt;\rActions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters.","tags":[],"title":"Actions"},{"content":"","date":"2024-04-07","id":10,"permalink":"/beacon-docs/docs/components/","summary":"","tags":[],"title":"Components"},{"content":"Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.\ninitRelay({ //...other methods computed: { [name: string]: { tokenBarValue?: boolean description?: string get: ( props: { character: Character }, ...args: string[] ) =\u0026gt; string | number | JSONValue set?: ( props: { character: Character dispatch: Dispatch }, ...args: string[] ) =\u0026gt; void | Promise\u0026lt;void\u0026gt; } }, }): Promise\u0026lt;Dispatch\u0026gt;\rComputed properties are passed into the initRelay function in an object where the keys are the names of the properties, and the value should be an object containing the following:\nget (required): It receives character data along with any number of string parameters and should return the computed value. tokenBarValue (optional): A boolean indicating whether this property should be available for use in token bars. description (optional): A text value indicating what this computed summary property represents. set (optional): This method receives character data and a dispatch, along with string arguments. This method does not need to return a value. Setting tokenBarValue to true will make the property available to use as a value for token bars. To work correctly, the get function must not rely on any additional arguments and must return either a simple value (a string or number) or an object: { current: number | string, max: number | string }\rIf the set function is omitted, the value will not be editable from the token itself. If defined, set methods will receive one string argument, which is whatever the user types into the input for modifying the bar. ","date":"2024-04-07","id":11,"permalink":"/beacon-docs/docs/components/computed/","summary":"Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.","tags":[],"title":"Computed"},{"content":"Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. It is the main agrument that must be passed into initRelay or the sheet will never fully load.\ninitRelay({ handlers: { onInit, onChange, onSettingsChange, onSharedSettingsChange, onTranslationsRequest, onDragOver, // optional onDropOver, // optional } //...other methods }): Promise\u0026lt;Dispatch\u0026gt;\ronInit The onInit method receives the initial data from the host.\nThis will be the first time we have access to character data, sheet settings, as well as compendium data if this character is made as a result of a compendium drag and drop on the host.\nonInit(event: { character: Character, // Initial Data of the primary character for this sheet. settings: { // Campaign and character specific settings colorTheme: string, // \u0026#39;dark\u0026#39; or \u0026#39;light\u0026#39; language: string, // two-letter language code, i.e. \u0026#39;en\u0026#39; gm: boolean, // whether or not the current player has gm permissions owned: boolean, // whether or not the current player controls the primary character settingsSheet: boolean, // whether or not this sheet is the settings sheet headless: boolean, // whether or not it should be displayed, set by the host sandbox: boolean, campaignId: number, // The id of the current campaign environment: string, // VTT, CHARACTERS, DISCORD currentUserId: string, // user id of user opening the sheet singleSheet: boolean }, sharedSettings: {}, // Data shared between all characters in this campaign compendiumDropData: { // Populated when the character sheet is created from a compendium entry such as a creature or NPC. pageName: string, categoryName: string, expansion: number, }, }, dispatch: Dispatch): void;\rThis function may be called multiple times during development in the sheet sandbox as part of hot reloads.\nonChange onChange is called whenever a character’s data is changed on the host’s end. The event object contains a partial character with only the character’s ID and the changed data. This could be the character’s bio, GM notes, or attributes (only the changed attributes).\nonChange(e: { character: Partial\u0026lt;Character\u0026gt; }, dispatch: Dispatch): void;\ronSettingsChange onSettingsChange is called when either the host’s color theme is changed, or when the current player’s ownership of the primary character changes.\nonSettingsChange(e: { colorTheme: string, owned: boolean }, dispatch: Dispatch): void;\ronSharedSettingsChange onSharedSettingsChange is called when someone changes a shared setting in the host.\nonSharedSettingsChange({ settings: { [key: string]: any } }): void;\ronTranslationsRequest onTranslationsRequest is called before the relay is fully initialized and returns the translation JSON data corresponding to the two-letter language argument.\nonTranslationsRequest(language: string): { [key: string]: string };\ronDragOver (optional) onDragOver is called when a compendium item from the compendium tab is dragged over the iframe window containing the character sheet.\nCoordinates of the drag are provided via top and left values, and basic compendium data is passed so that a subsequent compendium request can be made via the provided dispatch. If the item is moved outside of the iframe, dragData and coordinates are null.\nonDragOver(e: { coordinates: { top: number, left: number }, dragData: { pageName: string categoryName: string expansionId: number } | null, }, dispatch: Dispatch) =\u0026gt; void\ronDropOver (optional) onDropOver is called when a compendium item from the compendium tab is dropped over the iframe window containing the character sheet.\nCoordinates of the drop are provided via top and left values, and basic compendium data is passed so that a subsequent compendium request can be made via the provided dispatch.\nonDropOver(e: { coordinates: { top: number, left: number }, dropData: { pageName: string categoryName: string expansionId: number } }, dispatch: Dispatch) =\u0026gt; void\r","date":"2024-03-07","id":12,"permalink":"/beacon-docs/docs/components/handlers/","summary":"Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet.","tags":[],"title":"Handlers"},{"content":"","date":"2024-02-07","id":13,"permalink":"/beacon-docs/docs/about/","summary":"","tags":[],"title":"About"},{"content":"Release Date: 2022-03-17\nNew Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development. Basic and advanced sheet examples. Improvements Detailed comments added to example files for better understanding. Support for complex roll templates and rich sheet actions. Bug Fixes N/A (initial release). Version 2.0.0 Release Date: 2023-03-17\nNew Features SCSS support for styling. Integration with Roll20 and VTT. Mock Relay for offline development. Improvements TypeScript integration for type checking and improved development experience. Unit testing with Vitest. End-to-End testing with Cypress. Bug Fixes N/A (initial release). ","date":"2024-01-07","id":14,"permalink":"/beacon-docs/docs/about/changelog/","summary":"Release Date: 2022-03-17\nNew Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development.","tags":[],"title":"Changelog"},{"content":"The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed. These features include attributes and elements that allow for dynamic roll results and interactivity within the host. Vist the Roll20 help center to learn more about Roll20\u0026rsquo;s Dice Rolling system\nThe most command way to trigger a dice roll is through the dispatch object returned from the initRelay, but it could also be called from actions:\ndispatch.roll({ rolls: { [rollName: string]: string } // Ex. {attack: \u0026#39;1d20+4\u0026#39;, damage: `3d6+2`} messageId?: string }): Promise\u0026lt;{messageId: string, results: RollResults }\u0026gt;\rThe roll method takes one or more rolls in the form of an object, where the keys are unique roll names and the values are roll strings.\nmessageId can be provided to attach the roll to an existing chat message, either overriding it or appending to it in the chat log. If messageId is omitted, the roll will be associated with a new chat message and a new messageId for that message will be returned with the roll results. The method returns a promise that resolves with an object containing the messageId and the RollResults. The roll result is returned in the same format as in the non-beacon dice rolls computed roll system.\nThe dispatch roll method and the actions roll section do not post to the chat, instead they will return a promise which will resolve to the roll results and the message id.\nPosting A Roll to the Chat The roll method does not send or post any data to the chat on it\u0026rsquo;s own. We instead have to use dispatch\u0026rsquo;s post method to send our roll results along with any other content to the chat.\ndispatch.post({ characterId: \u0026#39;-O0KZhMTxLkn2HArFj8f\u0026#39;, content: `I rolled a ${diceRoll.results.attack.results.result} to hit and did ${diceRoll.results.damage.results.result} damage!`, })\rAdditional Roll Posting Options data-rollname The data-rollname attribute tells the host that this HTML element is displaying the result of a roll.\n\u0026lt;span data-rollname=\u0026#34;attack\u0026#34;\u0026gt;\u0026lt;/span\u0026gt;\rThe host will both add the Quantum Roll signature element and replace the contents of the element with the result from the roll.\nThis is the preferred method for displaying roll results wherever possible, that is, sending the whole roll formula to the roll server and allowing the host to display the result.\ndata-computed Tagging an element with both a data-rollname and a data-computed=\u0026quot;true\u0026quot; tells the host that this element is associated with a roll, but the results of that roll were computed by the author, as opposed to the roll server computing the result.\n\u0026lt;span data-rollname=\u0026#34;complex\u0026#34; data-computed=\u0026#34;true\u0026#34;\u0026gt;25\u0026lt;/span\u0026gt;\rThe host will add the Quantum Roll signature tooltip, but the content of the element will not be modified. Generally, this should only be used when the roll server does not support a particular dice mechanic.\nRoll Buttons Roll buttons are interactive elements that trigger sheet actions, such as damage rolls, when clicked. These buttons use the data-sheet-action attribute to specify the action to be executed.\n\u0026lt;button data-sheet-action=\u0026#34;damage\u0026#34; data-args=\u0026#34;arg1:arg2\u0026#34;\u0026gt;Click Me\u0026lt;/button\u0026gt;\rAdditional arguments can be provided using the data-args attribute, and the character, messageId, and original rolls will be included automatically.\nRolls Results Format type RollResults = { [name: string]: { expression: string //The original expression (i.e. 1d20+3d6) rollName: string //The name of the roll results: { //The results of the roll(s) expression: string dice?: number[] // result: number //The final result of the roll rolls?: { //Detailed results of each part of the roll (i.e. 3d6) sides: number //The type of die for this part of the roll (i.e. 6) dice: number //The number of dice (i.e. 3) results: number[] //The result of each die (i.e. [4, 2, 5]) }[] } } }\r","date":"2024-01-07","id":15,"permalink":"/beacon-docs/docs/components/rolls/","summary":"The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed.","tags":[],"title":"Rolls"},{"content":"The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host. Except when specified every method below will return a promise.\nupdate dispatch.update({ options: { overwrite?: boolean } character: Partial\u0026lt;Character\u0026gt; }): Promise\u0026lt;void\u0026gt;\rThe update method sends character changes to the host (Roll20 Tabletop or Roll20 Characters) to be persisted.\nThe partial character passed in here must contain the character\u0026rsquo;s id, and can contain any combination of the attributes, bio, and gmNotes properties. When updating a character’s attributes, only include those attributes that have changed.\nupdateCharacter dispatch.updateCharacter({ character: Partial\u0026lt;Character\u0026gt; }): Promise\u0026lt;void\u0026gt;\rLike the update method, updateCharacter sends character changes to the host page (Roll20 Tabletop or Roll20 Characters) to be persisted.\nHowever, this method takes a full set of character attributes as the character argument, and automatically computes the diff with existing character attributes, so that only changed attributes are sent to the data store.\nroll dispatch.roll({ rolls: { [rollName: string]: string } // Ex. {attack: \u0026#39;1d20+4\u0026#39;, damage: `3d6+2`} messageId?: string }): Promise\u0026lt;{messageId: string, results: RollResults }\u0026gt;\rThe roll method takes one or more rolls in the form of an object, where the keys are unique roll names and the values are roll strings. messageId can be provided to attach the roll to an existing chat message, either overriding it or appending to it in the chat log.\nIf messageId is omitted, the roll will be associated with a new chat message and a new messageId for that message will be returned with the roll results.\nThe method returns a promise that resolves with an object containing the messageId and the RollResult (see Types). The roll result is returned in the same format as in the non-beacon dice rolls computed roll system.\npost dispatch.post({ characterId: string, messageId?: string, content: string, options?: { whisper?: \u0026#39;gm\u0026#39;, secret?: boolean, } }): Promise\u0026lt;string\u0026gt;\rpost posts a message to chat, either creating a new message or overwriting an existing one. It requires a character id and message content, a string containing either plain text or HTML to be posted.\nThe method also accepts an options object. Currently, only whisper and secret are supported, the only valid value for whisper is gm, which will send the message as a whisper to the gm.\nThe secret option is ignored unless whisper is also set, toggling to true will cause the message to not be visible to the controlling player.\nLike roll, messageId can be provided to update an existing chat message, but if omitted the method will generate a new messageId and post a new chat message. The method returns the messageId.\nquery dispatch.query(options: Swal2Options): { isConfirmed: boolean, isDenied: boolean, isDismissed: boolean, value?: string | number, dismiss?: \u0026#34;cancel\u0026#34; | \u0026#34;backdrop\u0026#34; | \u0026#34;close\u0026#34; | \u0026#34;esc\u0026#34; | \u0026#34;timer\u0026#34;, errors?: string[], }: Promise\u0026lt;{ results: { isConfirmed: boolean isDenied: boolean isDismissed: boolean value: string | number dismiss: string }, errors: [string] }\u0026gt;\rThe query method takes an options object and uses them to display a SweetAlert2 prompt to the user. It returns the results of the query as a SweetAlertResult, along with any errors encountered. The options work exactly as described in the documentation for SweetAlert2, however not all options are allowed. Here is a list of the allowed options:\ntitleText, text, iconColor, input, width, padding, background, position, grow, timer, timerProgressBar, showConfirmButton, showDenyButton, showCancelButton, ariaLabel, confirmButtonText, denyButtonText, cancelButtonText, confirmButtonAriaLabel, confirmButtonColor, cancelButtonAriaLabel, cancelButtonColor, denyButtonAriaLabel, denyButtonColor, reverseButtons, showCloseButton, closeButtonAriaLabel, returnInputValueOnDeny, imageUrl, imageWidth, imageHeight, imageAlt, inputLabel, inputPlaceholder, inputValue, inputOptions, inputPlaceholder, inputAutoTrim, inputAttributes, validationMessage, progressSteps, currentProgressStep, progressStepsDistance.\nPerform dispatch.perform({ characterId: string, action: string, args: string[], }): Promise\u0026lt;void\u0026gt;;\rperform executes the specified action on behalf of the character (designated by the character id), passing in args to the action method. This method can perform actions on behalf of any character, even a character that the sheet does not have data for.\ngetComputed dispatch.getComputed({ characterId: string, property: string, args: string[] }): Promise\u0026lt;string | number | object\u0026gt;\rsee setComputed below\nsetComputed dispatch.setComputed({ characterId: string, property: string, args: string[] }): Promise\u0026lt;string | number | object\u0026gt;\rgetComputed and setComputed are both nearly identical in how they are called, taking a character id and a property with the name of the computed property you wish to get or set, and an array of string args. Both methods return a promise that resolves with the computed value.\ncompendiumRequest dispatch.compendiumRequest({ query: string }): Promise\u0026lt;{ data: Object errors: Array\u0026lt;Error\u0026gt; extensions: Record\u0026lt;string, any\u0026gt; }\u0026gt;\rcompendiumRequest executes an AJAX request to the compendium service’s graphQL endpoint. It takes in a graphQL query string written according to the Compendium service’s schema. The query string does not need to include the ruleSystem shortName as this is set automatically according to the campaign override or sheet.json value in the Roll20 Tabletop.\ndebouncedCompendiumRequest dispatch.debouncedCompendiumRequest({ query: string }): Promise\u0026lt;{ data: Object }\u0026gt;\rLike compendiumRequest, except that calls to this method are automatically debounced (at 100ms) and grouped together into a single request to the compendium service. Note that this method will only return the requested data, it does not return errors or extensions.\ngetTokens dispatch.getTokens({ characterId: string }): Promise\u0026lt;{ selected: Token[], tokens: Token[] }\u0026gt;: Promise\u0026lt;{ selected: Token[] tokens: Token[] }\u0026gt;\rgetTokens requires a character id string and returns information about tokens on the user’s current page. The return value contains two arrays of tokens. The tokens array contains all tokens on the current page that represent the character whose id was provided to the method. The selected array contains any tokens that are currently selected, regardless of which character they represent. The returned token objects contain all of the token attributes available to the API, you can find documentation here and here.\naddToTracker dispatch.addToTracker({ tokenId?: string, custom?: { name: string img?: string } formula?: string value: string | number }): Promise\u0026lt;void\u0026gt;\raddToTracker adds or updates a single item in the turn tracker. Passing in a tokenId will add the specified token to the tracker, while passing in custom with a name and an optional image url (img) will add a custom item, not connected to any character or token. A round calculation string can be added via the optional formula parameter. value is the initiative number for the item.\naddActionsToHost dispatch.addActionsToHost({ sheetAction?: { characterId: string action: string args?: string[] } action?: string locations?: [\u0026#39;macroBar\u0026#39;] | [\u0026#39;tokenActionBar\u0026#39;] | [\u0026#39;macroBar\u0026#39;, \u0026#39;tokenActionBar\u0026#39;] actionId?: string name: string requestId?: string }): void\raddActionsToHost adds a specific action(macro) to an area of the Roll20 Tabletop UI; either the macrobar or the token action bar. Either sheetAction or action can be passed in but not both at the same time. The sheetAction arg should be passed in when an the action is to designated to a character. While the action arg should be passed in when the action is more generic.\ngetActions dispatch.getActions({ args: { characterId?: string } }): Promise\u0026lt;{ actions?: {} | { [id: string]: ActionFromHost } }\u0026gt;\rgetActions gets a specific character’s actions(macro).\nsetContainerSize dispatch.setContainerSize({ args: { width?: number height?: number } }): Promise\u0026lt;void\u0026gt;\rsetContainerSize updates the size of the container which holds the sheet shared settings. Returns a promise that can be awaited. This can be used in conjunction with something like the ResizeSensor event listener from npm: css-element-queries to automatically resize the container on the host.\nupdateTokensByCharacter dispatch.updateTokensByCharacter({ args: { characterId: string token: Partial\u0026lt;Token\u0026gt; } }): Promise\u0026lt;void\u0026gt;\rupdateTokensByCharacter updates a particular character’s default token as well as all existing tokens representing that character. Returns a promise that can be awaited.\nupdateTokensByIds dispatch.updateTokensByIds({ args: { tokenIds: array of ids as strings token: Partial\u0026lt;Token\u0026gt; } }): Promise\u0026lt;void\u0026gt;\rupdateTokensByIds updates a single or several tokens. Returns a promise that can be awaited.\nautoLinkText dispatch.autoLinkText({ args: { text: string } }): Promise\u0026lt;string\u0026gt;\rautoLinkText goes through the text to find handout names between square brackets and converts them into links with the handoutID. For example in a game with a handout named Dragon, passing in the text string of this is a [Dragon] to autoLinkText returns something similar to this is a \u0026lt;a href=\u0026quot;https://journal.roll20.net/8je02j0kd02k\u0026quot;\u0026gt;Dragon\u0026lt;/a\u0026gt;.\nopenDialogFromLink dispatch.openDialogFromLink({ args: { urlString: string } }): void\ropenDialogFromLink opens the supplied urlString through the Roll20 Tabletop.\nIf the url is for a handout, it will open the corresponding handout in the campaign. This will also check if the user opening the link has access to the handout. If the url is for a compendium, it will open a pop up to the compendium page, it will also check to ensure the user has access to view the page. If the url is for an external page, a confirmation pop up will display to warn the user that the link is for an external site and open a new tab in their main window if confirmed. ","date":"2023-09-07","id":16,"permalink":"/beacon-docs/docs/components/dispatch/","summary":"The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host.","tags":[],"title":"Dispatch"},{"content":"When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.\nThis scenario commonly arises when transitioning from an existing legacy sheet to a Beacon sheet. During such transitions, it\u0026rsquo;s possible that the attributes or roll templates called from the legacy macro may not align with the structure of attributes or the lack of roll templates in the Beacon Sheet.\nconvertLegacyMacroAttributes The convertLegacyMacroAttributes method allows us to determine the mapping strategy for legacy attributes to the new Beacon Sheet.\ninitRelay({ convertLegacyMacroAttributes: (messages: { attribute: string, characterId: string, character: Character }) =\u0026gt; {}: any, }): Promise\u0026lt;Dispatch\u0026gt;\rThis method is defined during the initial SDK initialization process and is invoked by the host when it attempts to parse a macro and encounters a failure in locating an attribute\u0026rsquo;s value during an macro\u0026rsquo;s execution.\nAdvanced sheet actions typically will first search through the defined computed properties before resorting to the convertLegacyMacroAttributes method as a fallback.\nThe method\u0026rsquo;s purpose is to return a value that will be substituted in the macro. However, it grants us the autonomy to devise the preferred approach for handling legacy attribute values.\nhandleLegacyRollTemplates Since Beacon sheets no longer require or use roll templates as previously needed in older custom sheets, there will be times where a legacy macro might make include a reference to a legacy roll template. We can use the handleLegacyRollTemplates to determine how to handle these cases.\ninitRelay({ handleLegacyRollTemplates: (message: { templateName: string, // name of the template that triggered this method properties: Record\u0026lt;string, any\u0026gt;, // a list of the values and formulas for rolls and macro in the template // along with values for other properties in the template dispatch: Dispatch, playerid: string , originalInput: string // the original text input for the entire roll template string }) =\u0026gt; {}: any, }): Promise\u0026lt;Dispatch\u0026gt;\rThe properites object will also include a plainText key for roll template arguments not inside the curly brace syntax.\n{ //... other arguments properties: { attack: { value: 12, formula: \u0026#39;1d20\u0026#39; }, damage: { value: 5, formula: \u0026#39;2d6\u0026#39; }, foo: { value: \u0026#39;bar\u0026#39; }, name: { formula: \u0026#34;@{Helga|name}\u0026#34; value: \u0026#34;Helga\u0026#34; }, plainText: [\u0026#39;apicallback\u0026#39;, \u0026#39;apple=red\u0026#39;], something: { value: \u0026#34;I went to get tacos\u0026#34; }, ............ } }\r","date":"2023-09-07","id":17,"permalink":"/beacon-docs/docs/components/handling-legacy-methods/","summary":"When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.","tags":[],"title":"Handling Legacy methods"},{"content":"Prerequisites To set this sheet up properly, make sure that you have the following tools installed:\nVue.js Vite SCSS To download the community quick start sheet, refer to these repositories:\nCommunity Sheet Repo\nQuick Start Sheet\nFigure 1: Quickstart sheet\nUse the following steps to get started:\nInstall the Beacon SDK: Run the following command. npm i @roll20-official/beacon-sdk\rInstall dependencies: Install the dependencies for the project. npm install\rStart the Vite server: After installing the project\u0026rsquo;s dependencies, you\u0026rsquo;ll need to start the Vite server. There are two ways to do this: a. Offline Development: This method will run the Vite server with the default port and environment set to development.\nnpm run dev\rOnce this code executes successfully, you can access the Vite server at http://localhost:5173.\nThis method is useful when you do not have access to the Roll20 website or would like to work on parts of your project that do not depend on a connection to the Roll20 Tabletop or Roll20 Characters, such as working on styling, mocking up the environment, building Vue components, testing functionality, etc.\nIn development mode, you cannot save or access existing character data or use the Beacon SDK functions that depend on Roll20 Tabletop or Roll20 Characters functionality, such as dice rolling and token manipulation.\nb. Sandbox Development: This method will run the Vite server with the port set to 7620 and the environment set to staging mode.\nnpm run sandbox\rThis command will build the SCSS files and then run the Vite server. This will set the server up for connecting to a Roll20 Tabletop custom sheet sandbox as well as through the sandbox in Roll20 Characters.\nTo test your changes in the Roll20 Tabletop custom sheet sandbox, you will need to add the following to the sheet.json editor in the game settings:\n{ \u0026#34;advanced\u0026#34;: true, \u0026#34;advancedPort\u0026#34;: 7620 }\rUseful Commands The following set of commands can come in handy when working with this sheet:\nFor Hot reloading and building CSS files, use the following command: npm run watch-scss\rFor linting, use the following command: npm run lint\rFor formatting with Prettier, use the following command: npm run format\r","date":"2024-04-07","id":18,"permalink":"/beacon-docs/docs/gettingstarted/quick-start-sheet-template/","summary":"Prerequisites To set this sheet up properly, make sure that you have the following tools installed:\nVue.js Vite SCSS To download the community quick start sheet, refer to these repositories:","tags":[],"title":"Quick Start Sheet Template"},{"content":"Prerequisites To set this sheet up properly, make sure that you have the following:\nVue framework \u0026amp; Routing Multiple Data Stores Complex Roll Templates Rich Sheet Actions TypeScript Vite SCSS Ability to run Unit \u0026amp; End-to-End Tests To download the community quick start sheet, refer to these repositories:\nCommunity Sheet Repo\nQuick Start Sheet\nFigure 1: Advanced sheet\nThis sheet uses the same steps listed in the . Immediately after implementing those three steps, you\u0026rsquo;ll add the following step:\nRun a CI check: This will run several checks to ensure your code is as optimal as possible, including formatting, linting, type checking, unit tests, and end-to-end tests. npm run ci-check\rYou can think of this command as a sanity check you can leverage when pushing a big release for your sheet!\nUseful Commands The following set of commands can come in handy when working with this sheet:\nFor Hot reloading and building CSS files, use the following command: npm run watch-scss\rFor linting, use the following command: npm run lint\rFor formatting with Prettier, use the following command: npm run format\rFor type checking with TypeScript, use the following command: npm run type-check\rFor running unit tests with Vitest, use the following command: npm run test:unit\rTo open up and develop local end-to-end tests with Cypress, use the following command: npm run test:e2e:open:local\rFor running local end-to-end tests with Cypress, use the following command: npm run test:e2e:local\rTo run CDN-hosted end-to-end tests with Cypress, use the following command: npm run test:e2e\r","date":"2024-03-07","id":19,"permalink":"/beacon-docs/docs/gettingstarted/example-patterns-sheet/","summary":"Prerequisites To set this sheet up properly, make sure that you have the following:\nVue framework \u0026amp; Routing Multiple Data Stores Complex Roll Templates Rich Sheet Actions TypeScript Vite SCSS Ability to run Unit \u0026amp; End-to-End Tests To download the community quick start sheet, refer to these repositories:","tags":[],"title":"Example Patterns Sheet"},{"content":"We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:\nHow to Contribute Reporting Bugs If you find a bug, please report it by opening an issue in the GitHub repository. Provide as much detail as possible to help us understand and reproduce the issue.\nSuggesting Features We welcome suggestions for new features. Please open an issue in the GitHub repository with a detailed description of the feature you would like to see and why you think it would be useful.\nCode Contributions Fork the Repository: Create a personal fork of the project on GitHub.\nClone the Fork: Clone your fork to your local machine.\ngit clone Create a Branch: Create a new branch for your work.\ngit checkout -b feature-or-bugfix-description\rMake Changes: Make your changes to the codebase. Follow the existing code style and conventions.\nRun Tests: Ensure that all tests pass before submitting your changes.\nnpm run ci-check\rCommit Changes: Commit your changes with a descriptive commit message.\ngit commit -m \u0026#34;Description of your changes\u0026#34;\rPush Changes: Push your changes to your fork.\ngit push origin feature-or-bugfix-description\rCreate a Pull Request: Open a pull request from your fork to the main repository. Provide a detailed description of your changes and why they should be merged.\nRunning Tests Unit Tests: Run unit tests with Vitest.\nnpm run test:unit\rEnd-to-End Tests: Run End-to-End tests with Cypress.\nnpm run test:e2e\rCode Style Follow the existing code style and conventions.\nUse ESLint for linting.\nnpm run lint\rFormat code with Prettier.\nnpm run format\rCommunication GitHub Issues: Use GitHub issues for bug reports, feature requests, and questions. Pull Requests: Use GitHub pull requests to submit your code contributions. Thank you for contributing to the Beacon SDK project!\n","date":"2024-02-07","id":20,"permalink":"/beacon-docs/docs/about/how-to-contribute/","summary":"We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:","tags":[],"title":"How to Contribute"},{"content":"There are two ways you can publish a Beacon sheet.\nYou can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access. When publishing a sheet, you will need to includes all the necessary code, assets, and metadata packaged together to be easily deployed and tested on the Roll20 platform. When a sheet is published, either publicly or privately for testing purposes, the sheet will run on Roll20 and will no longer require a local development environment to use it.\nReleasing a Test Sheet The following steps will aid you while releasing your sheet:\nCreate a Build Command:\nYou must have a build command that will produce the minified production-ready code. You can find more information in our Quickstart Package JSON. The build command must be able to create these exact files:\nsheet.js sheet.css host.css (optional) - This is the styling for any sheet rolls made to the chat. Add a local folder that contains fonts and images used in the sheet (optional). Add a sheet.json file:\nAdd a sheet.json file to your sheet folder to ensure the metadata for your sheet is up-to-date. You can find more information about the sheet.json options on the Roll20 Wiki as well as on the Quickstart sheet.\nCreate a Pull Request in the Beacon Community Sheet Repo:\nIn the Beacon Community Sheet Repo, create a pull request that must include the submission checklist listed for reference below.\nThe name of the pull request should\u0026hellip;\nContain the short name of the sheet being submitted, and State the type of change being submitted (New/Update/Bugfix/etc.). Pull Request Title Example: Sheet/\u0026lt;TYPE_OF_CHANGE\u0026gt;/\u0026lt;SHEET_SHORT_NAME\u0026gt; If this is the first time you are submitting this sheet to the repository, please make sure to have the following information ready.\nThe full name of the game associated with the sheet (i.e. Dungeons \u0026amp; Dragons 5th Edition, The Dresden Files RPG). The name of this game system/family associated with the shee (i.e. Dungeons \u0026amp; Dragons, FATE). The publisher of the game associated with the sheet (i.e. Wizards of the Coast, Evil Hat). The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you\u0026rsquo;d like them to be displayed. To see example of how this information will show up, create a new game on Roll20. The name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.\nPull requests that contain changes to files outside the sheet sub-folder on which you\u0026rsquo;re working will be rejected.\nGive Specific Roll20 Users Access:\nBefore your testing sheet is finally approved, you want choose to give specific Roll20 Users access to the testing sheet. This will allow only those users to see the sheet in Roll20 Tabletop and Roll20 Characters. These users will be able to use it just like the final users will when the sheet is public. You can give access to friends, group members, or even clients and publishers you\u0026rsquo;re working with.\nTo give access to one ore more specific user\u0026rsquo;s, fill out the Beacon Sheet Access Form. You will need the email associated with the Roll20 Account that will have access to the sheet for each person you\u0026rsquo;d like to give access.\nWe can always grant more people access to the sheet after it is released. Resubmit the Beacon Sheet Access Form to the new people for which you\u0026rsquo;d like to give access.\nWait for Approval and Access:\nAfter you create a pull request, our team will approve it and add your sheet to the sheet selection in Roll20 Tabletop and Roll20 Characters. We will then give only your Roll20 user and any others you\u0026rsquo;ve listed in the pull request comments access to the sheet in Roll20. This sheet will then be available for you and others with access to test it.\nSubmission Checklist The Pull Request title contains the short name of the sheet being submitted. The Pull Request title states the type of change being submitted (New/Update/Bugfix/etc.). I have authorization from the game\u0026rsquo;s publisher to make this an official sheet on Roll20 with their name attached. This game is not a traditionally published game, but a copy of the game rules can be purchased/downloaded/found at: \u0026lt; \u0026gt; This sheet is for an unofficial fan game, modification to an existing game, or a homebrew system. New Sheet Checklist If you are submitting a new sheet to the repository, please fill in any empty spaces indicated by \u0026lt; \u0026gt;.\nThe full name of the game associated with the sheet is: \u0026lt; \u0026gt; (i.e. Dungeons \u0026amp; Dragons 5th Edition, The Dresden Files RPG) The name of this game system/family associated with the sheet is: \u0026lt; \u0026gt; (i.e. Dungeons \u0026amp; Dragons, FATE) The publisher of the game associated with the sheet is: \u0026lt; \u0026gt; (i.e. Wizards of the Coast, Evil Hat) The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you\u0026rsquo;d like them to be displayed. To see example of where this information will show up, create a new game on Roll20. The Name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.\nPlease check any that apply:\nChanges / Description (optional) Provide any notes relevant to this pull request here. This can include a description of the code changes, references to related pull requests, etc.\nMore Help Additional information for the beacon sdk can be found at the Beacon SDK Documentation Site. You can also post additional questions using the Beacon Community GitHub Issues Tab.\nReleasing a Final Version After you have released a test version of your sheet, you can follow the same steps as releasing a test version to make your sheet available to everyone. This time, the pull request comments state that it is a final release version.\nOnce you have created the pull request, our team will review the sheet functionality, code, and metadata for consistency, best practices, and overall system security. We reserve the right to reject any sheet that does not meet our terms of use or conflicts with our partnerships.\n","date":"2024-02-07","id":21,"permalink":"/beacon-docs/docs/gettingstarted/releasing-a-sheet/","summary":"There are two ways you can publish a Beacon sheet.\nYou can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access.","tags":[],"title":"Releasing a Sheet"},{"content":"Link to valuable, relevant resources.\n","date":"2024-02-27","id":22,"permalink":"/beacon-docs/docs/resources/","summary":"Link to valuable, relevant resources.","tags":[],"title":"Resources"},{"content":"","date":"2023-09-07","id":23,"permalink":"/beacon-docs/docs/","summary":"","tags":[],"title":"Docs"},{"content":"","date":"2023-09-07","id":24,"permalink":"/beacon-docs/privacy/","summary":"","tags":[],"title":"Privacy Policy"},{"content":"","date":"2023-09-07","id":25,"permalink":"/beacon-docs/","summary":"","tags":[],"title":"Welcome to Beacon SDK"},{"content":"","date":"0001-01-01","id":26,"permalink":"/beacon-docs/categories/","summary":"","tags":[],"title":"Categories"},{"content":"","date":"0001-01-01","id":27,"permalink":"/beacon-docs/contributors/","summary":"","tags":[],"title":"Contributors"},{"content":"","date":"0001-01-01","id":28,"permalink":"/beacon-docs/tags/","summary":"","tags":[],"title":"Tags"}] \ No newline at end of file +[{"content":"\rThis project is currently in closed beta.\nPlease complete the form to request access to the closed beta.\nFor more info about the release of the closed beta, refer to this document\nThe Beacon SDK is a toolset designed to enhance and streamline the development of virtual tabletop (VTT) character sheets and other interactive elements.\nWhether you\u0026rsquo;re a game master (GM), a developer, or a player, the Beacon SDK provides a framework to create dynamic, responsive, and fully integrated Roll20 Tabletop experiences.\nWhat is the Beacon SDK? The Beacon SDK is a specialized software development kit for virtual tabletops.\nIt facilitates creating and managing interactive character sheets, roll templates, macros, and other Roll20 Tabletop functionalities.\nThe SDK ensures easy communication between the Roll20 Tabletop platform and the character sheets, allowing real-time updates and interactions.\nKey Features Character Sheets: Design and implement detailed character sheets with dynamic attributes and real-time updates. Roll Mechanics: Integrate complex roll formulas and display roll results directly within the Roll20 Tabletop. Macros: Create and manage macros for automated actions and roll calculations. Event Handling: Utilize a comprehensive set of handlers to manage various events and interactions within the Roll20 Tabletop. Legacy Support: Convert and integrate legacy macros and roll templates with the new Beacon architecture. Customization: Define custom actions computed properties and handle specific roll templates tailored to your game\u0026rsquo;s needs. Components Overview The Beacon SDK is composed of several key components:\nActions: Define and manage custom actions that can be triggered within the Roll20 Tabletop. Handlers: Event handlers that process and respond to various Roll20 Tabletop events and messages. Computed Properties: Define dynamically computed properties based on other attributes. Macro Attributes: Convert and manage legacy macro attributes for compatibility with the Beacon SDK. Rolls: Implement advanced roll mechanics and display results dynamically within the Roll20 Tabletop. For a comprehensive overview of these components, view the components section.\nGetting Started To get started with the Beacon SDK, you must initialize the relay, set up your character sheets, and define the necessary actions, handlers, and computed properties.\nThis documentation provides detailed guides and examples to help you through each step of the process.\nBy leveraging the Beacon SDK, you can create rich, interactive, fully integrated Roll20 Tabletop experiences that enhance gameplay and streamline game management.\nWhether adapting existing character sheets or building new ones from scratch, the Beacon SDK offers the tools and flexibility to bring your virtual tabletop to life.\n","date":"2024-05-07","id":0,"permalink":"/beacon-docs/docs/gettingstarted/introduction/","summary":"This project is currently in closed beta.\nPlease complete the form to request access to the closed beta.\nFor more info about the release of the closed beta, refer to this document","tags":[],"title":"Introduction"},{"content":"This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.\nTo get started quickly with a boilerplate, you can download and start editing the Quick Start Example Sheet which already has the Beacon SDK installed, along with several recommanded patterns implemented in a Vue.js project.\nPrerequisites Before you can install the Beacon SDK, you\u0026rsquo;ll need to have the following:\nA local web development environment with a code editor. Node.js installed on your machine. If you don\u0026rsquo;t have Node.js installed, use the following steps in the official Node.js documentation. A javascript project, we recommand Vue.js but you can choose whichever you are more comfortable with. These steps use npm but you are free to use any package manager and framework you prefer.\nThe following steps will guide you in installing the Beacon SDK in your application:\nStep 1: Add the package to your project You can find the latest version of the package on the NPM registry.\nIn your project\u0026rsquo;s directory, run the following:\nnpm i @roll20-official/beacon-sdk\rThis will install the Beacon SDK package to your project\u0026rsquo;s package.json file.\nStep 2: Use the Beacon package in your project The Beacon package exports various utilities you can use in your application. The main one that needs to be setup to enable the connection between Beacon SDK and Roll20 is initRelay.\nIdeally you would want to call this when your sheet is initalizing, and it is the function where you will define sheet actions, computed values, and how the sheet will response to or send character data changes. visit the initRelay page for a more detailed breakdown.\nAdd the following to your project:\nimport { initRelay } from \u0026#39;@roll20/beacon-sdk\u0026#39;; const dispatch = initRelay({ handlers: { onInit: ({ character } ) =\u0026gt; { console.log(\u0026#39;sheet character\u0026#39;, character) }, onChange: () =\u0026gt; {}, onSettingsChange: () =\u0026gt; {}, onSharedSettingsChange: () =\u0026gt; {}, onTranslationsRequest: () =\u0026gt; {}, onDragOver: () =\u0026gt; {} }, // Refer to our advanced example sheet on how to setup actions and computed properties. actions: {}, computed: {} })\rinitRelay returns a dispatch function that allows you to call methods or send changes from the sheet to Roll20. Check out the page on dispatch to learn more about the different methods.\nStep 3: Settings up the Roll20 tabletop sandbox On the Roll20 website visit the custom sheet sandbox and create a new sandbox, we\u0026rsquo;ll use this sandbox to develop our sheet but we must set it up to listen to our local project\u0026rsquo;s web server.\nAfter creating a new sandbox, we\u0026rsquo;ll be taken to the sandbox details page, here you will find a collapseable section called Sheet.json Editor, opening this we can add the settings we need to connect to our project:\n{ \u0026#34;advanced\u0026#34;: true, \u0026#34;advancedPort\u0026#34;: 7620 // or the port of your webserver }\rAfter adding these changes make sure to click Save Changes at the bottom of the page. After which you can click Launch Game on the page to go into the game and start testing your sheet.\n","date":"2024-04-07","id":1,"permalink":"/beacon-docs/docs/gettingstarted/installing-beacon/","summary":"This installation guide is designed for sheet developers with experience in web development, that want to start creating a character sheet from scratch or already have an existing project they wish to add Beacon to.","tags":[],"title":"Installing Beacon"},{"content":"Prerequisites To set this sheet up properly, make sure that you have the following tools installed:\nVue.js Vite SCSS To download the community quick start sheet, refer to these repositories:\nCommunity Sheet Repo\nQuick Start Sheet\nFigure 1: Quickstart sheet\nUse the following steps to get started:\nInstall the Beacon SDK: Run the following command. npm i @roll20-official/beacon-sdk\rInstall dependencies: Install the dependencies for the project. npm install\rStart the Vite server: After installing the project\u0026rsquo;s dependencies, you\u0026rsquo;ll need to start the Vite server. There are two ways to do this: a. Offline Development: This method will run the Vite server with the default port and environment set to development.\nnpm run dev\rOnce this code executes successfully, you can access the Vite server at http://localhost:5173.\nThis method is useful when you do not have access to the Roll20 website or would like to work on parts of your project that do not depend on a connection to the Roll20 Tabletop or Roll20 Characters, such as working on styling, mocking up the environment, building Vue components, testing functionality, etc.\nIn development mode, you cannot save or access existing character data or use the Beacon SDK functions that depend on Roll20 Tabletop or Roll20 Characters functionality, such as dice rolling and token manipulation.\nb. Sandbox Development: This method will run the Vite server with the port set to 7620 and the environment set to staging mode.\nnpm run sandbox\rThis command will build the SCSS files and then run the Vite server. This will set the server up for connecting to a Roll20 Tabletop custom sheet sandbox as well as through the sandbox in Roll20 Characters.\nTo test your changes in the Roll20 Tabletop custom sheet sandbox, you will need to add the following to the sheet.json editor in the game settings:\n{ \u0026#34;advanced\u0026#34;: true, \u0026#34;advancedPort\u0026#34;: 7620 }\rUseful Commands The following set of commands can come in handy when working with this sheet:\nFor Hot reloading and building CSS files, use the following command: npm run watch-scss\rFor linting, use the following command: npm run lint\rFor formatting with Prettier, use the following command: npm run format\r","date":"2024-04-07","id":2,"permalink":"/beacon-docs/docs/gettingstarted/quick-start-sheet-template/","summary":"Prerequisites To set this sheet up properly, make sure that you have the following tools installed:\nVue.js Vite SCSS To download the community quick start sheet, refer to these repositories:","tags":[],"title":"Quick Start Sheet Template"},{"content":"Prerequisites To set this sheet up properly, make sure that you have the following:\nVue framework \u0026amp; Routing Multiple Data Stores Complex Roll Templates Rich Sheet Actions TypeScript Vite SCSS Ability to run Unit \u0026amp; End-to-End Tests To download the community quick start sheet, refer to these repositories:\nCommunity Sheet Repo\nQuick Start Sheet\nFigure 1: Advanced sheet\nThis sheet uses the same steps listed in the . Immediately after implementing those three steps, you\u0026rsquo;ll add the following step:\nRun a CI check: This will run several checks to ensure your code is as optimal as possible, including formatting, linting, type checking, unit tests, and end-to-end tests. npm run ci-check\rYou can think of this command as a sanity check you can leverage when pushing a big release for your sheet!\nUseful Commands The following set of commands can come in handy when working with this sheet:\nFor Hot reloading and building CSS files, use the following command: npm run watch-scss\rFor linting, use the following command: npm run lint\rFor formatting with Prettier, use the following command: npm run format\rFor type checking with TypeScript, use the following command: npm run type-check\rFor running unit tests with Vitest, use the following command: npm run test:unit\rTo open up and develop local end-to-end tests with Cypress, use the following command: npm run test:e2e:open:local\rFor running local end-to-end tests with Cypress, use the following command: npm run test:e2e:local\rTo run CDN-hosted end-to-end tests with Cypress, use the following command: npm run test:e2e\r","date":"2024-03-07","id":3,"permalink":"/beacon-docs/docs/gettingstarted/example-patterns-sheet/","summary":"Prerequisites To set this sheet up properly, make sure that you have the following:\nVue framework \u0026amp; Routing Multiple Data Stores Complex Roll Templates Rich Sheet Actions TypeScript Vite SCSS Ability to run Unit \u0026amp; End-to-End Tests To download the community quick start sheet, refer to these repositories:","tags":[],"title":"Example Patterns Sheet"},{"content":"There are two ways you can publish a Beacon sheet.\nYou can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access. When publishing a sheet, you will need to includes all the necessary code, assets, and metadata packaged together to be easily deployed and tested on the Roll20 platform. When a sheet is published, either publicly or privately for testing purposes, the sheet will run on Roll20 and will no longer require a local development environment to use it.\nReleasing a Test Sheet The following steps will aid you while releasing your sheet:\nCreate a Build Command:\nYou must have a build command that will produce the minified production-ready code. You can find more information in our Quickstart Package JSON. The build command must be able to create these exact files:\nsheet.js sheet.css host.css (optional) - This is the styling for any sheet rolls made to the chat. Add a local folder that contains fonts and images used in the sheet (optional). Add a sheet.json file:\nAdd a sheet.json file to your sheet folder to ensure the metadata for your sheet is up-to-date. You can find more information about the sheet.json options on the Roll20 Wiki as well as on the Quickstart sheet.\nCreate a Pull Request in the Beacon Community Sheet Repo:\nIn the Beacon Community Sheet Repo, create a pull request that must include the submission checklist listed for reference below.\nThe name of the pull request should\u0026hellip;\nContain the short name of the sheet being submitted, and State the type of change being submitted (New/Update/Bugfix/etc.). Pull Request Title Example: Sheet/\u0026lt;TYPE_OF_CHANGE\u0026gt;/\u0026lt;SHEET_SHORT_NAME\u0026gt; If this is the first time you are submitting this sheet to the repository, please make sure to have the following information ready.\nThe full name of the game associated with the sheet (i.e. Dungeons \u0026amp; Dragons 5th Edition, The Dresden Files RPG). The name of this game system/family associated with the shee (i.e. Dungeons \u0026amp; Dragons, FATE). The publisher of the game associated with the sheet (i.e. Wizards of the Coast, Evil Hat). The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you\u0026rsquo;d like them to be displayed. To see example of how this information will show up, create a new game on Roll20. The name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.\nPull requests that contain changes to files outside the sheet sub-folder on which you\u0026rsquo;re working will be rejected.\nGive Specific Roll20 Users Access:\nBefore your testing sheet is finally approved, you want choose to give specific Roll20 Users access to the testing sheet. This will allow only those users to see the sheet in Roll20 Tabletop and Roll20 Characters. These users will be able to use it just like the final users will when the sheet is public. You can give access to friends, group members, or even clients and publishers you\u0026rsquo;re working with.\nTo give access to one ore more specific user\u0026rsquo;s, fill out the Beacon Sheet Access Form. You will need the email associated with the Roll20 Account that will have access to the sheet for each person you\u0026rsquo;d like to give access.\nWe can always grant more people access to the sheet after it is released. Resubmit the Beacon Sheet Access Form to the new people for which you\u0026rsquo;d like to give access.\nWait for Approval and Access:\nAfter you create a pull request, our team will approve it and add your sheet to the sheet selection in Roll20 Tabletop and Roll20 Characters. We will then give only your Roll20 user and any others you\u0026rsquo;ve listed in the pull request comments access to the sheet in Roll20. This sheet will then be available for you and others with access to test it.\nSubmission Checklist The Pull Request title contains the short name of the sheet being submitted. The Pull Request title states the type of change being submitted (New/Update/Bugfix/etc.). I have authorization from the game\u0026rsquo;s publisher to make this an official sheet on Roll20 with their name attached. This game is not a traditionally published game, but a copy of the game rules can be purchased/downloaded/found at: \u0026lt; \u0026gt; This sheet is for an unofficial fan game, modification to an existing game, or a homebrew system. New Sheet Checklist If you are submitting a new sheet to the repository, please fill in any empty spaces indicated by \u0026lt; \u0026gt;.\nThe full name of the game associated with the sheet is: \u0026lt; \u0026gt; (i.e. Dungeons \u0026amp; Dragons 5th Edition, The Dresden Files RPG) The name of this game system/family associated with the sheet is: \u0026lt; \u0026gt; (i.e. Dungeons \u0026amp; Dragons, FATE) The publisher of the game associated with the sheet is: \u0026lt; \u0026gt; (i.e. Wizards of the Coast, Evil Hat) The information that is provided here will be used to help users find the sheet in Roll20 Tabletop and Roll20 Characters. Please make sure that all names that you provide read exactly how you\u0026rsquo;d like them to be displayed. To see example of where this information will show up, create a new game on Roll20. The Name and the publisher will show up in the dropdown menu and as the title of the sheet that is selected.\nPlease check any that apply:\nChanges / Description (optional) Provide any notes relevant to this pull request here. This can include a description of the code changes, references to related pull requests, etc.\nMore Help Additional information for the beacon sdk can be found at the Beacon SDK Documentation Site. You can also post additional questions using the Beacon Community GitHub Issues Tab.\nReleasing a Final Version After you have released a test version of your sheet, you can follow the same steps as releasing a test version to make your sheet available to everyone. This time, the pull request comments state that it is a final release version.\nOnce you have created the pull request, our team will review the sheet functionality, code, and metadata for consistency, best practices, and overall system security. We reserve the right to reject any sheet that does not meet our terms of use or conflicts with our partnerships.\n","date":"2024-02-07","id":4,"permalink":"/beacon-docs/docs/gettingstarted/releasing-a-sheet/","summary":"There are two ways you can publish a Beacon sheet.\nYou can publish a testing verison of the sheet privately and give specific Roll20 users access to it on Roll20 Characters and Roll20 Tabletop, or You can submit a request to publish your sheet publicly for all users on Roll20 Characters and Roll20 Tabletop to have access.","tags":[],"title":"Releasing a Sheet"},{"content":"Well-thought-through product announcements will help increase feature awareness and engage users with new functionality. Just like sharing your public roadmap, it\u0026rsquo;s also a great way to let potential customers see that you\u0026rsquo;re constantly improving.\nFurther reading Read How to announce product updates and features ","date":"2023-09-07","id":5,"permalink":"/beacon-docs/blog/example-post/","summary":"You can use blog posts for announcing product updates and features.","tags":[],"title":"Example Post"},{"content":"","date":"2023-09-07","id":6,"permalink":"/beacon-docs/blog/","summary":"","tags":[],"title":"Blog"},{"content":"The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games. initRelay is the main method that initializes the Beacon SDK communication channel with the host (Either the Roll20 tabletop or in Roll20 Characters). It should be initialized as soon as the sheet loads, as its onInit handler will be the earliest we can get access to that character\u0026rsquo;s data.\ninitRelay({ handlers: { onInit, onChange, onSettingsChange, onSharedSettingsChange, onTranslationsRequest, onDragOver, onDropOver, }, actions: {}, computed: {}, convertLegacyMacroAttributes, handleLegacyRollTemplates }): Promise\u0026lt;Dispatch\u0026gt;\rThese components are crucial for handling actions, computations, macros, and rolls. This overview provides a high-level summary of each section, helping you understand their roles and how they integrate within the SDK.\nActions\rActions define specific operations that can be performed by characters within the Roll20 Tabletop. These operations can range from simple tasks like rolling a dice to more complex interactions such as casting spells or activating abilities.\nHandlers\rHandlers are event listeners that manage communication between the Roll20 Tabletop and the character sheet. They respond to various events, such as changes in character attributes or settings, and trigger appropriate actions or updates.\nComputed\rComputed properties are dynamic values derived from other character attributes. They allow for the creation of complex, calculated attributes that automatically update when their dependencies change.\nMacro Attributes\rMacro attributes handle the conversion of legacy macro attributes to the new format used in the Beacon SDK. This ensures compatibility with older character sheets and macros, allowing for a smooth transition to the new system.\nRolls\rThe Rolls component allows for advanced dice-rolling mechanics within the Roll20 Tabletop. It supports both simple and complex rolls, providing flexibility in how roll results are displayed and computed.\nDispatch\rThe dispatch object provides methods for sending commands from the character sheet back to the host. Except when specified every method returns a promise.\n","date":"2024-06-07","id":7,"permalink":"/beacon-docs/docs/components/initrelay/","summary":"The Beacon SDK is composed of various methods and components that allow developers to create dynamic and interactive character sheets for virtual tabletop (VTT) games.","tags":[],"title":"InitRelay"},{"content":"\rinitRelay({ //...other methods actions: {}, }): Promise\u0026lt;Dispatch\u0026gt;\rActions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters. These actions are used for any rolls that may need to be triggered outside of the sheet itself, such as from a macro or a chat button. Generally, most or all of a sheet’s rolls should be defined as actions.\nactions: { [name: string]: { method: (props: { dispatch: Dispatch, character: Character, messageId?: string, rolls?: RollResults }, ...args: string[]): void | Promise\u0026lt;void\u0026gt; } }\rActions are passed into the initRelay function in an object, where the keys are the unique names of the actions, and the values are objects containing a method property (additional metadata fields may be added to this object in the future).\nThe action\u0026rsquo;s method receives a props object from the host containing the following properties:\ndispatch: A Dispatch object. character: The data of the character performing the action. Currently, the action will not receive the character’s bio or GM notes, regardless of whether the player has access to those fields. messageId (optional): A unique ID for an existing chat message. It\u0026rsquo;s included in actions triggered from chat buttons to provide context for the original roll. rolls (optional): Included when action is triggered from a chat button. Contains the roll results of the original roll. These methods can also receive an unlimited number of additional arguments. This is because these actions can be triggered by plain text via a macro. However, all additional arguments must be strings. Additionally, these methods can be synchronous or asynchronous and do not return a value.\n","date":"2024-05-07","id":8,"permalink":"/beacon-docs/docs/components/actions/","summary":"initRelay({ //...other methods actions: {}, }): Promise\u0026lt;Dispatch\u0026gt;\rActions are a collection of methods that can be executed from the Roll20 Tabletop or Roll20 Characters.","tags":[],"title":"Actions"},{"content":"Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.\ninitRelay({ //...other methods computed: { [name: string]: { tokenBarValue?: boolean description?: string get: ( props: { character: Character }, ...args: string[] ) =\u0026gt; string | number | JSONValue set?: ( props: { character: Character dispatch: Dispatch }, ...args: string[] ) =\u0026gt; void | Promise\u0026lt;void\u0026gt; } }, }): Promise\u0026lt;Dispatch\u0026gt;\rComputed properties are passed into the initRelay function in an object where the keys are the names of the properties, and the value should be an object containing the following:\nget (required): It receives character data along with any number of string parameters and should return the computed value. tokenBarValue (optional): A boolean indicating whether this property should be available for use in token bars. description (optional): A text value indicating what this computed summary property represents. set (optional): This method receives character data and a dispatch, along with string arguments. This method does not need to return a value. Setting tokenBarValue to true will make the property available to use as a value for token bars. To work correctly, the get function must not rely on any additional arguments and must return either a simple value (a string or number) or an object: { current: number | string, max: number | string }\rIf the set function is omitted, the value will not be editable from the token itself. If defined, set methods will receive one string argument, which is whatever the user types into the input for modifying the bar. ","date":"2024-04-07","id":9,"permalink":"/beacon-docs/docs/components/computed/","summary":"Sheet authors define computed properties that are accessed by the Roll20 Tabletop or Roll20 Characters. These computed properties can be used as attributes in macros and are available to assign as values to token bars - if the tokenBarValue property is set to true.","tags":[],"title":"Computed"},{"content":"Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet. It is the main agrument that must be passed into initRelay or the sheet will never fully load.\ninitRelay({ handlers: { onInit, onChange, onSettingsChange, onSharedSettingsChange, onTranslationsRequest, onDragOver, // optional onDropOver, // optional } //...other methods }): Promise\u0026lt;Dispatch\u0026gt;\ronInit The onInit method receives the initial data from the host.\nThis will be the first time we have access to character data, sheet settings, as well as compendium data if this character is made as a result of a compendium drag and drop on the host.\nonInit(event: { character: Character, // Initial Data of the primary character for this sheet. settings: { // Campaign and character specific settings colorTheme: string, // \u0026#39;dark\u0026#39; or \u0026#39;light\u0026#39; language: string, // two-letter language code, i.e. \u0026#39;en\u0026#39; gm: boolean, // whether or not the current player has gm permissions owned: boolean, // whether or not the current player controls the primary character settingsSheet: boolean, // whether or not this sheet is the settings sheet headless: boolean, // whether or not it should be displayed, set by the host sandbox: boolean, campaignId: number, // The id of the current campaign environment: string, // VTT, CHARACTERS, DISCORD currentUserId: string, // user id of user opening the sheet singleSheet: boolean }, sharedSettings: {}, // Data shared between all characters in this campaign compendiumDropData: { // Populated when the character sheet is created from a compendium entry such as a creature or NPC. pageName: string, categoryName: string, expansion: number, }, }, dispatch: Dispatch): void;\rThis function may be called multiple times during development in the sheet sandbox as part of hot reloads.\nonChange onChange is called whenever a character’s data is changed on the host’s end. The event object contains a partial character with only the character’s ID and the changed data. This could be the character’s bio, GM notes, or attributes (only the changed attributes).\nonChange(e: { character: Partial\u0026lt;Character\u0026gt; }, dispatch: Dispatch): void;\ronSettingsChange onSettingsChange is called when either the host’s color theme is changed, or when the current player’s ownership of the primary character changes.\nonSettingsChange(e: { colorTheme: string, owned: boolean }, dispatch: Dispatch): void;\ronSharedSettingsChange onSharedSettingsChange is called when someone changes a shared setting in the host.\nonSharedSettingsChange({ settings: { [key: string]: any } }): void;\ronTranslationsRequest onTranslationsRequest is called before the relay is fully initialized and returns the translation JSON data corresponding to the two-letter language argument.\nonTranslationsRequest(language: string): { [key: string]: string };\ronDragOver (optional) onDragOver is called when a compendium item from the compendium tab is dragged over the iframe window containing the character sheet.\nCoordinates of the drag are provided via top and left values, and basic compendium data is passed so that a subsequent compendium request can be made via the provided dispatch. If the item is moved outside of the iframe, dragData and coordinates are null.\nonDragOver(e: { coordinates: { top: number, left: number }, dragData: { pageName: string categoryName: string expansionId: number } | null, }, dispatch: Dispatch) =\u0026gt; void\ronDropOver (optional) onDropOver is called when a compendium item from the compendium tab is dropped over the iframe window containing the character sheet.\nCoordinates of the drop are provided via top and left values, and basic compendium data is passed so that a subsequent compendium request can be made via the provided dispatch.\nonDropOver(e: { coordinates: { top: number, left: number }, dropData: { pageName: string categoryName: string expansionId: number } }, dispatch: Dispatch) =\u0026gt; void\r","date":"2024-03-07","id":10,"permalink":"/beacon-docs/docs/components/handlers/","summary":"Handler methods allow the sheet to respond to data passed from the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page) to the sheet.","tags":[],"title":"Handlers"},{"content":"The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed. These features include attributes and elements that allow for dynamic roll results and interactivity within the host. Vist the Roll20 help center to learn more about Roll20\u0026rsquo;s Dice Rolling system\nThe most command way to trigger a dice roll is through the dispatch object returned from the initRelay, but it could also be called from actions:\ndispatch.roll({ rolls: { [rollName: string]: string } // Ex. {attack: \u0026#39;1d20+4\u0026#39;, damage: `3d6+2`} messageId?: string }): Promise\u0026lt;{messageId: string, results: RollResults }\u0026gt;\rThe roll method takes one or more rolls in the form of an object, where the keys are unique roll names and the values are roll strings.\nmessageId can be provided to attach the roll to an existing chat message, either overriding it or appending to it in the chat log. If messageId is omitted, the roll will be associated with a new chat message and a new messageId for that message will be returned with the roll results. The method returns a promise that resolves with an object containing the messageId and the RollResults. The roll result is returned in the same format as in the non-beacon dice rolls computed roll system.\nThe dispatch roll method and the actions roll section do not post to the chat, instead they will return a promise which will resolve to the roll results and the message id.\nPosting A Roll to the Chat The roll method does not send or post any data to the chat on it\u0026rsquo;s own. We instead have to use dispatch\u0026rsquo;s post method to send our roll results along with any other content to the chat.\ndispatch.post({ characterId: \u0026#39;-O0KZhMTxLkn2HArFj8f\u0026#39;, content: `I rolled a ${diceRoll.results.attack.results.result} to hit and did ${diceRoll.results.damage.results.result} damage!`, })\rAdditional Roll Posting Options data-rollname The data-rollname attribute tells the host that this HTML element is displaying the result of a roll.\n\u0026lt;span data-rollname=\u0026#34;attack\u0026#34;\u0026gt;\u0026lt;/span\u0026gt;\rThe host will both add the Quantum Roll signature element and replace the contents of the element with the result from the roll.\nThis is the preferred method for displaying roll results wherever possible, that is, sending the whole roll formula to the roll server and allowing the host to display the result.\ndata-computed Tagging an element with both a data-rollname and a data-computed=\u0026quot;true\u0026quot; tells the host that this element is associated with a roll, but the results of that roll were computed by the author, as opposed to the roll server computing the result.\n\u0026lt;span data-rollname=\u0026#34;complex\u0026#34; data-computed=\u0026#34;true\u0026#34;\u0026gt;25\u0026lt;/span\u0026gt;\rThe host will add the Quantum Roll signature tooltip, but the content of the element will not be modified. Generally, this should only be used when the roll server does not support a particular dice mechanic.\nRoll Buttons Roll buttons are interactive elements that trigger sheet actions, such as damage rolls, when clicked. These buttons use the data-sheet-action attribute to specify the action to be executed.\n\u0026lt;button data-sheet-action=\u0026#34;damage\u0026#34; data-args=\u0026#34;arg1:arg2\u0026#34;\u0026gt;Click Me\u0026lt;/button\u0026gt;\rAdditional arguments can be provided using the data-args attribute, and the character, messageId, and original rolls will be included automatically.\nRolls Results Format type RollResults = { [name: string]: { expression: string //The original expression (i.e. 1d20+3d6) rollName: string //The name of the roll results: { //The results of the roll(s) expression: string dice?: number[] // result: number //The final result of the roll rolls?: { //Detailed results of each part of the roll (i.e. 3d6) sides: number //The type of die for this part of the roll (i.e. 6) dice: number //The number of dice (i.e. 3) results: number[] //The result of each die (i.e. [4, 2, 5]) }[] } } }\r","date":"2024-01-07","id":11,"permalink":"/beacon-docs/docs/components/rolls/","summary":"The Roll20 Tabletop and Roll20 Characters (both refered to as host throughout the rest of this page) have several new features that enhance the way rolls are handled and displayed.","tags":[],"title":"Rolls"},{"content":"The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host. Except when specified every method below will return a promise.\nupdate dispatch.update({ options: { overwrite?: boolean } character: Partial\u0026lt;Character\u0026gt; }): Promise\u0026lt;void\u0026gt;\rThe update method sends character changes to the host (Roll20 Tabletop or Roll20 Characters) to be persisted.\nThe partial character passed in here must contain the character\u0026rsquo;s id, and can contain any combination of the attributes, bio, and gmNotes properties. When updating a character’s attributes, only include those attributes that have changed.\nupdateCharacter dispatch.updateCharacter({ character: Partial\u0026lt;Character\u0026gt; }): Promise\u0026lt;void\u0026gt;\rLike the update method, updateCharacter sends character changes to the host page (Roll20 Tabletop or Roll20 Characters) to be persisted.\nHowever, this method takes a full set of character attributes as the character argument, and automatically computes the diff with existing character attributes, so that only changed attributes are sent to the data store.\nroll dispatch.roll({ rolls: { [rollName: string]: string } // Ex. {attack: \u0026#39;1d20+4\u0026#39;, damage: `3d6+2`} messageId?: string }): Promise\u0026lt;{messageId: string, results: RollResults }\u0026gt;\rThe roll method takes one or more rolls in the form of an object, where the keys are unique roll names and the values are roll strings. messageId can be provided to attach the roll to an existing chat message, either overriding it or appending to it in the chat log.\nIf messageId is omitted, the roll will be associated with a new chat message and a new messageId for that message will be returned with the roll results.\nThe method returns a promise that resolves with an object containing the messageId and the RollResult (see Types). The roll result is returned in the same format as in the non-beacon dice rolls computed roll system.\npost dispatch.post({ characterId: string, messageId?: string, content: string, options?: { whisper?: \u0026#39;gm\u0026#39;, secret?: boolean, } }): Promise\u0026lt;string\u0026gt;\rpost posts a message to chat, either creating a new message or overwriting an existing one. It requires a character id and message content, a string containing either plain text or HTML to be posted.\nThe method also accepts an options object. Currently, only whisper and secret are supported, the only valid value for whisper is gm, which will send the message as a whisper to the gm.\nThe secret option is ignored unless whisper is also set, toggling to true will cause the message to not be visible to the controlling player.\nLike roll, messageId can be provided to update an existing chat message, but if omitted the method will generate a new messageId and post a new chat message. The method returns the messageId.\nquery dispatch.query(options: Swal2Options): { isConfirmed: boolean, isDenied: boolean, isDismissed: boolean, value?: string | number, dismiss?: \u0026#34;cancel\u0026#34; | \u0026#34;backdrop\u0026#34; | \u0026#34;close\u0026#34; | \u0026#34;esc\u0026#34; | \u0026#34;timer\u0026#34;, errors?: string[], }: Promise\u0026lt;{ results: { isConfirmed: boolean isDenied: boolean isDismissed: boolean value: string | number dismiss: string }, errors: [string] }\u0026gt;\rThe query method takes an options object and uses them to display a SweetAlert2 prompt to the user. It returns the results of the query as a SweetAlertResult, along with any errors encountered. The options work exactly as described in the documentation for SweetAlert2, however not all options are allowed. Here is a list of the allowed options:\ntitleText, text, iconColor, input, width, padding, background, position, grow, timer, timerProgressBar, showConfirmButton, showDenyButton, showCancelButton, ariaLabel, confirmButtonText, denyButtonText, cancelButtonText, confirmButtonAriaLabel, confirmButtonColor, cancelButtonAriaLabel, cancelButtonColor, denyButtonAriaLabel, denyButtonColor, reverseButtons, showCloseButton, closeButtonAriaLabel, returnInputValueOnDeny, imageUrl, imageWidth, imageHeight, imageAlt, inputLabel, inputPlaceholder, inputValue, inputOptions, inputPlaceholder, inputAutoTrim, inputAttributes, validationMessage, progressSteps, currentProgressStep, progressStepsDistance.\nPerform dispatch.perform({ characterId: string, action: string, args: string[], }): Promise\u0026lt;void\u0026gt;;\rperform executes the specified action on behalf of the character (designated by the character id), passing in args to the action method. This method can perform actions on behalf of any character, even a character that the sheet does not have data for.\ngetComputed dispatch.getComputed({ characterId: string, property: string, args: string[] }): Promise\u0026lt;string | number | object\u0026gt;\rsee setComputed below\nsetComputed dispatch.setComputed({ characterId: string, property: string, args: string[] }): Promise\u0026lt;string | number | object\u0026gt;\rgetComputed and setComputed are both nearly identical in how they are called, taking a character id and a property with the name of the computed property you wish to get or set, and an array of string args. Both methods return a promise that resolves with the computed value.\ncompendiumRequest dispatch.compendiumRequest({ query: string }): Promise\u0026lt;{ data: Object errors: Array\u0026lt;Error\u0026gt; extensions: Record\u0026lt;string, any\u0026gt; }\u0026gt;\rcompendiumRequest executes an AJAX request to the compendium service’s graphQL endpoint. It takes in a graphQL query string written according to the Compendium service’s schema. The query string does not need to include the ruleSystem shortName as this is set automatically according to the campaign override or sheet.json value in the Roll20 Tabletop.\ndebouncedCompendiumRequest dispatch.debouncedCompendiumRequest({ query: string }): Promise\u0026lt;{ data: Object }\u0026gt;\rLike compendiumRequest, except that calls to this method are automatically debounced (at 100ms) and grouped together into a single request to the compendium service. Note that this method will only return the requested data, it does not return errors or extensions.\ngetTokens dispatch.getTokens({ characterId: string }): Promise\u0026lt;{ selected: Token[], tokens: Token[] }\u0026gt;: Promise\u0026lt;{ selected: Token[] tokens: Token[] }\u0026gt;\rgetTokens requires a character id string and returns information about tokens on the user’s current page. The return value contains two arrays of tokens. The tokens array contains all tokens on the current page that represent the character whose id was provided to the method. The selected array contains any tokens that are currently selected, regardless of which character they represent. The returned token objects contain all of the token attributes available to the API, you can find documentation here and here.\naddToTracker dispatch.addToTracker({ tokenId?: string, custom?: { name: string img?: string } formula?: string value: string | number }): Promise\u0026lt;void\u0026gt;\raddToTracker adds or updates a single item in the turn tracker. Passing in a tokenId will add the specified token to the tracker, while passing in custom with a name and an optional image url (img) will add a custom item, not connected to any character or token. A round calculation string can be added via the optional formula parameter. value is the initiative number for the item.\naddActionsToHost dispatch.addActionsToHost({ sheetAction?: { characterId: string action: string args?: string[] } action?: string locations?: [\u0026#39;macroBar\u0026#39;] | [\u0026#39;tokenActionBar\u0026#39;] | [\u0026#39;macroBar\u0026#39;, \u0026#39;tokenActionBar\u0026#39;] actionId?: string name: string requestId?: string }): void\raddActionsToHost adds a specific action(macro) to an area of the Roll20 Tabletop UI; either the macrobar or the token action bar. Either sheetAction or action can be passed in but not both at the same time. The sheetAction arg should be passed in when an the action is to designated to a character. While the action arg should be passed in when the action is more generic.\ngetActions dispatch.getActions({ args: { characterId?: string } }): Promise\u0026lt;{ actions?: {} | { [id: string]: ActionFromHost } }\u0026gt;\rgetActions gets a specific character’s actions(macro).\nsetContainerSize dispatch.setContainerSize({ args: { width?: number height?: number } }): Promise\u0026lt;void\u0026gt;\rsetContainerSize updates the size of the container which holds the sheet shared settings. Returns a promise that can be awaited. This can be used in conjunction with something like the ResizeSensor event listener from npm: css-element-queries to automatically resize the container on the host.\nupdateTokensByCharacter dispatch.updateTokensByCharacter({ args: { characterId: string token: Partial\u0026lt;Token\u0026gt; } }): Promise\u0026lt;void\u0026gt;\rupdateTokensByCharacter updates a particular character’s default token as well as all existing tokens representing that character. Returns a promise that can be awaited.\nupdateTokensByIds dispatch.updateTokensByIds({ args: { tokenIds: array of ids as strings token: Partial\u0026lt;Token\u0026gt; } }): Promise\u0026lt;void\u0026gt;\rupdateTokensByIds updates a single or several tokens. Returns a promise that can be awaited.\nautoLinkText dispatch.autoLinkText({ args: { text: string } }): Promise\u0026lt;string\u0026gt;\rautoLinkText goes through the text to find handout names between square brackets and converts them into links with the handoutID. For example in a game with a handout named Dragon, passing in the text string of this is a [Dragon] to autoLinkText returns something similar to this is a \u0026lt;a href=\u0026quot;https://journal.roll20.net/8je02j0kd02k\u0026quot;\u0026gt;Dragon\u0026lt;/a\u0026gt;.\nopenDialogFromLink dispatch.openDialogFromLink({ args: { urlString: string } }): void\ropenDialogFromLink opens the supplied urlString through the Roll20 Tabletop.\nIf the url is for a handout, it will open the corresponding handout in the campaign. This will also check if the user opening the link has access to the handout. If the url is for a compendium, it will open a pop up to the compendium page, it will also check to ensure the user has access to view the page. If the url is for an external page, a confirmation pop up will display to warn the user that the link is for an external site and open a new tab in their main window if confirmed. ","date":"2023-09-07","id":12,"permalink":"/beacon-docs/docs/components/dispatch/","summary":"The dispatch is returned by the initRelay and provides methods for sending commands from the character sheet back to the host.","tags":[],"title":"Dispatch"},{"content":"When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.\nThis scenario commonly arises when transitioning from an existing legacy sheet to a Beacon sheet. During such transitions, it\u0026rsquo;s possible that the attributes or roll templates called from the legacy macro may not align with the structure of attributes or the lack of roll templates in the Beacon Sheet.\nconvertLegacyMacroAttributes The convertLegacyMacroAttributes method allows us to determine the mapping strategy for legacy attributes to the new Beacon Sheet.\ninitRelay({ convertLegacyMacroAttributes: (messages: { attribute: string, characterId: string, character: Character }) =\u0026gt; {}: any, }): Promise\u0026lt;Dispatch\u0026gt;\rThis method is defined during the initial SDK initialization process and is invoked by the host when it attempts to parse a macro and encounters a failure in locating an attribute\u0026rsquo;s value during an macro\u0026rsquo;s execution.\nAdvanced sheet actions typically will first search through the defined computed properties before resorting to the convertLegacyMacroAttributes method as a fallback.\nThe method\u0026rsquo;s purpose is to return a value that will be substituted in the macro. However, it grants us the autonomy to devise the preferred approach for handling legacy attribute values.\nhandleLegacyRollTemplates Since Beacon sheets no longer require or use roll templates as previously needed in older custom sheets, there will be times where a legacy macro might make include a reference to a legacy roll template. We can use the handleLegacyRollTemplates to determine how to handle these cases.\ninitRelay({ handleLegacyRollTemplates: (message: { templateName: string, // name of the template that triggered this method properties: Record\u0026lt;string, any\u0026gt;, // a list of the values and formulas for rolls and macro in the template // along with values for other properties in the template dispatch: Dispatch, playerid: string , originalInput: string // the original text input for the entire roll template string }) =\u0026gt; {}: any, }): Promise\u0026lt;Dispatch\u0026gt;\rThe properites object will also include a plainText key for roll template arguments not inside the curly brace syntax.\n{ //... other arguments properties: { attack: { value: 12, formula: \u0026#39;1d20\u0026#39; }, damage: { value: 5, formula: \u0026#39;2d6\u0026#39; }, foo: { value: \u0026#39;bar\u0026#39; }, name: { formula: \u0026#34;@{Helga|name}\u0026#34; value: \u0026#34;Helga\u0026#34; }, plainText: [\u0026#39;apicallback\u0026#39;, \u0026#39;apple=red\u0026#39;], something: { value: \u0026#34;I went to get tacos\u0026#34; }, ............ } }\r","date":"2023-09-07","id":13,"permalink":"/beacon-docs/docs/components/handling-legacy-methods/","summary":"When utilizing Macroswithin the Roll20 Tabletop or Roll20 Characters (both refered to as host throughout this page), there are instances where a legacy macro might need to be employed for a Beacon sheet.","tags":[],"title":"Handling Legacy methods"},{"content":"","date":"2024-06-07","id":14,"permalink":"/beacon-docs/docs/gettingstarted/","summary":"","tags":[],"title":"Getting Started"},{"content":"","date":"2024-04-07","id":15,"permalink":"/beacon-docs/docs/components/","summary":"","tags":[],"title":"Components"},{"content":"","date":"2024-02-07","id":16,"permalink":"/beacon-docs/docs/about/","summary":"","tags":[],"title":"About"},{"content":"\rQ: How is Beacon better than the old way of building sheets (known as Custom Sheets)?\rIt depends on your web development skill level. There are a number of benefits to the Beacon SDK if you know how to build web applications. If you don\u0026rsquo;t know how to set up your own local environment, than the Beacon SDK might now be the first place you should start. Learn more about sheet development using the custom sheet.\nIf you have the skill to take advantage of the Beacon SDK, there are a number of improvements that will make it much easier to build characters sheets.\nFirst, the Beacon SDK allows you to develop locally and preview your changes automatically in the Roll20 Tabletop and Roll20 Character sandboxes. This means that you don\u0026rsquo;t have to keep uploading your HTML and CSS into the custom sheet to see your changes.\nNext, it allows you to develop your character sheet with all the power of JavaScript frameworks and modern web development libraries. In our example sheets, we use Vue.js, but you are free to use whatever you are most comfortable with. Also, you could use something like Cypress to create automated testing. That\u0026rsquo;s what we use in our Beacon sheets.\nLastly, the Beacon SDK makes it much easier for a web developer who knows JSON and Javascript to access character data and manage attributes on the character. If you\u0026rsquo;re familiar with the custom sheet, you no longer have to deal with sheet workers to get the data you need for a character. Also, the Beacon SDK introduces nested and computed attributes that make complex data models for your character sheet easier to create and maintain.\nQ: I\u0026rsquo;m not really a web developer, should I use Beacon or the custom sheet to make a my own character sheet?\rThat is up to you and your comfort level. If you\u0026rsquo;re looking to learn more about web development, building a character sheet with the Beacon SDK is a great way to level up your skills. What you learn during this process can be taken with you into any other web development project you work on in the future.\nIf setting up your own development environment is too intimidating for you, than it might be easier for you to start with the custom sheet and to go from there.\nQ: I\u0026rsquo;m interested in using Beacon, but I don\u0026rsquo;t know the basics of setting up a local environment. Where can I go to learn more about web development?\rYou can start learning how to build a local development environment by reading or watching the following tutorials. Note: these are not tutorials that we\u0026rsquo;ve produced, but we have found them helpful in getting started with web development.\nhttps://learn.microsoft.com/en-us/windows/dev-environment/javascript/vue-on-wsl https://www.youtube.com/watch?v=WPqXP_kLzpo Q: Now that Roll20 has acquired Demiplane, will you continue to support character sheets built on Beacon?\rThe recent acquisition of Demiplane brings exciting new opportunities for character sheets and compendiums on Roll20. At the same time, we are fully committed to supporting the Beacon SDK and character sheets that are built in our new advanced sheets ecosystem on Roll20. In fact, we believe that the Beacon SDK will be a key component of our future plans for Demiplane integration. In addition, our new D\u0026amp;D 2024 sheet is built on top of the Beacon SDK, and we will continue to utilize it to build first-class experiences on Roll20.\nIn short, you can rest assured that the Beacon SDK is an important tool in our toolbox moving forward.\nQ: What are actions in the context of Beacon?\rActions are methods executed in the chat log of Roll20 Tabletop or Roll20 Characters, often used for rolls triggered from macros or chat buttons. They are defined in the sheet\u0026rsquo;s configuration and can interact with character data. Q: How are computed properties used in Roll20?\rComputed properties are attributes which are accessible by users of your character sheet. They are usable in macros to create custom rolls or common actions for each character. Computed properties can represent derived values or complex calculations based on character data. Q: What is the dispatch function used for?\rThe dispatch function provides methods for sending commands from the character sheet back to Roll20, including updating character data, performing actions, and interacting with the interface. Q: What are roll buttons, and how do they work?\rRoll buttons are HTML elements with specific attributes that execute designated sheet actions when clicked. They can pass arguments to the action method and are commonly used for triggering rolls from the character sheet. Q: How are legacy attributes handled in Beacon?\rBeacon gives you the ability to transition your legacy attributes to new attributes you create in Beacon. This means that when a user updates their sheet to the new Beacon sheet, their legacy attribute can be mapped to Beacon attributes using the convertLegacyMacroAttributes function. Sheet developers can define how to handle legacy attribute values to ensure compatibility with existing macros. Q: What is the purpose of the query function?\rThe query function displays a SweetAlert2 prompt to users and returns the results along with any errors. It is commonly used for interactive prompts or confirmations within the VTT interface. Q: How are tokens managed in the VTT?\rTokens represent characters or objects on Roll20 Tabletop (VTT). Functions like getTokens, updateTokensByCharacter, and addToTracker are used to retrieve token information, update token data, and manage tokens in the turn tracker. Q: What is the role of the convertLegacyMacroAttributesArgs type?\rThe convertLegacyMacroAttributesArgs type defines the arguments used for handling legacy macro attributes. It includes the attribute name, character ID, and character data needed for mapping legacy attributes to the new sheet structure. ","date":"2024-01-07","id":17,"permalink":"/beacon-docs/docs/about/faq/","summary":"Q: How is Beacon better than the old way of building sheets (known as Custom Sheets)?\rIt depends on your web development skill level.","tags":[],"title":"FAQ"},{"content":"Background: The background color of the alert box.\nCharacter: An entity in the game with attributes, bio, GM notes, and a token representation.\nCharacter sheet: A digital or printed page used to track a character\u0026rsquo;s attributes, abilities, and other relevant information in a role-playing game.\nComputed Property: Properties that have both get and set methods, which can be dynamically calculated.\nConvertLegacyMacroAttributes: A function to handle mapping legacy macro attributes to the new Beacon Sheet format.\nDispatch: A set of functions enabling the sheet to send commands back to the VTT.\nGM (Game Master): The person who runs the game, controls the NPCs \u0026amp; the story, and provides challenges for the players.\nHandler: Methods that act as event handlers to process messages from the host.\nInitRelay: Function to initialize the SDK relay, setting up communication between the host and the character sheet.\nMacro: A script that automates repetitive tasks in the VTT.\nRoll Template: A predefined format for displaying the results of a dice roll.\nToken: A visual representation of a character or object on the virtual tabletop, with various properties like position, size, and attributes.\nVTT (Virtual Tabletop): An online platform that allows players to play tabletop role-playing games over the internet.\nValidationMessage: A message displayed when an input value does not meet specific criteria.\nQuantum Roll: A system that ensures the fairness and authenticity of dice rolls in the VTT by using cryptographic methods.\n","date":"2024-03-07","id":18,"permalink":"/beacon-docs/docs/about/glossary/","summary":"Background: The background color of the alert box.\nCharacter: An entity in the game with attributes, bio, GM notes, and a token representation.","tags":[],"title":"Glossary"},{"content":"We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:\nHow to Contribute Reporting Bugs If you find a bug, please report it by opening an issue in the GitHub repository. Provide as much detail as possible to help us understand and reproduce the issue.\nSuggesting Features We welcome suggestions for new features. Please open an issue in the GitHub repository with a detailed description of the feature you would like to see and why you think it would be useful.\nCode Contributions Fork the Repository: Create a personal fork of the project on GitHub.\nClone the Fork: Clone your fork to your local machine.\ngit clone Create a Branch: Create a new branch for your work.\ngit checkout -b feature-or-bugfix-description\rMake Changes: Make your changes to the codebase. Follow the existing code style and conventions.\nRun Tests: Ensure that all tests pass before submitting your changes.\nnpm run ci-check\rCommit Changes: Commit your changes with a descriptive commit message.\ngit commit -m \u0026#34;Description of your changes\u0026#34;\rPush Changes: Push your changes to your fork.\ngit push origin feature-or-bugfix-description\rCreate a Pull Request: Open a pull request from your fork to the main repository. Provide a detailed description of your changes and why they should be merged.\nRunning Tests Unit Tests: Run unit tests with Vitest.\nnpm run test:unit\rEnd-to-End Tests: Run End-to-End tests with Cypress.\nnpm run test:e2e\rCode Style Follow the existing code style and conventions.\nUse ESLint for linting.\nnpm run lint\rFormat code with Prettier.\nnpm run format\rCommunication GitHub Issues: Use GitHub issues for bug reports, feature requests, and questions. Pull Requests: Use GitHub pull requests to submit your code contributions. Thank you for contributing to the Beacon SDK project!\n","date":"2024-02-07","id":19,"permalink":"/beacon-docs/docs/about/how-to-contribute/","summary":"We appreciate your interest in contributing to the Beacon SDK project. Here are some guidelines to help you get started:","tags":[],"title":"How to Contribute"},{"content":"Release Date: 2022-03-17\nNew Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development. Basic and advanced sheet examples. Improvements Detailed comments added to example files for better understanding. Support for complex roll templates and rich sheet actions. Bug Fixes N/A (initial release). Version 2.0.0 Release Date: 2023-03-17\nNew Features SCSS support for styling. Integration with Roll20 and VTT. Mock Relay for offline development. Improvements TypeScript integration for type checking and improved development experience. Unit testing with Vitest. End-to-End testing with Cypress. Bug Fixes N/A (initial release). ","date":"2024-01-07","id":20,"permalink":"/beacon-docs/docs/about/changelog/","summary":"Release Date: 2022-03-17\nNew Features Initial release of the Beacon SDK. Support for Vue.js framework. Setup with Vite for rapid development.","tags":[],"title":"Changelog"},{"content":"","date":"2023-09-07","id":21,"permalink":"/beacon-docs/docs/","summary":"","tags":[],"title":"Docs"},{"content":"","date":"2023-09-07","id":22,"permalink":"/beacon-docs/privacy/","summary":"","tags":[],"title":"Privacy Policy"},{"content":"","date":"2023-09-07","id":23,"permalink":"/beacon-docs/","summary":"","tags":[],"title":"Welcome to Beacon SDK"},{"content":"","date":"0001-01-01","id":24,"permalink":"/beacon-docs/categories/","summary":"","tags":[],"title":"Categories"},{"content":"","date":"0001-01-01","id":25,"permalink":"/beacon-docs/contributors/","summary":"","tags":[],"title":"Contributors"},{"content":"","date":"0001-01-01","id":26,"permalink":"/beacon-docs/tags/","summary":"","tags":[],"title":"Tags"}] \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml index af67eee..c18660f 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1 +1 @@ -https://roll20.github.io/beacon-docs/blog/example-post/2023-09-07T16:27:22+02:00monthly0.5https://roll20.github.io/beacon-docs/blog/2023-09-07T16:21:44+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/2023-09-07T16:06:50+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/2024-01-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/initrelay/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/actions/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/computed/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handlers/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/rolls/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/dispatch/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handling-legacy-methods/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/2024-05-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/resources/2024-02-27T09:30:56+01:00monthly0.5https://roll20.github.io/beacon-docs/docs/2023-09-07T16:12:03+02:00monthly0.5https://roll20.github.io/beacon-docs/privacy/2023-09-07T17:19:07+02:00monthly0.5https://roll20.github.io/beacon-docs/2023-09-07T16:33:54+02:00monthly0.5https://roll20.github.io/beacon-docs/categories/monthly0.5https://roll20.github.io/beacon-docs/contributors/monthly0.5https://roll20.github.io/beacon-docs/tags/monthly0.5 \ No newline at end of file +https://roll20.github.io/beacon-docs/docs/gettingstarted/introduction/2024-01-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/installing-beacon/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/quick-start-sheet-template/2024-05-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/example-patterns-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/releasing-a-sheet/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/blog/example-post/2023-09-07T16:27:22+02:00monthly0.5https://roll20.github.io/beacon-docs/blog/2023-09-07T16:21:44+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/initrelay/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/actions/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/computed/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handlers/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/rolls/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/dispatch/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/handling-legacy-methods/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/gettingstarted/2023-09-07T16:06:50+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/components/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/faq/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/glossary/2024-02-07T16:04:48+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/how-to-contribute/2024-09-07T16:13:18+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/about/changelog/2023-09-07T16:12:37+02:00monthly0.5https://roll20.github.io/beacon-docs/docs/2023-09-07T16:12:03+02:00monthly0.5https://roll20.github.io/beacon-docs/privacy/2023-09-07T17:19:07+02:00monthly0.5https://roll20.github.io/beacon-docs/2023-09-07T16:33:54+02:00monthly0.5https://roll20.github.io/beacon-docs/categories/monthly0.5https://roll20.github.io/beacon-docs/contributors/monthly0.5https://roll20.github.io/beacon-docs/tags/monthly0.5 \ No newline at end of file diff --git a/public/tags/index.html b/public/tags/index.html index 17e86f1..77a908a 100644 --- a/public/tags/index.html +++ b/public/tags/index.html @@ -1 +1 @@ -Tags |

Tags

\ No newline at end of file +Tags |

Tags

\ No newline at end of file diff --git a/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.content b/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.content index d33478c..cb2a8fc 100644 --- a/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.content +++ b/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.content @@ -1 +1 @@ -:root[data-bs-theme="light"],[data-bs-theme="light"] ::backdrop{--sl-color-white: hsl(224, 10%, 10%);--sl-color-gray-1: hsl(224, 14%, 16%);--sl-color-gray-2: hsl(224, 10%, 23%);--sl-color-gray-3: hsl(224, 7%, 36%);--sl-color-gray-4: hsl(224, 6%, 56%);--sl-color-gray-5: hsl(224, 6%, 77%);--sl-color-gray-6: hsl(224, 20%, 94%);--sl-color-gray-7: hsl(224, 19%, 97%);--sl-color-black: hsl(0, 0%, 100%)}:root,::backdrop{--sl-color-white: hsl(0, 0%, 100%);--sl-color-gray-1: hsl(224, 20%, 94%);--sl-color-gray-2: hsl(224, 6%, 77%);--sl-color-gray-3: hsl(224, 6%, 56%);--sl-color-gray-4: hsl(224, 7%, 36%);--sl-color-gray-5: hsl(224, 10%, 23%);--sl-color-gray-6: hsl(224, 14%, 16%);--sl-color-black: hsl(224, 10%, 10%);--sl-hue-orange: 41;--sl-color-orange-low: hsl(var(--sl-hue-orange), 39%, 22%);--sl-color-orange: hsl(var(--sl-hue-orange), 82%, 63%);--sl-color-orange-high: hsl(var(--sl-hue-orange), 82%, 87%);--sl-hue-green: 101;--sl-color-green-low: hsl(var(--sl-hue-green), 39%, 22%);--sl-color-green: hsl(var(--sl-hue-green), 82%, 63%);--sl-color-green-high: hsl(var(--sl-hue-green), 82%, 80%);--sl-hue-blue: 234;--sl-color-blue-low: hsl(var(--sl-hue-blue), 54%, 20%);--sl-color-blue: hsl(var(--sl-hue-blue), 100%, 60%);--sl-color-blue-high: hsl(var(--sl-hue-blue), 100%, 87%);--sl-hue-purple: 281;--sl-color-purple-low: hsl(var(--sl-hue-purple), 39%, 22%);--sl-color-purple: hsl(var(--sl-hue-purple), 82%, 63%);--sl-color-purple-high: hsl(var(--sl-hue-purple), 82%, 89%);--sl-hue-red: 339;--sl-color-red-low: hsl(var(--sl-hue-red), 39%, 22%);--sl-color-red: hsl(var(--sl-hue-red), 82%, 63%);--sl-color-red-high: hsl(var(--sl-hue-red), 82%, 87%);--sl-color-accent-low: hsl(224, 54%, 20%);--sl-color-accent: hsl(224, 100%, 60%);--sl-color-accent-high: hsl(224, 100%, 85%);--sl-color-text: var(--sl-color-gray-2);--sl-color-text-accent: var(--sl-color-accent-high);--sl-color-text-invert: var(--sl-color-accent-low);--sl-color-bg: var(--sl-color-black);--sl-color-bg-nav: var(--sl-color-gray-6);--sl-color-bg-sidebar: var(--sl-color-gray-6);--sl-color-bg-inline-code: var(--sl-color-gray-5);--sl-color-hairline-light: var(--sl-color-gray-5);--sl-color-hairline: var(--sl-color-gray-6);--sl-color-hairline-shade: var(--sl-color-black);--sl-color-backdrop-overlay: hsla(223, 13%, 10%, 0.66);--sl-shadow-sm: 0px 1px 1px hsla(0, 0%, 0%, 0.12), 0px 2px 1px hsla(0, 0%, 0%, 0.24);--sl-shadow-md: 0px 8px 4px hsla(0, 0%, 0%, 0.08), 0px 5px 2px hsla(0, 0%, 0%, 0.08), 0px 3px 2px hsla(0, 0%, 0%, 0.12), 0px 1px 1px hsla(0, 0%, 0%, 0.15);--sl-shadow-lg: 0px 25px 7px hsla(0, 0%, 0%, 0.03), 0px 16px 6px hsla(0, 0%, 0%, 0.1), 0px 9px 5px hsla(223, 13%, 10%, 0.33), 0px 4px 4px hsla(0, 0%, 0%, 0.75), 0px 4px 2px hsla(0, 0%, 0%, 0.25);--sl-text-xs: 0.8125rem;--sl-text-sm: 0.875rem;--sl-text-base: 1rem;--sl-text-lg: 1.125rem;--sl-text-xl: 1.25rem;--sl-text-2xl: 1.5rem;--sl-text-3xl: 1.8125rem;--sl-text-4xl: 2.1875rem;--sl-text-5xl: 2.625rem;--sl-text-6xl: 4rem;--sl-text-body: var(--sl-text-base);--sl-text-body-sm: var(--sl-text-xs);--sl-text-code: var(--sl-text-sm);--sl-text-code-sm: var(--sl-text-xs);--sl-text-h1: var(--sl-text-4xl);--sl-text-h2: var(--sl-text-3xl);--sl-text-h3: var(--sl-text-2xl);--sl-text-h4: var(--sl-text-xl);--sl-text-h5: var(--sl-text-lg);--sl-line-height: 1.8;--sl-line-height-headings: 1.2;--sl-font-system: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--sl-font-system-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--__sl-font: var(--sl-font, ""), var(--sl-font-system);--__sl-font-mono: var(--sl-font-mono, ""), var(--sl-font-system-mono);--sl-nav-height: 3.5rem;--sl-nav-pad-x: 1rem;--sl-nav-pad-y: 0.75rem;--sl-mobile-toc-height: 3rem;--sl-sidebar-width: 18.75rem;--sl-sidebar-pad-x: 1rem;--sl-content-width: 45rem;--sl-content-pad-x: 1rem;--sl-menu-button-size: 2rem;--sl-nav-gap: var(--sl-content-pad-x);--sl-outline-offset-inside: -0.1875rem;--sl-z-index-toc: 4;--sl-z-index-menu: 5;--sl-z-index-navbar: 10;--sl-z-index-skiplink: 20}:root{--purple-hsl: 255, 60%, 60%;--overlay-blurple: hsla(var(--purple-hsl), 0.2)}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0.75rem;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}:root,[data-bs-theme="light"]{--bs-blue: #3347ff;--bs-indigo: #6610f2;--bs-purple: #bd53ee;--bs-pink: #d63384;--bs-red: #ee5389;--bs-orange: #fd7e14;--bs-yellow: #eebd53;--bs-green: #84ee53;--bs-teal: #20c997;--bs-cyan: #0dcaf0;--bs-black: #000;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #5d2f86;--bs-secondary: #6c757d;--bs-success: #84ee53;--bs-info: #3347ff;--bs-warning: #eebd53;--bs-danger: #ee5389;--bs-light: #f8f9fa;--bs-dark: #212529;--bs-primary-rgb: 93,47,134;--bs-secondary-rgb: 108,117,125;--bs-success-rgb: 132.2821,238.017,83.283;--bs-info-rgb: 51,71.4,255;--bs-warning-rgb: 238.017,189.0179,83.283;--bs-danger-rgb: 238.017,83.283,137.4399;--bs-light-rgb: 248,249,250;--bs-dark-rgb: 33,37,41;--bs-primary-text-emphasis: #251336;--bs-secondary-text-emphasis: #2b2f32;--bs-success-text-emphasis: #355f21;--bs-info-text-emphasis: #141d66;--bs-warning-text-emphasis: #5f4c21;--bs-danger-text-emphasis: #5f2137;--bs-light-text-emphasis: #495057;--bs-dark-text-emphasis: #495057;--bs-primary-bg-subtle: #dfd5e7;--bs-secondary-bg-subtle: #e2e3e5;--bs-success-bg-subtle: #e6fcdd;--bs-info-bg-subtle: #d6daff;--bs-warning-bg-subtle: #fcf2dd;--bs-danger-bg-subtle: #fcdde7;--bs-light-bg-subtle: #fcfcfd;--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: #beaccf;--bs-secondary-border-subtle: #c4c8cb;--bs-success-border-subtle: #cef8ba;--bs-info-border-subtle: #adb6ff;--bs-warning-border-subtle: #f8e5ba;--bs-danger-border-subtle: #f8bad0;--bs-light-border-subtle: #e9ecef;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-font-sans-serif: "Jost", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #1d2d35;--bs-body-color-rgb: 29,45,53;--bs-body-bg: #fff;--bs-body-bg-rgb: 255,255,255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0,0,0;--bs-secondary-color: rgba(29,45,53,0.75);--bs-secondary-color-rgb: 29,45,53;--bs-secondary-bg: #e9ecef;--bs-secondary-bg-rgb: 233,236,239;--bs-tertiary-color: rgba(29,45,53,0.5);--bs-tertiary-color-rgb: 29,45,53;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248,249,250;--bs-heading-color: inherit;--bs-link-color: #5d2f86;--bs-link-color-rgb: 93,47,134;--bs-link-decoration: none;--bs-link-hover-color: #4a266b;--bs-link-hover-color-rgb: 74,38,107;--bs-link-hover-decoration: underline;--bs-code-color: #d63384;--bs-highlight-color: #1d2d35;--bs-highlight-bg: #fcf2dd;--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0,0,0,0.175);--bs-border-radius: .375rem;--bs-border-radius-sm: .25rem;--bs-border-radius-lg: .5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0,0,0,0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0,0,0,0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0,0,0,0.075);--bs-focus-ring-width: .25rem;--bs-focus-ring-opacity: .25;--bs-focus-ring-color: rgba(93,47,134,0.25);--bs-form-valid-color: #84ee53;--bs-form-valid-border-color: #84ee53;--bs-form-invalid-color: #ee5389;--bs-form-invalid-border-color: #ee5389}[data-bs-theme="dark"]{color-scheme:dark;--bs-body-color: #c1c3c8;--bs-body-color-rgb: 192.831,194.7078,199.869;--bs-body-bg: #17181c;--bs-body-bg-rgb: 22.95,24.31,28.05;--bs-emphasis-color: #fff;--bs-emphasis-color-rgb: 255,255,255;--bs-secondary-color: rgba(193,195,200,0.75);--bs-secondary-color-rgb: 192.831,194.7078,199.869;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52,58,64;--bs-tertiary-color: rgba(193,195,200,0.5);--bs-tertiary-color-rgb: 192.831,194.7078,199.869;--bs-tertiary-bg: #2b3035;--bs-tertiary-bg-rgb: 43,48,53;--bs-primary-text-emphasis: #9e82b6;--bs-secondary-text-emphasis: #a7acb1;--bs-success-text-emphasis: #b5f598;--bs-info-text-emphasis: #8591ff;--bs-warning-text-emphasis: #f5d798;--bs-danger-text-emphasis: #f598b8;--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: #13091b;--bs-secondary-bg-subtle: #161719;--bs-success-bg-subtle: #1a3011;--bs-info-bg-subtle: #0a0e33;--bs-warning-bg-subtle: #302611;--bs-danger-bg-subtle: #30111b;--bs-light-bg-subtle: #23262f;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: #381c50;--bs-secondary-border-subtle: #41464b;--bs-success-border-subtle: #4f8f32;--bs-info-border-subtle: #1f2b99;--bs-warning-border-subtle: #8f7132;--bs-danger-border-subtle: #8f3252;--bs-light-border-subtle: #353841;--bs-dark-border-subtle: #343a40;--bs-heading-color: #fff;--bs-link-color: #b3c7ff;--bs-link-hover-color: #c2d2ff;--bs-link-color-rgb: 178.5,198.9,255;--bs-link-hover-color-rgb: 194,210,255;--bs-code-color: #e685b5;--bs-highlight-color: #c1c3c8;--bs-highlight-bg: #5f4c21;--bs-border-color: #495057;--bs-border-color-translucent: rgba(255,255,255,0.15);--bs-form-valid-color: #b5f598;--bs-form-valid-border-color: #b5f598;--bs-form-invalid-color: #f598b8;--bs-form-invalid-border-color: #f598b8}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:700;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width: 1200px){h1,.h1{font-size:2.5rem}}h2,.h2{font-size:calc(1.325rem + .9vw)}@media (min-width: 1200px){h2,.h2{font-size:2rem}}h3,.h3{font-size:calc(1.3rem + .6vw)}@media (min-width: 1200px){h3,.h3{font-size:1.75rem}}h4,.h4{font-size:calc(1.275rem + .3vw)}@media (min-width: 1200px){h4,.h4{font-size:1.5rem}}h5,.h5{font-size:1.25rem}p{margin-top:0;margin-bottom:1rem}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}strong{font-weight:bolder}small,.small{font-size:.875em}mark,.mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:none}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb);text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator{display:none !important}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}summary{display:list-item;cursor:pointer}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:400}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.img-fluid{max-width:100%;height:auto}.figure{display:inline-block}.container,.container-fluid,.container-lg{--bs-gutter-x: 3rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container-lg,.container{max-width:960px}}@media (min-width: 1200px){.container-lg,.container{max-width:1240px}}@media (min-width: 1400px){.container-lg,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.row{--bs-gutter-x: 3rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width: 768px){.col-md-12{flex:0 0 auto;width:75%}}@media (min-width: 992px){.col-lg-5{flex:0 0 auto;width:31.25%}.col-lg-8{flex:0 0 auto;width:50%}.col-lg-9{flex:0 0 auto;width:56.25%}.col-lg-10{flex:0 0 auto;width:62.5%}.col-lg-11{flex:0 0 auto;width:68.75%}.col-lg-12{flex:0 0 auto;width:75%}}@media (min-width: 1200px){.col-xl-3{flex:0 0 auto;width:18.75%}.col-xl-4{flex:0 0 auto;width:25%}.col-xl-8{flex:0 0 auto;width:50%}.col-xl-9{flex:0 0 auto;width:56.25%}}.sticky-top{position:sticky;top:0;z-index:1020}.visually-hidden{width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}li input[type="checkbox"]{--bs-form-check-bg: var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;print-color-adjust:exact}li input[type="checkbox"]{border-radius:.25em}li input[type="radio"][type="checkbox"]{border-radius:50%}li input[type="checkbox"]:active{filter:brightness(90%)}li input[type="checkbox"]:focus{border-color:#ae97c3;outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}li input:checked[type="checkbox"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}li input[type="checkbox"]:checked[type="radio"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}li input[type="checkbox"]:indeterminate{background-color:#5d2f86;border-color:#5d2f86;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:.5}.btn{--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 0 rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);text-decoration:none;background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #5d2f86;--bs-btn-border-color: #5d2f86;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #4f2872;--bs-btn-hover-border-color: #4a266b;--bs-btn-focus-shadow-rgb: 117,78,152;--bs-btn-active-color: #fff;--bs-btn-active-bg: #4a266b;--bs-btn-active-border-color: #462365;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #5d2f86;--bs-btn-disabled-border-color: #5d2f86}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: var(--bs-link-color);--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: var(--bs-link-hover-color);--bs-btn-hover-border-color: transparent;--bs-btn-active-color: var(--bs-link-hover-color);--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 117,78,152;text-decoration:none}.btn-link:hover,.btn-link:focus-visible{text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.nav{--bs-nav-link-padding-x: 1rem;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-link-color);--bs-nav-link-hover-color: var(--bs-link-hover-color);--bs-nav-link-disabled-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);background:none;border:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color);text-decoration:none}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: .5rem;--bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y: .3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x: .5rem;--bs-navbar-toggler-padding-y: .25rem;--bs-navbar-toggler-padding-x: .75rem;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2829,45,53,0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius: var(--bs-border-radius);--bs-navbar-toggler-focus-width: 0;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color);text-decoration:none}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:transparent !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar[data-bs-theme="dark"]{--bs-navbar-color: #c1c3c8;--bs-navbar-hover-color: #b3c7ff;--bs-navbar-disabled-color: rgba(255,255,255,0.25);--bs-navbar-active-color: #b3c7ff;--bs-navbar-brand-color: #b3c7ff;--bs-navbar-brand-hover-color: #b3c7ff;--bs-navbar-toggler-border-color: rgba(255,255,255,0.1);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23c1c3c8' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: .5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: var(--bs-border-width);--bs-card-border-color: #e9ecef;--bs-card-border-radius: var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y: .5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: var(--bs-body-bg);--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 1.5rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-text:last-child{margin-bottom:0}.breadcrumb{--bs-breadcrumb-padding-x: 0;--bs-breadcrumb-padding-y: 0;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color: var(--bs-secondary-color);--bs-breadcrumb-item-padding-x: .5rem;--bs-breadcrumb-item-active-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);text-decoration:none;background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: .5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.offcanvas{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 332px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: var(--bs-body-color);--bs-offcanvas-bg: var(--bs-body-bg);--bs-offcanvas-border-width: var(--bs-border-width);--bs-offcanvas-border-color: var(--bs-border-color-translucent);--bs-offcanvas-box-shadow: var(--bs-box-shadow-sm);--bs-offcanvas-transition: transform .3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.position-relative{position:relative !important}.w-100{width:100% !important}.h-auto{height:auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-grow-1{flex-grow:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.order-3{order:3 !important}.m-2{margin:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.mt-1{margin-top:.25rem !important}.mt-4{margin-top:1.5rem !important}.me-2{margin-right:.5rem !important}.me-auto{margin-right:auto !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.ms-2{margin-left:.5rem !important}.ms-auto{margin-left:auto !important}.mt-n3{margin-top:-1rem !important}.p-0{padding:0 !important}.p-2{padding:.5rem !important}.pt-4{padding-top:1.5rem !important}.pe-4{padding-right:1.5rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.ps-3{padding-left:1rem !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-nowrap{white-space:nowrap !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.rounded-circle{border-radius:50% !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}}@media (min-width: 992px){.d-lg-block{display:block !important}.d-lg-none{display:none !important}.flex-lg-row{flex-direction:row !important}.order-lg-4{order:4 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-3{margin-right:1rem !important}.ms-lg-2{margin-left:.5rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}}@media (min-width: 1200px){.d-xl-block{display:block !important}.d-xl-none{display:none !important}.flex-xl-nowrap{flex-wrap:nowrap !important}}@font-face{font-family:Jost;font-style:normal;font-weight:400;font-display:swap;src:local("Jost Regular Regular"),local("Jost-Regular"),local("Jost* Book"),local("Jost-Book"),url("fonts/vendor/jost/jost-v4-latin-regular.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-regular.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:500;font-display:swap;src:local("Jost Regular Medium"),local("JostRoman-Medium"),local("Jost* Medium"),local("Jost-Medium"),url("fonts/vendor/jost/jost-v4-latin-500.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:700;font-display:swap;src:local("Jost Regular Bold"),local("JostRoman-Bold"),local("Jost* Bold"),local("Jost-Bold"),url("fonts/vendor/jost/jost-v4-latin-700.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:400;font-display:swap;src:local("Jost Italic Italic"),local("Jost-Italic"),local("Jost* BookItalic"),local("Jost-BookItalic"),url("fonts/vendor/jost/jost-v4-latin-italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:500;font-display:swap;src:local("Jost Italic Medium Italic"),local("JostItalic-Medium"),local("Jost* Medium Italic"),local("Jost-MediumItalic"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:700;font-display:swap;src:local("Jost Italic Bold Italic"),local("JostItalic-Bold"),local("Jost* Bold Italic"),local("Jost-BoldItalic"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff") format("woff")}html[data-bs-theme="dark"] .icon-tabler-sun{display:block}html[data-bs-theme="dark"] .icon-tabler-moon{display:none}html[data-bs-theme="light"] .icon-tabler-sun{display:none}html[data-bs-theme="light"] .icon-tabler-moon{display:block}.privacy .content,.contributors .content,.blog .content,.error404 .content,.docs.list .content,.categories.list .content,.tags.list .content,.list.section .content{padding-top:1rem;padding-bottom:3rem}.content img{max-width:100%}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:2rem;margin-bottom:1rem}@media (min-width: 768px){body{font-size:1.125rem}h1,h2,h3,h4,h5,.h1,.h2,.h3,.h4,.h5{margin-bottom:1.125rem}}.home h1,.home .h1{font-size:calc(1.875rem + 1.5vw);margin-top:-1rem}a:hover,a:focus{text-decoration:underline}a.btn:hover,a.btn:focus{text-decoration:none}.section{padding-top:5rem;padding-bottom:5rem}body.section{padding-top:0;padding-bottom:0}.section-md{padding-top:3rem;padding-bottom:3rem}.docs-sidebar{order:2}@media (min-width: 992px){.docs-sidebar{order:0;border-right:1px solid #e9ecef}@supports (position: sticky){.docs-sidebar{position:sticky;top:4.25rem;z-index:1000;height:calc(100vh - 4.25rem)}}}@media (min-width: 1200px){.docs-sidebar{flex:0 1 320px}}.docs-links{padding-bottom:5rem}@media (min-width: 992px){@supports (position: sticky){.docs-links{max-height:calc(100vh - 4rem);overflow-y:scroll}}}@media (min-width: 992px){.docs-links{display:block;width:auto;margin-right:-1.5rem;padding-bottom:4rem}}.docs-toc{order:2}@supports (position: sticky){.docs-toc{position:sticky;top:4.25rem;height:calc(100vh - 4.25rem);overflow-y:auto}}.docs-content{padding-bottom:3rem;order:1}.navbar a:hover,.navbar a:focus{text-decoration:none}#TableOfContents ul,#toc ul{padding-left:0;list-style:none}#toc a.active{color:#5d2f86;font-weight:500}.section-features{padding-top:2rem}.bg-dots{background-image:radial-gradient(#dee2e6 15%, transparent 15%);background-position:0 0;background-size:1rem 1rem;-webkit-mask:linear-gradient(to top, #fff, transparent);mask:linear-gradient(to top, #fff, transparent);width:100%;height:11rem;margin-top:-10rem;z-index:-1}.modal-backdrop{background-color:#fff}.modal-backdrop.show{opacity:0.7}@media (min-width: 768px){.modal-backdrop.show{opacity:0}}li input[type="checkbox"]{margin:0.25rem;border:1px solid #ced4da}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:1}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}[data-bs-theme="dark"] li input[type="checkbox"]{border:1px solid #6c757d}[data-bs-theme="dark"] li input[type="checkbox"]:checked{background-color:#b3c7ff;border-color:#b3c7ff;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%231d2d35' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.content .svg-inline{margin-bottom:1.5rem}.content .svg-inline:not(.svg-inline-custom){height:1.875rem;width:1.875rem;stroke-width:1.5}.card-nav{-moz-column-gap:1rem;column-gap:1rem}.card-nav .card{margin:0.5rem 0}.card-nav .card:hover{border:1px solid #d9d9d9;background-color:var(--sl-color-gray-7)}[data-bs-theme="dark"] .card-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .card-nav .card:hover{border:1px solid #888c96;background-color:var(--sl-color-gray-6)}.highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.bg{background-color:var(--sl-color-gray-7)}.chroma{background-color:var(--sl-color-gray-7)}.chroma .err{color:inherit}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{background-color:#0000001a}.chroma .hl{border-inline-start:0.15rem solid #00000055;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .line{display:flex}.chroma .k{color:#000000;font-weight:bold}.chroma .kc{color:#000000;font-weight:bold}.chroma .kd{color:#000000;font-weight:bold}.chroma .kn{color:#000000;font-weight:bold}.chroma .kp{color:#000000;font-weight:bold}.chroma .kr{color:#000000;font-weight:bold}.chroma .kt{color:#445588;font-weight:bold}.chroma .na{color:#008080}.chroma .nb{color:#0086b3}.chroma .bp{color:#999999}.chroma .nc{color:#445588;font-weight:bold}.chroma .no{color:#008080}.chroma .nd{color:#3c5d5d;font-weight:bold}.chroma .ni{color:#800080}.chroma .ne{color:#990000;font-weight:bold}.chroma .nf{color:#990000;font-weight:bold}.chroma .nl{color:#990000;font-weight:bold}.chroma .nn{color:#555555}.chroma .nt{color:#000080}.chroma .nv{color:#008080}.chroma .vc{color:#008080}.chroma .vg{color:#008080}.chroma .vi{color:#008080}.chroma .s{color:#dd1144}.chroma .sa{color:#dd1144}.chroma .sb{color:#dd1144}.chroma .sc{color:#dd1144}.chroma .dl{color:#dd1144}.chroma .sd{color:#dd1144}.chroma .s2{color:#dd1144}.chroma .se{color:#dd1144}.chroma .sh{color:#dd1144}.chroma .si{color:#dd1144}.chroma .sx{color:#dd1144}.chroma .sr{color:#009926}.chroma .s1{color:#dd1144}.chroma .ss{color:#990073}.chroma .m{color:#009999}.chroma .mb{color:#009999}.chroma .mf{color:#009999}.chroma .mh{color:#009999}.chroma .mi{color:#009999}.chroma .il{color:#009999}.chroma .mo{color:#009999}.chroma .o{color:#000000;font-weight:bold}.chroma .ow{color:#000000;font-weight:bold}.chroma .c{color:#999988;font-style:italic}.chroma .ch{color:#999988;font-style:italic}.chroma .cm{color:#999988;font-style:italic}.chroma .c1{color:#999988;font-style:italic}.chroma .cs{color:#999999;font-weight:bold;font-style:italic}.chroma .cp{color:#999999;font-weight:bold;font-style:italic}.chroma .cpf{color:#999999;font-weight:bold;font-style:italic}.chroma .gd{color:#000000;background-color:#ffdddd}.chroma .ge{color:inherit;font-style:italic}.chroma .gr{color:#aa0000}.chroma .gh{color:#999999}.chroma .gi{color:#000000;background-color:#ddffdd}.chroma .go{color:#888888}.chroma .gp{color:#555555}.chroma .gs{font-weight:bold}.chroma .gu{color:#aaaaaa}.chroma .gt{color:#aa0000}.chroma .gl{text-decoration:underline}.chroma .w{color:#bbbbbb}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .bg{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma .err{color:inherit}[data-bs-theme="dark"] .chroma .lnlinks{outline:none;text-decoration:none;color:inherit}[data-bs-theme="dark"] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .hl{background-color:#ffffff17}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}[data-bs-theme="dark"] .chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#64686c}[data-bs-theme="dark"] .chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681}[data-bs-theme="dark"] .chroma .line{display:flex}[data-bs-theme="dark"] .chroma .k{color:#ff7b72}[data-bs-theme="dark"] .chroma .kc{color:#79c0ff}[data-bs-theme="dark"] .chroma .kd{color:#ff7b72}[data-bs-theme="dark"] .chroma .kn{color:#ff7b72}[data-bs-theme="dark"] .chroma .kp{color:#79c0ff}[data-bs-theme="dark"] .chroma .kr{color:#ff7b72}[data-bs-theme="dark"] .chroma .kt{color:#ff7b72}[data-bs-theme="dark"] .chroma .na{color:#d2a8ff}[data-bs-theme="dark"] .chroma .nc{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .no{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nd{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .ni{color:#ffa657}[data-bs-theme="dark"] .chroma .ne{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .nf{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nl{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nn{color:#ff7b72}[data-bs-theme="dark"] .chroma .py{color:#79c0ff}[data-bs-theme="dark"] .chroma .nt{color:#7ee787}[data-bs-theme="dark"] .chroma .nv{color:#79c0ff}[data-bs-theme="dark"] .chroma .l{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ld{color:#79c0ff}[data-bs-theme="dark"] .chroma .s{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sa{color:#79c0ff}[data-bs-theme="dark"] .chroma .sb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sc{color:#a5d6ff}[data-bs-theme="dark"] .chroma .dl{color:#79c0ff}[data-bs-theme="dark"] .chroma .sd{color:#a5d6ff}[data-bs-theme="dark"] .chroma .s2{color:#a5d6ff}[data-bs-theme="dark"] .chroma .se{color:#79c0ff}[data-bs-theme="dark"] .chroma .sh{color:#79c0ff}[data-bs-theme="dark"] .chroma .si{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sx{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sr{color:#79c0ff}[data-bs-theme="dark"] .chroma .s1{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ss{color:#a5d6ff}[data-bs-theme="dark"] .chroma .m{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mf{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mh{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mi{color:#a5d6ff}[data-bs-theme="dark"] .chroma .il{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mo{color:#a5d6ff}[data-bs-theme="dark"] .chroma .o{color:inherit;font-weight:bold}[data-bs-theme="dark"] .chroma .ow{color:#ff7b72;font-weight:bold}[data-bs-theme="dark"] .chroma .c{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .ch{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cm{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .c1{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cs{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cp{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cpf{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .gd{color:#ffa198;background-color:#490202}[data-bs-theme="dark"] .chroma .ge{font-style:italic}[data-bs-theme="dark"] .chroma .gr{color:#ffa198}[data-bs-theme="dark"] .chroma .gh{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .gi{color:#56d364;background-color:#0f5323}[data-bs-theme="dark"] .chroma .go{color:#8b949e}[data-bs-theme="dark"] .chroma .gp{color:#8b949e}[data-bs-theme="dark"] .chroma .gs{font-weight:bold}[data-bs-theme="dark"] .chroma .gu{color:#79c0ff}[data-bs-theme="dark"] .chroma .gt{color:#ff7b72}[data-bs-theme="dark"] .chroma .gl{text-decoration:underline}[data-bs-theme="dark"] .chroma .w{color:#6e7681}[data-bs-theme="dark"] h1,[data-bs-theme="dark"] .h1,[data-bs-theme="dark"] h2,[data-bs-theme="dark"] .h2,[data-bs-theme="dark"] h3,[data-bs-theme="dark"] .h3,[data-bs-theme="dark"] h4,[data-bs-theme="dark"] .h4{color:#fff}[data-bs-theme="dark"] body{background:#17181c;color:#c1c3c8}[data-bs-theme="dark"] a{color:#b3c7ff}[data-bs-theme="dark"] .callout a{color:inherit}[data-bs-theme="dark"] .btn-primary{--bs-btn-color: #000;--bs-btn-bg: #b3c7ff;--bs-btn-border-color: #b3c7ff;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #becfff;--bs-btn-hover-border-color: #bacdff;--bs-btn-focus-shadow-rgb: 152,169,217;--bs-btn-active-color: #000;--bs-btn-active-bg: #c2d2ff;--bs-btn-active-border-color: #bacdff;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #b3c7ff;--bs-btn-disabled-border-color: #b3c7ff;color:#17181c}[data-bs-theme="dark"] .navbar{background-color:rgba(23,24,28,0.95);border-bottom:1px solid #23262f}[data-bs-theme="dark"] body.home .navbar{border-bottom:0}[data-bs-theme="dark"] .offcanvas-header{border-bottom:1px solid #343a40}[data-bs-theme="dark"] .offcanvas .nav-link{color:#c1c3c8}[data-bs-theme="dark"] .offcanvas .nav-link:hover,[data-bs-theme="dark"] .offcanvas .nav-link:focus{color:#b3c7ff}[data-bs-theme="dark"] .offcanvas .nav-link.active{color:#b3c7ff}[data-bs-theme="dark"] .page-links a{color:#c1c3c8}[data-bs-theme="dark"] .page-links a:hover{text-decoration:none;color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link{color:#c1c3c8}[data-bs-theme="dark"] .content .btn-link{color:#b3c7ff}[data-bs-theme="dark"] .content .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:active{color:#b3c7ff}@media (min-width: 992px){[data-bs-theme="dark"] .docs-sidebar{order:0;border-right:1px solid #23262f}}[data-bs-theme="dark"] .footer{border-top:1px solid #23262f}[data-bs-theme="dark"] .docs-links,[data-bs-theme="dark"] .docs-toc{scrollbar-width:thin;scrollbar-color:#17181c #17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar{width:5px}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-track,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-track{background:#17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb{background:#17181c}[data-bs-theme="dark"] .docs-links:hover,[data-bs-theme="dark"] .docs-toc:hover{scrollbar-width:thin;scrollbar-color:#23262f #17181c}[data-bs-theme="dark"] .docs-links:hover::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc:hover::-webkit-scrollbar-thumb{background:#23262f}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb:hover,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb:hover{background:#23262f}[data-bs-theme="dark"] .docs-links h3:not(:first-child),[data-bs-theme="dark"] .docs-links .h3:not(:first-child){border-top:1px solid #23262f}[data-bs-theme="dark"] .page-links li:not(:first-child){border-top:1px dashed #23262f}[data-bs-theme="dark"] .card{background:#17181c;border:1px solid #23262f}[data-bs-theme="dark"] .bg-dots{background-image:radial-gradient(#414349 15%, transparent 15%)}[data-bs-theme="dark"] .text-muted{color:#adafb6 !important}[data-bs-theme="dark"] .offcanvas{background-color:#17181c}[data-bs-theme="dark"] .page-link{color:#b3c7ff;background-color:transparent;border:var(--bs-border-width) solid #23262f}[data-bs-theme="dark"] .page-link:hover{color:#17181c;background-color:#c1c3c8;border-color:#c1c3c8}[data-bs-theme="dark"] .page-link:focus{color:#17181c;background-color:#c1c3c8}[data-bs-theme="dark"] .page-item.active .page-link{color:#17181c;background-color:#b3c7ff;border-color:#b3c7ff}[data-bs-theme="dark"] .page-item.disabled .page-link{color:var(--bs-secondary-color);background-color:#23262f;border-color:#23262f}[data-bs-theme="dark"] details{border:1px solid #23262f}[data-bs-theme="dark"] summary:hover{background:#23262f}[data-bs-theme="dark"] details[open]>summary{border-bottom:1px solid #23262f}[data-bs-theme="dark"] details summary::after{content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e")}[data-bs-theme="dark"] #toc a.active{color:#b3c7ff}.navbar .btn-link{color:rgba(var(--bs-emphasis-color-rgb), 0.65);padding:0.4375rem 0}.btn-link:focus{outline:0;box-shadow:none}@media (min-width: 992px){.navbar .btn-link{padding:0.5625em 0.25rem 0.5rem 0.125rem}}.navbar .btn-link:hover{color:rgba(var(--bs-emphasis-color-rgb), 0.8)}.navbar .btn-link:active{color:rgba(var(--bs-emphasis-color-rgb), 1)}.clipboard{position:relative;float:right}.btn-clipboard{transition:opacity 0.25s ease-in-out;opacity:0;position:absolute;right:0.5rem;top:0.5rem;line-height:1;padding:0.3125rem 0.3125rem 0.1875rem;background-color:transparent;border-color:transparent}@media (max-width: 767.98px){.btn-clipboard{position:absolute;right:-0.5rem;top:0.5rem}}.btn-clipboard::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#495057}.btn-clipboard:hover{border-color:transparent}.btn-clipboard:hover::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}.btn-clipboard:focus,.btn-clipboard:active{border-color:transparent !important}.btn-clipboard:focus::after,.btn-clipboard:active::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}[data-bs-theme="dark"] .btn-clipboard{background-color:transparent;border-color:transparent}[data-bs-theme="dark"] .btn-clipboard::after{background-color:#ced4da}[data-bs-theme="dark"] .btn-clipboard:hover{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:hover::after{background-color:#e9ecef}[data-bs-theme="dark"] .btn-clipboard:focus,[data-bs-theme="dark"] .btn-clipboard:active{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:focus::after,[data-bs-theme="dark"] .btn-clipboard:active::after{background-color:#e9ecef}.highlight{position:relative}@media (min-width: 768px){.highlight:hover .btn-clipboard{opacity:1}}#toTop{opacity:0;transition:opacity 0.3s ease-in-out}.callout{--bs-link-color-rgb: var(--callout-link);--bs-code-color: var(--callout-code-color);color:var(--callout-color, inherit);background-color:var(--callout-bg, var(--bs-gray-100));border-left:0.25rem solid var(--callout-border, var(--bs-gray-300));border-radius:0}.callout a{text-decoration:underline}.callout .highlight{background-color:rgba(0,0,0,0.05)}.callout .callout-icon.svg-inline{flex-shrink:0;height:calc(1.5 * 1.125rem)}.callout .callout-title{font-weight:700}.callout-content{min-width:0}.callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-high)}.callout.callout-note .callout-icon,.callout.callout-note .callout-title,.callout.callout-note .callout-body a{color:var(--sl-color-blue-low)}.callout.callout-note .callout-body,.callout.callout-note .callout-body a:hover,.callout.callout-note .callout-body a:active{color:var(--sl-color-white)}.callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-high)}.callout.callout-tip .callout-icon,.callout.callout-tip .callout-title,.callout.callout-tip .callout-body a{color:var(--sl-color-purple-low)}.callout.callout-tip .callout-body,.callout.callout-tip .callout-body a:hover,.callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}.callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-high)}.callout.callout-caution .callout-icon,.callout.callout-caution .callout-title,.callout.callout-caution .callout-body a{color:var(--sl-color-orange-low)}.callout.callout-caution .callout-body,.callout.callout-caution .callout-body a:hover,.callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}.callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-high)}.callout.callout-danger .callout-icon,.callout.callout-danger .callout-title,.callout.callout-danger .callout-body a{color:var(--sl-color-red-low)}.callout.callout-danger .callout-body,.callout.callout-danger .callout-body a:hover,.callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout{color:var(--sl-color-gray-1)}[data-bs-theme="dark"] .callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-low)}[data-bs-theme="dark"] .callout.callout-note .callout-icon,[data-bs-theme="dark"] .callout.callout-note .callout-title,[data-bs-theme="dark"] .callout.callout-note .callout-body a{color:var(--sl-color-blue-high)}[data-bs-theme="dark"] .callout.callout-note .callout-body,[data-bs-theme="dark"] .callout.callout-note .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-note .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-note code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-low)}[data-bs-theme="dark"] .callout.callout-tip .callout-icon,[data-bs-theme="dark"] .callout.callout-tip .callout-title,[data-bs-theme="dark"] .callout.callout-tip .callout-body a{color:var(--sl-color-purple-high)}[data-bs-theme="dark"] .callout.callout-tip .callout-body,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-tip code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-low)}[data-bs-theme="dark"] .callout.callout-caution .callout-icon,[data-bs-theme="dark"] .callout.callout-caution .callout-title,[data-bs-theme="dark"] .callout.callout-caution .callout-body a{color:var(--sl-color-orange-high)}[data-bs-theme="dark"] .callout.callout-caution .callout-body,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-caution code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-low)}[data-bs-theme="dark"] .callout.callout-danger .callout-icon,[data-bs-theme="dark"] .callout.callout-danger .callout-title,[data-bs-theme="dark"] .callout.callout-danger .callout-body a{color:var(--sl-color-red-high)}[data-bs-theme="dark"] .callout.callout-danger .callout-body,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-danger code:not(:where(.not-content *)){color:var(--ec-codeFg)}.expressive-code{font-family:var(--ec-uiFontFml);font-size:var(--ec-uiFontSize);line-height:var(--ec-uiLineHt);-moz-text-size-adjust:none;text-size-adjust:none;-webkit-text-size-adjust:none;margin:1.5rem 0}.expressive-code *:not(path){all:revert;box-sizing:border-box}.expressive-code pre{display:flex;margin:0;padding:0;border:var(--ec-brdWd) solid var(--ec-brdCol);border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));background:var(--ec-codeBg)}.expressive-code pre:focus-visible{outline:3px solid var(--ec-focusBrd);outline-offset:-3px}.expressive-code pre>code{all:unset;display:block;flex:1 0 100%;padding:var(--ec-codePadBlk) 0;color:var(--ec-codeFg);font-family:var(--ec-codeFontFml);font-size:var(--ec-codeFontSize);line-height:var(--ec-codeLineHt)}.expressive-code pre{overflow-x:auto}.expressive-code pre::-webkit-scrollbar,.expressive-code pre::-webkit-scrollbar-track{background-color:inherit;border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));border-top-left-radius:0;border-top-right-radius:0}.expressive-code pre::-webkit-scrollbar-thumb{background-color:var(--ec-sbThumbCol);border:4px solid transparent;background-clip:content-box;border-radius:10px}.expressive-code pre::-webkit-scrollbar-thumb:hover{background-color:var(--ec-sbThumbHoverCol)}.expressive-code .ec-line{padding-inline:var(--ec-codePadInl);padding-inline-end:calc(2rem + var(--ec-codePadInl));direction:ltr;unicode-bidi:isolate}.expressive-code .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.expressive-code .ec-line.mark{--tmLineBgCol: var(--ec-tm-markBg);--tmLineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line.ins{--tmLineBgCol: var(--ec-tm-insBg);--tmLineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line.ins::before{content:var(--ec-tm-insDiffIndContent);color:var(--ec-tm-insDiffIndCol)}.expressive-code .ec-line.del{--tmLineBgCol: var(--ec-tm-delBg);--tmLineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line.del::before{content:var(--ec-tm-delDiffIndContent);color:var(--ec-tm-delDiffIndCol)}.expressive-code .ec-line.mark,.expressive-code .ec-line.ins,.expressive-code .ec-line.del{position:relative;background:var(--tmLineBgCol);min-width:calc(100% - var(--ec-tm-lineMarkerAccentMarg));margin-inline-start:var(--ec-tm-lineMarkerAccentMarg);border-inline-start:var(--ec-tm-lineMarkerAccentWd) solid var(--tmLineBrdCol);padding-inline-start:calc(var(--ec-codePadInl) - var(--ec-tm-lineMarkerAccentMarg) - var(--ec-tm-lineMarkerAccentWd)) !important}.expressive-code .ec-line.mark::before,.expressive-code .ec-line.ins::before,.expressive-code .ec-line.del::before{position:absolute;left:var(--ec-tm-lineDiffIndMargLeft)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark{--tmInlineBgCol: var(--ec-tm-markBg);--tmInlineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line ins{--tmInlineBgCol: var(--ec-tm-insBg);--tmInlineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line del{--tmInlineBgCol: var(--ec-tm-delBg);--tmInlineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark,.expressive-code .ec-line ins,.expressive-code .ec-line del{all:unset;display:inline-block;position:relative;--tmBrdL: var(--ec-tm-inlMarkerBrdWd);--tmBrdR: var(--ec-tm-inlMarkerBrdWd);--tmRadL: var(--ec-tm-inlMarkerBrdRad);--tmRadR: var(--ec-tm-inlMarkerBrdRad);margin-inline:0.025rem;padding-inline:var(--ec-tm-inlMarkerPad);border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);background:var(--tmInlineBgCol);background-clip:padding-box}.expressive-code .ec-line mark.open-start,.expressive-code .ec-line .open-start.mark,.expressive-code .ec-line ins.open-start,.expressive-code .ec-line del.open-start{margin-inline-start:0;padding-inline-start:0;--tmBrdL: 0px;--tmRadL: 0}.expressive-code .ec-line mark.open-end,.expressive-code .ec-line .open-end.mark,.expressive-code .ec-line ins.open-end,.expressive-code .ec-line del.open-end{margin-inline-end:0;padding-inline-end:0;--tmBrdR: 0px;--tmRadR: 0}.expressive-code .ec-line mark::before,.expressive-code .ec-line .mark::before,.expressive-code .ec-line ins::before,.expressive-code .ec-line del::before{content:"";position:absolute;pointer-events:none;display:inline-block;inset:0;border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);border:var(--ec-tm-inlMarkerBrdWd) solid var(--tmInlineBrdCol);border-inline-width:var(--tmBrdL) var(--tmBrdR)}.expressive-code .frame{all:unset;position:relative;display:block;--header-border-radius: calc(var(--ec-brdRad) + var(--ec-brdWd));--tab-border-radius: calc(var(--ec-frm-edTabBrdRad) + var(--ec-brdWd));--button-spacing: 0.4rem;--code-background: var(--ec-frm-edBg);border-radius:var(--header-border-radius);box-shadow:var(--ec-frm-frameBoxShdCssVal)}.expressive-code .frame .header{display:none;z-index:1;position:relative;border-radius:var(--header-border-radius) var(--header-border-radius) 0 0}.expressive-code .frame.has-title pre,.expressive-code .frame.has-title code,.expressive-code .frame.is-terminal pre,.expressive-code .frame.is-terminal code{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.expressive-code .frame .title:empty:before{content:"\a0"}.expressive-code .frame.has-title:not(.is-terminal){--button-spacing: calc(1.9rem + 2 * (var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)))}.expressive-code .frame.has-title:not(.is-terminal) .title{position:relative;color:var(--ec-frm-edActTabFg);background:var(--ec-frm-edActTabBg);background-clip:padding-box;margin-block-start:var(--ec-frm-edTabsMargBlkStart);padding:calc(var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)) var(--ec-uiPadInl);border:var(--ec-brdWd) solid var(--ec-frm-edActTabBrdCol);border-radius:var(--tab-border-radius) var(--tab-border-radius) 0 0;border-bottom:none;overflow:hidden}.expressive-code .frame.has-title:not(.is-terminal) .title::after{content:"";position:absolute;pointer-events:none;inset:0;border-top:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndTopCol);border-bottom:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndBtmCol)}.expressive-code .frame.has-title:not(.is-terminal) .header{display:flex;background:linear-gradient(to top, var(--ec-frm-edTabBarBrdBtmCol) var(--ec-brdWd), transparent var(--ec-brdWd)),linear-gradient(var(--ec-frm-edTabBarBg), var(--ec-frm-edTabBarBg));background-repeat:no-repeat;padding-inline-start:var(--ec-frm-edTabsMargInlStart)}.expressive-code .frame.has-title:not(.is-terminal) .header::before{content:"";position:absolute;pointer-events:none;inset:0;border:var(--ec-brdWd) solid var(--ec-frm-edTabBarBrdCol);border-radius:inherit;border-bottom:none}.expressive-code .frame.is-terminal{--button-spacing: calc(1.9rem + var(--ec-brdWd) + 2 * var(--ec-uiPadBlk));--code-background: var(--ec-frm-trmBg)}.expressive-code .frame.is-terminal .header{display:flex;align-items:center;justify-content:center;padding-block:var(--ec-uiPadBlk);padding-block-end:calc(var(--ec-uiPadBlk) + var(--ec-brdWd));position:relative;font-weight:500;letter-spacing:0.025ch;color:var(--ec-frm-trmTtbFg);background:var(--ec-frm-trmTtbBg);border:var(--ec-brdWd) solid var(--ec-brdCol);border-bottom:none}.expressive-code .frame.is-terminal .header::before{content:"";position:absolute;pointer-events:none;left:var(--ec-uiPadInl);width:2.1rem;height:0.56rem;line-height:0;background-color:var(--ec-frm-trmTtbDotsFg);opacity:var(--ec-frm-trmTtbDotsOpa);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");mask-repeat:no-repeat}.expressive-code .frame.is-terminal .header::after{content:"";position:absolute;pointer-events:none;inset:0;border-bottom:var(--ec-brdWd) solid var(--ec-frm-trmTtbBrdBtmCol)}.expressive-code .frame pre{background:var(--code-background)}.expressive-code .copy{display:flex;gap:0.25rem;flex-direction:row;position:absolute;inset-block-start:calc(var(--ec-brdWd) + var(--button-spacing));inset-inline-end:calc(var(--ec-brdWd) + var(--ec-uiPadInl) / 2);direction:ltr;unicode-bidi:isolate}.expressive-code .copy button{position:relative;align-self:flex-end;margin:0;padding:0;border:none;border-radius:0.2rem;z-index:1;cursor:pointer;transition-property:opacity, background, border-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.25, 0.46, 0.45, 0.94);width:2.5rem;height:2.5rem;background:var(--code-background);opacity:0.75}.expressive-code .copy button div{position:absolute;inset:0;border-radius:inherit;background:var(--ec-frm-inlBtnBg);opacity:var(--ec-frm-inlBtnBgIdleOpa);transition-property:inherit;transition-duration:inherit;transition-timing-function:inherit}.expressive-code .copy button::before{content:"";position:absolute;pointer-events:none;inset:0;border-radius:inherit;border:var(--ec-brdWd) solid var(--ec-frm-inlBtnBrd);opacity:var(--ec-frm-inlBtnBrdOpa)}.expressive-code .copy button::after{content:"";position:absolute;pointer-events:none;inset:0;background-color:var(--ec-frm-inlBtnFg);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");mask-repeat:no-repeat;margin:0.475rem;line-height:0}.expressive-code .copy button:focus::after,.expressive-code .copy button:active::after{display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;margin:0.2375rem}.expressive-code .copy button:hover,.expressive-code .copy button:focus:focus-visible{opacity:1}.expressive-code .copy button:hover div,.expressive-code .copy button:focus:focus-visible div{opacity:var(--ec-frm-inlBtnBgHoverOrFocusOpa)}.expressive-code .copy button:active{opacity:1}.expressive-code .copy button:active div{opacity:var(--ec-frm-inlBtnBgActOpa)}.expressive-code .copy .feedback{--tooltip-arrow-size: 0.35rem;--tooltip-bg: var(--ec-frm-tooltipSuccessBg);color:var(--ec-frm-tooltipSuccessFg);pointer-events:none;-moz-user-select:none;user-select:none;-webkit-user-select:none;position:relative;align-self:center;background-color:var(--tooltip-bg);z-index:99;padding:0.125rem 0.75rem;border-radius:0.2rem;margin-inline-end:var(--tooltip-arrow-size);opacity:0;transition-property:opacity, transform;transition-duration:0.2s;transition-timing-function:ease-in-out;transform:translate3d(0, 0.25rem, 0)}.expressive-code .copy .feedback::after{content:"";position:absolute;pointer-events:none;top:calc(50% - var(--tooltip-arrow-size));inset-inline-end:calc(-2 * (var(--tooltip-arrow-size) - 0.5px));border:var(--tooltip-arrow-size) solid transparent;border-inline-start-color:var(--tooltip-bg)}.expressive-code .copy .feedback.show{opacity:1;transform:translate3d(0, 0, 0)}@media (hover: hover){.expressive-code .copy button{opacity:0;width:2rem;height:2rem}.expressive-code .frame:hover .copy button:not(:hover),.expressive-code .frame:focus-within :focus-visible~.copy button:not(:hover),.expressive-code .frame .copy .feedback.show~button:not(:hover){opacity:0.75}}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}.expressive-code .ec-line span[style^="--"]:not([class]){color:var(0, inherit);font-style:var(0fs, inherit);font-weight:var(0fw, inherit);-webkit-text-decoration:var(0td, inherit);text-decoration:var(0td, inherit)}@media (prefers-color-scheme: light){:root:not([data-bs-theme="dark"]){--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root:not([data-bs-theme="dark"]) .expressive-code .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}}:root[data-bs-theme="light"] .expressive-code,.expressive-code[data-bs-theme="light"]{--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root[data-bs-theme="light"] .expressive-code .ec-line span[style^="--"]:not([class]),.expressive-code[data-bs-theme="light"] .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875rem}code:not(:where(.not-content *)){background-color:var(--sl-color-gray-6);margin-block:-0.125rem;padding:0.125rem 0.375rem;color:inherit}[data-bs-theme="dark"] code:not(:where(.not-content *)){background-color:var(--sl-color-gray-5)}.math-block{display:block;margin:2rem 0;overflow-x:auto}.math-inline{display:inline}[data-bs-theme="dark"] .math-inline img,[data-bs-theme="dark"] .math-block img{filter:invert(1)}img.diagram{height:auto;width:100%;margin:1rem 0 2rem}img.diagram-kroki-mermaid{background:#fff}.highlight>pre{padding:0.875rem 1rem}.highlight div{padding:0}.highlight>.chroma{overflow-x:auto;border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.chroma .ln{padding:0 0.5rem 0 0}.chroma .hl{border-inline-start:0.15rem solid #0005;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.highlight .chroma .lntable .lnt,.highlight .chroma .lntable .hl{display:flex}.chroma .lntd:first-child{padding:0}.chroma .lntd:first-child .lnt{padding-left:1rem}.chroma .lntd:nth-child(2){padding:0}.highlight .chroma .lntable .lntd+.lntd{width:100%}[data-bs-theme="dark"] .chroma .ln{padding:0 0.5em 0 0}.chroma .lntd pre{padding:1rem 0;margin-bottom:0}.highlight>.chroma::-webkit-scrollbar,.highlight>.chroma::-webkit-scrollbar-track{background-color:inherit;border-radius:1px;border-top-left-radius:0;border-top-right-radius:0}.highlight>.chroma::-webkit-scrollbar-thumb{background-color:#dddee0;border:4px solid transparent;background-clip:content-box;border-radius:10px}.highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#9d9e9f}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb{background-color:#ffffff17}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#ffffff49}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}details{display:block;position:relative;border:1px solid #e9ecef;border-radius:0.25rem;padding:0.5rem 1rem 0;margin:0.5rem 0}summary{list-style:none;display:inline-block;width:calc(100% + 2rem);margin:-0.5rem -1rem 0;padding:0.5rem 1rem}summary::-webkit-details-marker{display:none}summary:hover{background:#f8f9fa}details summary::after{display:inline-block;content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");transition:transform 0.35s ease;transform-origin:center center;position:absolute;right:1rem}details[open]>summary::after{transform:rotate(90deg)}details[open]{padding:0.5rem 1rem}details[open]>summary{border-bottom:1px solid #dee2e6;margin-bottom:0.5rem}details h2,details .h2,details h3,details .h3,details h4,details .h4{margin:1rem 0 0.5rem}details p:last-child{margin-bottom:0}details ul,details ol{margin-bottom:0}details pre{margin:0 0 1rem}img{max-width:100%;height:auto}img[data-sizes="auto"]{display:block}img{font-size:0}figcaption{font-size:1rem;margin-top:0.5rem;font-style:italic}.blur-up{filter:blur(5px);transition:filter 400ms}.blur-up.lazyloaded{filter:unset}.section-nav{padding-top:2rem}.section-nav details{border:0;padding:0;margin:0.5rem 0}.section-nav details[open]{padding:0}.section-nav summary{width:100%;padding:0;margin:0;font-weight:700}.section-nav summary:hover{background:none}.section-nav details[open]>summary{border-bottom:0;margin-bottom:0}.section-nav ul.list-nested details{padding-left:1rem;margin-top:0.5rem}.section-nav ul.list-nested li{margin:0}.section-nav a{display:block;margin:0.5rem 0;color:#1d2d35;font-size:1rem;text-decoration:none}.section-nav a:hover,.section-nav a:active{color:#5d2f86}.section-nav li.active a{color:#5d2f86;font-weight:500}.section-nav ul.list-nested li a{padding-left:1rem}.section-nav ul.list-nested{border-left:1px solid #e9ecef}[data-bs-theme="dark"] .section-nav ul.list-nested{border-left:1px solid #23262f}[data-bs-theme="dark"] .section-nav a{color:#c1c3c8}[data-bs-theme="dark"] .section-nav a:hover,[data-bs-theme="dark"] .section-nav a:active{color:var(--sl-color-text-accent)}[data-bs-theme="dark"] .section-nav li.active a{color:var(--sl-color-text-accent);font-weight:500}[data-bs-theme="dark"] .section-nav summary{color:#fff}.footer{border-top:1px solid #e9ecef;padding-top:1.125rem;padding-bottom:1.125rem}.footer ul{margin-bottom:0}.footer li{font-size:.875rem;margin-bottom:0}.footer .list-inline-item:not(:last-child){margin-right:1rem}@media (max-width: 991.98px){.footer .col-lg-8{margin-top:0.25rem;margin-bottom:0.25rem}}@media (min-width: 768px){.footer li{font-size:1rem}}.fixed-bottom-right{position:fixed;right:0;bottom:0;z-index:1000}.navbar-brand{font-weight:700}.navbar-brand svg{margin-right:0.25rem}[data-bs-theme="dark"] .navbar-brand{color:inherit}.navbar{z-index:1000;background-color:rgba(255,255,255,0.95);border-bottom:1px solid #e9ecef}@media (min-width: 992px){.navbar{z-index:1025}}@media (min-width: 768px){.navbar-brand{font-size:1.375rem}}.nav-item{margin-left:0}@media (max-width: 991.98px){.navbar-nav .nav-link{font-weight:400}}@media (min-width: 768px){.nav-item{margin-left:0.5rem}}@media (max-width: 575.98px){.navbar .offcanvas.offcanvas-start,.navbar .offcanvas.offcanvas-end{width:80vw}}.offcanvas-header{border-bottom:1px solid #dee2e6;padding-top:1.0625rem;padding-bottom:0.8125rem}h5.offcanvas-title,.offcanvas-title.h5{margin:0;color:inherit}.offcanvas .nav-link{color:#1d2d35}.offcanvas .nav-link:hover,.offcanvas .nav-link:focus{color:#5d2f86}.offcanvas .nav-link.active{color:#5d2f86}.home .navbar{border-bottom:0}@media (min-width: 992px){.navbar-brand{margin-right:0.75rem !important}}.social-link{padding-right:0.375rem;padding-left:0.375rem}@media (max-width: 991.98px){#buttonColorMode{margin:0.5rem 0}#socialMenu{margin:0.5rem 0 0.5rem -0.25rem}.navbar-nav{margin-top:1rem}.nav-item .nav-link{font-weight:400;font-size:1.125rem}}.modal-backdrop,.offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}[data-bs-theme="dark"] .modal-backdrop,[data-bs-theme="dark"] .offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}.modal-backdrop.show,.offcanvas-backdrop.show{visibility:visible;opacity:1;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.showing,.hiding{transition:none;display:none}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{padding-right:0.75rem}.docs-content>h2[id]::before,.docs-content>[id].h2::before,.docs-content>h3[id]::before,.docs-content>[id].h3::before,.docs-content>h4[id]::before,.docs-content>[id].h4::before{display:block;height:6rem;margin-top:-6rem;content:""}.docs-content ul,.docs-content ol{margin-bottom:1rem}.anchor{visibility:hidden;margin-left:0.375rem}h1:hover a,.h1:hover a,h2:hover a,.h2:hover a,h3:hover a,.h3:hover a,h4:hover a,.h4:hover a{visibility:visible;text-decoration:none}.card-list{margin-top:2.25rem}.page-footer-meta{margin-top:2rem;margin-bottom:2rem}p.meta{margin-top:0.5rem;font-size:1rem}.breadcrumb{margin-top:2.25rem;font-size:1rem}.toc-mobile{margin-top:2rem;margin-bottom:2rem}.page-link:hover{text-decoration:none}ul li{margin:0.25rem 0}.page-nav .card .icon-tabler-arrow-left{margin-right:0.75rem}.page-nav .card .icon-tabler-arrow-right{margin-left:0.75rem}.page-nav .card:hover{border:1px solid #d9d9d9}[data-bs-theme="dark"] .page-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .page-nav .card:hover{border:1px solid #888c96}.home .card,.contributors.list .card,.blog.list .card,.blog.single .card,.categories.list .card,.tags.list .card{margin-top:2rem;margin-bottom:2rem;transition:transform 0.3s}.home .content .card:hover,.contributors.list .content .card:hover,.blog.list .content .card:hover,.blog.single .content .card:hover,.categories.list .content .card:hover,.tags.list .content .card:hover{transform:scale(1.025)}.home .content .card-body,.contributors.list .content .card-body,.blog.list .content .card-body,.blog.single .content .card-body,.categories.list .content .card-body,.tags.list .content .card-body{padding:0 2rem 1rem}.blog-header{text-align:center;margin-bottom:2rem}.page-item:first-child,.page-item:last-child,.page-item.disabled{display:none}.page-item a{margin-left:0.5rem;margin-right:0.5rem;padding-left:0.875rem;padding-right:0.875rem}span.reading-time{margin-left:2rem}span.reading-time svg{margin-right:0.3rem;vertical-align:-0.4rem}.docs-links,.docs-toc{scrollbar-width:thin;scrollbar-color:#fff #fff}.docs-links::-webkit-scrollbar,.docs-toc::-webkit-scrollbar{width:5px}.docs-links::-webkit-scrollbar-track,.docs-toc::-webkit-scrollbar-track{background:#fff}.docs-links::-webkit-scrollbar-thumb,.docs-toc::-webkit-scrollbar-thumb{background:#fff}.docs-links:hover,.docs-toc:hover{scrollbar-width:thin;scrollbar-color:#e9ecef #fff}.docs-links:hover::-webkit-scrollbar-thumb,.docs-toc:hover::-webkit-scrollbar-thumb{background:#e9ecef}.docs-links::-webkit-scrollbar-thumb:hover,.docs-toc::-webkit-scrollbar-thumb:hover{background:#e9ecef}.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{font-size:1.125rem;margin:1.25rem 0 0.5rem;padding:1.5rem 0 0}@media (min-width: 992px){.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{margin:1.125rem 1.5rem 0.75rem 0;padding:1.375rem 0 0}}.docs-links h3:not(:first-child),.docs-links .h3:not(:first-child){border-top:1px solid #e9ecef}.page-links li{margin-top:0.375rem;padding-top:0.375rem}.page-links li ul li{border-top:none;padding-left:1rem;margin-top:0.125rem;padding-top:0.125rem}.page-links li:not(:first-child){border-top:1px dashed #e9ecef}.page-links a{color:#1d2d35;display:block;padding:0.125rem 0;font-size:.9375rem;text-decoration:none}.page-links a:hover,.page-links a.active{text-decoration:none;color:#5d2f86}.nav-link.active{font-weight:500} +:root[data-bs-theme="light"],[data-bs-theme="light"] ::backdrop{--sl-color-white: hsl(224, 10%, 10%);--sl-color-gray-1: hsl(224, 14%, 16%);--sl-color-gray-2: hsl(224, 10%, 23%);--sl-color-gray-3: hsl(224, 7%, 36%);--sl-color-gray-4: hsl(224, 6%, 56%);--sl-color-gray-5: hsl(224, 6%, 77%);--sl-color-gray-6: hsl(224, 20%, 94%);--sl-color-gray-7: hsl(224, 19%, 97%);--sl-color-black: hsl(0, 0%, 100%)}:root,::backdrop{--sl-color-white: hsl(0, 0%, 100%);--sl-color-gray-1: hsl(224, 20%, 94%);--sl-color-gray-2: hsl(224, 6%, 77%);--sl-color-gray-3: hsl(224, 6%, 56%);--sl-color-gray-4: hsl(224, 7%, 36%);--sl-color-gray-5: hsl(224, 10%, 23%);--sl-color-gray-6: hsl(224, 14%, 16%);--sl-color-black: hsl(224, 10%, 10%);--sl-hue-orange: 41;--sl-color-orange-low: hsl(var(--sl-hue-orange), 39%, 22%);--sl-color-orange: hsl(var(--sl-hue-orange), 82%, 63%);--sl-color-orange-high: hsl(var(--sl-hue-orange), 82%, 87%);--sl-hue-green: 101;--sl-color-green-low: hsl(var(--sl-hue-green), 39%, 22%);--sl-color-green: hsl(var(--sl-hue-green), 82%, 63%);--sl-color-green-high: hsl(var(--sl-hue-green), 82%, 80%);--sl-hue-blue: 234;--sl-color-blue-low: hsl(var(--sl-hue-blue), 54%, 20%);--sl-color-blue: hsl(var(--sl-hue-blue), 100%, 60%);--sl-color-blue-high: hsl(var(--sl-hue-blue), 100%, 87%);--sl-hue-purple: 281;--sl-color-purple-low: hsl(var(--sl-hue-purple), 39%, 22%);--sl-color-purple: hsl(var(--sl-hue-purple), 82%, 63%);--sl-color-purple-high: hsl(var(--sl-hue-purple), 82%, 89%);--sl-hue-red: 339;--sl-color-red-low: hsl(var(--sl-hue-red), 39%, 22%);--sl-color-red: hsl(var(--sl-hue-red), 82%, 63%);--sl-color-red-high: hsl(var(--sl-hue-red), 82%, 87%);--sl-color-accent-low: hsl(224, 54%, 20%);--sl-color-accent: hsl(224, 100%, 60%);--sl-color-accent-high: hsl(224, 100%, 85%);--sl-color-text: var(--sl-color-gray-2);--sl-color-text-accent: var(--sl-color-accent-high);--sl-color-text-invert: var(--sl-color-accent-low);--sl-color-bg: var(--sl-color-black);--sl-color-bg-nav: var(--sl-color-gray-6);--sl-color-bg-sidebar: var(--sl-color-gray-6);--sl-color-bg-inline-code: var(--sl-color-gray-5);--sl-color-hairline-light: var(--sl-color-gray-5);--sl-color-hairline: var(--sl-color-gray-6);--sl-color-hairline-shade: var(--sl-color-black);--sl-color-backdrop-overlay: hsla(223, 13%, 10%, 0.66);--sl-shadow-sm: 0px 1px 1px hsla(0, 0%, 0%, 0.12), 0px 2px 1px hsla(0, 0%, 0%, 0.24);--sl-shadow-md: 0px 8px 4px hsla(0, 0%, 0%, 0.08), 0px 5px 2px hsla(0, 0%, 0%, 0.08), 0px 3px 2px hsla(0, 0%, 0%, 0.12), 0px 1px 1px hsla(0, 0%, 0%, 0.15);--sl-shadow-lg: 0px 25px 7px hsla(0, 0%, 0%, 0.03), 0px 16px 6px hsla(0, 0%, 0%, 0.1), 0px 9px 5px hsla(223, 13%, 10%, 0.33), 0px 4px 4px hsla(0, 0%, 0%, 0.75), 0px 4px 2px hsla(0, 0%, 0%, 0.25);--sl-text-xs: 0.8125rem;--sl-text-sm: 0.875rem;--sl-text-base: 1rem;--sl-text-lg: 1.125rem;--sl-text-xl: 1.25rem;--sl-text-2xl: 1.5rem;--sl-text-3xl: 1.8125rem;--sl-text-4xl: 2.1875rem;--sl-text-5xl: 2.625rem;--sl-text-6xl: 4rem;--sl-text-body: var(--sl-text-base);--sl-text-body-sm: var(--sl-text-xs);--sl-text-code: var(--sl-text-sm);--sl-text-code-sm: var(--sl-text-xs);--sl-text-h1: var(--sl-text-4xl);--sl-text-h2: var(--sl-text-3xl);--sl-text-h3: var(--sl-text-2xl);--sl-text-h4: var(--sl-text-xl);--sl-text-h5: var(--sl-text-lg);--sl-line-height: 1.8;--sl-line-height-headings: 1.2;--sl-font-system: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--sl-font-system-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--__sl-font: var(--sl-font, ""), var(--sl-font-system);--__sl-font-mono: var(--sl-font-mono, ""), var(--sl-font-system-mono);--sl-nav-height: 3.5rem;--sl-nav-pad-x: 1rem;--sl-nav-pad-y: 0.75rem;--sl-mobile-toc-height: 3rem;--sl-sidebar-width: 18.75rem;--sl-sidebar-pad-x: 1rem;--sl-content-width: 45rem;--sl-content-pad-x: 1rem;--sl-menu-button-size: 2rem;--sl-nav-gap: var(--sl-content-pad-x);--sl-outline-offset-inside: -0.1875rem;--sl-z-index-toc: 4;--sl-z-index-menu: 5;--sl-z-index-navbar: 10;--sl-z-index-skiplink: 20}:root{--purple-hsl: 255, 60%, 60%;--overlay-blurple: hsla(var(--purple-hsl), 0.2)}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0.75rem;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}:root,[data-bs-theme="light"]{--bs-blue: #3347ff;--bs-indigo: #6610f2;--bs-purple: #bd53ee;--bs-pink: #d63384;--bs-red: #ee5389;--bs-orange: #fd7e14;--bs-yellow: #eebd53;--bs-green: #84ee53;--bs-teal: #20c997;--bs-cyan: #0dcaf0;--bs-black: #000;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #5d2f86;--bs-secondary: #6c757d;--bs-success: #84ee53;--bs-info: #3347ff;--bs-warning: #eebd53;--bs-danger: #ee5389;--bs-light: #f8f9fa;--bs-dark: #212529;--bs-primary-rgb: 93,47,134;--bs-secondary-rgb: 108,117,125;--bs-success-rgb: 132.2821,238.017,83.283;--bs-info-rgb: 51,71.4,255;--bs-warning-rgb: 238.017,189.0179,83.283;--bs-danger-rgb: 238.017,83.283,137.4399;--bs-light-rgb: 248,249,250;--bs-dark-rgb: 33,37,41;--bs-primary-text-emphasis: #251336;--bs-secondary-text-emphasis: #2b2f32;--bs-success-text-emphasis: #355f21;--bs-info-text-emphasis: #141d66;--bs-warning-text-emphasis: #5f4c21;--bs-danger-text-emphasis: #5f2137;--bs-light-text-emphasis: #495057;--bs-dark-text-emphasis: #495057;--bs-primary-bg-subtle: #dfd5e7;--bs-secondary-bg-subtle: #e2e3e5;--bs-success-bg-subtle: #e6fcdd;--bs-info-bg-subtle: #d6daff;--bs-warning-bg-subtle: #fcf2dd;--bs-danger-bg-subtle: #fcdde7;--bs-light-bg-subtle: #fcfcfd;--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: #beaccf;--bs-secondary-border-subtle: #c4c8cb;--bs-success-border-subtle: #cef8ba;--bs-info-border-subtle: #adb6ff;--bs-warning-border-subtle: #f8e5ba;--bs-danger-border-subtle: #f8bad0;--bs-light-border-subtle: #e9ecef;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-font-sans-serif: "Jost", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #1d2d35;--bs-body-color-rgb: 29,45,53;--bs-body-bg: #fff;--bs-body-bg-rgb: 255,255,255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0,0,0;--bs-secondary-color: rgba(29,45,53,0.75);--bs-secondary-color-rgb: 29,45,53;--bs-secondary-bg: #e9ecef;--bs-secondary-bg-rgb: 233,236,239;--bs-tertiary-color: rgba(29,45,53,0.5);--bs-tertiary-color-rgb: 29,45,53;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248,249,250;--bs-heading-color: inherit;--bs-link-color: #5d2f86;--bs-link-color-rgb: 93,47,134;--bs-link-decoration: none;--bs-link-hover-color: #4a266b;--bs-link-hover-color-rgb: 74,38,107;--bs-link-hover-decoration: underline;--bs-code-color: #d63384;--bs-highlight-color: #1d2d35;--bs-highlight-bg: #fcf2dd;--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0,0,0,0.175);--bs-border-radius: .375rem;--bs-border-radius-sm: .25rem;--bs-border-radius-lg: .5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0,0,0,0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0,0,0,0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0,0,0,0.075);--bs-focus-ring-width: .25rem;--bs-focus-ring-opacity: .25;--bs-focus-ring-color: rgba(93,47,134,0.25);--bs-form-valid-color: #84ee53;--bs-form-valid-border-color: #84ee53;--bs-form-invalid-color: #ee5389;--bs-form-invalid-border-color: #ee5389}[data-bs-theme="dark"]{color-scheme:dark;--bs-body-color: #c1c3c8;--bs-body-color-rgb: 192.831,194.7078,199.869;--bs-body-bg: #17181c;--bs-body-bg-rgb: 22.95,24.31,28.05;--bs-emphasis-color: #fff;--bs-emphasis-color-rgb: 255,255,255;--bs-secondary-color: rgba(193,195,200,0.75);--bs-secondary-color-rgb: 192.831,194.7078,199.869;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52,58,64;--bs-tertiary-color: rgba(193,195,200,0.5);--bs-tertiary-color-rgb: 192.831,194.7078,199.869;--bs-tertiary-bg: #2b3035;--bs-tertiary-bg-rgb: 43,48,53;--bs-primary-text-emphasis: #9e82b6;--bs-secondary-text-emphasis: #a7acb1;--bs-success-text-emphasis: #b5f598;--bs-info-text-emphasis: #8591ff;--bs-warning-text-emphasis: #f5d798;--bs-danger-text-emphasis: #f598b8;--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: #13091b;--bs-secondary-bg-subtle: #161719;--bs-success-bg-subtle: #1a3011;--bs-info-bg-subtle: #0a0e33;--bs-warning-bg-subtle: #302611;--bs-danger-bg-subtle: #30111b;--bs-light-bg-subtle: #23262f;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: #381c50;--bs-secondary-border-subtle: #41464b;--bs-success-border-subtle: #4f8f32;--bs-info-border-subtle: #1f2b99;--bs-warning-border-subtle: #8f7132;--bs-danger-border-subtle: #8f3252;--bs-light-border-subtle: #353841;--bs-dark-border-subtle: #343a40;--bs-heading-color: #fff;--bs-link-color: #b3c7ff;--bs-link-hover-color: #c2d2ff;--bs-link-color-rgb: 178.5,198.9,255;--bs-link-hover-color-rgb: 194,210,255;--bs-code-color: #e685b5;--bs-highlight-color: #c1c3c8;--bs-highlight-bg: #5f4c21;--bs-border-color: #495057;--bs-border-color-translucent: rgba(255,255,255,0.15);--bs-form-valid-color: #b5f598;--bs-form-valid-border-color: #b5f598;--bs-form-invalid-color: #f598b8;--bs-form-invalid-border-color: #f598b8}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:700;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width: 1200px){h1,.h1{font-size:2.5rem}}h2,.h2{font-size:calc(1.325rem + .9vw)}@media (min-width: 1200px){h2,.h2{font-size:2rem}}h3,.h3{font-size:calc(1.3rem + .6vw)}@media (min-width: 1200px){h3,.h3{font-size:1.75rem}}h4,.h4{font-size:calc(1.275rem + .3vw)}@media (min-width: 1200px){h4,.h4{font-size:1.5rem}}h5,.h5{font-size:1.25rem}p{margin-top:0;margin-bottom:1rem}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}strong{font-weight:bolder}small,.small{font-size:.875em}mark,.mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:none}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb);text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator{display:none !important}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}summary{display:list-item;cursor:pointer}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:400}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.img-fluid{max-width:100%;height:auto}.figure{display:inline-block}.container,.container-fluid,.container-lg{--bs-gutter-x: 3rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container-lg,.container{max-width:960px}}@media (min-width: 1200px){.container-lg,.container{max-width:1240px}}@media (min-width: 1400px){.container-lg,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.row{--bs-gutter-x: 3rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width: 768px){.col-md-12{flex:0 0 auto;width:75%}}@media (min-width: 992px){.col-lg-5{flex:0 0 auto;width:31.25%}.col-lg-8{flex:0 0 auto;width:50%}.col-lg-9{flex:0 0 auto;width:56.25%}.col-lg-10{flex:0 0 auto;width:62.5%}.col-lg-11{flex:0 0 auto;width:68.75%}.col-lg-12{flex:0 0 auto;width:75%}}@media (min-width: 1200px){.col-xl-3{flex:0 0 auto;width:18.75%}.col-xl-4{flex:0 0 auto;width:25%}.col-xl-8{flex:0 0 auto;width:50%}.col-xl-9{flex:0 0 auto;width:56.25%}}.sticky-top{position:sticky;top:0;z-index:1020}.visually-hidden{width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}li input[type="checkbox"]{--bs-form-check-bg: var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;print-color-adjust:exact}li input[type="checkbox"]{border-radius:.25em}li input[type="radio"][type="checkbox"]{border-radius:50%}li input[type="checkbox"]:active{filter:brightness(90%)}li input[type="checkbox"]:focus{border-color:#ae97c3;outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}li input:checked[type="checkbox"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}li input[type="checkbox"]:checked[type="radio"]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}li input[type="checkbox"]:indeterminate{background-color:#5d2f86;border-color:#5d2f86;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:.5}.btn{--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 0 rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);text-decoration:none;background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #5d2f86;--bs-btn-border-color: #5d2f86;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #4f2872;--bs-btn-hover-border-color: #4a266b;--bs-btn-focus-shadow-rgb: 117,78,152;--bs-btn-active-color: #fff;--bs-btn-active-bg: #4a266b;--bs-btn-active-border-color: #462365;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #5d2f86;--bs-btn-disabled-border-color: #5d2f86}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: var(--bs-link-color);--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: var(--bs-link-hover-color);--bs-btn-hover-border-color: transparent;--bs-btn-active-color: var(--bs-link-hover-color);--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 117,78,152;text-decoration:none}.btn-link:hover,.btn-link:focus-visible{text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.nav{--bs-nav-link-padding-x: 1rem;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-link-color);--bs-nav-link-hover-color: var(--bs-link-hover-color);--bs-nav-link-disabled-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);background:none;border:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color);text-decoration:none}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(93,47,134,0.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: .5rem;--bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y: .3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x: .5rem;--bs-navbar-toggler-padding-y: .25rem;--bs-navbar-toggler-padding-x: .75rem;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2829,45,53,0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius: var(--bs-border-radius);--bs-navbar-toggler-focus-width: 0;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color);text-decoration:none}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: .5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:transparent !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar[data-bs-theme="dark"]{--bs-navbar-color: #c1c3c8;--bs-navbar-hover-color: #b3c7ff;--bs-navbar-disabled-color: rgba(255,255,255,0.25);--bs-navbar-active-color: #b3c7ff;--bs-navbar-brand-color: #b3c7ff;--bs-navbar-brand-hover-color: #b3c7ff;--bs-navbar-toggler-border-color: rgba(255,255,255,0.1);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23c1c3c8' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: .5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: var(--bs-border-width);--bs-card-border-color: #e9ecef;--bs-card-border-radius: var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y: .5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: var(--bs-body-bg);--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 1.5rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-text:last-child{margin-bottom:0}.breadcrumb{--bs-breadcrumb-padding-x: 0;--bs-breadcrumb-padding-y: 0;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color: var(--bs-secondary-color);--bs-breadcrumb-item-padding-x: .5rem;--bs-breadcrumb-item-active-color: var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);text-decoration:none;background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: .5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.offcanvas{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 332px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: var(--bs-body-color);--bs-offcanvas-bg: var(--bs-body-bg);--bs-offcanvas-border-width: var(--bs-border-width);--bs-offcanvas-border-color: var(--bs-border-color-translucent);--bs-offcanvas-box-shadow: var(--bs-box-shadow-sm);--bs-offcanvas-transition: transform .3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.position-relative{position:relative !important}.w-100{width:100% !important}.h-auto{height:auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-grow-1{flex-grow:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.order-3{order:3 !important}.m-2{margin:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.mt-1{margin-top:.25rem !important}.mt-4{margin-top:1.5rem !important}.me-2{margin-right:.5rem !important}.me-auto{margin-right:auto !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.ms-2{margin-left:.5rem !important}.ms-auto{margin-left:auto !important}.mt-n3{margin-top:-1rem !important}.p-0{padding:0 !important}.p-2{padding:.5rem !important}.pt-4{padding-top:1.5rem !important}.pe-4{padding-right:1.5rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.ps-3{padding-left:1rem !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-nowrap{white-space:nowrap !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.rounded-circle{border-radius:50% !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}}@media (min-width: 992px){.d-lg-block{display:block !important}.d-lg-none{display:none !important}.flex-lg-row{flex-direction:row !important}.order-lg-4{order:4 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-3{margin-right:1rem !important}.ms-lg-2{margin-left:.5rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}}@media (min-width: 1200px){.d-xl-block{display:block !important}.d-xl-none{display:none !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}}@font-face{font-family:Jost;font-style:normal;font-weight:400;font-display:swap;src:local("Jost Regular Regular"),local("Jost-Regular"),local("Jost* Book"),local("Jost-Book"),url("fonts/vendor/jost/jost-v4-latin-regular.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-regular.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:500;font-display:swap;src:local("Jost Regular Medium"),local("JostRoman-Medium"),local("Jost* Medium"),local("Jost-Medium"),url("fonts/vendor/jost/jost-v4-latin-500.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500.woff") format("woff")}@font-face{font-family:Jost;font-style:normal;font-weight:700;font-display:swap;src:local("Jost Regular Bold"),local("JostRoman-Bold"),local("Jost* Bold"),local("Jost-Bold"),url("fonts/vendor/jost/jost-v4-latin-700.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:400;font-display:swap;src:local("Jost Italic Italic"),local("Jost-Italic"),local("Jost* BookItalic"),local("Jost-BookItalic"),url("fonts/vendor/jost/jost-v4-latin-italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:500;font-display:swap;src:local("Jost Italic Medium Italic"),local("JostItalic-Medium"),local("Jost* Medium Italic"),local("Jost-MediumItalic"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-500italic.woff") format("woff")}@font-face{font-family:Jost;font-style:italic;font-weight:700;font-display:swap;src:local("Jost Italic Bold Italic"),local("JostItalic-Bold"),local("Jost* Bold Italic"),local("Jost-BoldItalic"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff2") format("woff2"),url("fonts/vendor/jost/jost-v4-latin-700italic.woff") format("woff")}html[data-bs-theme="dark"] .icon-tabler-sun{display:block}html[data-bs-theme="dark"] .icon-tabler-moon{display:none}html[data-bs-theme="light"] .icon-tabler-sun{display:none}html[data-bs-theme="light"] .icon-tabler-moon{display:block}.privacy .content,.contributors .content,.blog .content,.error404 .content,.docs.list .content,.categories.list .content,.tags.list .content,.list.section .content{padding-top:1rem;padding-bottom:3rem}.content img{max-width:100%}h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:2rem;margin-bottom:1rem}@media (min-width: 768px){body{font-size:1.125rem}h1,h2,h3,h4,h5,.h1,.h2,.h3,.h4,.h5{margin-bottom:1.125rem}}.home h1,.home .h1{font-size:calc(1.875rem + 1.5vw);margin-top:-1rem}a:hover,a:focus{text-decoration:underline}a.btn:hover,a.btn:focus{text-decoration:none}.section{padding-top:5rem;padding-bottom:5rem}body.section{padding-top:0;padding-bottom:0}.section-md{padding-top:3rem;padding-bottom:3rem}.docs-sidebar{order:2}@media (min-width: 992px){.docs-sidebar{order:0;border-right:1px solid #e9ecef}@supports (position: sticky){.docs-sidebar{position:sticky;top:4.25rem;z-index:1000;height:calc(100vh - 4.25rem)}}}@media (min-width: 1200px){.docs-sidebar{flex:0 1 320px}}.docs-links{padding-bottom:5rem}@media (min-width: 992px){@supports (position: sticky){.docs-links{max-height:calc(100vh - 4rem);overflow-y:scroll}}}@media (min-width: 992px){.docs-links{display:block;width:auto;margin-right:-1.5rem;padding-bottom:4rem}}.docs-toc{order:2}@supports (position: sticky){.docs-toc{position:sticky;top:4.25rem;height:calc(100vh - 4.25rem);overflow-y:auto}}.docs-content{padding-bottom:3rem;order:1}.navbar a:hover,.navbar a:focus{text-decoration:none}#TableOfContents ul,#toc ul{padding-left:0;list-style:none}#toc a.active{color:#5d2f86;font-weight:500}.section-features{padding-top:2rem}.bg-dots{background-image:radial-gradient(#dee2e6 15%, transparent 15%);background-position:0 0;background-size:1rem 1rem;-webkit-mask:linear-gradient(to top, #fff, transparent);mask:linear-gradient(to top, #fff, transparent);width:100%;height:11rem;margin-top:-10rem;z-index:-1}.modal-backdrop{background-color:#fff}.modal-backdrop.show{opacity:0.7}@media (min-width: 768px){.modal-backdrop.show{opacity:0}}li input[type="checkbox"]{margin:0.25rem;border:1px solid #ced4da}li input[type="checkbox"]:disabled{pointer-events:none;filter:none;opacity:1}li input[type="checkbox"]:checked{background-color:#5d2f86;border-color:#5d2f86}[data-bs-theme="dark"] li input[type="checkbox"]{border:1px solid #6c757d}[data-bs-theme="dark"] li input[type="checkbox"]:checked{background-color:#b3c7ff;border-color:#b3c7ff;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%231d2d35' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.content .svg-inline{margin-bottom:1.5rem}.content .svg-inline:not(.svg-inline-custom){height:1.875rem;width:1.875rem;stroke-width:1.5}.card-nav{-moz-column-gap:1rem;column-gap:1rem}.card-nav .card{margin:0.5rem 0}.card-nav .card:hover{border:1px solid #d9d9d9;background-color:var(--sl-color-gray-7)}[data-bs-theme="dark"] .card-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .card-nav .card:hover{border:1px solid #888c96;background-color:var(--sl-color-gray-6)}.highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.bg{background-color:var(--sl-color-gray-7)}.chroma{background-color:var(--sl-color-gray-7)}.chroma .err{color:inherit}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{background-color:#0000001a}.chroma .hl{border-inline-start:0.15rem solid #00000055;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f}.chroma .line{display:flex}.chroma .k{color:#000000;font-weight:bold}.chroma .kc{color:#000000;font-weight:bold}.chroma .kd{color:#000000;font-weight:bold}.chroma .kn{color:#000000;font-weight:bold}.chroma .kp{color:#000000;font-weight:bold}.chroma .kr{color:#000000;font-weight:bold}.chroma .kt{color:#445588;font-weight:bold}.chroma .na{color:#008080}.chroma .nb{color:#0086b3}.chroma .bp{color:#999999}.chroma .nc{color:#445588;font-weight:bold}.chroma .no{color:#008080}.chroma .nd{color:#3c5d5d;font-weight:bold}.chroma .ni{color:#800080}.chroma .ne{color:#990000;font-weight:bold}.chroma .nf{color:#990000;font-weight:bold}.chroma .nl{color:#990000;font-weight:bold}.chroma .nn{color:#555555}.chroma .nt{color:#000080}.chroma .nv{color:#008080}.chroma .vc{color:#008080}.chroma .vg{color:#008080}.chroma .vi{color:#008080}.chroma .s{color:#dd1144}.chroma .sa{color:#dd1144}.chroma .sb{color:#dd1144}.chroma .sc{color:#dd1144}.chroma .dl{color:#dd1144}.chroma .sd{color:#dd1144}.chroma .s2{color:#dd1144}.chroma .se{color:#dd1144}.chroma .sh{color:#dd1144}.chroma .si{color:#dd1144}.chroma .sx{color:#dd1144}.chroma .sr{color:#009926}.chroma .s1{color:#dd1144}.chroma .ss{color:#990073}.chroma .m{color:#009999}.chroma .mb{color:#009999}.chroma .mf{color:#009999}.chroma .mh{color:#009999}.chroma .mi{color:#009999}.chroma .il{color:#009999}.chroma .mo{color:#009999}.chroma .o{color:#000000;font-weight:bold}.chroma .ow{color:#000000;font-weight:bold}.chroma .c{color:#999988;font-style:italic}.chroma .ch{color:#999988;font-style:italic}.chroma .cm{color:#999988;font-style:italic}.chroma .c1{color:#999988;font-style:italic}.chroma .cs{color:#999999;font-weight:bold;font-style:italic}.chroma .cp{color:#999999;font-weight:bold;font-style:italic}.chroma .cpf{color:#999999;font-weight:bold;font-style:italic}.chroma .gd{color:#000000;background-color:#ffdddd}.chroma .ge{color:inherit;font-style:italic}.chroma .gr{color:#aa0000}.chroma .gh{color:#999999}.chroma .gi{color:#000000;background-color:#ddffdd}.chroma .go{color:#888888}.chroma .gp{color:#555555}.chroma .gs{font-weight:bold}.chroma .gu{color:#aaaaaa}.chroma .gt{color:#aa0000}.chroma .gl{text-decoration:underline}.chroma .w{color:#bbbbbb}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .bg{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma{color:#c9d1d9;background-color:var(--sl-color-gray-6)}[data-bs-theme="dark"] .chroma .err{color:inherit}[data-bs-theme="dark"] .chroma .lnlinks{outline:none;text-decoration:none;color:inherit}[data-bs-theme="dark"] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}[data-bs-theme="dark"] .chroma .hl{background-color:#ffffff17}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}[data-bs-theme="dark"] .chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#64686c}[data-bs-theme="dark"] .chroma .ln{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681}[data-bs-theme="dark"] .chroma .line{display:flex}[data-bs-theme="dark"] .chroma .k{color:#ff7b72}[data-bs-theme="dark"] .chroma .kc{color:#79c0ff}[data-bs-theme="dark"] .chroma .kd{color:#ff7b72}[data-bs-theme="dark"] .chroma .kn{color:#ff7b72}[data-bs-theme="dark"] .chroma .kp{color:#79c0ff}[data-bs-theme="dark"] .chroma .kr{color:#ff7b72}[data-bs-theme="dark"] .chroma .kt{color:#ff7b72}[data-bs-theme="dark"] .chroma .na{color:#d2a8ff}[data-bs-theme="dark"] .chroma .nc{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .no{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nd{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .ni{color:#ffa657}[data-bs-theme="dark"] .chroma .ne{color:#f0883e;font-weight:bold}[data-bs-theme="dark"] .chroma .nf{color:#d2a8ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nl{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .nn{color:#ff7b72}[data-bs-theme="dark"] .chroma .py{color:#79c0ff}[data-bs-theme="dark"] .chroma .nt{color:#7ee787}[data-bs-theme="dark"] .chroma .nv{color:#79c0ff}[data-bs-theme="dark"] .chroma .l{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ld{color:#79c0ff}[data-bs-theme="dark"] .chroma .s{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sa{color:#79c0ff}[data-bs-theme="dark"] .chroma .sb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sc{color:#a5d6ff}[data-bs-theme="dark"] .chroma .dl{color:#79c0ff}[data-bs-theme="dark"] .chroma .sd{color:#a5d6ff}[data-bs-theme="dark"] .chroma .s2{color:#a5d6ff}[data-bs-theme="dark"] .chroma .se{color:#79c0ff}[data-bs-theme="dark"] .chroma .sh{color:#79c0ff}[data-bs-theme="dark"] .chroma .si{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sx{color:#a5d6ff}[data-bs-theme="dark"] .chroma .sr{color:#79c0ff}[data-bs-theme="dark"] .chroma .s1{color:#a5d6ff}[data-bs-theme="dark"] .chroma .ss{color:#a5d6ff}[data-bs-theme="dark"] .chroma .m{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mb{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mf{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mh{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mi{color:#a5d6ff}[data-bs-theme="dark"] .chroma .il{color:#a5d6ff}[data-bs-theme="dark"] .chroma .mo{color:#a5d6ff}[data-bs-theme="dark"] .chroma .o{color:inherit;font-weight:bold}[data-bs-theme="dark"] .chroma .ow{color:#ff7b72;font-weight:bold}[data-bs-theme="dark"] .chroma .c{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .ch{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cm{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .c1{color:#8b949e;font-style:italic}[data-bs-theme="dark"] .chroma .cs{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cp{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .cpf{color:#8b949e;font-weight:bold;font-style:italic}[data-bs-theme="dark"] .chroma .gd{color:#ffa198;background-color:#490202}[data-bs-theme="dark"] .chroma .ge{font-style:italic}[data-bs-theme="dark"] .chroma .gr{color:#ffa198}[data-bs-theme="dark"] .chroma .gh{color:#79c0ff;font-weight:bold}[data-bs-theme="dark"] .chroma .gi{color:#56d364;background-color:#0f5323}[data-bs-theme="dark"] .chroma .go{color:#8b949e}[data-bs-theme="dark"] .chroma .gp{color:#8b949e}[data-bs-theme="dark"] .chroma .gs{font-weight:bold}[data-bs-theme="dark"] .chroma .gu{color:#79c0ff}[data-bs-theme="dark"] .chroma .gt{color:#ff7b72}[data-bs-theme="dark"] .chroma .gl{text-decoration:underline}[data-bs-theme="dark"] .chroma .w{color:#6e7681}[data-bs-theme="dark"] h1,[data-bs-theme="dark"] .h1,[data-bs-theme="dark"] h2,[data-bs-theme="dark"] .h2,[data-bs-theme="dark"] h3,[data-bs-theme="dark"] .h3,[data-bs-theme="dark"] h4,[data-bs-theme="dark"] .h4{color:#fff}[data-bs-theme="dark"] body{background:#17181c;color:#c1c3c8}[data-bs-theme="dark"] a{color:#b3c7ff}[data-bs-theme="dark"] .callout a{color:inherit}[data-bs-theme="dark"] .btn-primary{--bs-btn-color: #000;--bs-btn-bg: #b3c7ff;--bs-btn-border-color: #b3c7ff;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #becfff;--bs-btn-hover-border-color: #bacdff;--bs-btn-focus-shadow-rgb: 152,169,217;--bs-btn-active-color: #000;--bs-btn-active-bg: #c2d2ff;--bs-btn-active-border-color: #bacdff;--bs-btn-active-shadow: inset 0 3px 5px rgba(0,0,0,0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #b3c7ff;--bs-btn-disabled-border-color: #b3c7ff;color:#17181c}[data-bs-theme="dark"] .navbar{background-color:rgba(23,24,28,0.95);border-bottom:1px solid #23262f}[data-bs-theme="dark"] body.home .navbar{border-bottom:0}[data-bs-theme="dark"] .offcanvas-header{border-bottom:1px solid #343a40}[data-bs-theme="dark"] .offcanvas .nav-link{color:#c1c3c8}[data-bs-theme="dark"] .offcanvas .nav-link:hover,[data-bs-theme="dark"] .offcanvas .nav-link:focus{color:#b3c7ff}[data-bs-theme="dark"] .offcanvas .nav-link.active{color:#b3c7ff}[data-bs-theme="dark"] .page-links a{color:#c1c3c8}[data-bs-theme="dark"] .page-links a:hover{text-decoration:none;color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link{color:#c1c3c8}[data-bs-theme="dark"] .content .btn-link{color:#b3c7ff}[data-bs-theme="dark"] .content .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:hover{color:#b3c7ff}[data-bs-theme="dark"] .navbar .btn-link:active{color:#b3c7ff}@media (min-width: 992px){[data-bs-theme="dark"] .docs-sidebar{order:0;border-right:1px solid #23262f}}[data-bs-theme="dark"] .footer{border-top:1px solid #23262f}[data-bs-theme="dark"] .docs-links,[data-bs-theme="dark"] .docs-toc{scrollbar-width:thin;scrollbar-color:#17181c #17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar{width:5px}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-track,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-track{background:#17181c}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb{background:#17181c}[data-bs-theme="dark"] .docs-links:hover,[data-bs-theme="dark"] .docs-toc:hover{scrollbar-width:thin;scrollbar-color:#23262f #17181c}[data-bs-theme="dark"] .docs-links:hover::-webkit-scrollbar-thumb,[data-bs-theme="dark"] .docs-toc:hover::-webkit-scrollbar-thumb{background:#23262f}[data-bs-theme="dark"] .docs-links::-webkit-scrollbar-thumb:hover,[data-bs-theme="dark"] .docs-toc::-webkit-scrollbar-thumb:hover{background:#23262f}[data-bs-theme="dark"] .docs-links h3:not(:first-child),[data-bs-theme="dark"] .docs-links .h3:not(:first-child){border-top:1px solid #23262f}[data-bs-theme="dark"] .page-links li:not(:first-child){border-top:1px dashed #23262f}[data-bs-theme="dark"] .card{background:#17181c;border:1px solid #23262f}[data-bs-theme="dark"] .bg-dots{background-image:radial-gradient(#414349 15%, transparent 15%)}[data-bs-theme="dark"] .text-muted{color:#adafb6 !important}[data-bs-theme="dark"] .offcanvas{background-color:#17181c}[data-bs-theme="dark"] .page-link{color:#b3c7ff;background-color:transparent;border:var(--bs-border-width) solid #23262f}[data-bs-theme="dark"] .page-link:hover{color:#17181c;background-color:#c1c3c8;border-color:#c1c3c8}[data-bs-theme="dark"] .page-link:focus{color:#17181c;background-color:#c1c3c8}[data-bs-theme="dark"] .page-item.active .page-link{color:#17181c;background-color:#b3c7ff;border-color:#b3c7ff}[data-bs-theme="dark"] .page-item.disabled .page-link{color:var(--bs-secondary-color);background-color:#23262f;border-color:#23262f}[data-bs-theme="dark"] details{border:1px solid #23262f}[data-bs-theme="dark"] summary:hover{background:#23262f}[data-bs-theme="dark"] details[open]>summary{border-bottom:1px solid #23262f}[data-bs-theme="dark"] details summary::after{content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e")}[data-bs-theme="dark"] #toc a.active{color:#b3c7ff}.navbar .btn-link{color:rgba(var(--bs-emphasis-color-rgb), 0.65);padding:0.4375rem 0}.btn-link:focus{outline:0;box-shadow:none}@media (min-width: 992px){.navbar .btn-link{padding:0.5625em 0.25rem 0.5rem 0.125rem}}.navbar .btn-link:hover{color:rgba(var(--bs-emphasis-color-rgb), 0.8)}.navbar .btn-link:active{color:rgba(var(--bs-emphasis-color-rgb), 1)}.clipboard{position:relative;float:right}.btn-clipboard{transition:opacity 0.25s ease-in-out;opacity:0;position:absolute;right:0.5rem;top:0.5rem;line-height:1;padding:0.3125rem 0.3125rem 0.1875rem;background-color:transparent;border-color:transparent}@media (max-width: 767.98px){.btn-clipboard{position:absolute;right:-0.5rem;top:0.5rem}}.btn-clipboard::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#495057}.btn-clipboard:hover{border-color:transparent}.btn-clipboard:hover::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-copy' width='22' height='22' viewBox='0 0 24 24' stroke-width='1' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z'%3E%3C/path%3E%3Cpath d='M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}.btn-clipboard:focus,.btn-clipboard:active{border-color:transparent !important}.btn-clipboard:focus::after,.btn-clipboard:active::after{width:22px;height:22px;display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;background-color:#212529}[data-bs-theme="dark"] .btn-clipboard{background-color:transparent;border-color:transparent}[data-bs-theme="dark"] .btn-clipboard::after{background-color:#ced4da}[data-bs-theme="dark"] .btn-clipboard:hover{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:hover::after{background-color:#e9ecef}[data-bs-theme="dark"] .btn-clipboard:focus,[data-bs-theme="dark"] .btn-clipboard:active{border-color:transparent}[data-bs-theme="dark"] .btn-clipboard:focus::after,[data-bs-theme="dark"] .btn-clipboard:active::after{background-color:#e9ecef}.highlight{position:relative}@media (min-width: 768px){.highlight:hover .btn-clipboard{opacity:1}}#toTop{opacity:0;transition:opacity 0.3s ease-in-out}.callout{--bs-link-color-rgb: var(--callout-link);--bs-code-color: var(--callout-code-color);color:var(--callout-color, inherit);background-color:var(--callout-bg, var(--bs-gray-100));border-left:0.25rem solid var(--callout-border, var(--bs-gray-300));border-radius:0}.callout a{text-decoration:underline}.callout .highlight{background-color:rgba(0,0,0,0.05)}.callout .callout-icon.svg-inline{flex-shrink:0;height:calc(1.5 * 1.125rem)}.callout .callout-title{font-weight:700}.callout-content{min-width:0}.callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-high)}.callout.callout-note .callout-icon,.callout.callout-note .callout-title,.callout.callout-note .callout-body a{color:var(--sl-color-blue-low)}.callout.callout-note .callout-body,.callout.callout-note .callout-body a:hover,.callout.callout-note .callout-body a:active{color:var(--sl-color-white)}.callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-high)}.callout.callout-tip .callout-icon,.callout.callout-tip .callout-title,.callout.callout-tip .callout-body a{color:var(--sl-color-purple-low)}.callout.callout-tip .callout-body,.callout.callout-tip .callout-body a:hover,.callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}.callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-high)}.callout.callout-caution .callout-icon,.callout.callout-caution .callout-title,.callout.callout-caution .callout-body a{color:var(--sl-color-orange-low)}.callout.callout-caution .callout-body,.callout.callout-caution .callout-body a:hover,.callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}.callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-high)}.callout.callout-danger .callout-icon,.callout.callout-danger .callout-title,.callout.callout-danger .callout-body a{color:var(--sl-color-red-low)}.callout.callout-danger .callout-body,.callout.callout-danger .callout-body a:hover,.callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout{color:var(--sl-color-gray-1)}[data-bs-theme="dark"] .callout.callout-note{border-color:var(--sl-color-blue);background-color:var(--sl-color-blue-low)}[data-bs-theme="dark"] .callout.callout-note .callout-icon,[data-bs-theme="dark"] .callout.callout-note .callout-title,[data-bs-theme="dark"] .callout.callout-note .callout-body a{color:var(--sl-color-blue-high)}[data-bs-theme="dark"] .callout.callout-note .callout-body,[data-bs-theme="dark"] .callout.callout-note .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-note .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-note code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-tip{border-color:var(--sl-color-purple);background-color:var(--sl-color-purple-low)}[data-bs-theme="dark"] .callout.callout-tip .callout-icon,[data-bs-theme="dark"] .callout.callout-tip .callout-title,[data-bs-theme="dark"] .callout.callout-tip .callout-body a{color:var(--sl-color-purple-high)}[data-bs-theme="dark"] .callout.callout-tip .callout-body,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-tip .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-tip code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-caution{border-color:var(--sl-color-orange);background-color:var(--sl-color-orange-low)}[data-bs-theme="dark"] .callout.callout-caution .callout-icon,[data-bs-theme="dark"] .callout.callout-caution .callout-title,[data-bs-theme="dark"] .callout.callout-caution .callout-body a{color:var(--sl-color-orange-high)}[data-bs-theme="dark"] .callout.callout-caution .callout-body,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-caution .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-caution code:not(:where(.not-content *)){color:var(--ec-codeFg)}[data-bs-theme="dark"] .callout.callout-danger{border-color:var(--sl-color-red);background-color:var(--sl-color-red-low)}[data-bs-theme="dark"] .callout.callout-danger .callout-icon,[data-bs-theme="dark"] .callout.callout-danger .callout-title,[data-bs-theme="dark"] .callout.callout-danger .callout-body a{color:var(--sl-color-red-high)}[data-bs-theme="dark"] .callout.callout-danger .callout-body,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:hover,[data-bs-theme="dark"] .callout.callout-danger .callout-body a:active{color:var(--sl-color-white)}[data-bs-theme="dark"] .callout.callout-danger code:not(:where(.not-content *)){color:var(--ec-codeFg)}.expressive-code{font-family:var(--ec-uiFontFml);font-size:var(--ec-uiFontSize);line-height:var(--ec-uiLineHt);-moz-text-size-adjust:none;text-size-adjust:none;-webkit-text-size-adjust:none;margin:1.5rem 0}.expressive-code *:not(path){all:revert;box-sizing:border-box}.expressive-code pre{display:flex;margin:0;padding:0;border:var(--ec-brdWd) solid var(--ec-brdCol);border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));background:var(--ec-codeBg)}.expressive-code pre:focus-visible{outline:3px solid var(--ec-focusBrd);outline-offset:-3px}.expressive-code pre>code{all:unset;display:block;flex:1 0 100%;padding:var(--ec-codePadBlk) 0;color:var(--ec-codeFg);font-family:var(--ec-codeFontFml);font-size:var(--ec-codeFontSize);line-height:var(--ec-codeLineHt)}.expressive-code pre{overflow-x:auto}.expressive-code pre::-webkit-scrollbar,.expressive-code pre::-webkit-scrollbar-track{background-color:inherit;border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));border-top-left-radius:0;border-top-right-radius:0}.expressive-code pre::-webkit-scrollbar-thumb{background-color:var(--ec-sbThumbCol);border:4px solid transparent;background-clip:content-box;border-radius:10px}.expressive-code pre::-webkit-scrollbar-thumb:hover{background-color:var(--ec-sbThumbHoverCol)}.expressive-code .ec-line{padding-inline:var(--ec-codePadInl);padding-inline-end:calc(2rem + var(--ec-codePadInl));direction:ltr;unicode-bidi:isolate}.expressive-code .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.expressive-code .ec-line.mark{--tmLineBgCol: var(--ec-tm-markBg);--tmLineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line.ins{--tmLineBgCol: var(--ec-tm-insBg);--tmLineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line.ins::before{content:var(--ec-tm-insDiffIndContent);color:var(--ec-tm-insDiffIndCol)}.expressive-code .ec-line.del{--tmLineBgCol: var(--ec-tm-delBg);--tmLineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line.del::before{content:var(--ec-tm-delDiffIndContent);color:var(--ec-tm-delDiffIndCol)}.expressive-code .ec-line.mark,.expressive-code .ec-line.ins,.expressive-code .ec-line.del{position:relative;background:var(--tmLineBgCol);min-width:calc(100% - var(--ec-tm-lineMarkerAccentMarg));margin-inline-start:var(--ec-tm-lineMarkerAccentMarg);border-inline-start:var(--ec-tm-lineMarkerAccentWd) solid var(--tmLineBrdCol);padding-inline-start:calc(var(--ec-codePadInl) - var(--ec-tm-lineMarkerAccentMarg) - var(--ec-tm-lineMarkerAccentWd)) !important}.expressive-code .ec-line.mark::before,.expressive-code .ec-line.ins::before,.expressive-code .ec-line.del::before{position:absolute;left:var(--ec-tm-lineDiffIndMargLeft)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark{--tmInlineBgCol: var(--ec-tm-markBg);--tmInlineBrdCol: var(--ec-tm-markBrdCol)}.expressive-code .ec-line ins{--tmInlineBgCol: var(--ec-tm-insBg);--tmInlineBrdCol: var(--ec-tm-insBrdCol)}.expressive-code .ec-line del{--tmInlineBgCol: var(--ec-tm-delBg);--tmInlineBrdCol: var(--ec-tm-delBrdCol)}.expressive-code .ec-line mark,.expressive-code .ec-line .mark,.expressive-code .ec-line ins,.expressive-code .ec-line del{all:unset;display:inline-block;position:relative;--tmBrdL: var(--ec-tm-inlMarkerBrdWd);--tmBrdR: var(--ec-tm-inlMarkerBrdWd);--tmRadL: var(--ec-tm-inlMarkerBrdRad);--tmRadR: var(--ec-tm-inlMarkerBrdRad);margin-inline:0.025rem;padding-inline:var(--ec-tm-inlMarkerPad);border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);background:var(--tmInlineBgCol);background-clip:padding-box}.expressive-code .ec-line mark.open-start,.expressive-code .ec-line .open-start.mark,.expressive-code .ec-line ins.open-start,.expressive-code .ec-line del.open-start{margin-inline-start:0;padding-inline-start:0;--tmBrdL: 0px;--tmRadL: 0}.expressive-code .ec-line mark.open-end,.expressive-code .ec-line .open-end.mark,.expressive-code .ec-line ins.open-end,.expressive-code .ec-line del.open-end{margin-inline-end:0;padding-inline-end:0;--tmBrdR: 0px;--tmRadR: 0}.expressive-code .ec-line mark::before,.expressive-code .ec-line .mark::before,.expressive-code .ec-line ins::before,.expressive-code .ec-line del::before{content:"";position:absolute;pointer-events:none;display:inline-block;inset:0;border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);border:var(--ec-tm-inlMarkerBrdWd) solid var(--tmInlineBrdCol);border-inline-width:var(--tmBrdL) var(--tmBrdR)}.expressive-code .frame{all:unset;position:relative;display:block;--header-border-radius: calc(var(--ec-brdRad) + var(--ec-brdWd));--tab-border-radius: calc(var(--ec-frm-edTabBrdRad) + var(--ec-brdWd));--button-spacing: 0.4rem;--code-background: var(--ec-frm-edBg);border-radius:var(--header-border-radius);box-shadow:var(--ec-frm-frameBoxShdCssVal)}.expressive-code .frame .header{display:none;z-index:1;position:relative;border-radius:var(--header-border-radius) var(--header-border-radius) 0 0}.expressive-code .frame.has-title pre,.expressive-code .frame.has-title code,.expressive-code .frame.is-terminal pre,.expressive-code .frame.is-terminal code{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.expressive-code .frame .title:empty:before{content:"\a0"}.expressive-code .frame.has-title:not(.is-terminal){--button-spacing: calc(1.9rem + 2 * (var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)))}.expressive-code .frame.has-title:not(.is-terminal) .title{position:relative;color:var(--ec-frm-edActTabFg);background:var(--ec-frm-edActTabBg);background-clip:padding-box;margin-block-start:var(--ec-frm-edTabsMargBlkStart);padding:calc(var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)) var(--ec-uiPadInl);border:var(--ec-brdWd) solid var(--ec-frm-edActTabBrdCol);border-radius:var(--tab-border-radius) var(--tab-border-radius) 0 0;border-bottom:none;overflow:hidden}.expressive-code .frame.has-title:not(.is-terminal) .title::after{content:"";position:absolute;pointer-events:none;inset:0;border-top:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndTopCol);border-bottom:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndBtmCol)}.expressive-code .frame.has-title:not(.is-terminal) .header{display:flex;background:linear-gradient(to top, var(--ec-frm-edTabBarBrdBtmCol) var(--ec-brdWd), transparent var(--ec-brdWd)),linear-gradient(var(--ec-frm-edTabBarBg), var(--ec-frm-edTabBarBg));background-repeat:no-repeat;padding-inline-start:var(--ec-frm-edTabsMargInlStart)}.expressive-code .frame.has-title:not(.is-terminal) .header::before{content:"";position:absolute;pointer-events:none;inset:0;border:var(--ec-brdWd) solid var(--ec-frm-edTabBarBrdCol);border-radius:inherit;border-bottom:none}.expressive-code .frame.is-terminal{--button-spacing: calc(1.9rem + var(--ec-brdWd) + 2 * var(--ec-uiPadBlk));--code-background: var(--ec-frm-trmBg)}.expressive-code .frame.is-terminal .header{display:flex;align-items:center;justify-content:center;padding-block:var(--ec-uiPadBlk);padding-block-end:calc(var(--ec-uiPadBlk) + var(--ec-brdWd));position:relative;font-weight:500;letter-spacing:0.025ch;color:var(--ec-frm-trmTtbFg);background:var(--ec-frm-trmTtbBg);border:var(--ec-brdWd) solid var(--ec-brdCol);border-bottom:none}.expressive-code .frame.is-terminal .header::before{content:"";position:absolute;pointer-events:none;left:var(--ec-uiPadInl);width:2.1rem;height:0.56rem;line-height:0;background-color:var(--ec-frm-trmTtbDotsFg);opacity:var(--ec-frm-trmTtbDotsOpa);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");mask-repeat:no-repeat}.expressive-code .frame.is-terminal .header::after{content:"";position:absolute;pointer-events:none;inset:0;border-bottom:var(--ec-brdWd) solid var(--ec-frm-trmTtbBrdBtmCol)}.expressive-code .frame pre{background:var(--code-background)}.expressive-code .copy{display:flex;gap:0.25rem;flex-direction:row;position:absolute;inset-block-start:calc(var(--ec-brdWd) + var(--button-spacing));inset-inline-end:calc(var(--ec-brdWd) + var(--ec-uiPadInl) / 2);direction:ltr;unicode-bidi:isolate}.expressive-code .copy button{position:relative;align-self:flex-end;margin:0;padding:0;border:none;border-radius:0.2rem;z-index:1;cursor:pointer;transition-property:opacity, background, border-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.25, 0.46, 0.45, 0.94);width:2.5rem;height:2.5rem;background:var(--code-background);opacity:0.75}.expressive-code .copy button div{position:absolute;inset:0;border-radius:inherit;background:var(--ec-frm-inlBtnBg);opacity:var(--ec-frm-inlBtnBgIdleOpa);transition-property:inherit;transition-duration:inherit;transition-timing-function:inherit}.expressive-code .copy button::before{content:"";position:absolute;pointer-events:none;inset:0;border-radius:inherit;border:var(--ec-brdWd) solid var(--ec-frm-inlBtnBrd);opacity:var(--ec-frm-inlBtnBrdOpa)}.expressive-code .copy button::after{content:"";position:absolute;pointer-events:none;inset:0;background-color:var(--ec-frm-inlBtnFg);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");mask-repeat:no-repeat;margin:0.475rem;line-height:0}.expressive-code .copy button:focus::after,.expressive-code .copy button:active::after{display:inline-block;content:"";-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' stroke-width='1.25' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M5 12l5 5l10 -10'%3E%3C/path%3E%3C/svg%3E") no-repeat 50% 50%;-webkit-mask-size:cover;mask-size:cover;margin:0.2375rem}.expressive-code .copy button:hover,.expressive-code .copy button:focus:focus-visible{opacity:1}.expressive-code .copy button:hover div,.expressive-code .copy button:focus:focus-visible div{opacity:var(--ec-frm-inlBtnBgHoverOrFocusOpa)}.expressive-code .copy button:active{opacity:1}.expressive-code .copy button:active div{opacity:var(--ec-frm-inlBtnBgActOpa)}.expressive-code .copy .feedback{--tooltip-arrow-size: 0.35rem;--tooltip-bg: var(--ec-frm-tooltipSuccessBg);color:var(--ec-frm-tooltipSuccessFg);pointer-events:none;-moz-user-select:none;user-select:none;-webkit-user-select:none;position:relative;align-self:center;background-color:var(--tooltip-bg);z-index:99;padding:0.125rem 0.75rem;border-radius:0.2rem;margin-inline-end:var(--tooltip-arrow-size);opacity:0;transition-property:opacity, transform;transition-duration:0.2s;transition-timing-function:ease-in-out;transform:translate3d(0, 0.25rem, 0)}.expressive-code .copy .feedback::after{content:"";position:absolute;pointer-events:none;top:calc(50% - var(--tooltip-arrow-size));inset-inline-end:calc(-2 * (var(--tooltip-arrow-size) - 0.5px));border:var(--tooltip-arrow-size) solid transparent;border-inline-start-color:var(--tooltip-bg)}.expressive-code .copy .feedback.show{opacity:1;transform:translate3d(0, 0, 0)}@media (hover: hover){.expressive-code .copy button{opacity:0;width:2rem;height:2rem}.expressive-code .frame:hover .copy button:not(:hover),.expressive-code .frame:focus-within :focus-visible~.copy button:not(:hover),.expressive-code .frame .copy .feedback.show~button:not(:hover){opacity:0.75}}:root{--ec-brdRad: 0px;--ec-brdWd: 1px;--ec-brdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml: var(--__sl-font-mono);--ec-codeFontSize: var(--sl-text-code);--ec-codeFontWg: 400;--ec-codeLineHt: var(--sl-line-height);--ec-codePadBlk: 0;--ec-codePadInl: 1rem;--ec-codeBg: #011627;--ec-codeFg: #d6deeb;--ec-codeSelBg: #1d3b53;--ec-uiFontFml: var(--__sl-font);--ec-uiFontSize: 0.9rem;--ec-uiFontWg: 400;--ec-uiLineHt: 1.65;--ec-uiPadBlk: 0.25rem;--ec-uiPadInl: 1rem;--ec-uiSelBg: #234d708c;--ec-uiSelFg: #ffffff;--ec-focusBrd: #122d42;--ec-sbThumbCol: #ffffff17;--ec-sbThumbHoverCol: #ffffff49;--ec-tm-lineMarkerAccentMarg: 0rem;--ec-tm-lineMarkerAccentWd: 0.15rem;--ec-tm-lineDiffIndMargLeft: 0.25rem;--ec-tm-inlMarkerBrdWd: 1.5px;--ec-tm-inlMarkerBrdRad: 0.2rem;--ec-tm-inlMarkerPad: 0.15rem;--ec-tm-insDiffIndContent: "+";--ec-tm-delDiffIndContent: "-";--ec-tm-markBg: #ffffff17;--ec-tm-markBrdCol: #ffffff40;--ec-tm-insBg: #1e571599;--ec-tm-insBrdCol: #487f3bd0;--ec-tm-insDiffIndCol: #79b169d0;--ec-tm-delBg: #862d2799;--ec-tm-delBrdCol: #b4554bd0;--ec-tm-delDiffIndCol: #ed8779d0;--ec-frm-shdCol: #011627;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edActTabBg: var(--sl-color-gray-6);--ec-frm-edActTabFg: var(--sl-color-text);--ec-frm-edActTabBrdCol: transparent;--ec-frm-edActTabIndHt: 1px;--ec-frm-edActTabIndTopCol: var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol: transparent;--ec-frm-edTabsMargInlStart: 0;--ec-frm-edTabsMargBlkStart: 0;--ec-frm-edTabBrdRad: 0px;--ec-frm-edTabBarBg: var(--sl-color-black);--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg: var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa: 0.75;--ec-frm-trmTtbBg: var(--sl-color-black);--ec-frm-trmTtbFg: var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol: color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg: var(--sl-color-gray-6);--ec-frm-inlBtnFg: var(--sl-color-text);--ec-frm-inlBtnBg: var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa: 0;--ec-frm-inlBtnBgHoverOrFocusOpa: 0.2;--ec-frm-inlBtnBgActOpa: 0.3;--ec-frm-inlBtnBrd: var(--sl-color-text);--ec-frm-inlBtnBrdOpa: 0.4;--ec-frm-tooltipSuccessBg: #158744;--ec-frm-tooltipSuccessFg: white}.expressive-code .ec-line span[style^="--"]:not([class]){color:var(0, inherit);font-style:var(0fs, inherit);font-weight:var(0fw, inherit);-webkit-text-decoration:var(0td, inherit);text-decoration:var(0td, inherit)}@media (prefers-color-scheme: light){:root:not([data-bs-theme="dark"]){--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root:not([data-bs-theme="dark"]) .expressive-code .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}}:root[data-bs-theme="light"] .expressive-code,.expressive-code[data-bs-theme="light"]{--ec-codeBg: #fbfbfb;--ec-codeFg: #403f53;--ec-codeSelBg: #e0e0e0;--ec-uiSelBg: #d3e8f8;--ec-uiSelFg: #403f53;--ec-focusBrd: #93a1a1;--ec-sbThumbCol: #0000001a;--ec-sbThumbHoverCol: #0000005c;--ec-tm-markBg: #0000001a;--ec-tm-markBrdCol: #00000055;--ec-tm-insBg: #8ec77d99;--ec-tm-insDiffIndCol: #336a28d0;--ec-tm-delBg: #ff9c8e99;--ec-tm-delDiffIndCol: #9d4138d0;--ec-frm-shdCol: #d9d9d9;--ec-frm-edActTabBg: var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol: #5d2f86;--ec-frm-edTabBarBg: var(--sl-color-gray-6);--ec-frm-edBg: var(--sl-color-gray-7);--ec-frm-trmTtbBg: var(--sl-color-gray-6);--ec-frm-trmBg: var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg: #078662}:root[data-bs-theme="light"] .expressive-code .ec-line span[style^="--"]:not([class]),.expressive-code[data-bs-theme="light"] .ec-line span[style^="--"]:not([class]){color:var(1, inherit);font-style:var(1fs, inherit);font-weight:var(1fw, inherit);-webkit-text-decoration:var(1td, inherit);text-decoration:var(1td, inherit)}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875rem}code:not(:where(.not-content *)){background-color:var(--sl-color-gray-6);margin-block:-0.125rem;padding:0.125rem 0.375rem;color:inherit}[data-bs-theme="dark"] code:not(:where(.not-content *)){background-color:var(--sl-color-gray-5)}.math-block{display:block;margin:2rem 0;overflow-x:auto}.math-inline{display:inline}[data-bs-theme="dark"] .math-inline img,[data-bs-theme="dark"] .math-block img{filter:invert(1)}img.diagram{height:auto;width:100%;margin:1rem 0 2rem}img.diagram-kroki-mermaid{background:#fff}.highlight>pre{padding:0.875rem 1rem}.highlight div{padding:0}.highlight>.chroma{overflow-x:auto;border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}.chroma .ln{padding:0 0.5rem 0 0}.chroma .hl{border-inline-start:0.15rem solid #0005;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}.chroma .hl .ln{margin-left:-0.15rem}.highlight .chroma .lntable .lnt,.highlight .chroma .lntable .hl{display:flex}.chroma .lntd:first-child{padding:0}.chroma .lntd:first-child .lnt{padding-left:1rem}.chroma .lntd:nth-child(2){padding:0}.highlight .chroma .lntable .lntd+.lntd{width:100%}[data-bs-theme="dark"] .chroma .ln{padding:0 0.5em 0 0}.chroma .lntd pre{padding:1rem 0;margin-bottom:0}.highlight>.chroma::-webkit-scrollbar,.highlight>.chroma::-webkit-scrollbar-track{background-color:inherit;border-radius:1px;border-top-left-radius:0;border-top-right-radius:0}.highlight>.chroma::-webkit-scrollbar-thumb{background-color:#dddee0;border:4px solid transparent;background-clip:content-box;border-radius:10px}.highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#9d9e9f}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb{background-color:#ffffff17}[data-bs-theme="dark"] .highlight>.chroma::-webkit-scrollbar-thumb:hover{background-color:#ffffff49}[data-bs-theme="dark"] .highlight>.chroma{border:1px solid color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)}[data-bs-theme="dark"] .chroma .hl{border-inline-start:0.15rem solid #ffffff40;margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem}[data-bs-theme="dark"] .chroma .hl .ln{margin-left:-0.15rem}details{display:block;position:relative;border:1px solid #e9ecef;border-radius:0.25rem;padding:0.5rem 1rem 0;margin:0.5rem 0}summary{list-style:none;display:inline-block;width:calc(100% + 2rem);margin:-0.5rem -1rem 0;padding:0.5rem 1rem}summary::-webkit-details-marker{display:none}summary:hover{background:#f8f9fa}details summary::after{display:inline-block;content:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");transition:transform 0.35s ease;transform-origin:center center;position:absolute;right:1rem}details[open]>summary::after{transform:rotate(90deg)}details[open]{padding:0.5rem 1rem}details[open]>summary{border-bottom:1px solid #dee2e6;margin-bottom:0.5rem}details h2,details .h2,details h3,details .h3,details h4,details .h4{margin:1rem 0 0.5rem}details p:last-child{margin-bottom:0}details ul,details ol{margin-bottom:0}details pre{margin:0 0 1rem}img{max-width:100%;height:auto}img[data-sizes="auto"]{display:block}img{font-size:0}figcaption{font-size:1rem;margin-top:0.5rem;font-style:italic}.blur-up{filter:blur(5px);transition:filter 400ms}.blur-up.lazyloaded{filter:unset}.section-nav{padding-top:2rem}.section-nav details{border:0;padding:0;margin:0.5rem 0}.section-nav details[open]{padding:0}.section-nav summary{width:100%;padding:0;margin:0;font-weight:700}.section-nav summary:hover{background:none}.section-nav details[open]>summary{border-bottom:0;margin-bottom:0}.section-nav ul.list-nested details{padding-left:1rem;margin-top:0.5rem}.section-nav ul.list-nested li{margin:0}.section-nav a{display:block;margin:0.5rem 0;color:#1d2d35;font-size:1rem;text-decoration:none}.section-nav a:hover,.section-nav a:active{color:#5d2f86}.section-nav li.active a{color:#5d2f86;font-weight:500}.section-nav ul.list-nested li a{padding-left:1rem}.section-nav ul.list-nested{border-left:1px solid #e9ecef}[data-bs-theme="dark"] .section-nav ul.list-nested{border-left:1px solid #23262f}[data-bs-theme="dark"] .section-nav a{color:#c1c3c8}[data-bs-theme="dark"] .section-nav a:hover,[data-bs-theme="dark"] .section-nav a:active{color:var(--sl-color-text-accent)}[data-bs-theme="dark"] .section-nav li.active a{color:var(--sl-color-text-accent);font-weight:500}[data-bs-theme="dark"] .section-nav summary{color:#fff}.footer{border-top:1px solid #e9ecef;padding-top:1.125rem;padding-bottom:1.125rem}.footer ul{margin-bottom:0}.footer li{font-size:.875rem;margin-bottom:0}.footer .list-inline-item:not(:last-child){margin-right:1rem}@media (max-width: 991.98px){.footer .col-lg-8{margin-top:0.25rem;margin-bottom:0.25rem}}@media (min-width: 768px){.footer li{font-size:1rem}}.fixed-bottom-right{position:fixed;right:0;bottom:0;z-index:1000}.navbar-brand{font-weight:700}.navbar-brand svg{margin-right:0.25rem}[data-bs-theme="dark"] .navbar-brand{color:inherit}.navbar{z-index:1000;background-color:rgba(255,255,255,0.95);border-bottom:1px solid #e9ecef}@media (min-width: 992px){.navbar{z-index:1025}}@media (min-width: 768px){.navbar-brand{font-size:1.375rem}}.nav-item{margin-left:0}@media (max-width: 991.98px){.navbar-nav .nav-link{font-weight:400}}@media (min-width: 768px){.nav-item{margin-left:0.5rem}}@media (max-width: 575.98px){.navbar .offcanvas.offcanvas-start,.navbar .offcanvas.offcanvas-end{width:80vw}}.offcanvas-header{border-bottom:1px solid #dee2e6;padding-top:1.0625rem;padding-bottom:0.8125rem}h5.offcanvas-title,.offcanvas-title.h5{margin:0;color:inherit}.offcanvas .nav-link{color:#1d2d35}.offcanvas .nav-link:hover,.offcanvas .nav-link:focus{color:#5d2f86}.offcanvas .nav-link.active{color:#5d2f86}.home .navbar{border-bottom:0}@media (min-width: 992px){.navbar-brand{margin-right:0.75rem !important}}.social-link{padding-right:0.375rem;padding-left:0.375rem}@media (max-width: 991.98px){#buttonColorMode{margin:0.5rem 0}#socialMenu{margin:0.5rem 0 0.5rem -0.25rem}.navbar-nav{margin-top:1rem}.nav-item .nav-link{font-weight:400;font-size:1.125rem}}.modal-backdrop,.offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}[data-bs-theme="dark"] .modal-backdrop,[data-bs-theme="dark"] .offcanvas-backdrop{visibility:hidden;background:rgba(23,24,28,0.5);opacity:0}.modal-backdrop.show,.offcanvas-backdrop.show{visibility:visible;opacity:1;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.showing,.hiding{transition:none;display:none}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg{padding-right:0.75rem}.docs-content>h2[id]::before,.docs-content>[id].h2::before,.docs-content>h3[id]::before,.docs-content>[id].h3::before,.docs-content>h4[id]::before,.docs-content>[id].h4::before{display:block;height:6rem;margin-top:-6rem;content:""}.docs-content ul,.docs-content ol{margin-bottom:1rem}.anchor{visibility:hidden;margin-left:0.375rem}h1:hover a,.h1:hover a,h2:hover a,.h2:hover a,h3:hover a,.h3:hover a,h4:hover a,.h4:hover a{visibility:visible;text-decoration:none}.card-list{margin-top:2.25rem}.page-footer-meta{margin-top:2rem;margin-bottom:2rem}p.meta{margin-top:0.5rem;font-size:1rem}.breadcrumb{margin-top:2.25rem;font-size:1rem}.toc-mobile{margin-top:2rem;margin-bottom:2rem}.page-link:hover{text-decoration:none}ul li{margin:0.25rem 0}.page-nav .card .icon-tabler-arrow-left{margin-right:0.75rem}.page-nav .card .icon-tabler-arrow-right{margin-left:0.75rem}.page-nav .card:hover{border:1px solid #d9d9d9}[data-bs-theme="dark"] .page-nav .card{border:1px solid #353841}[data-bs-theme="dark"] .page-nav .card:hover{border:1px solid #888c96}.home .card,.contributors.list .card,.blog.list .card,.blog.single .card,.categories.list .card,.tags.list .card{margin-top:2rem;margin-bottom:2rem;transition:transform 0.3s}.home .content .card:hover,.contributors.list .content .card:hover,.blog.list .content .card:hover,.blog.single .content .card:hover,.categories.list .content .card:hover,.tags.list .content .card:hover{transform:scale(1.025)}.home .content .card-body,.contributors.list .content .card-body,.blog.list .content .card-body,.blog.single .content .card-body,.categories.list .content .card-body,.tags.list .content .card-body{padding:0 2rem 1rem}.blog-header{text-align:center;margin-bottom:2rem}.page-item:first-child,.page-item:last-child,.page-item.disabled{display:none}.page-item a{margin-left:0.5rem;margin-right:0.5rem;padding-left:0.875rem;padding-right:0.875rem}span.reading-time{margin-left:2rem}span.reading-time svg{margin-right:0.3rem;vertical-align:-0.4rem}.docs-links,.docs-toc{scrollbar-width:thin;scrollbar-color:#fff #fff}.docs-links::-webkit-scrollbar,.docs-toc::-webkit-scrollbar{width:5px}.docs-links::-webkit-scrollbar-track,.docs-toc::-webkit-scrollbar-track{background:#fff}.docs-links::-webkit-scrollbar-thumb,.docs-toc::-webkit-scrollbar-thumb{background:#fff}.docs-links:hover,.docs-toc:hover{scrollbar-width:thin;scrollbar-color:#e9ecef #fff}.docs-links:hover::-webkit-scrollbar-thumb,.docs-toc:hover::-webkit-scrollbar-thumb{background:#e9ecef}.docs-links::-webkit-scrollbar-thumb:hover,.docs-toc::-webkit-scrollbar-thumb:hover{background:#e9ecef}.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{font-size:1.125rem;margin:1.25rem 0 0.5rem;padding:1.5rem 0 0}@media (min-width: 992px){.docs-links h3,.docs-links .h3,.page-links h3,.page-links .h3{margin:1.125rem 1.5rem 0.75rem 0;padding:1.375rem 0 0}}.docs-links h3:not(:first-child),.docs-links .h3:not(:first-child){border-top:1px solid #e9ecef}.page-links li{margin-top:0.375rem;padding-top:0.375rem}.page-links li ul li{border-top:none;padding-left:1rem;margin-top:0.125rem;padding-top:0.125rem}.page-links li:not(:first-child){border-top:1px dashed #e9ecef}.page-links a{color:#1d2d35;display:block;padding:0.125rem 0;font-size:.9375rem;text-decoration:none}.page-links a:hover,.page-links a.active{text-decoration:none;color:#5d2f86}.nav-link.active{font-weight:500} diff --git a/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.json b/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.json index dd38183..9ea7ec6 100644 --- a/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.json +++ b/resources/_gen/assets/scss/app.scss_cdf9d7c9eb97e4550ded64a8776dd9e8.json @@ -1 +1 @@ -{"Target":"main.cc9dcf79b8764d805c85c7626bd7c72f14fc506040b036fee0cf99a9f0cbab0812866b7a57d59508a02d0660ea872e57daaef7cb0dadc801462c3939341f794e.css","MediaType":"text/css","Data":{"Integrity":"sha512-zJ3Pebh2TYBchcdia9fHLxT8UGBAsDb+4M+ZqfDLqwgShmt6V9WVCKAtBmDqhy5X2q73yw2tyAFGLDk5NB95Tg=="}} \ No newline at end of file +{"Target":"main.bdaa5498903a6087c6d7e8fac6133113e5fa6b01e7c78680535b430bf606cfeae8afc6aec4d97aef96360230e5daa359104994b997c7440f7b802ca82c774b7e.css","MediaType":"text/css","Data":{"Integrity":"sha512-vapUmJA6YIfG1+j6xhMxE+X6awHnx4aAU1tDC/YGz+ror8auxNl675Y2AjDl2qNZEEmUuZfHRA97gCyoLHdLfg=="}} \ No newline at end of file