diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..0a2f026
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,40 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# All files
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# TypeScript, JavaScript, CSS, HTML, JSON, Markdown
+[*.{ts,js,css,html,md}]
+indent_style = space
+indent_size = 4
+max_line_length = 150
+
+# Markdown files
+[*.md]
+trim_trailing_whitespace = false
+max_line_length = off
+
+# CSS files specific
+[*.{css,postcss}]
+indent_style = space
+indent_size = 2
+block_comment_start = /*
+block_comment = *
+block_comment_end = */
+
+# Package files
+[*.json]
+indent_style = space
+indent_size = 2
+
+# Config files
+[*.{yml,yaml,conf}]
+indent_style = space
+indent_size = 2
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index f504fb7..0000000
--- a/.eslintrc
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "extends": "airbnb-base/legacy",
- "rules": {
- "indent": ["error", 4], // Use 4 spaces for indentation
- "func-names": ["error", "never"], // Allow anonymous functions
- "no-param-reassign": ["error", { "props": false }], // Allow parameter reassignment for object properties
- "quotes": "off", // Disable quotes enforcement
- "object-curly-spacing": ["off"], // Disable spacing inside curly braces
- "block-spacing": ["off"], // Disable spacing enforcement inside blocks
- "semi": ["off"], // Allow missing semicolons
- "no-plusplus": ["off"], // Allow ++ and -- operators
- "prefer-arrow-callback": ["off"], // Allow traditional function expressions
- "vars-on-top": ["off"], // Allow variable declarations anywhere
- "consistent-return": ["off"], // Allow inconsistent returns in functions
- "no-loop-func": ["off"], // Allow functions inside loops
- "object-shorthand": ["off"], // Allow verbose object property declarations
- "no-prototype-builtins": ["off"], // Allow direct use of Object.prototype methods
- "prefer-template": ["off"] // Allow string concatenation with `+`
- },
- "parserOptions": {
- "ecmaVersion": 6
- }
-}
diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml
new file mode 100644
index 0000000..1eee51c
--- /dev/null
+++ b/.github/workflows/deploy-pages.yml
@@ -0,0 +1,43 @@
+# Simple workflow for deploying static content to GitHub Pages
+name: Deploy static content to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches: ["master"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ # Single deploy job since we're just deploying
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Pages
+ uses: actions/configure-pages@v5
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ # Upload docs/dist directory
+ path: 'docs/dist'
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index c8229fc..e12a58e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,5 @@
node_modules
-bower_components
-yarn-error.log
-
-# IntelliJ project files
-.idea
-
+dist_tests
+yarn.lock
+package-lock.json
+pnpm-lock.yaml
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..bb8c76c
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+v22.11.0
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..ec70dac
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+
+{
+ "recommendations": [
+ "dbaeumer.vscode-eslint",
+ "esbenp.prettier-vscode",
+ "EditorConfig.EditorConfig"
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..e3d9194
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,29 @@
+{
+ "editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": "never"
+ },
+ "editor.defaultFormatter": null,
+ "[javascript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[json]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[css]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[html]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "editor.tabSize": 2,
+ "editor.insertSpaces": true,
+ "files.eol": "\n",
+ "files.trimTrailingWhitespace": true,
+ "files.insertFinalNewline": true,
+ "editor.rulers": [150],
+ "editor.wordWrapColumn": 150
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c264d10..d3a6db5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,9 +1,124 @@
-### Contributing
-- Give it a [star](https://github.com/VincentLoy/simplyCountdown.js/stargazers) !
-- [Report a bug](https://github.com/VincentLoy/simplyCountdown.js/issues)
-- Tweet about it :)
-
-#### Pull Requests
-- **Solve a problem**
-- For code enhancement, use [ESLint](https://eslint.org/) as a code quality tool.
-- Small is better than Big.
+# Contributing to SimplyCountdown.js
+
+π Thank you for considering contributing to SimplyCountdown.js! I appreciate your support and I'm excited to collaborate with you. Below are the guidelines to help you get started.
+
+## How to Contribute
+
+### β 0. Give a Star to the Repository
+
+This step is totally optional... but seriously, who doesn't love some stars? π
+It's like giving a virtual high-five to the project! π β π
+
+### π± 1. Fork the Repository
+
+Start by forking the repository to your GitHub account.
+
+### π₯ 2. Clone Your Fork
+
+Clone your forked repository to your local machine:
+
+```bash
+git clone git@github.com:your-username/simplyCountdown.js.git
+cd simplyCountdown.js
+```
+
+### π§ 3. Node.js Version
+
+Make sure you're using the correct Node.js version. You can check the required version in `.nvmrc`. If you use [nvm](https://github.com/nvm-sh/nvm), simply run:
+
+```bash
+nvm use
+```
+
+This will automatically switch to the correct Node.js version for the project.
+
+### π οΈ 4. Set Up the Development Environment
+
+Install the necessary dependencies:
+We recommend using [bun](https://bun.sh/) as it offers superior performance and seamless dependency management.
+
+```bash
+bun install
+```
+
+**NOTE:** _For now, `package.json` is running bun commands only, maybe we will have to update this to be compatible with any package management system in the future_
+
+### πΏ 5. Create a Branch
+
+Create a new branch for your feature or bugfix:
+
+```bash
+git checkout -b feature/your-feature-name
+```
+
+### π» 6. Make Your Changes
+
+Make your changes to the codebase. Ensure your code follows the project's code style and formatting guidelines.
+While developping, you should run this command:
+
+```bash
+bun run dev
+```
+
+**NOTE:** _This will run a dev server with Vite, update the sources from `src/core` and tests your new features in `docs/src` files like `docs/src/index.html` and `docs/src/assets/js/main.js`. Each changes inside those files will refresh the dev page_
+
+### β
7. Test Your Changes
+
+Build, then, run the tests to make sure your changes don't break anything:
+
+```bash
+bun run build
+```
+
+then:
+
+```bash
+bun run dist:test:serve
+```
+
+**NOTE:** _This will generate various HTML files inside a `dist_test` directory and run a temporary node.js server where you can check different implementations and use-cases of the distribution files. Every HTML pages should run a working countdown._
+
+### πΎ 8. Commit Your Changes
+
+Commit your changes with a clear and concise commit message:
+
+```bash
+git add .
+git commit -m "Add feature: your feature description"
+```
+
+### π 9. Push to Your Fork
+
+Push your changes to your forked repository:
+
+```bash
+git push origin feature/your-feature-name
+```
+
+### π 10. Open a Pull Request
+
+Open a pull request from your forked repository to the main repository. Provide a detailed description of your changes and any relevant information.
+
+## Pull Request Process
+
+- Provide a detailed description of your changes in the pull request.
+- Link any relevant issues in the pull request description.
+- Wait for a maintainer to review your pull request.
+
+## Creating Issues
+
+If you find a bug or have a feature request, please create an issue in the repository. Provide as much detail as possible, including steps to reproduce the issue or a clear description of the feature.
+
+## Code Review Process
+
+All pull requests will be reviewed by a maintainer. The review process includes:
+
+- Checking for code quality and adherence to the style guide.
+- Ensuring tests are passing.
+- Providing feedback and requesting changes if necessary.
+
+## Documentation
+
+For more information about the project, please refer to the [README.md](README.md) and the [documentation website](https://vincentloy.github.io/simplyCountdown.js/).
+
+Thank you for contributing! π
diff --git a/LICENSE b/LICENSE
index 80536d6..f4350ce 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015 Vincent Loy
+Copyright (c) 2015-present Vincent Loy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+THE SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 6e01b55..0c0ae19 100644
--- a/README.md
+++ b/README.md
@@ -1,222 +1,355 @@
-# simplyCountdown.js
+![SimplyCountdown.js](docs/src/assets/images/simplyCountdown_banner.webp)
-## Why another countdown ?
+# SimplyCountdown.js
-I developed this little library in a boring day. I regularly use this kind of Javascript's libraries to display countdowns on websites and this one exactly meets the needs that I have. It is perfect to make 'under construction' pages, etc.
+A simple yet powerful countdown plugin, with no dependencies. Create beautiful countdowns with ease!
-This is a very (very) basic Javascript CountDown.
+## Features
-## Getting Started
+- Zero dependencies
+- TypeScript support
+- Multiple module formats (ES, UMD, CommonJS)
+- Multiple themes included
+- Lightweight and performant
+- Count up or down functionality
+- UTC support
+- Highly customizable
+- Control API (stop, resume, update)
+- Comprehensive event callbacks
-install via npm or bower
+## Installation
+```bash
+npm install simplycountdown
+# or
+yarn add simplycountdown
+# or
+bun install simplycountdown
```
-$ yarn add simplycountdown.js
-// or
+## Basic Usage
-$ npm install simplycountdown.js
+### ES Module
+
+```javascript
+import simplyCountdown from "simplycountdown.js";
+
+simplyCountdown("#mycountdown", {
+ year: 2025,
+ month: 12,
+ day: 25,
+});
+```
+
+## Accessing Source Files
+
+If you want to import and compile the TypeScript source files directly, you can include the source files in your project:
+
+```typescript
+import simplyCountdown from "simplycountdown.js/src/core/simplyCountdown";
+```
+
+### CommonJS
+
+```javascript
+const simplyCountdown = require("simplycountdown");
+
+simplyCountdown("#mycountdown", {
+ year: 2025,
+ month: 12,
+ day: 25,
+});
```
-### Insert simplyCountdown to your HTML
+### Browser (UMD)
```html
-
-
+
+
```
+
+## Configuration Options
+
```javascript
- // This is an example with default parameters
-
- simplyCountdown('[CSS-SELECTOR]', {
- year: 2015, // Target year (required)
- month: 6, // Target month [1-12] (required)
- day: 28, // Target day [1-31] (required)
- hours: 0, // Target hour [0-23], default: 0
- minutes: 0, // Target minute [0-59], default: 0
- seconds: 0, // Target second [0-59], default: 0
- words: { // Custom labels, with lambda for plurals
- days: { root: 'day', lambda: (root, n) => n > 1 ? root + 's' : root },
- hours: { root: 'hour', lambda: (root, n) => n > 1 ? root + 's' : root },
- minutes: { root: 'minute', lambda: (root, n) => n > 1 ? root + 's' : root },
- seconds: { root: 'second', lambda: (root, n) => n > 1 ? root + 's' : root }
+simplyCountdown("#mycountdown", {
+ // Target date (Required)
+ year: 2025, // Target year [YYYY]
+ month: 12, // Target month [1-12]
+ day: 25, // Target day [1-31]
+ hours: 0, // Target hours [0-23]
+ minutes: 0, // Target minutes [0-59]
+ seconds: 0, // Target seconds [0-59]
+
+ // Words customization
+ words: {
+ days: {
+ // Function to handle pluralization
+ lambda: (root, count) => (count > 1 ? root + "s" : root),
+ root: "day", // Base word for days
},
- plural: true, // Use plurals for labels
- inline: false, // Inline format: e.g., "24 days, 4 hours, 2 minutes"
- inlineSeparator: ', ', // Separator for inline format, default: ", "
- inlineClass: 'simply-countdown-inline', // CSS class for inline countdown
- enableUtc: false, // Use UTC time if true
- onEnd: function () {}, // Callback when countdown ends
- refresh: 1000, // Refresh interval in ms, default: 1000
- sectionClass: 'simply-section', // CSS class for each countdown section
- amountClass: 'simply-amount', // CSS class for numeric values
- wordClass: 'simply-word', // CSS class for unit labels
- zeroPad: false, // Pad numbers with leading zero
- removeZeroUnits: false, // Remove units with zero value
- countUp: false // Count up after reaching zero
- });
+ hours: {
+ lambda: (root, count) => (count > 1 ? root + "s" : root),
+ root: "hour",
+ },
+ minutes: {
+ lambda: (root, count) => (count > 1 ? root + "s" : root),
+ root: "minute",
+ },
+ seconds: {
+ lambda: (root, count) => (count > 1 ? root + "s" : root),
+ root: "second",
+ },
+ },
+
+ // Display options
+ plural: true, // Enable/disable pluralization
+ inline: false, // Display inline (true) or in blocks (false)
+ inlineSeparator: ", ", // Separator for inline display
+ enableUtc: false, // Use UTC time instead of local time
+
+ // Styling classes
+ inlineClass: "simply-countdown-inline", // Class for inline display
+ sectionClass: "simply-section", // Class for each time unit section
+ amountClass: "simply-amount", // Class for number display
+ wordClass: "simply-word", // Class for word display
+
+ // Formatting options
+ zeroPad: false, // Add leading zeros to numbers (e.g., 05 instead of 5)
+ countUp: false, // Count up from target date instead of down to it
+ removeZeroUnits: false, // Hide time units when they reach zero
+ refresh: 1000, // Update interval in milliseconds (1 second = 1000)
+
+ // Event handlers
+ onEnd: () => {
+ // Callback function when countdown ends
+ console.log("Countdown finished!");
+ },
+ onStop: () => {}, // Callback when countdown is stopped
+ onResume: () => {}, // Callback when countdown is resumed
+ onUpdate: (params) => {}, // Callback when countdown is updated
+});
+```
+
+## HTML Structure
+
+The plugin generates the following HTML structure:
- // Also, you can init with already existing Javascript Object.
- let myElement = document.querySelector('.my-countdown');
- simplyCountdown(myElement, { /* options */ });
+### Block Display (default)
- let multipleElements = document.querySelectorAll('.my-countdown');
- simplyCountdown(multipleElements, { /* options */ });
+```html
+
```
-### You can use it with jQuery too (not required)
+### Inline Display
+
+```html
+24 days, 3 hours, 45 minutes, 12 seconds
+```
+
+## Themes
+
+The library comes with several built-in themes:
+
+- `default.css` - Classic theme with clean, modern design
+- `dark.css` - Dark mode theme
+- `circle.css` - Circular display with modern aesthetics
+- `cyber.css` - Cyberpunk-inspired design
+- `losange.css` - Diamond-shaped display
+
+To use a theme, include its CSS file:
+
+```html
+
+```
+
+## Examples
+
+### New Year Countdown with UTC
```javascript
-// jQuery Example
-$('[CSS-SELECTOR]').simplyCountdown({
- year: 2019, // required
- month: 6, // required
- day: 28, // required
- ...
+simplyCountdown("#newyear", {
+ year: 2025,
+ month: 1,
+ day: 1,
+ enableUtc: true,
+ zeroPad: true,
+ onEnd: () => {
+ alert("Happy New Year!");
+ },
});
```
-## Parameters
-| Parameter | Type | Description | Default |
-|--------------------|-----------------|---------------------------------------------------------------------------------------------|-----------------------------|
-| `year` | Number (required) | The target year for the countdown. | - |
-| `month` | Number (required) | The target month [1-12] for the countdown. | - |
-| `day` | Number (required) | The target day [1-31] for the countdown. | - |
-| `hours` | Number | The target hour [0-23]. | 0 |
-| `minutes` | Number | The target minute [0-59]. | 0 |
-| `seconds` | Number | The target second [0-59]. | 0 |
-| `words` | Object | Custom labels for the units (days, hours, minutes, seconds) with optional lambda for pluralization. | `{ days: { root: 'day', lambda: (root, n) => n > 1 ? root + 's' : root }, ... }` |
-| `plural` | Boolean | Whether to use plural forms for the unit labels. | `true` |
-| `inline` | Boolean | Set to `true` for a simple inline countdown (e.g., "24 days, 4 hours, 2 minutes"). | `false` |
-| `inlineSeparator` | String | Separator used in the inline countdown format. | `, ` |
-| `inlineClass` | String | CSS class applied to the inline countdown container. | `"simply-countdown-inline"` |
-| `enableUtc` | Boolean | Set to `true` to use UTC time for the countdown calculations. | `false` |
-| `onEnd` | Function | Callback function executed when the countdown ends. | `() => {}` |
-| `refresh` | Number | The countdown refresh interval in milliseconds. | `1000` |
-| `sectionClass` | String | CSS class applied to each countdown section (days, hours, minutes, seconds). | `"simply-section"` |
-| `amountClass` | String | CSS class applied to the numeric value of each countdown section. | `"simply-amount"` |
-| `wordClass` | String | CSS class applied to the unit label of each countdown section. | `"simply-word"` |
-| `zeroPad` | Boolean | Whether to pad the numeric values with leading zeros (e.g., "05"). | `false` |
-| `removeZeroUnits` | Boolean | Remove units with zero value (e.g., remove "0 days" if days are zero). | `false` |
-| `countUp` | Boolean | Count up after reaching zero if set to `true`. | `false` |
-
-## Easy to customize
-
-You can easly customize the countdown using the css theme starter file or create your own like so :
-
-/!\ The following theme template works with default class in parameters.
-
- ```css
- /*
- * Project : simply-countdown
- * File : simplyCountdown.theme.custom
- * Author : Your Name
- */
-
- .simply-countdown {
- /* The countdown */
- }
- .simply-countdown > .simply-section {
- /* coutndown blocks */
- }
-
- .simply-countdown > .simply-section > div {
- /* countdown block inner div */
- }
-
- .simply-countdown > .simply-section .simply-amount,
- .simply-countdown > .simply-section .simply-word {
- /* amounts and words */
- }
-
- .simply-countdown > .simply-section .simply-amount {
- /* amounts */
- }
-
- .simply-countdown > .simply-section .simply-word {
- /* words */
- }
-```
+### Event Timer (Count Up) with Zero Padding
-### Contributing
-- Give it a [star](https://github.com/VincentLoy/simplyCountdown.js/stargazers) !
-- [Report a bug](https://github.com/VincentLoy/simplyCountdown.js/issues)
-- Tweet about it :)
-
-#### Pull Requests
-- **Solve a problem**
-- For code enhancement, use [ESLint](https://eslint.org/) as a code quality tool.
-- Small is better than Big.
-
-### Changelog
-
-#### 2.0.1
-Update all 2015 npm dependencies and rebuild the plugin with new deps.
-
-#### 2.0.0
-This version may have breaking changes, if your website is working well with 1.7.0, you may want to stay on the previous version.
-- fix plurals in a generic way [#52](https://github.com/VincentLoy/simplyCountdown.js/pull/52)
- - Thumbs up to [mira01](https://github.com/mira01) that fixed [#51](https://github.com/VincentLoy/simplyCountdown.js/issues/51), [#23](https://github.com/VincentLoy/simplyCountdown.js/issues/23) & [#42](https://github.com/VincentLoy/simplyCountdown.js/issues/42) !
-- Added the `inlineSeparator` parameter. Previously, the inline mode only supported a comma-separated countdown. Now, you can customize the separator, using options like |, /, -, or any character that suits your needs.
-- Fix potential UTC-related issues (fingers crossed!).
-
-
-#### 1.7.0
-- Countdowns can be initialized directly with HTML elements with variables like
- - document.getElementById
- - document.querySelector
- - document.querySelectorAll
- - etc...
-
-##### 1.6.0
-- Compatibility with languages like german for plurals ([PR #15](https://github.com/VincentLoy/simplyCountdown.js/pull/15)), thanks to [q30t](https://github.com/q30t)
-
-##### 1.5.0
-- Resolve #10 - Add countup support
-- Upgrade yarn dev dependencies
-- Some minor code reformatting
-
-##### 1.4.0
-- Remove bower support
-- migrate from LESS to SASS (scss) / for demo and themes
-- migrate lib from ES5 to a really basic ES6
- - Remove JSLint support
- - Add ESLint support based on customized [airbnb rules](https://www.npmjs.com/package/eslint-config-airbnb-base)
-
-##### 1.3.2
-- add zeroPad parameter
```javascript
-zeroPad: false //default
+simplyCountdown("#timer", {
+ year: 2024,
+ month: 1,
+ day: 1,
+ countUp: true,
+ zeroPad: true,
+ removeZeroUnits: true,
+});
```
-- fixed Flash of Unstyled Content
-##### 1.3.1
-- clean some code
-- add refresh parameter
+### Custom Words with Inline Display
+
```javascript
-refresh: 1000 //default
+simplyCountdown("#inline", {
+ year: 2025,
+ month: 12,
+ day: 25,
+ inline: true,
+ inlineSeparator: " | ",
+ words: {
+ days: {
+ lambda: (root, count) => (count === 1 ? "day" : "days"),
+ root: "day",
+ },
+ hours: {
+ lambda: (root, count) => (count === 1 ? "hour" : "hours"),
+ root: "hour",
+ },
+ minutes: {
+ lambda: (root, count) => (count === 1 ? "minute" : "minutes"),
+ root: "minute",
+ },
+ seconds: {
+ lambda: (root, count) => (count === 1 ? "second" : "seconds"),
+ root: "second",
+ },
+ },
+});
```
-##### 1.3.0
-- Add onEnd callback
+## Selector Support
+
+The plugin accepts various selector types:
+
```javascript
-onEnd: function () {
- // some code
-}
+// CSS selector string
+simplyCountdown("#countdown", parameters);
+
+// Single DOM element
+simplyCountdown(document.getElementById("countdown"), parameters);
+
+// Multiple elements
+simplyCountdown(document.querySelectorAll(".countdown"), parameters);
```
-##### 1.2.0
-- Resolve #4 - Add UTC support adding enableUtc parameter
+## Control Features
+
+The countdown instance returns a controller object that allows you to manipulate the countdown:
+
```javascript
-enableUtc: true //true is default
+// Initialize countdown
+const countdown = simplyCountdown("#mycountdown", parameters);
+
+// Stop the countdown
+countdown.pause();
+
+// Resume countdown
+countdown.resume();
+
+// Update countdown parameters
+countdown.update({
+ year: 2026,
+ month: 1,
+ day: 1,
+});
+
+// Chain control methods
+countdown.pause();
+countdown.resume();
+countdown.update({ year: 2026, hours: 12, minutes: 51 });
```
-##### 1.1.1
-- Resolve #3 - Remove ID Only compatibility
-##### 1.1.0
-- Add hours, minutes, seconds in available settings to set the target Date
+## Development Commands
+
+### Main Commands
+
+- `npm run dev`: Start development server for the documentation site & Core library (port 3000)
+- `npm run build`: Build everything (library, themes, and documentation)
+- `npm run preview`: Preview the documentation site
+
+### Build Commands
+
+- `npm run build:lib`: Build the library (ES and UMD formats)
+- `npm run build:themes`: Build CSS themes
+- `npm run build:docs`: Build the documentation site
+
+### Test Commands
+
+- `npm run test`: Run tests
+- `npm run test:watch`: Run tests in watch mode
+- `npm run dist:test`: Generate test files for different module formats
+- `npm run dist:test:serve`: Generate and serve test files locally
+
+## Module Format Testing
+
+Test different usecases using:
+
+```bash
+npm run dist:test:serve
+```
+
+Available test files:
+
+1. ES Module (`index.es.html`)
+2. UMD Global (`index.umd-global.html`)
+3. UMD AMD/RequireJS (`index.umd-amd.html`)
+4. UMD CommonJS (`index.umd-commonjs.html`)
+5. UMD Dynamic Loading (`index.umd-dynamic.html`)
+
+## Browser Support
+
+The library supports all modern browsers (Chrome, Firefox, Safari, Edge) and IE11+.
+
+## Key Changes from v1.x/v2.x to v3.x π
+
+### π Removal of jQuery Support
+
+jQuery is no longer supported in simplyCountdown to reduce dependencies and improve performance. This change ensures a more lightweight and modern library.
+
+**Note:** You can still use simplyCountdown in your jQuery projects by using the vanilla JavaScript syntax instead of the jQuery-specific one:
+
+- Old jQuery-compatible syntax: `$('.some-countdowns').simplyCountdown(options)`
+- New vanilla JavaScript syntax: `simplyCountdown('.some-countdowns', options)`
+
+### β‘ Transition from Gulp to Vite
+
+The build process has been migrated from Gulp to Vite. Vite offers faster builds, better development server capabilities, and improved support for modern JavaScript features.
+
+### π Migration from ES6 JavaScript to TypeScript
+
+The source code has been rewritten in TypeScript to enhance code quality, provide better type checking, and improve developer experience.
+
+### π New Documentation Website
+
+A new documentation website has been launched to provide comprehensive guides, examples, and API references. This site aims to make it easier for developers to integrate and use simplyCountdown.
+
+### π¦ Updated Distribution Files
+
+The distribution files have been reorganized to include multiple module formats (ES, UMD, CommonJS) and themes. This change ensures compatibility with various development environments and build tools.
+
+### πββοΈ Transition from npm to Bun
+
+The package manager has been switched from npm to Bun for faster installs and improved performance. Bun offers a more efficient and modern package management experience.
-##### 1.0.1
-- Fix console error when not using jQuery
+## License
-##### 1.0.0
-- initial release
+MIT Β© 2015-present - Vincent Loy-Serre
diff --git a/bun.lockb b/bun.lockb
new file mode 100755
index 0000000..64747cc
Binary files /dev/null and b/bun.lockb differ
diff --git a/css/demo-only/prism.css b/css/demo-only/prism.css
deleted file mode 100644
index 4412600..0000000
--- a/css/demo-only/prism.css
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * prism.js default theme for JavaScript, CSS and HTML
- * Based on dabblet (http://dabblet.com)
- * @author Lea Verou
- */
-
-code[class*="language-"],
-pre[class*="language-"] {
- color: black;
- text-shadow: 0 1px white;
- font-family: Consolas, Monaco, 'Andale Mono', monospace;
- direction: ltr;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- line-height: 1.5;
-
- -moz-tab-size: 4;
- -o-tab-size: 4;
- tab-size: 4;
-
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-}
-
-pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
-code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
- text-shadow: none;
- background: #b3d4fc;
-}
-
-pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
-code[class*="language-"]::selection, code[class*="language-"] ::selection {
- text-shadow: none;
- background: #b3d4fc;
-}
-
-@media print {
- code[class*="language-"],
- pre[class*="language-"] {
- text-shadow: none;
- }
-}
-
-/* Code blocks */
-pre[class*="language-"] {
- padding: 1em;
- margin: .5em 0;
- overflow: auto;
-}
-
-:not(pre) > code[class*="language-"],
-pre[class*="language-"] {
- background: #f5f2f0;
-}
-
-/* Inline code */
-:not(pre) > code[class*="language-"] {
- padding: .1em;
- border-radius: .3em;
-}
-
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: slategray;
-}
-
-.token.punctuation {
- color: #999;
-}
-
-.namespace {
- opacity: .7;
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol,
-.token.deleted {
- color: #905;
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted {
- color: #690;
-}
-
-.token.operator,
-.token.entity,
-.token.url,
-.language-css .token.string,
-.style .token.string {
- color: #a67f59;
- background: hsla(0, 0%, 100%, .5);
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
- color: #07a;
-}
-
-.token.function {
- color: #DD4A68;
-}
-
-.token.regex,
-.token.important,
-.token.variable {
- color: #e90;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
diff --git a/css/demo.css b/css/demo.css
deleted file mode 100644
index f2518c3..0000000
--- a/css/demo.css
+++ /dev/null
@@ -1 +0,0 @@
-a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}*{box-sizing:border-box}body,html{font-family:"Wix Madefor Text",serif;font-optical-sizing:auto;font-style:normal;overflow-x:hidden;font-size:16px}p{font-size:1.2rem;line-height:1.6;font-weight:400;margin:20px 0 45px}h1,h2,h3{font-family:"Montserrat",sans-serif}header{display:flex;align-items:center;justify-content:center;background:#112d4e;border-bottom:5px solid #3f72af;padding:20px;height:450px}@media screen and (min-width:970px){header{height:650px}}header .header-content{text-align:center}header .header-content h1{font-style:italic;font-size:2rem;font-weight:600;color:#f9f7f7}@media screen and (min-width:970px){header .header-content h1{font-size:4rem}}header .header-content h2{font-size:1.33rem;color:#f9f7f7;margin:20px 0;font-weight:500}@media screen and (min-width:970px){header .header-content h2{font-size:1.75rem;margin:40px 0 60px 0}}header .header-content .repo-buttons{display:flex;align-items:center;justify-content:center}.button{color:#f9f7f7;border:2px solid #f9f7f7;border-radius:2px;text-decoration:none;padding:10px;transition:.1s ease-in-out all;display:block;margin:0 20px 20px 20px}.button span{display:none}@media screen and (min-width:970px){.button{margin-bottom:0}.button span{display:inline}}@media screen and (min-width:970px){.button>i{margin-right:10px}}.button:hover{background:#f9f7f7;color:#112d4e}.container{width:100%;padding:0 20px;margin:auto}@media screen and (min-width:970px){.container{width:960px}}.note{background:#3f72af;color:#fff;font-style:italic;border-radius:2px;padding:6.6666666667px 20px;border-radius:5px}.note p{margin-bottom:20px}main>section:not(:last-of-type){border-bottom:1px solid #112d4e;padding-bottom:20px}main h2{font-size:2rem;color:#3f72af;font-weight:700;margin:20px 0}@media screen and (min-width:970px){main h2{font-size:3rem;margin:40px 0}}main h3{font-size:20px;color:#3f72af;font-weight:700;margin:20px 0}@media screen and (min-width:970px){main h3{font-size:25px;margin:40px 0}}main h3 a{color:#6995ca;text-decoration:none}main h3 a:hover{text-decoration:underline}main a{font-weight:700;text-decoration:none;color:#6995ca;transition:.2s ease all}main a:hover{color:#112d4e;text-decoration:underline}.simply-countdown-inline{margin-top:20px;font-weight:700;font-size:1.3rem}.sc-inline-header{color:#f9f7f7;font-weight:100;font-size:1.4rem;font-style:italic}.alert{position:fixed;bottom:-60px;left:0;right:0;margin:auto;padding:20px;display:table;background:#112d4e;color:#fff;border-radius:5px;font-size:1.3rem;opacity:0;transition:.3s ease all}.alert.show-after-header-cd.active{opacity:1;bottom:60px}.alert.show-after-header-cd a{font-weight:700;color:#f9f7f7}footer{background:#112d4e;color:#fff;text-align:center;padding:20px;margin-top:40px;font-weight:600}footer a{color:#c7d8eb;text-decoration:none;font-weight:700}footer a:hover{text-decoration:underline}.table-wrapper{width:100%;overflow-x:auto}.table-wrapper table{width:100%;margin-bottom:1rem;color:#212529;border-collapse:collapse;min-width:600px}.table-wrapper table th,.table-wrapper table td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table-wrapper table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6;background-color:#f8f9fa;font-weight:700}.table-wrapper table tbody tr:nth-child(even){background-color:#f2f2f2}.table-wrapper table.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-wrapper table.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-wrapper table.table-bordered{border:1px solid #dee2e6}.table-wrapper table.table-bordered th,.table-wrapper table.table-bordered td{border:1px solid #dee2e6}.table-wrapper table.table-sm th,.table-wrapper table.table-sm td{padding:.3rem}.text-center{text-align:center}.text-right{text-align:right}.bold{font-weight:700}.ff-code{font-family:monospace;font-size:.9rem}.hide{display:none}
\ No newline at end of file
diff --git a/css/scss/demo.scss b/css/scss/demo.scss
deleted file mode 100644
index 84906f4..0000000
--- a/css/scss/demo.scss
+++ /dev/null
@@ -1,343 +0,0 @@
-/**
-* Project : simply-countdown
-* File : demo
-* Date : 27/06/2015
-* Author : Vincent Loy
-*/
-@use "sass:color";
-
-$color-main: #3F72AF;
-$color-main-darken: #112D4E;
-$color-main-lighten: #6995ca;
-$color-secondary: #F9F7F7;
-$color-secondary-lighten: #F9F7F7;
-$color-white: #fff;
-
-$ff-base: "Wix Madefor Text", serif;
-$ff-title: "Montserrat", sans-serif;
-
-$spacing: 20px;
-
-$tablet: "screen and (min-width: 970px)";
-
-a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}
-
-* {
- box-sizing: border-box;
-}
-
-body, html {
- font-family: $ff-base;
- font-optical-sizing: auto;
- font-style: normal;
- overflow-x: hidden;
- font-size: 16px;
-}
-
-p {
- font-size: 1.2rem;
- line-height: 1.6;
- font-weight: 400;
- margin: $spacing 0 45px;
-}
-
-h1, h2, h3 {
- font-family: $ff-title;
-}
-
-
-header {
- display: flex;
- align-items: center;
- justify-content: center;
- background: $color-main-darken;
- border-bottom: 5px solid $color-main;
- padding: $spacing;
- height: 450px;
-
- @media #{$tablet} {
- height: 650px;
- }
-
- .header-content {
- text-align: center;
-
- h1 {
- font-style: italic;
- font-size: 2rem;
- font-weight: 600;
- color: $color-secondary-lighten;
-
- @media #{$tablet} {
- font-size: 4rem;
- }
- }
-
- h2 {
- font-size: 1.33rem;
- color: $color-secondary-lighten;
- margin: $spacing 0;
- font-weight: 500;
-
- @media #{$tablet} {
- font-size: 1.75rem;
- margin: calc($spacing * 2) 0 calc($spacing * 3) 0;
- }
- }
-
- .repo-buttons {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
-}
-
-.button {
- color: $color-secondary-lighten;
- border:2px solid $color-secondary-lighten;
- border-radius: 2px;
- text-decoration: none;
- padding: calc($spacing / 2);
- transition: 0.1s ease-in-out all;
- display: block;
- margin: 0 $spacing $spacing $spacing;
-
- span {
- display: none;
- }
-
- @media #{$tablet} {
- margin-bottom: 0;
-
- span {
- display: inline;
- }
- }
-
- > i {
- @media #{$tablet} {
- margin-right: calc($spacing / 2);
- }
- }
-
- &:hover {
- background: $color-secondary-lighten;
- color: $color-main-darken;
- }
-}
-
-.container {
- width: 100%;
- padding: 0 $spacing;
- margin: auto;
-
- @media #{$tablet} {
- width: 960px;
- }
-}
-
-.note {
- background: $color-main;
- color: $color-white;
- font-style: italic;
- border-radius: 2px;
- padding: calc($spacing / 3) $spacing;
- border-radius: 5px;
-
- p {
- margin-bottom: $spacing;
- }
-}
-
-main {
- > section:not(:last-of-type) {
- border-bottom: 1px solid $color-main-darken;
- padding-bottom: $spacing;
- }
-
- h2 {
- font-size: 2rem;
- color: $color-main;
- font-weight: 700;
- margin: $spacing 0;
-
- @media #{$tablet} {
- font-size: 3rem;
- margin: $spacing * 2 0;
- }
- }
-
- h3 {
- font-size: 20px;
- color: $color-main;
- font-weight: 700;
- margin: $spacing 0;
-
- @media #{$tablet} {
- font-size: 25px;
- margin: calc($spacing * 2) 0;
- }
-
- a {
- color: $color-main-lighten;
- text-decoration: none;
- &:hover {
- text-decoration: underline;
- }
- }
- }
-
- a {
- font-weight: bold;
- text-decoration: none;
- color: $color-main-lighten;
- transition: 0.2s ease all;
-
- &:hover {
- color: $color-main-darken;
- text-decoration: underline;
- }
- }
-}
-
-.simply-countdown-inline {
- margin-top: $spacing;
- font-weight: bold;
- font-size: 1.3rem;
-}
-
-.sc-inline-header {
- color: $color-secondary-lighten;
- font-weight: 100;
- font-size: 1.4rem;
- font-style: italic;
-}
-
-.alert {
- position: fixed;
- bottom: -60px;
- left: 0;
- right: 0;
- margin: auto;
- padding: 20px;
- display: table;
- background: $color-main-darken;
- color: white;
- border-radius: 5px;
- font-size: 1.3rem;
- opacity: 0;
- transition: 0.3s ease all;
-
- &.show-after-header-cd {
-
- &.active {
- opacity: 1;
- bottom: 60px;
- }
-
- a {
- font-weight: bold;
- color: $color-secondary-lighten;
- }
- }
-}
-
-footer {
- background: $color-main-darken;
- color: $color-white;
- text-align: center;
- padding: $spacing;
- margin-top: $spacing * 2;
- font-weight: 600;
-
- a {
- color: color.adjust($color-main-lighten, $lightness: 25%);
- text-decoration: none;
- font-weight: bold;
-
- &:hover{
- text-decoration: underline;
- }
- }
-}
-
-.table-wrapper {
- width: 100%;
- overflow-x: auto;
-
- table {
- width: 100%;
- margin-bottom: 1rem;
- color: #212529;
- border-collapse: collapse;
- min-width: 600px; // Ensures the table maintains its width with a scrollbar on smaller screens
-
- th,
- td {
- padding: 0.75rem;
- vertical-align: top;
- border-top: 1px solid #dee2e6;
- }
-
- thead {
- th {
- vertical-align: bottom;
- border-bottom: 2px solid #dee2e6;
- background-color: #f8f9fa;
- font-weight: bold;
- }
- }
-
- tbody {
- tr {
- &:nth-child(even) {
- background-color: #f2f2f2;
- }
- }
- }
-
- &.table-striped tbody tr:nth-of-type(odd) {
- background-color: rgba(0, 0, 0, 0.05);
- }
-
- &.table-hover tbody tr:hover {
- background-color: rgba(0, 0, 0, 0.075);
- }
-
- &.table-bordered {
- border: 1px solid #dee2e6;
-
- th,
- td {
- border: 1px solid #dee2e6;
- }
- }
-
- &.table-sm th,
- &.table-sm td {
- padding: 0.3rem;
- }
- }
-}
-
-.text-center {
- text-align: center;
-}
-
-.text-right {
- text-align: right;
-}
-
-.bold {
- font-weight: bold;
-}
-
-.ff-code {
- font-family: monospace;
- font-size: 0.9rem;
-}
-
-.hide {
- display: none;
-}
\ No newline at end of file
diff --git a/css/scss/simplyCountdown.theme.default.scss b/css/scss/simplyCountdown.theme.default.scss
deleted file mode 100644
index 00b1dc3..0000000
--- a/css/scss/simplyCountdown.theme.default.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
-* Project : simply-countdown
-* File : simplyCountdown.theme.default
-* Date : 27/06/2015
-* Author : Vincent Loy
-*/
-
-.simply-countdown {
- overflow: hidden;
- display: table;
- font-family: 'Arial', sans-serif;
-
- & > .simply-section {
- width: 50px;
- height: 50px;
- padding: 50px;
- display: flex;
- align-items: center;
- justify-content: center;
- float: left;
- margin: 15px;
- background: #fff;
- box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
-
- .simply-amount,
- .simply-word {
- display: block;
- text-align: center;
- }
- }
-}
diff --git a/css/scss/simplyCountdown.theme.losange.scss b/css/scss/simplyCountdown.theme.losange.scss
deleted file mode 100644
index 051f28c..0000000
--- a/css/scss/simplyCountdown.theme.losange.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
-* Project : simply-countdown
-* File : simplyCountdown.theme.losange
-* Date : 27/06/2015
-* Author : Vincent Loy
-*/
-
-.simply-countdown-losange {
- overflow: visible;
- display: table;
- font-family: 'Arial', sans-serif;
-
- > .simply-section {
- width: 100px;
- height: 100px;
- display: flex;
- justify-content: center;
- align-items: center;
- transform: rotate(-45deg);
- float: left;
- margin: 30px;
- background: #024772;
-
- > div {
- transform: rotate(45deg);
- .simply-amount,
- .simply-word {
- display: block;
- color: #fff;
- font-weight: bold;
- text-align: center;
- }
- }
- }
-}
diff --git a/css/simplyCountdown.theme.custom.css b/css/simplyCountdown.theme.custom.css
deleted file mode 100644
index 38452a9..0000000
--- a/css/simplyCountdown.theme.custom.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
-* Project : simply-countdown
-* File : simplyCountdown.theme.custom
-* Author : Your Name
-*/
-
-.simply-countdown {
- /* The countdown */
-}
-.simply-countdown > .simply-section {
- /* coutndown blocks */
-}
-
-.simply-countdown > .simply-section > div {
- /* countdown block inner div */
-}
-
-.simply-countdown > .simply-section .simply-amount,
-.simply-countdown > .simply-section .simply-word {
- /* amounts and words */
-}
-
-.simply-countdown > .simply-section .simply-amount {
- /* amounts */
-}
-
-.simply-countdown > .simply-section .simply-word {
- /* words */
-}
diff --git a/css/simplyCountdown.theme.default.css b/css/simplyCountdown.theme.default.css
deleted file mode 100644
index 1efede8..0000000
--- a/css/simplyCountdown.theme.default.css
+++ /dev/null
@@ -1 +0,0 @@
-.simply-countdown{overflow:hidden;display:table;font-family:"Arial",sans-serif}.simply-countdown>.simply-section{width:50px;height:50px;padding:50px;display:flex;align-items:center;justify-content:center;float:left;margin:15px;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.simply-countdown>.simply-section .simply-amount,.simply-countdown>.simply-section .simply-word{display:block;text-align:center}
\ No newline at end of file
diff --git a/css/simplyCountdown.theme.losange.css b/css/simplyCountdown.theme.losange.css
deleted file mode 100644
index ac5262a..0000000
--- a/css/simplyCountdown.theme.losange.css
+++ /dev/null
@@ -1 +0,0 @@
-.simply-countdown-losange{overflow:visible;display:table;font-family:"Arial",sans-serif}.simply-countdown-losange>.simply-section{width:100px;height:100px;display:flex;justify-content:center;align-items:center;transform:rotate(-45deg);float:left;margin:30px;background:#024772}.simply-countdown-losange>.simply-section>div{transform:rotate(45deg)}.simply-countdown-losange>.simply-section>div .simply-amount,.simply-countdown-losange>.simply-section>div .simply-word{display:block;color:#fff;font-weight:700;text-align:center}
\ No newline at end of file
diff --git a/dev/simplyCountdown.js b/dev/simplyCountdown.js
deleted file mode 100644
index 8a775b7..0000000
--- a/dev/simplyCountdown.js
+++ /dev/null
@@ -1,325 +0,0 @@
-/* global Symbol */
-
-/*!
-* Project : simply-countdown
-* Date : 06/12/2024
-* License : MIT
-* Version : 2.0.1
-* Author : Vincent Loy
-* Contributors :
-* - Justin Beasley
-* - Nathan Smith
-*/
-(function (exports) {
- 'use strict';
-
- /**
- * Function that merge user parameters with defaults one.
- * @param output
- * @returns {*|{}}
- */
- let extend = function (output) {
- let obj;
- let out = output || {};
-
- for (let i = 1; i < arguments.length; i += 1) {
- obj = arguments[i];
- const keys = Object.keys(obj);
-
- if (keys.length) {
- for (let i2 = 0; i2 < keys.length; i2 += 1) {
- let key = keys[i2];
-
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- if (typeof obj[key] === 'object') {
- extend(out[key], obj[key]);
- } else {
- out[key] = obj[key];
- }
- }
- }
- }
- }
-
- return out;
- };
-
- let isIterableElement = (val) => {
- return val !== null && Symbol.iterator in Object(val);
- };
-
- /**
- * Function that create a countdown section
- * @param countdown
- * @param parameters
- * @param typeClass
- * @returns {{full: (*|Element), amount: (*|Element), word: (*|Element)}}
- */
- let createCountdownElt = (countdown, parameters, typeClass) => {
- let sectionTag = document.createElement('div');
- let amountTag = document.createElement('span');
- let wordTag = document.createElement('span');
- let innerSectionTag = document.createElement('div');
-
- innerSectionTag.appendChild(amountTag);
- innerSectionTag.appendChild(wordTag);
- sectionTag.appendChild(innerSectionTag);
-
- sectionTag.classList.add(parameters.sectionClass);
- sectionTag.classList.add(typeClass);
- amountTag.classList.add(parameters.amountClass);
- wordTag.classList.add(parameters.wordClass);
-
- countdown.appendChild(sectionTag);
-
- return {
- full: sectionTag,
- amount: amountTag,
- word: wordTag
- };
- };
-
- /**
- * Function that create full countdown DOM elements calling createCountdownElt
- * @param parameters
- * @param countdown
- * @returns {{days:(*|Element), hours:(*|Element), minutes:(*|Element), seconds:(*|Element)}}
- */
- let createElements = (parameters, countdown) => {
- let spanTag;
-
- if (!parameters.inline) {
- return {
- days: createCountdownElt(countdown, parameters, 'simply-days-section'),
- hours: createCountdownElt(countdown, parameters, 'simply-hours-section'),
- minutes: createCountdownElt(countdown, parameters, 'simply-minutes-section'),
- seconds: createCountdownElt(countdown, parameters, 'simply-seconds-section')
- };
- }
-
- spanTag = document.createElement('span');
- spanTag.classList.add(parameters.inlineClass);
- return spanTag;
- };
-
- /**
- * simplyCountdown, create and display the coundtown.
- * @param elt
- * @param args (parameters)
- */
- exports.simplyCountdown = (elt, args) => {
- const eltProto = Object.getPrototypeOf(elt);
- let parameters = extend({
- year: 2015,
- month: 6,
- day: 28,
- hours: 0,
- minutes: 0,
- seconds: 0,
- words: {
- days: {lambda: (root, n) => {return n > 1 ? root + "s" : root }, root: 'day'},
- hours: {lambda: (root, n) => {return n > 1 ? root + "s" : root }, root: 'hour'},
- minutes: {lambda: (root, n) => {return n > 1 ? root + "s" : root }, root: 'minute'},
- seconds: {lambda: (root, n) => {return n > 1 ? root + "s" : root }, root: 'second'}
- },
- plural: true,
- inline: false,
- inlineSeparator: ', ',
- enableUtc: false,
- onEnd: () => {
- },
- refresh: 1000,
- inlineClass: 'simply-countdown-inline',
- sectionClass: 'simply-section',
- amountClass: 'simply-amount',
- wordClass: 'simply-word',
- zeroPad: false,
- removeZeroUnits: false,
- countUp: false
- }, args);
- let interval;
- let targetDate;
- let now;
- let secondsLeft;
- let days;
- let hours;
- let minutes;
- let seconds;
- let cd;
-
- // console.log(typeof elt);
- //
- if (eltProto === String.prototype) {
- cd = document.querySelectorAll(elt);
- } else {
- cd = elt;
- }
-
- if (parameters.enableUtc) {
- // Use UTC for target date
- targetDate = new Date(Date.UTC(
- parameters.year,
- parameters.month - 1,
- parameters.day,
- parameters.hours,
- parameters.minutes,
- parameters.seconds
- ));
- } else {
- // Use local time for target date
- targetDate = new Date(
- parameters.year,
- parameters.month - 1,
- parameters.day,
- parameters.hours,
- parameters.minutes,
- parameters.seconds
- );
- }
-
- let runCountdown = (theCountdown) => {
- let countdown = theCountdown;
- let fullCountDown = createElements(parameters, countdown);
- let refresh;
-
- refresh = function () {
- let dayWord;
- let hourWord;
- let minuteWord;
- let secondWord;
-
- let updateDisplayDate = () => {
- days = parseInt(secondsLeft / 86400, 10);
- secondsLeft %= 86400;
-
- hours = parseInt(secondsLeft / 3600, 10);
- secondsLeft %= 3600;
-
- minutes = parseInt(secondsLeft / 60, 10);
- seconds = parseInt(secondsLeft % 60, 10);
- };
-
- if (parameters.enableUtc) {
- // Calculate "now" in UTC
- now = new Date();
- now = new Date(Date.UTC(
- now.getUTCFullYear(),
- now.getUTCMonth(),
- now.getUTCDate(),
- now.getUTCHours(),
- now.getUTCMinutes(),
- now.getUTCSeconds()
- ));
- } else {
- // Calculate "now" in local time
- now = new Date();
- }
-
- secondsLeft = Math.floor((targetDate - now.getTime()) / 1000);
-
- if (secondsLeft > 0) {
- updateDisplayDate();
- } else if (parameters.countUp) {
- secondsLeft = (now.getTime() - targetDate) / 1000;
- updateDisplayDate();
- } else {
- days = 0;
- hours = 0;
- minutes = 0;
- seconds = 0;
- window.clearInterval(interval);
- parameters.onEnd();
- }
-
- let getWord = (obj, n) => {
- return obj.hasOwnProperty('lambda')
- ? obj.lambda(obj.root, n)
- : obj.root
- };
- let words = parameters.words;
- dayWord = getWord(words.days, days);
- hourWord = getWord(words.hours, hours);
- minuteWord = getWord(words.minutes, minutes);
- secondWord = getWord(words.seconds, seconds);
-
- /* display an inline countdown into a span tag */
- if (parameters.inline) {
- let displayStr = '';
-
- if (!(parameters.removeZeroUnits && days === 0)) {
- displayStr += `${days} ${dayWord}${parameters.inlineSeparator}`;
- }
-
- if (!(parameters.removeZeroUnits && days === 0 && hours === 0)) {
- displayStr += `${hours} ${hourWord}${parameters.inlineSeparator}`;
- }
-
- if (!(parameters.removeZeroUnits && days === 0 && hours === 0 && minutes === 0)) {
- displayStr += `${minutes} ${minuteWord}${parameters.inlineSeparator}`;
- }
-
- // Seconds should always be displayed
- displayStr += `${seconds} ${secondWord}`;
-
- countdown.innerHTML = displayStr.replace(/, $/, ''); // Remove trailing comma if any
- } else {
- if (!(parameters.removeZeroUnits && days === 0)) {
- fullCountDown.days.amount.textContent = (parameters.zeroPad && days.toString().length < 2 ? '0' : '') + days;
- fullCountDown.days.word.textContent = dayWord;
- fullCountDown.days.full.style.display = '';
- } else {
- fullCountDown.days.full.style.display = 'none';
- }
-
- if (!(parameters.removeZeroUnits && days === 0 && hours === 0)) {
- fullCountDown.hours.amount.textContent = (parameters.zeroPad && hours.toString().length < 2 ? '0' : '') + hours;
- fullCountDown.hours.word.textContent = hourWord;
- fullCountDown.hours.full.style.display = '';
- } else {
- fullCountDown.hours.full.style.display = 'none';
- }
-
- if (!(parameters.removeZeroUnits && days === 0 && hours === 0 && minutes === 0)) {
- fullCountDown.minutes.amount.textContent = (parameters.zeroPad && minutes.toString().length < 2 ? '0' : '') + minutes;
- fullCountDown.minutes.word.textContent = minuteWord;
- fullCountDown.minutes.full.style.display = '';
- } else {
- fullCountDown.minutes.full.style.display = 'none';
- }
-
- // Seconds should always be displayed
- fullCountDown.seconds.amount.textContent = (parameters.zeroPad && seconds.toString().length < 2 ? '0' : '') + seconds;
- fullCountDown.seconds.word.textContent = secondWord;
- fullCountDown.seconds.full.style.display = '';
- }
- };
-
- // Refresh immediately to prevent a Flash of Unstyled Content
- refresh();
- interval = window.setInterval(refresh, parameters.refresh);
- };
-
- if (!isIterableElement(cd)) {
- runCountdown(cd);
- } else {
- Array.prototype.forEach.call(cd, (cdElt) => {
- runCountdown(cdElt);
- });
- }
- };
-}(window));
-
-/* global jQuery, simplyCountdown */
-if (window.jQuery) {
- (function ($, simplyCountdown) {
- 'use strict';
-
- function simplyCountdownify(el, options) {
- simplyCountdown(el, options);
- }
-
- $.fn.simplyCountdown = function (options) {
- return simplyCountdownify(this.selector, options);
- };
- }(jQuery, simplyCountdown));
-}
diff --git a/dist/simplyCountdown.js b/dist/simplyCountdown.js
new file mode 100644
index 0000000..0837e68
--- /dev/null
+++ b/dist/simplyCountdown.js
@@ -0,0 +1,190 @@
+const w = (n, e, o, t, l, d) => {
+ const u = document.createElement("div");
+ u.className = `${n} ${d.sectionClass}`;
+ const c = document.createElement("div"), a = document.createElement("span"), r = document.createElement("span");
+ return a.className = `${e} ${d.amountClass}`, r.className = `${o} ${d.wordClass}`, a.textContent = String(t), r.textContent = l, c.appendChild(a), c.appendChild(r), u.appendChild(c), u;
+}, b = (n, e, o) => {
+ const t = n.querySelector(".simply-amount"), l = n.querySelector(".simply-word");
+ t && (t.textContent = String(e)), l && (l.textContent = o);
+}, E = (n, e) => {
+ const o = "simply-amount", t = "simply-word", l = w("simply-section simply-days-section", o, t, 0, "day", e), d = w("simply-section simply-hours-section", o, t, 0, "hour", e), u = w("simply-section simply-minutes-section", o, t, 0, "minute", e), c = w("simply-section simply-seconds-section", o, t, 0, "second", e);
+ return n.appendChild(l), n.appendChild(d), n.appendChild(u), n.appendChild(c), {
+ days: l,
+ hours: d,
+ minutes: u,
+ seconds: c
+ };
+};
+/*!
+ * Project : simplyCountdown.js
+ * Date : 2024-12-27
+ * License : MIT
+ * Version : 3.0.0
+ * Author : Vincent Loy-Serre
+ * Contributors :
+ * - Justin Beasley
+ * - Nathan Smith
+ * - Mehdi Rezaei
+ * - mira01
+ */
+const m = {
+ year: 2024,
+ month: 12,
+ day: 25,
+ hours: 0,
+ minutes: 0,
+ seconds: 0,
+ words: {
+ days: { lambda: (n, e) => e > 1 ? n + "s" : n, root: "day" },
+ hours: { lambda: (n, e) => e > 1 ? n + "s" : n, root: "hour" },
+ minutes: { lambda: (n, e) => e > 1 ? n + "s" : n, root: "minute" },
+ seconds: { lambda: (n, e) => e > 1 ? n + "s" : n, root: "second" }
+ },
+ plural: !0,
+ inline: !1,
+ inlineSeparator: ", ",
+ enableUtc: !1,
+ onEnd: () => {
+ },
+ refresh: 1e3,
+ inlineClass: "simply-countdown-inline",
+ sectionClass: "simply-section",
+ amountClass: "simply-amount",
+ wordClass: "simply-word",
+ zeroPad: !1,
+ countUp: !1,
+ removeZeroUnits: !1,
+ onStop: () => {
+ },
+ onResume: () => {
+ },
+ onUpdate: () => {
+ }
+}, N = (n) => n instanceof NodeList;
+function I(n, e) {
+ return `${e.zeroPad ? String(n.value).padStart(2, "0") : n.value} ${e.words[n.word].lambda(e.words[n.word].root, n.value)}`;
+}
+function S(n, e, o) {
+ return o.removeZeroUnits ? n.value !== 0 || e.some((t) => t.value !== 0) : !0;
+}
+function M(n, e, o) {
+ const t = n.filter((l, d) => S(l, n.slice(0, d), e)).map((l) => I(l, e)).join(e.inlineSeparator);
+ o.innerHTML = t;
+}
+function $(n, e, o) {
+ n.forEach((t, l) => {
+ t.word === "seconds" || S(t, n.slice(0, l), e) ? (b(
+ o[t.word],
+ e.zeroPad ? String(t.value).padStart(2, "0") : t.value,
+ e.words[t.word].lambda(e.words[t.word].root, t.value)
+ ), o[t.word].style.display = "") : o[t.word].style.display = "none";
+ });
+}
+const y = (n, e) => {
+ let o = {
+ isPaused: !1,
+ interval: null,
+ targetDate: /* @__PURE__ */ new Date()
+ };
+ const t = (s) => s.enableUtc ? new Date(Date.UTC(s.year, s.month - 1, s.day, s.hours, s.minutes, s.seconds)) : new Date(s.year, s.month - 1, s.day, s.hours, s.minutes, s.seconds);
+ o.targetDate = t(e);
+ let l = null;
+ e.inline && (l = document.createElement("span"), l.className = e.inlineClass, n.appendChild(l));
+ const d = e.inline ? null : E(n, {
+ sectionClass: e.sectionClass,
+ amountClass: e.amountClass,
+ wordClass: e.wordClass
+ }), u = () => {
+ const s = e.enableUtc ? new Date(
+ Date.UTC(
+ (/* @__PURE__ */ new Date()).getUTCFullYear(),
+ (/* @__PURE__ */ new Date()).getUTCMonth(),
+ (/* @__PURE__ */ new Date()).getUTCDate(),
+ (/* @__PURE__ */ new Date()).getUTCHours(),
+ (/* @__PURE__ */ new Date()).getUTCMinutes(),
+ (/* @__PURE__ */ new Date()).getUTCSeconds()
+ )
+ ) : /* @__PURE__ */ new Date();
+ let i = e.countUp ? s.getTime() - o.targetDate.getTime() : o.targetDate.getTime() - s.getTime();
+ i <= 0 && !e.countUp && (i = 0, o.interval !== null && clearInterval(o.interval), e.onEnd && e.onEnd());
+ const f = Math.floor(i / (1e3 * 60 * 60 * 24));
+ i -= f * 1e3 * 60 * 60 * 24;
+ const C = Math.floor(i / (1e3 * 60 * 60));
+ i -= C * 1e3 * 60 * 60;
+ const v = Math.floor(i / (1e3 * 60));
+ i -= v * 1e3 * 60;
+ const g = Math.floor(i / 1e3);
+ e.inline && l ? M([
+ { value: f, word: "days" },
+ {
+ value: C,
+ word: "hours"
+ },
+ {
+ value: v,
+ word: "minutes"
+ },
+ {
+ value: g,
+ word: "seconds"
+ }
+ ], e, l) : d && $([
+ { value: f, word: "days" },
+ {
+ value: C,
+ word: "hours"
+ },
+ {
+ value: v,
+ word: "minutes"
+ },
+ {
+ value: g,
+ word: "seconds"
+ }
+ ], e, d);
+ }, c = () => {
+ o.interval = setInterval(u, e.refresh), u();
+ }, a = () => {
+ var s;
+ o.interval !== null && (clearInterval(o.interval), o.interval = null), o.isPaused = !0, (s = e.onStop) == null || s.call(e);
+ }, r = () => {
+ var s;
+ o.isPaused && (c(), o.isPaused = !1, (s = e.onResume) == null || s.call(e));
+ }, U = (s) => {
+ var i;
+ Object.assign(e, s), (s.year !== void 0 || s.month !== void 0 || s.day !== void 0 || s.hours !== void 0 || s.minutes !== void 0 || s.seconds !== void 0) && (o.targetDate = t(e)), (i = e.onUpdate) == null || i.call(e, s), o.isPaused || (o.interval && clearInterval(o.interval), c());
+ }, p = () => ({ ...o });
+ c();
+ const h = new MutationObserver((s) => {
+ s.forEach((i) => {
+ i.removedNodes.forEach((f) => {
+ f === n && (o.interval !== null && clearInterval(o.interval), h.disconnect());
+ });
+ });
+ });
+ return n.parentNode && h.observe(n.parentNode, { childList: !0 }), {
+ stopCountdown: a,
+ resumeCountdown: r,
+ updateCountdown: U,
+ getState: p
+ };
+}, D = (n) => {
+ const e = n;
+ return e.stopCountdown = () => n.forEach((o) => o.stopCountdown()), e.resumeCountdown = () => n.forEach((o) => o.resumeCountdown()), e.updateCountdown = (o) => n.forEach((t) => t.updateCountdown(o)), e.getState = () => n.map((o) => o.getState()), e;
+}, x = (n, e = m) => {
+ const o = { ...m, ...e };
+ if (typeof n == "string") {
+ const t = document.querySelectorAll(n), l = Array.from(t).map((d) => y(d, o));
+ return l.length === 1 ? l[0] : D(l);
+ }
+ if (N(n)) {
+ const t = Array.from(n).map((l) => y(l, o));
+ return t.length === 1 ? t[0] : D(t);
+ }
+ return y(n, o);
+};
+export {
+ x as default
+};
+//# sourceMappingURL=simplyCountdown.js.map
diff --git a/dist/simplyCountdown.js.map b/dist/simplyCountdown.js.map
new file mode 100644
index 0000000..dbe11d7
--- /dev/null
+++ b/dist/simplyCountdown.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"simplyCountdown.js","sources":["../src/core/dom.ts","../src/core/simplyCountdown.ts"],"sourcesContent":["/**\n * Creates a countdown section element\n */\nexport const createCountdownSection = (\n sectionClass: string,\n amountClass: string,\n wordClass: string,\n amount: number,\n word: string,\n params: {\n sectionClass: string;\n amountClass: string;\n wordClass: string;\n }\n): HTMLElement => {\n const section = document.createElement(\"div\");\n section.className = `${sectionClass} ${params.sectionClass}`;\n\n const wrap = document.createElement(\"div\");\n const amount_elem = document.createElement(\"span\");\n const word_elem = document.createElement(\"span\");\n\n amount_elem.className = `${amountClass} ${params.amountClass}`;\n word_elem.className = `${wordClass} ${params.wordClass}`;\n\n amount_elem.textContent = String(amount);\n word_elem.textContent = word;\n\n wrap.appendChild(amount_elem);\n wrap.appendChild(word_elem);\n section.appendChild(wrap);\n\n return section;\n};\n\n/**\n * Retrieves a countdown section element from a container\n */\nexport const getCountdownSection = (sectionClass: string, container: HTMLElement): HTMLElement | null => {\n return container.querySelector(`.simply-section.${sectionClass}`);\n};\n\n/**\n * Updates a countdown section element\n */\nexport const updateCountdownSection = (section: HTMLElement, amount: number | string, word: string): void => {\n const amountElement = section.querySelector(\".simply-amount\");\n const wordElement = section.querySelector(\".simply-word\");\n\n if (amountElement) {\n amountElement.textContent = String(amount);\n }\n if (wordElement) {\n wordElement.textContent = word;\n }\n};\n\n/**\n * Creates all countdown elements\n */\nexport const createCountdown = (\n container: HTMLElement,\n params: {\n sectionClass: string;\n amountClass: string;\n wordClass: string;\n }\n): {\n days: HTMLElement;\n hours: HTMLElement;\n minutes: HTMLElement;\n seconds: HTMLElement;\n} => {\n const amountCls = \"simply-amount\";\n const wordCls = \"simply-word\";\n\n const days = createCountdownSection(\"simply-section simply-days-section\", amountCls, wordCls, 0, \"day\", params);\n const hours = createCountdownSection(\"simply-section simply-hours-section\", amountCls, wordCls, 0, \"hour\", params);\n const minutes = createCountdownSection(\"simply-section simply-minutes-section\", amountCls, wordCls, 0, \"minute\", params);\n const seconds = createCountdownSection(\"simply-section simply-seconds-section\", amountCls, wordCls, 0, \"second\", params);\n\n container.appendChild(days);\n container.appendChild(hours);\n container.appendChild(minutes);\n container.appendChild(seconds);\n\n return {\n days,\n hours,\n minutes,\n seconds,\n };\n};\n","/*!\n * Project : simplyCountdown.js\n * Date : 2024-12-27\n * License : MIT\n * Version : 3.0.0\n * Author : Vincent Loy-Serre\n * Contributors :\n * - Justin Beasley\n * - Nathan Smith\n * - Mehdi Rezaei\n * - mira01\n */\n\nimport type { CountdownParameters, CountdownSelector, CountdownState, CountdownController, CountdownControllerArray } from \"../types\";\nimport { createCountdown, updateCountdownSection } from \"./dom\";\n\nconst defaultParams: CountdownParameters = {\n year: 2024,\n month: 12,\n day: 25,\n hours: 0,\n minutes: 0,\n seconds: 0,\n words: {\n days: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"day\" },\n hours: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"hour\" },\n minutes: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"minute\" },\n seconds: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"second\" },\n },\n plural: true,\n inline: false,\n inlineSeparator: \", \",\n enableUtc: false,\n onEnd: () => {},\n refresh: 1000,\n inlineClass: \"simply-countdown-inline\",\n sectionClass: \"simply-section\",\n amountClass: \"simply-amount\",\n wordClass: \"simply-word\",\n zeroPad: false,\n countUp: false,\n removeZeroUnits: false,\n onStop: () => {},\n onResume: () => {},\n onUpdate: () => {},\n};\n\nconst isNodeList = (element: CountdownSelector): element is NodeListOf => {\n return element instanceof NodeList;\n};\n\ninterface TimeUnit {\n value: number;\n word: keyof CountdownParameters[\"words\"];\n element?: HTMLElement;\n}\n\n/**\n * Formats a time unit with optional zero padding and pluralization\n * @param unit - The time unit object containing value and word properties\n * @param params - The countdown parameters containing formatting options and word definitions\n * @returns A formatted string containing the value and pluralized word for the time unit\n * @example\n * // With zeroPad: true\n * formatTimeUnit({value: 5, word: 'days'}, params) // returns \"05 days\"\n * // With zeroPad: false\n * formatTimeUnit({value: 5, word: 'days'}, params) // returns \"5 days\"\n */\nfunction formatTimeUnit(unit: TimeUnit, params: CountdownParameters): string {\n const value = params.zeroPad ? String(unit.value).padStart(2, \"0\") : unit.value;\n return `${value} ${params.words[unit.word].lambda(params.words[unit.word].root, unit.value)}`;\n}\n\n/**\n * Determines whether a time unit should be displayed based on its value and the values of previous units\n * @param unit - The current time unit to evaluate\n * @param previousUnits - Array of time units that come before the current unit\n * @param params - Configuration parameters for the countdown\n * @returns True if the unit should be displayed, false otherwise\n *\n * If removeZeroUnits is false in params, always returns true.\n * Otherwise, returns true if either:\n * - The current unit value is not zero\n * - Any previous unit has a non-zero value\n */\nfunction shouldDisplay(unit: TimeUnit, previousUnits: TimeUnit[], params: CountdownParameters): boolean {\n if (!params.removeZeroUnits) return true;\n return unit.value !== 0 || previousUnits.some((u) => u.value !== 0);\n}\n\n/**\n * Displays the countdown timer inline within the specified HTML element.\n *\n * @param timeUnits - Array of time units containing values and labels for display\n * @param params - Configuration parameters for the countdown display\n * @param element - The HTML element where the countdown will be rendered\n *\n * @remarks\n * The function filters and formats time units based on display rules, then joins them with\n * the specified separator from params.inlineSeparator before setting the element's innerHTML.\n */\nfunction displayInline(timeUnits: TimeUnit[], params: CountdownParameters, element: HTMLElement): void {\n const displayStr = timeUnits\n .filter((unit, index) => shouldDisplay(unit, timeUnits.slice(0, index), params))\n .map((unit) => formatTimeUnit(unit as { value: number; word: keyof typeof params.words }, params))\n .join(params.inlineSeparator);\n\n element.innerHTML = displayStr;\n}\n\n/**\n * Updates the display of time units in the countdown based on their values and display conditions\n * @param timeUnits - Array of TimeUnit objects containing the time values and their corresponding words\n * @param params - Configuration parameters for the countdown display\n * @param countdown - DOM elements representing the countdown display sections\n * @returns void\n *\n * @remarks\n * This function iterates through each time unit and determines whether it should be shown based on:\n * - If it's the seconds unit (always shown)\n * - If it meets display criteria based on previous units\n *\n * For units that should be shown, it:\n * - Updates the display value (with optional zero padding)\n * - Updates the word label using the configured lambda function\n * - Shows the unit's DOM element\n *\n * For units that shouldn't be shown, it hides their DOM elements\n */\nfunction displayBlocks(timeUnits: TimeUnit[], params: CountdownParameters, countdown: any): void {\n timeUnits.forEach((unit, index) => {\n const shouldShow = unit.word === \"seconds\" || shouldDisplay(unit, timeUnits.slice(0, index), params);\n\n if (shouldShow) {\n updateCountdownSection(\n countdown[unit.word],\n params.zeroPad ? String(unit.value).padStart(2, \"0\") : unit.value,\n params.words[unit.word].lambda(params.words[unit.word].root, unit.value)\n );\n countdown[unit.word].style.display = \"\";\n } else {\n countdown[unit.word].style.display = \"none\";\n }\n });\n}\n\n/**\n * Creates a countdown instance that manages the countdown timer functionality.\n *\n * @param targetElement - The HTML element where the countdown will be rendered\n * @param parameters - Configuration parameters for the countdown\n *\n * @returns A controller object with methods to control the countdown:\n * - stopCountdown: Pauses the countdown and triggers onStop callback\n * - resumeCountdown: Resumes a paused countdown and triggers onResume callback\n * - updateCountdown: Updates countdown parameters and triggers onUpdate callback\n * - getState: Returns current state of the countdown\n */\nconst createCountdownInstance = (targetElement: HTMLElement, parameters: CountdownParameters): CountdownController => {\n let state: CountdownState = {\n isPaused: false,\n interval: null,\n targetDate: new Date(),\n };\n\n const getTargetDate = (params: CountdownParameters): Date => {\n return params.enableUtc\n ? new Date(Date.UTC(params.year, params.month - 1, params.day, params.hours, params.minutes, params.seconds))\n : new Date(params.year, params.month - 1, params.day, params.hours, params.minutes, params.seconds);\n };\n\n state.targetDate = getTargetDate(parameters);\n\n // Create span element for inline mode\n let inlineElement: HTMLElement | null = null;\n if (parameters.inline) {\n inlineElement = document.createElement(\"span\");\n inlineElement.className = parameters.inlineClass;\n targetElement.appendChild(inlineElement);\n }\n\n const countdown = parameters.inline\n ? null\n : createCountdown(targetElement, {\n sectionClass: parameters.sectionClass,\n amountClass: parameters.amountClass,\n wordClass: parameters.wordClass,\n });\n\n const refresh = () => {\n // Fix UTC current date handling\n const currentDate = parameters.enableUtc\n ? new Date(\n Date.UTC(\n new Date().getUTCFullYear(),\n new Date().getUTCMonth(),\n new Date().getUTCDate(),\n new Date().getUTCHours(),\n new Date().getUTCMinutes(),\n new Date().getUTCSeconds()\n )\n )\n : new Date();\n\n let diff = parameters.countUp ? currentDate.getTime() - state.targetDate.getTime() : state.targetDate.getTime() - currentDate.getTime();\n\n if (diff <= 0 && !parameters.countUp) {\n diff = 0;\n // Clear interval before calling onEnd to prevent multiple calls\n if (state.interval !== null) {\n clearInterval(state.interval);\n }\n\n if (parameters.onEnd) {\n parameters.onEnd();\n }\n }\n\n const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n diff -= days * 1000 * 60 * 60 * 24;\n\n const hours = Math.floor(diff / (1000 * 60 * 60));\n diff -= hours * 1000 * 60 * 60;\n\n const minutes = Math.floor(diff / (1000 * 60));\n diff -= minutes * 1000 * 60;\n\n const seconds = Math.floor(diff / 1000);\n\n if (parameters.inline && inlineElement) {\n const timeUnits: TimeUnit[] = [\n { value: days, word: \"days\" as keyof CountdownParameters[\"words\"] },\n {\n value: hours,\n word: \"hours\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: minutes,\n word: \"minutes\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: seconds,\n word: \"seconds\" as keyof CountdownParameters[\"words\"],\n },\n ];\n displayInline(timeUnits, parameters, inlineElement);\n } else if (countdown) {\n const timeUnits: TimeUnit[] = [\n { value: days, word: \"days\" as keyof CountdownParameters[\"words\"] },\n {\n value: hours,\n word: \"hours\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: minutes,\n word: \"minutes\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: seconds,\n word: \"seconds\" as keyof CountdownParameters[\"words\"],\n },\n ];\n displayBlocks(timeUnits, parameters, countdown);\n }\n };\n\n const startInterval = () => {\n state.interval = setInterval(refresh, parameters.refresh);\n refresh();\n };\n\n const stopCountdown = () => {\n if (state.interval !== null) {\n clearInterval(state.interval);\n state.interval = null;\n }\n state.isPaused = true;\n parameters.onStop?.();\n };\n\n const resumeCountdown = () => {\n if (state.isPaused) {\n startInterval();\n state.isPaused = false;\n parameters.onResume?.();\n }\n };\n\n const updateCountdown = (newParams: Partial) => {\n Object.assign(parameters, newParams);\n if (\n newParams.year !== undefined ||\n newParams.month !== undefined ||\n newParams.day !== undefined ||\n newParams.hours !== undefined ||\n newParams.minutes !== undefined ||\n newParams.seconds !== undefined\n ) {\n state.targetDate = getTargetDate(parameters);\n }\n\n parameters.onUpdate?.(newParams);\n\n if (!state.isPaused) {\n if (state.interval) {\n clearInterval(state.interval);\n }\n startInterval();\n }\n };\n\n const getState = () => ({ ...state });\n\n // Start the countdown\n startInterval();\n\n // Cleanup on element removal\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.removedNodes.forEach((node) => {\n if (node === targetElement) {\n if (state.interval !== null) {\n clearInterval(state.interval);\n }\n observer.disconnect();\n }\n });\n });\n });\n\n if (targetElement.parentNode) {\n observer.observe(targetElement.parentNode, { childList: true });\n }\n\n // Return controller object\n return {\n stopCountdown,\n resumeCountdown,\n updateCountdown,\n getState,\n };\n};\n\n/**\n * Creates an enhanced array of countdown controllers with additional control methods.\n *\n * @param controllers - Array of individual countdown controllers to be combined\n * @returns An array of controllers enhanced with collective control methods:\n * - `stopCountdown()`: Stops all countdowns in the array\n * - `resumeCountdown()`: Resumes all countdowns in the array\n * - `updateCountdown(newParams)`: Updates all countdowns with new parameters\n * - `getState()`: Returns an array of states from all countdowns\n */\nconst createControllerArray = (controllers: CountdownController[]): CountdownControllerArray => {\n const array = controllers as CountdownControllerArray;\n\n array.stopCountdown = () => controllers.forEach((c) => c.stopCountdown());\n array.resumeCountdown = () => controllers.forEach((c) => c.resumeCountdown());\n array.updateCountdown = (newParams) => controllers.forEach((c) => c.updateCountdown(newParams));\n array.getState = () => controllers.map((c) => c.getState());\n\n return array;\n};\n\n/**\n * Creates a countdown timer on specified HTML elements\n * @param element - A CSS selector string, HTMLElement, or NodeList targeting the countdown container(s)\n * @param args - Optional configuration parameters for the countdown\n * @returns A CountdownController for single element or CountdownControllerArray for multiple elements\n */\nconst simplyCountdown = (\n element: CountdownSelector,\n args: Partial = defaultParams\n): CountdownController | CountdownControllerArray => {\n const parameters: CountdownParameters = { ...defaultParams, ...args };\n\n if (typeof element === \"string\") {\n const elements = document.querySelectorAll(element);\n const controllers = Array.from(elements).map((el) => createCountdownInstance(el, parameters));\n return controllers.length === 1 ? controllers[0] : createControllerArray(controllers);\n }\n\n if (isNodeList(element)) {\n const controllers = Array.from(element).map((el) => createCountdownInstance(el, parameters));\n return controllers.length === 1 ? controllers[0] : createControllerArray(controllers);\n }\n\n return createCountdownInstance(element, parameters);\n};\n\nexport default simplyCountdown;\n"],"names":["createCountdownSection","sectionClass","amountClass","wordClass","amount","word","params","section","wrap","amount_elem","word_elem","updateCountdownSection","amountElement","wordElement","createCountdown","container","amountCls","wordCls","days","hours","minutes","seconds","defaultParams","root","n","isNodeList","element","formatTimeUnit","unit","shouldDisplay","previousUnits","u","displayInline","timeUnits","displayStr","index","displayBlocks","countdown","createCountdownInstance","targetElement","parameters","state","getTargetDate","inlineElement","refresh","currentDate","diff","startInterval","stopCountdown","_a","resumeCountdown","updateCountdown","newParams","getState","observer","mutations","mutation","node","createControllerArray","controllers","array","c","simplyCountdown","args","elements","el"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/simplyCountdown.min.js b/dist/simplyCountdown.min.js
deleted file mode 100644
index fc5d6e2..0000000
--- a/dist/simplyCountdown.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-"use strict";
-/*!
-* Project : simply-countdown
-* Date : 06/12/2024
-* License : MIT
-* Version : 2.0.1
-* Author : Vincent Loy
-* Contributors :
-* - Justin Beasley
-* - Nathan Smith
-*/!function(e){let t=function(e){let n,o=e||{};for(let e=1;e{let o=document.createElement("div"),s=document.createElement("span"),l=document.createElement("span"),a=document.createElement("div");return a.appendChild(s),a.appendChild(l),o.appendChild(a),o.classList.add(t.sectionClass),o.classList.add(n),s.classList.add(t.amountClass),l.classList.add(t.wordClass),e.appendChild(o),{full:o,amount:s,word:l}};e.simplyCountdown=(e,o)=>{const s=Object.getPrototypeOf(e);let l,a,r,i,d,u,c,m,y,p=t({year:2015,month:6,day:28,hours:0,minutes:0,seconds:0,words:{days:{lambda:(e,t)=>t>1?e+"s":e,root:"day"},hours:{lambda:(e,t)=>t>1?e+"s":e,root:"hour"},minutes:{lambda:(e,t)=>t>1?e+"s":e,root:"minute"},seconds:{lambda:(e,t)=>t>1?e+"s":e,root:"second"}},plural:!0,inline:!1,inlineSeparator:", ",enableUtc:!1,onEnd:()=>{},refresh:1e3,inlineClass:"simply-countdown-inline",sectionClass:"simply-section",amountClass:"simply-amount",wordClass:"simply-word",zeroPad:!1,removeZeroUnits:!1,countUp:!1},o);y=s===String.prototype?document.querySelectorAll(e):e,a=p.enableUtc?new Date(Date.UTC(p.year,p.month-1,p.day,p.hours,p.minutes,p.seconds)):new Date(p.year,p.month-1,p.day,p.hours,p.minutes,p.seconds);let h=e=>{let t,o=e,s=((e,t)=>{let o;return e.inline?(o=document.createElement("span"),o.classList.add(e.inlineClass),o):{days:n(t,e,"simply-days-section"),hours:n(t,e,"simply-hours-section"),minutes:n(t,e,"simply-minutes-section"),seconds:n(t,e,"simply-seconds-section")}})(p,o);t=function(){let e,t,n,y,h=()=>{d=parseInt(i/86400,10),i%=86400,u=parseInt(i/3600,10),i%=3600,c=parseInt(i/60,10),m=parseInt(i%60,10)};p.enableUtc?(r=new Date,r=new Date(Date.UTC(r.getUTCFullYear(),r.getUTCMonth(),r.getUTCDate(),r.getUTCHours(),r.getUTCMinutes(),r.getUTCSeconds()))):r=new Date,i=Math.floor((a-r.getTime())/1e3),i>0?h():p.countUp?(i=(r.getTime()-a)/1e3,h()):(d=0,u=0,c=0,m=0,window.clearInterval(l),p.onEnd());let C=(e,t)=>e.hasOwnProperty("lambda")?e.lambda(e.root,t):e.root,w=p.words;if(e=C(w.days,d),t=C(w.hours,u),n=C(w.minutes,c),y=C(w.seconds,m),p.inline){let s="";p.removeZeroUnits&&0===d||(s+=`${d} ${e}${p.inlineSeparator}`),p.removeZeroUnits&&0===d&&0===u||(s+=`${u} ${t}${p.inlineSeparator}`),p.removeZeroUnits&&0===d&&0===u&&0===c||(s+=`${c} ${n}${p.inlineSeparator}`),s+=`${m} ${y}`,o.innerHTML=s.replace(/, $/,"")}else p.removeZeroUnits&&0===d?s.days.full.style.display="none":(s.days.amount.textContent=(p.zeroPad&&d.toString().length<2?"0":"")+d,s.days.word.textContent=e,s.days.full.style.display=""),p.removeZeroUnits&&0===d&&0===u?s.hours.full.style.display="none":(s.hours.amount.textContent=(p.zeroPad&&u.toString().length<2?"0":"")+u,s.hours.word.textContent=t,s.hours.full.style.display=""),p.removeZeroUnits&&0===d&&0===u&&0===c?s.minutes.full.style.display="none":(s.minutes.amount.textContent=(p.zeroPad&&c.toString().length<2?"0":"")+c,s.minutes.word.textContent=n,s.minutes.full.style.display=""),s.seconds.amount.textContent=(p.zeroPad&&m.toString().length<2?"0":"")+m,s.seconds.word.textContent=y,s.seconds.full.style.display=""},t(),l=window.setInterval(t,p.refresh)};var C;null!==(C=y)&&Symbol.iterator in Object(C)?Array.prototype.forEach.call(y,(e=>{h(e)})):h(y)}}(window),window.jQuery&&function(e,t){e.fn.simplyCountdown=function(e){return function(e,n){t(e,n)}(this.selector,e)}}(jQuery,simplyCountdown);
\ No newline at end of file
diff --git a/dist/simplyCountdown.umd.js b/dist/simplyCountdown.umd.js
new file mode 100644
index 0000000..de33ed3
--- /dev/null
+++ b/dist/simplyCountdown.umd.js
@@ -0,0 +1,2 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define("simplyCountdown",n):(e="undefined"!=typeof globalThis?globalThis:e||self).simplyCountdown=n()}(this,(function(){"use strict";const e=(e,n,t,o,s,a)=>{const l=document.createElement("div");l.className=`${e} ${a.sectionClass}`;const r=document.createElement("div"),d=document.createElement("span"),i=document.createElement("span");return d.className=`${n} ${a.amountClass}`,i.className=`${t} ${a.wordClass}`,d.textContent=String(o),i.textContent=s,r.appendChild(d),r.appendChild(i),l.appendChild(r),l},n={year:2024,month:12,day:25,hours:0,minutes:0,seconds:0,words:{days:{lambda:(e,n)=>n>1?e+"s":e,root:"day"},hours:{lambda:(e,n)=>n>1?e+"s":e,root:"hour"},minutes:{lambda:(e,n)=>n>1?e+"s":e,root:"minute"},seconds:{lambda:(e,n)=>n>1?e+"s":e,root:"second"}},plural:!0,inline:!1,inlineSeparator:", ",enableUtc:!1,onEnd:()=>{},refresh:1e3,inlineClass:"simply-countdown-inline",sectionClass:"simply-section",amountClass:"simply-amount",wordClass:"simply-word",zeroPad:!1,countUp:!1,removeZeroUnits:!1,onStop:()=>{},onResume:()=>{},onUpdate:()=>{}};function t(e,n,t){return!t.removeZeroUnits||(0!==e.value||n.some((e=>0!==e.value)))}function o(e,n,o){const s=e.filter(((o,s)=>t(o,e.slice(0,s),n))).map((e=>function(e,n){return`${n.zeroPad?String(e.value).padStart(2,"0"):e.value} ${n.words[e.word].lambda(n.words[e.word].root,e.value)}`}(e,n))).join(n.inlineSeparator);o.innerHTML=s}function s(e,n,o){e.forEach(((s,a)=>{"seconds"===s.word||t(s,e.slice(0,a),n)?(((e,n,t)=>{const o=e.querySelector(".simply-amount"),s=e.querySelector(".simply-word");o&&(o.textContent=String(n)),s&&(s.textContent=t)})(o[s.word],n.zeroPad?String(s.value).padStart(2,"0"):s.value,n.words[s.word].lambda(n.words[s.word].root,s.value)),o[s.word].style.display=""):o[s.word].style.display="none"}))}const a=(n,t)=>{let a={isPaused:!1,interval:null,targetDate:new Date};const l=e=>e.enableUtc?new Date(Date.UTC(e.year,e.month-1,e.day,e.hours,e.minutes,e.seconds)):new Date(e.year,e.month-1,e.day,e.hours,e.minutes,e.seconds);a.targetDate=l(t);let r=null;t.inline&&(r=document.createElement("span"),r.className=t.inlineClass,n.appendChild(r));const d=t.inline?null:((n,t)=>{const o="simply-amount",s="simply-word",a=e("simply-section simply-days-section",o,s,0,"day",t),l=e("simply-section simply-hours-section",o,s,0,"hour",t),r=e("simply-section simply-minutes-section",o,s,0,"minute",t),d=e("simply-section simply-seconds-section",o,s,0,"second",t);return n.appendChild(a),n.appendChild(l),n.appendChild(r),n.appendChild(d),{days:a,hours:l,minutes:r,seconds:d}})(n,{sectionClass:t.sectionClass,amountClass:t.amountClass,wordClass:t.wordClass}),i=()=>{const e=t.enableUtc?new Date(Date.UTC((new Date).getUTCFullYear(),(new Date).getUTCMonth(),(new Date).getUTCDate(),(new Date).getUTCHours(),(new Date).getUTCMinutes(),(new Date).getUTCSeconds())):new Date;let n=t.countUp?e.getTime()-a.targetDate.getTime():a.targetDate.getTime()-e.getTime();n<=0&&!t.countUp&&(n=0,null!==a.interval&&clearInterval(a.interval),t.onEnd&&t.onEnd());const l=Math.floor(n/864e5);n-=1e3*l*60*60*24;const i=Math.floor(n/36e5);n-=1e3*i*60*60;const u=Math.floor(n/6e4);n-=1e3*u*60;const c=Math.floor(n/1e3);if(t.inline&&r){o([{value:l,word:"days"},{value:i,word:"hours"},{value:u,word:"minutes"},{value:c,word:"seconds"}],t,r)}else if(d){s([{value:l,word:"days"},{value:i,word:"hours"},{value:u,word:"minutes"},{value:c,word:"seconds"}],t,d)}},u=()=>{a.interval=setInterval(i,t.refresh),i()};u();const c=new MutationObserver((e=>{e.forEach((e=>{e.removedNodes.forEach((e=>{e===n&&(null!==a.interval&&clearInterval(a.interval),c.disconnect())}))}))}));return n.parentNode&&c.observe(n.parentNode,{childList:!0}),{stopCountdown:()=>{var e;null!==a.interval&&(clearInterval(a.interval),a.interval=null),a.isPaused=!0,null==(e=t.onStop)||e.call(t)},resumeCountdown:()=>{var e;a.isPaused&&(u(),a.isPaused=!1,null==(e=t.onResume)||e.call(t))},updateCountdown:e=>{var n;Object.assign(t,e),void 0===e.year&&void 0===e.month&&void 0===e.day&&void 0===e.hours&&void 0===e.minutes&&void 0===e.seconds||(a.targetDate=l(t)),null==(n=t.onUpdate)||n.call(t,e),a.isPaused||(a.interval&&clearInterval(a.interval),u())},getState:()=>({...a})}},l=e=>{const n=e;return n.stopCountdown=()=>e.forEach((e=>e.stopCountdown())),n.resumeCountdown=()=>e.forEach((e=>e.resumeCountdown())),n.updateCountdown=n=>e.forEach((e=>e.updateCountdown(n))),n.getState=()=>e.map((e=>e.getState())),n},r=(e,t=n)=>{const o={...n,...t};if("string"==typeof e){const n=document.querySelectorAll(e),t=Array.from(n).map((e=>a(e,o)));return 1===t.length?t[0]:l(t)}if((e=>e instanceof NodeList)(e)){const n=Array.from(e).map((e=>a(e,o)));return 1===n.length?n[0]:l(n)}return a(e,o)};return"function"==typeof define&&define.amd?define((function(){return r})):"object"==typeof module&&module.exports?module.exports=r:window.simplyCountdown=r,r}));
+//# sourceMappingURL=simplyCountdown.umd.js.map
diff --git a/dist/simplyCountdown.umd.js.map b/dist/simplyCountdown.umd.js.map
new file mode 100644
index 0000000..aedb97e
--- /dev/null
+++ b/dist/simplyCountdown.umd.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"simplyCountdown.umd.js","sources":["../src/core/dom.ts","../src/core/simplyCountdown.ts","../src/core/simplyCountdown.umd.ts"],"sourcesContent":["/**\n * Creates a countdown section element\n */\nexport const createCountdownSection = (\n sectionClass: string,\n amountClass: string,\n wordClass: string,\n amount: number,\n word: string,\n params: {\n sectionClass: string;\n amountClass: string;\n wordClass: string;\n }\n): HTMLElement => {\n const section = document.createElement(\"div\");\n section.className = `${sectionClass} ${params.sectionClass}`;\n\n const wrap = document.createElement(\"div\");\n const amount_elem = document.createElement(\"span\");\n const word_elem = document.createElement(\"span\");\n\n amount_elem.className = `${amountClass} ${params.amountClass}`;\n word_elem.className = `${wordClass} ${params.wordClass}`;\n\n amount_elem.textContent = String(amount);\n word_elem.textContent = word;\n\n wrap.appendChild(amount_elem);\n wrap.appendChild(word_elem);\n section.appendChild(wrap);\n\n return section;\n};\n\n/**\n * Retrieves a countdown section element from a container\n */\nexport const getCountdownSection = (sectionClass: string, container: HTMLElement): HTMLElement | null => {\n return container.querySelector(`.simply-section.${sectionClass}`);\n};\n\n/**\n * Updates a countdown section element\n */\nexport const updateCountdownSection = (section: HTMLElement, amount: number | string, word: string): void => {\n const amountElement = section.querySelector(\".simply-amount\");\n const wordElement = section.querySelector(\".simply-word\");\n\n if (amountElement) {\n amountElement.textContent = String(amount);\n }\n if (wordElement) {\n wordElement.textContent = word;\n }\n};\n\n/**\n * Creates all countdown elements\n */\nexport const createCountdown = (\n container: HTMLElement,\n params: {\n sectionClass: string;\n amountClass: string;\n wordClass: string;\n }\n): {\n days: HTMLElement;\n hours: HTMLElement;\n minutes: HTMLElement;\n seconds: HTMLElement;\n} => {\n const amountCls = \"simply-amount\";\n const wordCls = \"simply-word\";\n\n const days = createCountdownSection(\"simply-section simply-days-section\", amountCls, wordCls, 0, \"day\", params);\n const hours = createCountdownSection(\"simply-section simply-hours-section\", amountCls, wordCls, 0, \"hour\", params);\n const minutes = createCountdownSection(\"simply-section simply-minutes-section\", amountCls, wordCls, 0, \"minute\", params);\n const seconds = createCountdownSection(\"simply-section simply-seconds-section\", amountCls, wordCls, 0, \"second\", params);\n\n container.appendChild(days);\n container.appendChild(hours);\n container.appendChild(minutes);\n container.appendChild(seconds);\n\n return {\n days,\n hours,\n minutes,\n seconds,\n };\n};\n","/*!\n * Project : simplyCountdown.js\n * Date : 2024-12-27\n * License : MIT\n * Version : 3.0.0\n * Author : Vincent Loy-Serre\n * Contributors :\n * - Justin Beasley\n * - Nathan Smith\n * - Mehdi Rezaei\n * - mira01\n */\n\nimport type { CountdownParameters, CountdownSelector, CountdownState, CountdownController, CountdownControllerArray } from \"../types\";\nimport { createCountdown, updateCountdownSection } from \"./dom\";\n\nconst defaultParams: CountdownParameters = {\n year: 2024,\n month: 12,\n day: 25,\n hours: 0,\n minutes: 0,\n seconds: 0,\n words: {\n days: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"day\" },\n hours: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"hour\" },\n minutes: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"minute\" },\n seconds: { lambda: (root, n) => (n > 1 ? root + \"s\" : root), root: \"second\" },\n },\n plural: true,\n inline: false,\n inlineSeparator: \", \",\n enableUtc: false,\n onEnd: () => {},\n refresh: 1000,\n inlineClass: \"simply-countdown-inline\",\n sectionClass: \"simply-section\",\n amountClass: \"simply-amount\",\n wordClass: \"simply-word\",\n zeroPad: false,\n countUp: false,\n removeZeroUnits: false,\n onStop: () => {},\n onResume: () => {},\n onUpdate: () => {},\n};\n\nconst isNodeList = (element: CountdownSelector): element is NodeListOf => {\n return element instanceof NodeList;\n};\n\ninterface TimeUnit {\n value: number;\n word: keyof CountdownParameters[\"words\"];\n element?: HTMLElement;\n}\n\n/**\n * Formats a time unit with optional zero padding and pluralization\n * @param unit - The time unit object containing value and word properties\n * @param params - The countdown parameters containing formatting options and word definitions\n * @returns A formatted string containing the value and pluralized word for the time unit\n * @example\n * // With zeroPad: true\n * formatTimeUnit({value: 5, word: 'days'}, params) // returns \"05 days\"\n * // With zeroPad: false\n * formatTimeUnit({value: 5, word: 'days'}, params) // returns \"5 days\"\n */\nfunction formatTimeUnit(unit: TimeUnit, params: CountdownParameters): string {\n const value = params.zeroPad ? String(unit.value).padStart(2, \"0\") : unit.value;\n return `${value} ${params.words[unit.word].lambda(params.words[unit.word].root, unit.value)}`;\n}\n\n/**\n * Determines whether a time unit should be displayed based on its value and the values of previous units\n * @param unit - The current time unit to evaluate\n * @param previousUnits - Array of time units that come before the current unit\n * @param params - Configuration parameters for the countdown\n * @returns True if the unit should be displayed, false otherwise\n *\n * If removeZeroUnits is false in params, always returns true.\n * Otherwise, returns true if either:\n * - The current unit value is not zero\n * - Any previous unit has a non-zero value\n */\nfunction shouldDisplay(unit: TimeUnit, previousUnits: TimeUnit[], params: CountdownParameters): boolean {\n if (!params.removeZeroUnits) return true;\n return unit.value !== 0 || previousUnits.some((u) => u.value !== 0);\n}\n\n/**\n * Displays the countdown timer inline within the specified HTML element.\n *\n * @param timeUnits - Array of time units containing values and labels for display\n * @param params - Configuration parameters for the countdown display\n * @param element - The HTML element where the countdown will be rendered\n *\n * @remarks\n * The function filters and formats time units based on display rules, then joins them with\n * the specified separator from params.inlineSeparator before setting the element's innerHTML.\n */\nfunction displayInline(timeUnits: TimeUnit[], params: CountdownParameters, element: HTMLElement): void {\n const displayStr = timeUnits\n .filter((unit, index) => shouldDisplay(unit, timeUnits.slice(0, index), params))\n .map((unit) => formatTimeUnit(unit as { value: number; word: keyof typeof params.words }, params))\n .join(params.inlineSeparator);\n\n element.innerHTML = displayStr;\n}\n\n/**\n * Updates the display of time units in the countdown based on their values and display conditions\n * @param timeUnits - Array of TimeUnit objects containing the time values and their corresponding words\n * @param params - Configuration parameters for the countdown display\n * @param countdown - DOM elements representing the countdown display sections\n * @returns void\n *\n * @remarks\n * This function iterates through each time unit and determines whether it should be shown based on:\n * - If it's the seconds unit (always shown)\n * - If it meets display criteria based on previous units\n *\n * For units that should be shown, it:\n * - Updates the display value (with optional zero padding)\n * - Updates the word label using the configured lambda function\n * - Shows the unit's DOM element\n *\n * For units that shouldn't be shown, it hides their DOM elements\n */\nfunction displayBlocks(timeUnits: TimeUnit[], params: CountdownParameters, countdown: any): void {\n timeUnits.forEach((unit, index) => {\n const shouldShow = unit.word === \"seconds\" || shouldDisplay(unit, timeUnits.slice(0, index), params);\n\n if (shouldShow) {\n updateCountdownSection(\n countdown[unit.word],\n params.zeroPad ? String(unit.value).padStart(2, \"0\") : unit.value,\n params.words[unit.word].lambda(params.words[unit.word].root, unit.value)\n );\n countdown[unit.word].style.display = \"\";\n } else {\n countdown[unit.word].style.display = \"none\";\n }\n });\n}\n\n/**\n * Creates a countdown instance that manages the countdown timer functionality.\n *\n * @param targetElement - The HTML element where the countdown will be rendered\n * @param parameters - Configuration parameters for the countdown\n *\n * @returns A controller object with methods to control the countdown:\n * - stopCountdown: Pauses the countdown and triggers onStop callback\n * - resumeCountdown: Resumes a paused countdown and triggers onResume callback\n * - updateCountdown: Updates countdown parameters and triggers onUpdate callback\n * - getState: Returns current state of the countdown\n */\nconst createCountdownInstance = (targetElement: HTMLElement, parameters: CountdownParameters): CountdownController => {\n let state: CountdownState = {\n isPaused: false,\n interval: null,\n targetDate: new Date(),\n };\n\n const getTargetDate = (params: CountdownParameters): Date => {\n return params.enableUtc\n ? new Date(Date.UTC(params.year, params.month - 1, params.day, params.hours, params.minutes, params.seconds))\n : new Date(params.year, params.month - 1, params.day, params.hours, params.minutes, params.seconds);\n };\n\n state.targetDate = getTargetDate(parameters);\n\n // Create span element for inline mode\n let inlineElement: HTMLElement | null = null;\n if (parameters.inline) {\n inlineElement = document.createElement(\"span\");\n inlineElement.className = parameters.inlineClass;\n targetElement.appendChild(inlineElement);\n }\n\n const countdown = parameters.inline\n ? null\n : createCountdown(targetElement, {\n sectionClass: parameters.sectionClass,\n amountClass: parameters.amountClass,\n wordClass: parameters.wordClass,\n });\n\n const refresh = () => {\n // Fix UTC current date handling\n const currentDate = parameters.enableUtc\n ? new Date(\n Date.UTC(\n new Date().getUTCFullYear(),\n new Date().getUTCMonth(),\n new Date().getUTCDate(),\n new Date().getUTCHours(),\n new Date().getUTCMinutes(),\n new Date().getUTCSeconds()\n )\n )\n : new Date();\n\n let diff = parameters.countUp ? currentDate.getTime() - state.targetDate.getTime() : state.targetDate.getTime() - currentDate.getTime();\n\n if (diff <= 0 && !parameters.countUp) {\n diff = 0;\n // Clear interval before calling onEnd to prevent multiple calls\n if (state.interval !== null) {\n clearInterval(state.interval);\n }\n\n if (parameters.onEnd) {\n parameters.onEnd();\n }\n }\n\n const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n diff -= days * 1000 * 60 * 60 * 24;\n\n const hours = Math.floor(diff / (1000 * 60 * 60));\n diff -= hours * 1000 * 60 * 60;\n\n const minutes = Math.floor(diff / (1000 * 60));\n diff -= minutes * 1000 * 60;\n\n const seconds = Math.floor(diff / 1000);\n\n if (parameters.inline && inlineElement) {\n const timeUnits: TimeUnit[] = [\n { value: days, word: \"days\" as keyof CountdownParameters[\"words\"] },\n {\n value: hours,\n word: \"hours\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: minutes,\n word: \"minutes\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: seconds,\n word: \"seconds\" as keyof CountdownParameters[\"words\"],\n },\n ];\n displayInline(timeUnits, parameters, inlineElement);\n } else if (countdown) {\n const timeUnits: TimeUnit[] = [\n { value: days, word: \"days\" as keyof CountdownParameters[\"words\"] },\n {\n value: hours,\n word: \"hours\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: minutes,\n word: \"minutes\" as keyof CountdownParameters[\"words\"],\n },\n {\n value: seconds,\n word: \"seconds\" as keyof CountdownParameters[\"words\"],\n },\n ];\n displayBlocks(timeUnits, parameters, countdown);\n }\n };\n\n const startInterval = () => {\n state.interval = setInterval(refresh, parameters.refresh);\n refresh();\n };\n\n const stopCountdown = () => {\n if (state.interval !== null) {\n clearInterval(state.interval);\n state.interval = null;\n }\n state.isPaused = true;\n parameters.onStop?.();\n };\n\n const resumeCountdown = () => {\n if (state.isPaused) {\n startInterval();\n state.isPaused = false;\n parameters.onResume?.();\n }\n };\n\n const updateCountdown = (newParams: Partial) => {\n Object.assign(parameters, newParams);\n if (\n newParams.year !== undefined ||\n newParams.month !== undefined ||\n newParams.day !== undefined ||\n newParams.hours !== undefined ||\n newParams.minutes !== undefined ||\n newParams.seconds !== undefined\n ) {\n state.targetDate = getTargetDate(parameters);\n }\n\n parameters.onUpdate?.(newParams);\n\n if (!state.isPaused) {\n if (state.interval) {\n clearInterval(state.interval);\n }\n startInterval();\n }\n };\n\n const getState = () => ({ ...state });\n\n // Start the countdown\n startInterval();\n\n // Cleanup on element removal\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.removedNodes.forEach((node) => {\n if (node === targetElement) {\n if (state.interval !== null) {\n clearInterval(state.interval);\n }\n observer.disconnect();\n }\n });\n });\n });\n\n if (targetElement.parentNode) {\n observer.observe(targetElement.parentNode, { childList: true });\n }\n\n // Return controller object\n return {\n stopCountdown,\n resumeCountdown,\n updateCountdown,\n getState,\n };\n};\n\n/**\n * Creates an enhanced array of countdown controllers with additional control methods.\n *\n * @param controllers - Array of individual countdown controllers to be combined\n * @returns An array of controllers enhanced with collective control methods:\n * - `stopCountdown()`: Stops all countdowns in the array\n * - `resumeCountdown()`: Resumes all countdowns in the array\n * - `updateCountdown(newParams)`: Updates all countdowns with new parameters\n * - `getState()`: Returns an array of states from all countdowns\n */\nconst createControllerArray = (controllers: CountdownController[]): CountdownControllerArray => {\n const array = controllers as CountdownControllerArray;\n\n array.stopCountdown = () => controllers.forEach((c) => c.stopCountdown());\n array.resumeCountdown = () => controllers.forEach((c) => c.resumeCountdown());\n array.updateCountdown = (newParams) => controllers.forEach((c) => c.updateCountdown(newParams));\n array.getState = () => controllers.map((c) => c.getState());\n\n return array;\n};\n\n/**\n * Creates a countdown timer on specified HTML elements\n * @param element - A CSS selector string, HTMLElement, or NodeList targeting the countdown container(s)\n * @param args - Optional configuration parameters for the countdown\n * @returns A CountdownController for single element or CountdownControllerArray for multiple elements\n */\nconst simplyCountdown = (\n element: CountdownSelector,\n args: Partial = defaultParams\n): CountdownController | CountdownControllerArray => {\n const parameters: CountdownParameters = { ...defaultParams, ...args };\n\n if (typeof element === \"string\") {\n const elements = document.querySelectorAll(element);\n const controllers = Array.from(elements).map((el) => createCountdownInstance(el, parameters));\n return controllers.length === 1 ? controllers[0] : createControllerArray(controllers);\n }\n\n if (isNodeList(element)) {\n const controllers = Array.from(element).map((el) => createCountdownInstance(el, parameters));\n return controllers.length === 1 ? controllers[0] : createControllerArray(controllers);\n }\n\n return createCountdownInstance(element, parameters);\n};\n\nexport default simplyCountdown;\n","import simplyCountdownCore from \"./simplyCountdown\";\n\ndeclare const define: {\n (factory: () => any): void;\n amd: boolean;\n};\n\nif (typeof define === \"function\" && define.amd) {\n // AMD\n define(function () {\n return simplyCountdownCore;\n });\n} else if (typeof module === \"object\" && module.exports) {\n // Node\n module.exports = simplyCountdownCore;\n} else {\n // Browser\n (window as any).simplyCountdown = simplyCountdownCore;\n}\n\n// Export for Vite/Rollup\nexport default simplyCountdownCore;\n"],"names":["createCountdownSection","sectionClass","amountClass","wordClass","amount","word","params","section","document","createElement","className","wrap","amount_elem","word_elem","textContent","String","appendChild","defaultParams","year","month","day","hours","minutes","seconds","words","days","lambda","root","n","plural","inline","inlineSeparator","enableUtc","onEnd","refresh","inlineClass","zeroPad","countUp","removeZeroUnits","onStop","onResume","onUpdate","shouldDisplay","unit","previousUnits","value","some","u","displayInline","timeUnits","element","displayStr","filter","index","slice","map","padStart","formatTimeUnit","join","innerHTML","displayBlocks","countdown","forEach","amountElement","querySelector","wordElement","updateCountdownSection","style","display","createCountdownInstance","targetElement","parameters","state","isPaused","interval","targetDate","Date","getTargetDate","UTC","inlineElement","container","amountCls","wordCls","createCountdown","currentDate","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","diff","getTime","clearInterval","Math","floor","startInterval","setInterval","observer","MutationObserver","mutations","mutation","removedNodes","node","disconnect","parentNode","observe","childList","stopCountdown","_a","call","resumeCountdown","updateCountdown","newParams","Object","assign","getState","createControllerArray","controllers","array","c","simplyCountdown","args","elements","querySelectorAll","Array","from","el","length","NodeList","isNodeList","define","amd","simplyCountdownCore","module","exports","window"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/themes/circle.css b/dist/themes/circle.css
new file mode 100644
index 0000000..c43dcfc
--- /dev/null
+++ b/dist/themes/circle.css
@@ -0,0 +1,73 @@
+.simply-countdown-circle {
+ --sc-circle-primary: #6366f1;
+ --sc-circle-secondary: #818cf8;
+ --sc-circle-bg: #1e1b4b;
+ --sc-circle-text: #fff;
+
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1.5rem;
+ font-family: "Inter", sans-serif;
+}
+
+.simply-countdown-circle > .simply-section {
+ position: relative;
+ width: 100px;
+ height: 100px;
+ padding: 1rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ border-radius: 50%;
+ background: linear-gradient(45deg, var(--sc-circle-primary), var(--sc-circle-secondary));
+ box-shadow: 0 0 25px -5px var(--sc-circle-primary);
+ animation: pulse-circle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+}
+
+.simply-countdown-circle > .simply-section::before {
+ content: "";
+ position: absolute;
+ inset: 6px;
+ border-radius: 50%;
+ background: var(--sc-circle-bg);
+ z-index: 0;
+}
+
+.simply-countdown-circle > .simply-section > div {
+ position: relative;
+ z-index: 1;
+ color: var(--sc-circle-text);
+ text-align: center;
+}
+
+.simply-countdown-circle .simply-amount {
+ display: block;
+ font-size: 1.75rem;
+ font-weight: 700;
+ line-height: 1;
+ background: linear-gradient(to right, var(--sc-circle-primary), var(--sc-circle-secondary));
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+.simply-countdown-circle .simply-word {
+ font-size: 0.7rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ opacity: 0.8;
+}
+
+@keyframes pulse-circle {
+ 0%,
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(0.98);
+ opacity: 0.9;
+ }
+}
diff --git a/dist/themes/circle.min.css b/dist/themes/circle.min.css
new file mode 100644
index 0000000..f8caa70
--- /dev/null
+++ b/dist/themes/circle.min.css
@@ -0,0 +1 @@
+.simply-countdown-circle{--sc-circle-primary:#6366f1;--sc-circle-secondary:#818cf8;--sc-circle-bg:#1e1b4b;--sc-circle-text:#fff;display:flex;flex-wrap:wrap;justify-content:center;gap:1.5rem;font-family:Inter,sans-serif}.simply-countdown-circle>.simply-section{position:relative;width:100px;height:100px;padding:1rem;display:flex;align-items:center;justify-content:center;flex-direction:column;border-radius:50%;background:linear-gradient(45deg,var(--sc-circle-primary),var(--sc-circle-secondary));box-shadow:0 0 25px -5px var(--sc-circle-primary);animation:2s cubic-bezier(.4,0,.6,1) infinite pulse-circle}.simply-countdown-circle>.simply-section::before{content:"";position:absolute;inset:6px;border-radius:50%;background:var(--sc-circle-bg);z-index:0}.simply-countdown-circle>.simply-section>div{position:relative;z-index:1;color:var(--sc-circle-text);text-align:center}.simply-countdown-circle .simply-amount{display:block;font-size:1.75rem;font-weight:700;line-height:1;background:linear-gradient(to right,var(--sc-circle-primary),var(--sc-circle-secondary));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}.simply-countdown-circle .simply-word{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;opacity:.8}@keyframes pulse-circle{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.98);opacity:.9}}
\ No newline at end of file
diff --git a/dist/themes/cyber.css b/dist/themes/cyber.css
new file mode 100644
index 0000000..9b733d0
--- /dev/null
+++ b/dist/themes/cyber.css
@@ -0,0 +1,155 @@
+/**
+* Project : simply-countdown
+* File : simplyCountdown.theme.cyberpunk
+* Author : Vincent Loy
+* Theme : Modern Cyberpunk
+*/
+
+.simply-countdown-cyber {
+ overflow: visible;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1.75rem;
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
+ perspective: 1000px;
+}
+
+.simply-countdown-cyber > .simply-section {
+ width: 70px;
+ height: 70px;
+ padding: 1.5rem;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, rgba(23, 25, 35, 0.9), rgba(15, 17, 25, 0.95));
+ border-radius: 0.5rem;
+ transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ backdrop-filter: blur(12px);
+ transform-style: preserve-3d;
+}
+
+.simply-countdown-cyber > .simply-section::before {
+ content: "";
+ position: absolute;
+ inset: -1px;
+ background: linear-gradient(135deg, rgba(120, 240, 255, 0.2), rgba(255, 90, 220, 0.2));
+ border-radius: 0.5rem;
+ z-index: -1;
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.simply-countdown-cyber > .simply-section::after {
+ content: "";
+ position: absolute;
+ inset: -2px;
+ background: linear-gradient(135deg, #78f0ff, #ff5adc);
+ border-radius: 0.5rem;
+ z-index: -2;
+ opacity: 0.15;
+ filter: blur(4px);
+ animation: pulse 4s ease-in-out infinite;
+}
+
+.simply-countdown-cyber > .simply-section .glass-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
+ border-radius: 0.5rem;
+}
+
+.simply-countdown-cyber > .simply-section:hover {
+ transform: translateY(-4px) translateZ(10px) rotateX(5deg);
+ box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.5), 0 0 20px rgba(120, 240, 255, 0.2), 0 0 0 1px rgba(120, 240, 255, 0.1);
+}
+
+.simply-countdown-cyber > .simply-section:hover::before {
+ opacity: 1;
+}
+
+.simply-countdown-cyber > .simply-section > div {
+ display: flex;
+ flex-direction: column;
+ gap: 0.4rem;
+ align-items: center;
+ transform-style: preserve-3d;
+}
+
+.simply-countdown-cyber > .simply-section .simply-amount {
+ font-size: 1.75rem;
+ font-weight: 700;
+ background: linear-gradient(to bottom right, #78f0ff, #ff5adc);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ text-shadow: 0 0 20px rgba(120, 240, 255, 0.3), 0 0 40px rgba(120, 240, 255, 0.2);
+ letter-spacing: -0.02em;
+ transform: translateZ(10px);
+}
+
+.simply-countdown-cyber > .simply-section .simply-word {
+ font-size: 0.6rem;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ color: rgba(255, 255, 255, 0.7);
+ transform: translateZ(5px);
+ position: relative;
+}
+
+.simply-countdown-cyber > .simply-section .simply-word::after {
+ content: "";
+ position: absolute;
+ left: -10%;
+ bottom: -4px;
+ width: 120%;
+ height: 1px;
+ background: linear-gradient(to right, rgba(120, 240, 255, 0), rgba(120, 240, 255, 0.5), rgba(255, 90, 220, 0.5), rgba(255, 90, 220, 0));
+}
+
+@media (min-width: 640px) {
+ .simply-countdown-cyber > .simply-section {
+ width: 80px;
+ height: 80px;
+ padding: 1.75rem;
+ }
+
+ .simply-countdown-cyber > .simply-section .simply-amount {
+ font-size: 2rem;
+ }
+
+ .simply-countdown-cyber > .simply-section .simply-word {
+ font-size: 0.75rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .simply-countdown-cyber > .simply-section {
+ width: 100px;
+ height: 100px;
+ padding: 2rem;
+ }
+
+ .simply-countdown-cyber > .simply-section .simply-amount {
+ font-size: 2.5rem;
+ }
+
+ .simply-countdown-cyber > .simply-section .simply-word {
+ font-size: 0.8rem;
+ }
+}
+
+/* Add subtle animation for extra futuristic feel */
+@keyframes pulse {
+ 0%,
+ 100% {
+ opacity: 0.15;
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 0.25;
+ transform: scale(1.05);
+ }
+}
diff --git a/dist/themes/cyber.min.css b/dist/themes/cyber.min.css
new file mode 100644
index 0000000..ed31a2f
--- /dev/null
+++ b/dist/themes/cyber.min.css
@@ -0,0 +1 @@
+.simply-countdown-cyber{overflow:visible;display:flex;flex-wrap:wrap;justify-content:center;gap:1.75rem;font-family:Inter,system-ui,-apple-system,sans-serif;perspective:1000px}.simply-countdown-cyber>.simply-section{width:70px;height:70px;padding:1.5rem;position:relative;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(23,25,35,.9),rgba(15,17,25,.95));border-radius:.5rem;transition:.4s cubic-bezier(.175, .885, .32, 1.275);backdrop-filter:blur(12px);transform-style:preserve-3d}.simply-countdown-cyber>.simply-section::before{content:"";position:absolute;inset:-1px;background:linear-gradient(135deg,rgba(120,240,255,.2),rgba(255,90,220,.2));border-radius:.5rem;z-index:-1;opacity:0;transition:opacity .3s}.simply-countdown-cyber>.simply-section::after{content:"";position:absolute;inset:-2px;background:linear-gradient(135deg,#78f0ff,#ff5adc);border-radius:.5rem;z-index:-2;opacity:.15;filter:blur(4px);animation:4s ease-in-out infinite pulse}.simply-countdown-cyber>.simply-section .glass-overlay{position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.1),rgba(255,255,255,.05));border-radius:.5rem}.simply-countdown-cyber>.simply-section:hover{transform:translateY(-4px) translateZ(10px) rotateX(5deg);box-shadow:0 20px 40px -10px rgba(0,0,0,.5),0 0 20px rgba(120,240,255,.2),0 0 0 1px rgba(120,240,255,.1)}.simply-countdown-cyber>.simply-section:hover::before{opacity:1}.simply-countdown-cyber>.simply-section>div{display:flex;flex-direction:column;gap:.4rem;align-items:center;transform-style:preserve-3d}.simply-countdown-cyber>.simply-section .simply-amount{font-size:1.75rem;font-weight:700;background:linear-gradient(to bottom right,#78f0ff,#ff5adc);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 0 20px rgba(120,240,255,.3),0 0 40px rgba(120,240,255,.2);letter-spacing:-.02em;transform:translateZ(10px)}.simply-countdown-cyber>.simply-section .simply-word{font-size:.6rem;font-weight:500;text-transform:uppercase;letter-spacing:.2em;color:rgba(255,255,255,.7);transform:translateZ(5px);position:relative}.simply-countdown-cyber>.simply-section .simply-word::after{content:"";position:absolute;left:-10%;bottom:-4px;width:120%;height:1px;background:linear-gradient(to right,rgba(120,240,255,0),rgba(120,240,255,.5),rgba(255,90,220,.5),rgba(255,90,220,0))}@media (min-width:640px){.simply-countdown-cyber>.simply-section{width:80px;height:80px;padding:1.75rem}.simply-countdown-cyber>.simply-section .simply-amount{font-size:2rem}.simply-countdown-cyber>.simply-section .simply-word{font-size:.75rem}}@media (min-width:1024px){.simply-countdown-cyber>.simply-section{width:100px;height:100px;padding:2rem}.simply-countdown-cyber>.simply-section .simply-amount{font-size:2.5rem}.simply-countdown-cyber>.simply-section .simply-word{font-size:.8rem}}@keyframes pulse{0%,100%{opacity:.15;transform:scale(1)}50%{opacity:.25;transform:scale(1.05)}}
\ No newline at end of file
diff --git a/dist/themes/dark.css b/dist/themes/dark.css
new file mode 100644
index 0000000..386f246
--- /dev/null
+++ b/dist/themes/dark.css
@@ -0,0 +1,85 @@
+/**
+* Project : simply-countdown
+* File : simplyCountdown.theme.dark
+* Author : Vincent Loy
+* Theme : Dark Modern
+*/
+
+.simply-countdown-dark {
+ overflow: hidden;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1.25rem;
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
+}
+
+.simply-countdown-dark > .simply-section {
+ width: 65px;
+ height: 65px;
+ padding: 1.5rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(15, 23, 42, 0.75);
+ border: 1px solid rgba(51, 65, 85, 0.6);
+ border-radius: 1rem;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2), 0 2px 4px -1px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.05);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ backdrop-filter: blur(10px);
+}
+
+.simply-countdown-dark > .simply-section > div {
+ display: flex;
+ flex-direction: column;
+ line-height: 1;
+ align-items: center;
+}
+
+.simply-countdown-dark > .simply-section .simply-amount {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: #f1f5f9;
+ line-height: 1.2;
+ letter-spacing: -0.025em;
+}
+
+.simply-countdown-dark > .simply-section .simply-word {
+ font-size: 0.6rem;
+ font-weight: 500;
+ color: #94a3b8;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+}
+
+@media (min-width: 640px) {
+ .simply-countdown-dark > .simply-section {
+ width: 75px;
+ height: 75px;
+ padding: 1.75rem;
+ }
+
+ .simply-countdown-dark > .simply-section .simply-amount {
+ font-size: 1.75rem;
+ }
+
+ .simply-countdown-dark > .simply-section .simply-word {
+ font-size: 0.75rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .simply-countdown-dark > .simply-section {
+ width: 90px;
+ height: 90px;
+ padding: 2rem;
+ }
+
+ .simply-countdown-dark > .simply-section .simply-amount {
+ font-size: 2rem;
+ }
+
+ .simply-countdown-dark > .simply-section .simply-word {
+ font-size: 0.8rem;
+ }
+}
diff --git a/dist/themes/dark.min.css b/dist/themes/dark.min.css
new file mode 100644
index 0000000..1495b0c
--- /dev/null
+++ b/dist/themes/dark.min.css
@@ -0,0 +1 @@
+.simply-countdown-dark{overflow:hidden;display:flex;flex-wrap:wrap;justify-content:center;gap:1.25rem;font-family:Inter,system-ui,-apple-system,sans-serif}.simply-countdown-dark>.simply-section{width:65px;height:65px;padding:1.5rem;display:flex;align-items:center;justify-content:center;background:rgba(15,23,42,.75);border:1px solid rgba(51,65,85,.6);border-radius:1rem;box-shadow:0 4px 6px -1px rgba(0,0,0,.2),0 2px 4px -1px rgba(0,0,0,.1),0 0 0 1px rgba(255,255,255,.05);transition:.3s cubic-bezier(.4, 0, .2, 1);backdrop-filter:blur(10px)}.simply-countdown-dark>.simply-section>div{display:flex;flex-direction:column;line-height:1;align-items:center}.simply-countdown-dark>.simply-section .simply-amount{font-size:1.5rem;font-weight:700;color:#f1f5f9;line-height:1.2;letter-spacing:-.025em}.simply-countdown-dark>.simply-section .simply-word{font-size:.6rem;font-weight:500;color:#94a3b8;text-transform:uppercase;letter-spacing:.1em}@media (min-width:640px){.simply-countdown-dark>.simply-section{width:75px;height:75px;padding:1.75rem}.simply-countdown-dark>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown-dark>.simply-section .simply-word{font-size:.75rem}}@media (min-width:1024px){.simply-countdown-dark>.simply-section{width:90px;height:90px;padding:2rem}.simply-countdown-dark>.simply-section .simply-amount{font-size:2rem}.simply-countdown-dark>.simply-section .simply-word{font-size:.8rem}}
\ No newline at end of file
diff --git a/dist/themes/default.css b/dist/themes/default.css
new file mode 100644
index 0000000..80e1514
--- /dev/null
+++ b/dist/themes/default.css
@@ -0,0 +1,85 @@
+/**
+* Project : simply-countdown
+* File : simplyCountdown.theme.default
+* Author : Vincent Loy
+* Theme : Light Modern
+*/
+
+.simply-countdown {
+ overflow: hidden;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1.25rem;
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
+}
+
+.simply-countdown > .simply-section {
+ width: 65px;
+ height: 65px;
+ padding: 1.5rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(226, 232, 240, 0.8);
+ border-radius: 1rem;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03), 0 0 0 1px rgba(0, 0, 0, 0.02);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ backdrop-filter: blur(10px);
+}
+
+.simply-countdown > .simply-section > div {
+ display: flex;
+ flex-direction: column;
+ line-height: 1;
+ align-items: center;
+}
+
+.simply-countdown > .simply-section .simply-amount {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: #1e293b;
+ line-height: 1.2;
+ letter-spacing: -0.025em;
+}
+
+.simply-countdown > .simply-section .simply-word {
+ font-size: 0.6rem;
+ font-weight: 500;
+ color: #64748b;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+}
+
+@media (min-width: 640px) {
+ .simply-countdown > .simply-section {
+ width: 75px;
+ height: 75px;
+ padding: 1.75rem;
+ }
+
+ .simply-countdown > .simply-section .simply-amount {
+ font-size: 1.75rem;
+ }
+
+ .simply-countdown > .simply-section .simply-word {
+ font-size: 0.75rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .simply-countdown > .simply-section {
+ width: 90px;
+ height: 90px;
+ padding: 2rem;
+ }
+
+ .simply-countdown > .simply-section .simply-amount {
+ font-size: 2rem;
+ }
+
+ .simply-countdown > .simply-section .simply-word {
+ font-size: 0.8rem;
+ }
+}
diff --git a/dist/themes/default.min.css b/dist/themes/default.min.css
new file mode 100644
index 0000000..a1d7f18
--- /dev/null
+++ b/dist/themes/default.min.css
@@ -0,0 +1 @@
+.simply-countdown{overflow:hidden;display:flex;flex-wrap:wrap;justify-content:center;gap:1.25rem;font-family:Inter,system-ui,-apple-system,sans-serif}.simply-countdown>.simply-section{width:65px;height:65px;padding:1.5rem;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.9);border:1px solid rgba(226,232,240,.8);border-radius:1rem;box-shadow:0 4px 6px -1px rgba(0,0,0,.05),0 2px 4px -1px rgba(0,0,0,.03),0 0 0 1px rgba(0,0,0,.02);transition:.3s cubic-bezier(.4, 0, .2, 1);backdrop-filter:blur(10px)}.simply-countdown>.simply-section>div{display:flex;flex-direction:column;line-height:1;align-items:center}.simply-countdown>.simply-section .simply-amount{font-size:1.5rem;font-weight:700;color:#1e293b;line-height:1.2;letter-spacing:-.025em}.simply-countdown>.simply-section .simply-word{font-size:.6rem;font-weight:500;color:#64748b;text-transform:uppercase;letter-spacing:.1em}@media (min-width:640px){.simply-countdown>.simply-section{width:75px;height:75px;padding:1.75rem}.simply-countdown>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown>.simply-section .simply-word{font-size:.75rem}}@media (min-width:1024px){.simply-countdown>.simply-section{width:90px;height:90px;padding:2rem}.simply-countdown>.simply-section .simply-amount{font-size:2rem}.simply-countdown>.simply-section .simply-word{font-size:.8rem}}
\ No newline at end of file
diff --git a/dist/themes/losange.css b/dist/themes/losange.css
new file mode 100644
index 0000000..198873b
--- /dev/null
+++ b/dist/themes/losange.css
@@ -0,0 +1,83 @@
+/**
+* Project : simply-countdown
+* File : simplyCountdown.theme.losange
+* Author : Vincent Loy
+*/
+
+.simply-countdown-losange {
+ overflow: visible;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 3rem;
+ font-family: "Inter", sans-serif;
+}
+
+.simply-countdown-losange > .simply-section {
+ width: 70px;
+ height: 70px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transform: rotate(-45deg);
+ background: linear-gradient(135deg, #4f46e5, #7c3aed);
+ border-radius: 0.5rem;
+ transition: all 0.2s ease-in-out;
+}
+
+.simply-countdown-losange > .simply-section > div {
+ transform: rotate(45deg);
+ display: flex;
+ flex-direction: column;
+ line-height: 1.2;
+}
+
+.simply-countdown-losange > .simply-section .simply-amount,
+.simply-countdown-losange > .simply-section .simply-word {
+ display: block;
+ text-align: center;
+}
+
+.simply-countdown-losange > .simply-section .simply-amount {
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: #fff;
+}
+
+.simply-countdown-losange > .simply-section .simply-word {
+ font-size: 0.65rem;
+ font-weight: 500;
+ color: rgba(255, 255, 255, 0.9);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+@media (min-width: 640px) {
+ .simply-countdown-losange > .simply-section {
+ width: 80px;
+ height: 80px;
+ }
+
+ .simply-countdown-losange > .simply-section .simply-amount {
+ font-size: 1.5rem;
+ }
+
+ .simply-countdown-losange > .simply-section .simply-word {
+ font-size: 0.7rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .simply-countdown-losange > .simply-section {
+ width: 90px;
+ height: 90px;
+ }
+
+ .simply-countdown-losange > .simply-section .simply-amount {
+ font-size: 1.75rem;
+ }
+
+ .simply-countdown-losange > .simply-section .simply-word {
+ font-size: 0.75rem;
+ }
+}
diff --git a/dist/themes/losange.min.css b/dist/themes/losange.min.css
new file mode 100644
index 0000000..4ddbfdd
--- /dev/null
+++ b/dist/themes/losange.min.css
@@ -0,0 +1 @@
+.simply-countdown-losange{overflow:visible;display:flex;flex-wrap:wrap;justify-content:center;gap:3rem;font-family:Inter,sans-serif}.simply-countdown-losange>.simply-section{width:70px;height:70px;display:flex;justify-content:center;align-items:center;transform:rotate(-45deg);background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:.5rem;transition:.2s ease-in-out}.simply-countdown-losange>.simply-section>div{transform:rotate(45deg);display:flex;flex-direction:column;line-height:1.2}.simply-countdown-losange>.simply-section .simply-amount,.simply-countdown-losange>.simply-section .simply-word{display:block;text-align:center}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.25rem;font-weight:700;color:#fff}.simply-countdown-losange>.simply-section .simply-word{font-size:.65rem;font-weight:500;color:rgba(255,255,255,.9);text-transform:uppercase;letter-spacing:.05em}@media (min-width:640px){.simply-countdown-losange>.simply-section{width:80px;height:80px}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.5rem}.simply-countdown-losange>.simply-section .simply-word{font-size:.7rem}}@media (min-width:1024px){.simply-countdown-losange>.simply-section{width:90px;height:90px}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown-losange>.simply-section .simply-word{font-size:.75rem}}
\ No newline at end of file
diff --git a/docs/dist/assets/main.min.css b/docs/dist/assets/main.min.css
new file mode 100644
index 0000000..59c2daf
--- /dev/null
+++ b/docs/dist/assets/main.min.css
@@ -0,0 +1 @@
+*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Montserrat,Arial,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"β""β""β""β";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%),0 3px rgb(var(--tw-prose-kbd-shadows) / 10%);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: 17 24 39;--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: 255 255 255;--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.icon-\[lucide--alarm-clock-plus\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='13' r='8'/%3E%3Cpath d='M5 3L2 6m20 0l-3-3M6.38 18.7L4 21m13.64-2.33L20 21m-8-11v6m-3-3h6'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--book-open\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 7v14m-9-3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4a4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3a3 3 0 0 0-3-3z'/%3E%3C/svg%3E")}.icon-\[lucide--braces\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2a2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1m8 0h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1'/%3E%3C/svg%3E")}.icon-\[lucide--check\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 6L9 17l-5-5'/%3E%3C/svg%3E")}.icon-\[lucide--chevron-up\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m18 15l-6-6l-6 6'/%3E%3C/svg%3E")}.icon-\[lucide--circle-play\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m10 8l6 4l-6 4z'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--circle-stop\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Crect width='6' height='6' x='9' y='9' rx='1'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--clock\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--code\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m16 18l6-6l-6-6M8 6l-6 6l6 6'/%3E%3C/svg%3E")}.icon-\[lucide--copy\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--crown\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294zM5 21h14'/%3E%3C/svg%3E")}.icon-\[lucide--download\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4m4-5l5 5l5-5m-5 5V3'/%3E%3C/svg%3E")}.icon-\[lucide--git-branch\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M6 3v12'/%3E%3Ccircle cx='18' cy='6' r='3'/%3E%3Ccircle cx='6' cy='18' r='3'/%3E%3Cpath d='M18 9a9 9 0 0 1-9 9'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--github\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5c.08-1.25-.27-2.48-1-3.5c.28-1.15.28-2.35 0-3.5c0 0-1 0-3 1.5c-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 9c0 3.5 3 5.5 6 5.5c-.39.49-.68 1.05-.85 1.65S8.93 17.38 9 18v4'/%3E%3Cpath d='M9 18c-4.51 2-5-2-7-2'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--heart\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2c-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.icon-\[lucide--package\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73zm1 .27V12'/%3E%3Cpath d='m3.3 7l7.703 4.734a2 2 0 0 0 1.994 0L20.7 7M7.5 4.27l9 5.15'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--palette\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='13.5' cy='6.5' r='.5' fill='black'/%3E%3Ccircle cx='17.5' cy='10.5' r='.5' fill='black'/%3E%3Ccircle cx='8.5' cy='7.5' r='.5' fill='black'/%3E%3Ccircle cx='6.5' cy='12.5' r='.5' fill='black'/%3E%3Cpath d='M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688c0-.437-.18-.835-.437-1.125c-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--plug-zap\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6l-2.3 2.3a2.4 2.4 0 0 0 0 3.4ZM2 22l3-3m2.5-5.5L10 11m.5 5.5L13 14m5-11l-4 4h6l-4 4'/%3E%3C/svg%3E")}.icon-\[lucide--star\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.12 2.12 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.12 2.12 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.12 2.12 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.12 2.12 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.12 2.12 0 0 0 1.597-1.16z'/%3E%3C/svg%3E")}.icon-\[lucide--terminal\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m4 17l6-6l-6-6m8 14h8'/%3E%3C/svg%3E")}.icon-\[lucide--timer-reset\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M10 2h4m-2 12v-4m-8 3a8 8 0 0 1 8-7a8 8 0 1 1-5.3 14L4 17.6'/%3E%3Cpath d='M9 17H4v5'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[lucide--toggle-left\]{display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='20' height='12' x='2' y='6' rx='6' ry='6'/%3E%3Ccircle cx='8' cy='12' r='2'/%3E%3C/g%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-bun\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cpath fill='%23fbf0df' d='M29 17c0 5.65-5.82 10.23-13 10.23S3 22.61 3 17c0-3.5 2.24-6.6 5.66-8.44S14.21 4.81 16 4.81s3.32 1.54 7.34 3.71C26.76 10.36 29 13.46 29 17'/%3E%3Cpath fill='none' stroke='%23000' d='M16 27.65c7.32 0 13.46-4.65 13.46-10.65c0-3.72-2.37-7-5.89-8.85c-1.39-.75-2.46-1.41-3.37-2l-1.13-.69A6.14 6.14 0 0 0 16 4.35a6.9 6.9 0 0 0-3.3 1.23c-.42.24-.86.51-1.32.8c-.87.54-1.83 1.13-3 1.73C4.91 10 2.54 13.24 2.54 17c0 6 6.14 10.65 13.46 10.65Z'/%3E%3Cellipse cx='21.65' cy='18.62' fill='%23febbd0' rx='2.17' ry='1.28'/%3E%3Cellipse cx='10.41' cy='18.62' fill='%23febbd0' rx='2.17' ry='1.28'/%3E%3Cpath fill-rule='evenodd' d='M11.43 18.11a2 2 0 1 0-2-2.05a2.05 2.05 0 0 0 2 2.05m9.2 0a2 2 0 1 0-2-2.05a2 2 0 0 0 2 2.05'/%3E%3Cpath fill='%23fff' fill-rule='evenodd' d='M10.79 16.19a.77.77 0 1 0-.76-.77a.76.76 0 0 0 .76.77m9.2 0a.77.77 0 1 0 0-1.53a.77.77 0 0 0 0 1.53'/%3E%3Cpath fill='%23b71422' stroke='%23000' stroke-width='.75' d='M18.62 19.67a3.3 3.3 0 0 1-1.09 1.75a2.48 2.48 0 0 1-1.5.69a2.53 2.53 0 0 1-1.5-.69a3.28 3.28 0 0 1-1.08-1.75a.26.26 0 0 1 .29-.3h4.58a.27.27 0 0 1 .3.3Z'/%3E%3Cpath fill='%23ccbea7' fill-rule='evenodd' d='M14.93 5.75a6.1 6.1 0 0 1-2.09 4.62c-.1.09 0 .27.11.22c1.25-.49 2.94-1.94 2.23-4.88c-.03-.15-.25-.11-.25.04m.85 0a6 6 0 0 1 .57 5c0 .13.12.24.21.13c.83-1 1.54-3.11-.59-5.31c-.1-.11-.27.04-.19.17Zm1-.06a6.1 6.1 0 0 1 2.53 4.38c0 .14.21.17.24 0c.34-1.3.15-3.51-2.66-4.66c-.12-.02-.21.18-.09.27ZM9.94 9.55a6.27 6.27 0 0 0 3.89-3.33c.07-.13.28-.08.25.07c-.64 3-2.79 3.59-4.13 3.51c-.14-.01-.14-.21-.01-.25'/%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-npm\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cpath fill='%23cb3837' d='M2 10.555h28v9.335H16v1.556H9.778v-1.557H2Zm1.556 7.779h3.111v-4.668h1.555v4.667h1.556v-6.222H3.556Zm7.778-6.223v7.779h3.111v-1.556h3.111v-6.223Zm3.111 1.556H16v3.112h-1.556Zm4.667-1.556v6.223h3.111v-4.668h1.556v4.667h1.556v-4.667h1.556v4.667h1.556v-6.222Z'/%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-pnpm\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cpath fill='%23f9ad00' d='M30 10.75h-8.749V2H30Zm-9.626 0h-8.75V2h8.75Zm-9.625 0H2V2h8.749ZM30 20.375h-8.749v-8.75H30Z'/%3E%3Cpath fill='%23fff' d='M20.374 20.375h-8.75v-8.75h8.75Zm0 9.625h-8.75v-8.75h8.75ZM30 30h-8.749v-8.75H30Zm-19.251 0H2v-8.75h8.749Z'/%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-typescript\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cpath fill='%23007acc' d='M23.827 8.243a4.4 4.4 0 0 1 2.223 1.281a6 6 0 0 1 .852 1.143c.011.045-1.534 1.083-2.471 1.662c-.034.023-.169-.124-.322-.35a2.01 2.01 0 0 0-1.67-1c-1.077-.074-1.771.49-1.766 1.433a1.3 1.3 0 0 0 .153.666c.237.49.677.784 2.059 1.383c2.544 1.095 3.636 1.817 4.31 2.843a5.16 5.16 0 0 1 .416 4.333a4.76 4.76 0 0 1-3.932 2.815a11 11 0 0 1-2.708-.028a6.53 6.53 0 0 1-3.616-1.884a6.3 6.3 0 0 1-.926-1.371a3 3 0 0 1 .327-.208c.158-.09.756-.434 1.32-.761l1.024-.6l.214.312a4.8 4.8 0 0 0 1.35 1.292a3.3 3.3 0 0 0 3.458-.175a1.545 1.545 0 0 0 .2-1.974c-.276-.395-.84-.727-2.443-1.422a8.8 8.8 0 0 1-3.349-2.055a4.7 4.7 0 0 1-.976-1.777a7.1 7.1 0 0 1-.062-2.268a4.33 4.33 0 0 1 3.644-3.374a9 9 0 0 1 2.691.084m-8.343 1.483l.011 1.454h-4.63v13.148H7.6V11.183H2.97V9.755a14 14 0 0 1 .04-1.466c.017-.023 2.832-.034 6.245-.028l6.211.017Z'/%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-vite\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cg fill='none'%3E%3Cpath fill='url(%23vscodeIconsFileTypeVite0)' d='m29.884 6.146l-13.142 23.5a.714.714 0 0 1-1.244.005L2.096 6.148a.714.714 0 0 1 .746-1.057l13.156 2.352a.7.7 0 0 0 .253 0l12.881-2.348a.714.714 0 0 1 .752 1.05z'/%3E%3Cpath fill='url(%23vscodeIconsFileTypeVite1)' d='M22.264 2.007L12.54 3.912a.36.36 0 0 0-.288.33l-.598 10.104a.357.357 0 0 0 .437.369l2.707-.625a.357.357 0 0 1 .43.42l-.804 3.939a.357.357 0 0 0 .454.413l1.672-.508a.357.357 0 0 1 .454.414l-1.279 6.187c-.08.387.435.598.65.267l.143-.222l7.925-15.815a.357.357 0 0 0-.387-.51l-2.787.537a.357.357 0 0 1-.41-.45l1.818-6.306a.357.357 0 0 0-.412-.45'/%3E%3Cdefs%3E%3ClinearGradient id='vscodeIconsFileTypeVite0' x1='6' x2='235' y1='33' y2='344' gradientTransform='translate(1.34 1.894)scale(.07142)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%2341D1FF'/%3E%3Cstop offset='1' stop-color='%23BD34FE'/%3E%3C/linearGradient%3E%3ClinearGradient id='vscodeIconsFileTypeVite1' x1='194.651' x2='236.076' y1='8.818' y2='292.989' gradientTransform='translate(1.34 1.894)scale(.07142)' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23FFEA83'/%3E%3Cstop offset='.083' stop-color='%23FFDD35'/%3E%3Cstop offset='1' stop-color='%23FFA800'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/g%3E%3C/svg%3E")}.icon-\[vscode-icons--file-type-yarn\]{display:inline-block;width:1em;height:1em;background-repeat:no-repeat;background-size:100% 100%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'%3E%3Cpath fill='%232188b6' d='M28.208 24.409a10.5 10.5 0 0 0-3.959 1.822a23.7 23.7 0 0 1-5.835 2.642a1.63 1.63 0 0 1-.983.55a62 62 0 0 1-6.447.577c-1.163.009-1.876-.3-2.074-.776a1.573 1.573 0 0 1 .866-2.074a4 4 0 0 1-.514-.379c-.171-.171-.352-.514-.406-.388c-.225.55-.343 1.894-.947 2.5c-.83.839-2.4.559-3.328.072c-1.019-.541.072-1.813.072-1.813a.73.73 0 0 1-.992-.343a4.85 4.85 0 0 1-.667-2.949a5.37 5.37 0 0 1 1.749-2.895a9.3 9.3 0 0 1 .658-4.4a10.45 10.45 0 0 1 3.165-3.661S6.628 10.747 7.35 8.817c.469-1.262.658-1.253.812-1.308a3.6 3.6 0 0 0 1.452-.857a5.27 5.27 0 0 1 4.41-1.7S15.2 1.4 16.277 2.09a18.4 18.4 0 0 1 1.533 2.886s1.281-.748 1.425-.469a11.33 11.33 0 0 1 .523 6.132a14 14 0 0 1-2.6 5.411c-.135.225 1.551.938 2.615 3.887c.983 2.7.108 4.96.262 5.212c.027.045.036.063.036.063s1.127.09 3.391-1.308a8.5 8.5 0 0 1 4.277-1.604a1.081 1.081 0 0 1 .469 2.11Z'/%3E%3C/svg%3E")}.btn{display:inline-flex;align-items:center;gap:.5rem;border-radius:.5rem;padding:.75rem 1.5rem;font-weight:600;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn:hover{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn-light{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.btn-indigo{--tw-bg-opacity: 1;background-color:rgb(55 48 163 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.sc-doc-block{border-radius:.75rem;--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1));padding:1.5rem;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.bottom-8{bottom:2rem}.left-0{left:0}.right-0{right:0}.right-3{right:.75rem}.right-8{right:2rem}.top-0{top:0}.top-3{top:.75rem}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-0{margin-bottom:0}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-20{margin-bottom:5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.mt-10{margin-top:2.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.w-12{width:3rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-full{width:100%}.flex-shrink-0{flex-shrink:0}.translate-y-10{--tw-translate-y: 2.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-indigo-400\/30{border-color:#818cf84d}.border-indigo-500\/20{border-color:#6366f133}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-indigo-500\/10{background-color:#6366f11a}.bg-indigo-500\/20{background-color:#6366f133}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-indigo-800{--tw-bg-opacity: 1;background-color:rgb(55 48 163 / var(--tw-bg-opacity, 1))}.bg-indigo-950\/50{background-color:#1e1b4b80}.bg-slate-700\/50{background-color:#33415580}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-800\/50{background-color:#1e293b80}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-indigo-600{--tw-gradient-from: #4f46e5 var(--tw-gradient-from-position);--tw-gradient-to: rgb(79 70 229 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-violet-600{--tw-gradient-to: #7c3aed var(--tw-gradient-to-position)}.p-0{padding:0}.p-2{padding:.5rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-20{padding-bottom:5rem}.pl-6{padding-left:1.5rem}.pt-40{padding-top:10rem}.text-center{text-align:center}.font-sans{font-family:Montserrat,Arial,sans-serif}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-indigo-100{--tw-text-opacity: 1;color:rgb(224 231 255 / var(--tw-text-opacity, 1))}.text-indigo-200{--tw-text-opacity: 1;color:rgb(199 210 254 / var(--tw-text-opacity, 1))}.text-indigo-300{--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.text-indigo-400{--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.text-indigo-500{--tw-text-opacity: 1;color:rgb(99 102 241 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-indigo-950\/10{--tw-shadow-color: rgb(30 27 75 / .1);--tw-shadow: var(--tw-shadow-colored)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.package-manager-btn{display:flex;align-items:center;gap:.375rem;border-radius:.5rem;background-color:#33415580;padding:.375rem .75rem;font-size:.75rem;line-height:1rem;font-weight:500;--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.package-manager-btn:hover{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}@media (min-width: 1024px){.package-manager-btn{font-size:.875rem;line-height:1.25rem}}.package-manager-btn.active{background-color:#6366f133;--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.package-manager-btn.active:hover{background-color:#6366f14d;--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.package-manager-content{display:none}.package-manager-content.active{display:block}.relative:hover .copy-button{opacity:1}pre{overflow-x:auto}.sc-doc-block{position:relative}.sc-doc-block:hover .copy-button{opacity:1}.sc-doc-block-glow{position:fixed;width:600px;height:600px;background:radial-gradient(circle at center,rgba(99,102,241,.06),transparent 40%);border-radius:50%;pointer-events:none;z-index:0;opacity:0;transform:translate(-50%,-50%);will-change:left,top,opacity;transition:opacity .2s ease-out}.sc-doc-block:hover .sc-doc-block-glow{opacity:1}.hover\:-translate-y-\[3px\]:hover{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-indigo-300:hover{--tw-border-opacity: 1;border-color:rgb(165 180 252 / var(--tw-border-opacity, 1))}.hover\:bg-indigo-500\/20:hover{background-color:#6366f133}.hover\:bg-indigo-500\/30:hover{background-color:#6366f14d}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-700:hover{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.hover\:text-indigo-200:hover{--tw-text-opacity: 1;color:rgb(199 210 254 / var(--tw-text-opacity, 1))}.hover\:text-indigo-300:hover{--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.hover\:text-slate-300:hover{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-indigo-200{--tw-text-opacity: 1;color:rgb(199 210 254 / var(--tw-text-opacity, 1))}.group[data-copied] .group-data-\[copied\]\:block{display:block}.group[data-copied] .group-data-\[copied\]\:hidden{display:none}@media (min-width: 640px){.sm\:flex-row{flex-direction:row}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width: 768px){.md\:flex{display:flex}.md\:w-auto{width:auto}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-col{flex-direction:column}.md\:justify-start{justify-content:flex-start}.md\:gap-6{gap:1.5rem}.md\:text-left{text-align:left}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width: 1024px){.lg\:h-5{height:1.25rem}.lg\:w-5{width:1.25rem}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:text-sm{font-size:.875rem;line-height:1.25rem}}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-formula{color:#c678dd}.hljs-section,.hljs-name,.hljs-selector-tag,.hljs-deletion,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-string,.hljs-regexp,.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string{color:#98c379}.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-type,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-number{color:#d19a66}.hljs-symbol,.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-title.class_,.hljs-class .hljs-title{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.simply-countdown{overflow:hidden;display:flex;flex-wrap:wrap;justify-content:center;gap:1.25rem;font-family:Inter,system-ui,-apple-system,sans-serif}.simply-countdown>.simply-section{width:65px;height:65px;padding:1.5rem;display:flex;align-items:center;justify-content:center;background:#ffffffe6;border:1px solid rgba(226,232,240,.8);border-radius:1rem;box-shadow:0 4px 6px -1px #0000000d,0 2px 4px -1px #00000008,0 0 0 1px #00000005;transition:all .3s cubic-bezier(.4,0,.2,1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.simply-countdown>.simply-section>div{display:flex;flex-direction:column;line-height:1;align-items:center}.simply-countdown>.simply-section .simply-amount{font-size:1.5rem;font-weight:700;color:#1e293b;line-height:1.2;letter-spacing:-.025em}.simply-countdown>.simply-section .simply-word{font-size:.6rem;font-weight:500;color:#64748b;text-transform:uppercase;letter-spacing:.1em}@media (min-width: 640px){.simply-countdown>.simply-section{width:75px;height:75px;padding:1.75rem}.simply-countdown>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown>.simply-section .simply-word{font-size:.75rem}}@media (min-width: 1024px){.simply-countdown>.simply-section{width:90px;height:90px;padding:2rem}.simply-countdown>.simply-section .simply-amount{font-size:2rem}.simply-countdown>.simply-section .simply-word{font-size:.8rem}}.simply-countdown-dark{overflow:hidden;display:flex;flex-wrap:wrap;justify-content:center;gap:1.25rem;font-family:Inter,system-ui,-apple-system,sans-serif}.simply-countdown-dark>.simply-section{width:65px;height:65px;padding:1.5rem;display:flex;align-items:center;justify-content:center;background:#0f172abf;border:1px solid rgba(51,65,85,.6);border-radius:1rem;box-shadow:0 4px 6px -1px #0003,0 2px 4px -1px #0000001a,0 0 0 1px #ffffff0d;transition:all .3s cubic-bezier(.4,0,.2,1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.simply-countdown-dark>.simply-section>div{display:flex;flex-direction:column;line-height:1;align-items:center}.simply-countdown-dark>.simply-section .simply-amount{font-size:1.5rem;font-weight:700;color:#f1f5f9;line-height:1.2;letter-spacing:-.025em}.simply-countdown-dark>.simply-section .simply-word{font-size:.6rem;font-weight:500;color:#94a3b8;text-transform:uppercase;letter-spacing:.1em}@media (min-width: 640px){.simply-countdown-dark>.simply-section{width:75px;height:75px;padding:1.75rem}.simply-countdown-dark>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown-dark>.simply-section .simply-word{font-size:.75rem}}@media (min-width: 1024px){.simply-countdown-dark>.simply-section{width:90px;height:90px;padding:2rem}.simply-countdown-dark>.simply-section .simply-amount{font-size:2rem}.simply-countdown-dark>.simply-section .simply-word{font-size:.8rem}}.simply-countdown-cyber{overflow:visible;display:flex;flex-wrap:wrap;justify-content:center;gap:1.75rem;font-family:Inter,system-ui,-apple-system,sans-serif;perspective:1000px}.simply-countdown-cyber>.simply-section{width:70px;height:70px;padding:1.5rem;position:relative;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#171923e6,#0f1119f2);border-radius:.5rem;transition:all .4s cubic-bezier(.175,.885,.32,1.275);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);transform-style:preserve-3d}.simply-countdown-cyber>.simply-section:before{content:"";position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;background:linear-gradient(135deg,#78f0ff33,#ff5adc33);border-radius:.5rem;z-index:-1;opacity:0;transition:opacity .3s ease}.simply-countdown-cyber>.simply-section:after{content:"";position:absolute;top:-2px;right:-2px;bottom:-2px;left:-2px;background:linear-gradient(135deg,#78f0ff,#ff5adc);border-radius:.5rem;z-index:-2;opacity:.15;filter:blur(4px);animation:pulse 4s ease-in-out infinite}.simply-countdown-cyber>.simply-section .glass-overlay{position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(135deg,#ffffff1a,#ffffff0d);border-radius:.5rem}.simply-countdown-cyber>.simply-section:hover{transform:translateY(-4px) translateZ(10px) rotateX(5deg);box-shadow:0 20px 40px -10px #00000080,0 0 20px #78f0ff33,0 0 0 1px #78f0ff1a}.simply-countdown-cyber>.simply-section:hover:before{opacity:1}.simply-countdown-cyber>.simply-section>div{display:flex;flex-direction:column;gap:.4rem;align-items:center;transform-style:preserve-3d}.simply-countdown-cyber>.simply-section .simply-amount{font-size:1.75rem;font-weight:700;background:linear-gradient(to bottom right,#78f0ff,#ff5adc);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 0 20px rgba(120,240,255,.3),0 0 40px rgba(120,240,255,.2);letter-spacing:-.02em;transform:translateZ(10px)}.simply-countdown-cyber>.simply-section .simply-word{font-size:.6rem;font-weight:500;text-transform:uppercase;letter-spacing:.2em;color:#ffffffb3;transform:translateZ(5px);position:relative}.simply-countdown-cyber>.simply-section .simply-word:after{content:"";position:absolute;left:-10%;bottom:-4px;width:120%;height:1px;background:linear-gradient(to right,#78f0ff00,#78f0ff80,#ff5adc80,#ff5adc00)}@media (min-width: 640px){.simply-countdown-cyber>.simply-section{width:80px;height:80px;padding:1.75rem}.simply-countdown-cyber>.simply-section .simply-amount{font-size:2rem}.simply-countdown-cyber>.simply-section .simply-word{font-size:.75rem}}@media (min-width: 1024px){.simply-countdown-cyber>.simply-section{width:100px;height:100px;padding:2rem}.simply-countdown-cyber>.simply-section .simply-amount{font-size:2.5rem}.simply-countdown-cyber>.simply-section .simply-word{font-size:.8rem}}@keyframes pulse{0%,to{opacity:.15;transform:scale(1)}50%{opacity:.25;transform:scale(1.05)}}.simply-countdown-losange{overflow:visible;display:flex;flex-wrap:wrap;justify-content:center;gap:3rem;font-family:Inter,sans-serif}.simply-countdown-losange>.simply-section{width:70px;height:70px;display:flex;justify-content:center;align-items:center;transform:rotate(-45deg);background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:.5rem;transition:all .2s ease-in-out}.simply-countdown-losange>.simply-section>div{transform:rotate(45deg);display:flex;flex-direction:column;line-height:1.2}.simply-countdown-losange>.simply-section .simply-amount,.simply-countdown-losange>.simply-section .simply-word{display:block;text-align:center}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.25rem;font-weight:700;color:#fff}.simply-countdown-losange>.simply-section .simply-word{font-size:.65rem;font-weight:500;color:#ffffffe6;text-transform:uppercase;letter-spacing:.05em}@media (min-width: 640px){.simply-countdown-losange>.simply-section{width:80px;height:80px}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.5rem}.simply-countdown-losange>.simply-section .simply-word{font-size:.7rem}}@media (min-width: 1024px){.simply-countdown-losange>.simply-section{width:90px;height:90px}.simply-countdown-losange>.simply-section .simply-amount{font-size:1.75rem}.simply-countdown-losange>.simply-section .simply-word{font-size:.75rem}}.simply-countdown-circle{--sc-circle-primary: #6366f1;--sc-circle-secondary: #818cf8;--sc-circle-bg: #1e1b4b;--sc-circle-text: #fff;display:flex;flex-wrap:wrap;justify-content:center;gap:1.5rem;font-family:Inter,sans-serif}.simply-countdown-circle>.simply-section{position:relative;width:100px;height:100px;padding:1rem;display:flex;align-items:center;justify-content:center;flex-direction:column;border-radius:50%;background:linear-gradient(45deg,var(--sc-circle-primary),var(--sc-circle-secondary));box-shadow:0 0 25px -5px var(--sc-circle-primary);animation:pulse-circle 2s cubic-bezier(.4,0,.6,1) infinite}.simply-countdown-circle>.simply-section:before{content:"";position:absolute;top:6px;right:6px;bottom:6px;left:6px;border-radius:50%;background:var(--sc-circle-bg);z-index:0}.simply-countdown-circle>.simply-section>div{position:relative;z-index:1;color:var(--sc-circle-text);text-align:center}.simply-countdown-circle .simply-amount{display:block;font-size:1.75rem;font-weight:700;line-height:1;background:linear-gradient(to right,var(--sc-circle-primary),var(--sc-circle-secondary));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}.simply-countdown-circle .simply-word{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;opacity:.8}@keyframes pulse-circle{0%,to{transform:scale(1);opacity:1}50%{transform:scale(.98);opacity:.9}}
diff --git a/docs/dist/assets/main.min.js b/docs/dist/assets/main.min.js
new file mode 100644
index 0000000..be257cd
--- /dev/null
+++ b/docs/dist/assets/main.min.js
@@ -0,0 +1,15 @@
+(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))i(a);new MutationObserver(a=>{for(const l of a)if(l.type==="childList")for(const s of l.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&i(s)}).observe(document,{childList:!0,subtree:!0});function n(a){const l={};return a.integrity&&(l.integrity=a.integrity),a.referrerPolicy&&(l.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?l.credentials="include":a.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function i(a){if(a.ep)return;a.ep=!0;const l=n(a);fetch(a.href,l)}})();function vt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const n=e[t],i=typeof n;(i==="object"||i==="function")&&!Object.isFrozen(n)&&Xe(n)}),e}class ze{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function Ye(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function P(e,...t){const n=Object.create(null);for(const i in e)n[i]=e[i];return t.forEach(function(i){for(const a in i)n[a]=i[a]}),n}const St="",$e=e=>!!e.scope,Nt=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const n=e.split(".");return[`${t}${n.shift()}`,...n.map((i,a)=>`${i}${"_".repeat(a+1)}`)].join(" ")}return`${t}${e}`};class xt{constructor(t,n){this.buffer="",this.classPrefix=n.classPrefix,t.walk(this)}addText(t){this.buffer+=Ye(t)}openNode(t){if(!$e(t))return;const n=Nt(t.scope,{prefix:this.classPrefix});this.span(n)}closeNode(t){$e(t)&&(this.buffer+=St)}value(){return this.buffer}span(t){this.buffer+=``}}const He=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class ke{constructor(){this.rootNode=He(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const n=He({scope:t});this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,n){return typeof n=="string"?t.addText(n):n.children&&(t.openNode(n),n.children.forEach(i=>this._walk(t,i)),t.closeNode(n)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(n=>typeof n=="string")?t.children=[t.children.join("")]:t.children.forEach(n=>{ke._collapse(n)}))}}class Mt extends ke{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,n){const i=t.root;n&&(i.scope=`language:${n}`),this.add(i)}toHTML(){return new xt(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function oe(e){return e?typeof e=="string"?e:e.source:null}function Je(e){return Z("(?=",e,")")}function Tt(e){return Z("(?:",e,")*")}function Ot(e){return Z("(?:",e,")?")}function Z(...e){return e.map(n=>oe(n)).join("")}function kt(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function Ae(...e){return"("+(kt(e).capture?"":"?:")+e.map(i=>oe(i)).join("|")+")"}function Qe(e){return new RegExp(e.toString()+"|").exec("").length-1}function At(e,t){const n=e&&e.exec(t);return n&&n.index===0}const Rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function Re(e,{joinWith:t}){let n=0;return e.map(i=>{n+=1;const a=n;let l=oe(i),s="";for(;l.length>0;){const o=Rt.exec(l);if(!o){s+=l;break}s+=l.substring(0,o.index),l=l.substring(o.index+o[0].length),o[0][0]==="\\"&&o[1]?s+="\\"+String(Number(o[1])+a):(s+=o[0],o[0]==="("&&n++)}return s}).map(i=>`(${i})`).join(t)}const Ct=/\b\B/,Ve="[a-zA-Z]\\w*",Ce="[a-zA-Z_]\\w*",et="\\b\\d+(\\.\\d+)?",tt="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",nt="\\b(0b[01]+)",It="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",Lt=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=Z(t,/.*\b/,e.binary,/\b.*/)),P({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(n,i)=>{n.index!==0&&i.ignoreMatch()}},e)},re={begin:"\\\\[\\s\\S]",relevance:0},Dt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[re]},Bt={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[re]},Ut={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},me=function(e,t,n={}){const i=P({scope:"comment",begin:e,end:t,contains:[]},n);i.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const a=Ae("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return i.contains.push({begin:Z(/[ ]+/,"(",a,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i},Pt=me("//","$"),zt=me("/\\*","\\*/"),$t=me("#","$"),Ht={scope:"number",begin:et,relevance:0},Gt={scope:"number",begin:tt,relevance:0},Ft={scope:"number",begin:nt,relevance:0},jt={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[re,{begin:/\[/,end:/\]/,relevance:0,contains:[re]}]},Kt={scope:"title",begin:Ve,relevance:0},Zt={scope:"title",begin:Ce,relevance:0},Wt={begin:"\\.\\s*"+Ce,relevance:0},qt=function(e){return Object.assign(e,{"on:begin":(t,n)=>{n.data._beginMatch=t[1]},"on:end":(t,n)=>{n.data._beginMatch!==t[1]&&n.ignoreMatch()}})};var ue=Object.freeze({__proto__:null,APOS_STRING_MODE:Dt,BACKSLASH_ESCAPE:re,BINARY_NUMBER_MODE:Ft,BINARY_NUMBER_RE:nt,COMMENT:me,C_BLOCK_COMMENT_MODE:zt,C_LINE_COMMENT_MODE:Pt,C_NUMBER_MODE:Gt,C_NUMBER_RE:tt,END_SAME_AS_BEGIN:qt,HASH_COMMENT_MODE:$t,IDENT_RE:Ve,MATCH_NOTHING_RE:Ct,METHOD_GUARD:Wt,NUMBER_MODE:Ht,NUMBER_RE:et,PHRASAL_WORDS_MODE:Ut,QUOTE_STRING_MODE:Bt,REGEXP_MODE:jt,RE_STARTERS_RE:It,SHEBANG:Lt,TITLE_MODE:Kt,UNDERSCORE_IDENT_RE:Ce,UNDERSCORE_TITLE_MODE:Zt});function Xt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function Yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function Jt(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Xt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Qt(e,t){Array.isArray(e.illegal)&&(e.illegal=Ae(...e.illegal))}function Vt(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function en(e,t){e.relevance===void 0&&(e.relevance=1)}const tn=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const n=Object.assign({},e);Object.keys(e).forEach(i=>{delete e[i]}),e.keywords=n.keywords,e.begin=Z(n.beforeMatch,Je(n.begin)),e.starts={relevance:0,contains:[Object.assign(n,{endsParent:!0})]},e.relevance=0,delete n.beforeMatch},nn=["of","and","for","in","not","or","if","then","parent","list","value"],on="keyword";function it(e,t,n=on){const i=Object.create(null);return typeof e=="string"?a(n,e.split(" ")):Array.isArray(e)?a(n,e):Object.keys(e).forEach(function(l){Object.assign(i,it(e[l],t,l))}),i;function a(l,s){t&&(s=s.map(o=>o.toLowerCase())),s.forEach(function(o){const d=o.split("|");i[d[0]]=[l,rn(d[0],d[1])]})}}function rn(e,t){return t?Number(t):sn(e)?0:1}function sn(e){return nn.includes(e.toLowerCase())}const Ge={},K=e=>{console.error(e)},Fe=(e,...t)=>{console.log(`WARN: ${e}`,...t)},X=(e,t)=>{Ge[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ge[`${e}/${t}`]=!0)},be=new Error;function ot(e,t,{key:n}){let i=0;const a=e[n],l={},s={};for(let o=1;o<=t.length;o++)s[o+i]=a[o],l[o+i]=!0,i+=Qe(t[o-1]);e[n]=s,e[n]._emit=l,e[n]._multi=!0}function an(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),be;if(typeof e.beginScope!="object"||e.beginScope===null)throw K("beginScope must be object"),be;ot(e,e.begin,{key:"beginScope"}),e.begin=Re(e.begin,{joinWith:""})}}function cn(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"),be;if(typeof e.endScope!="object"||e.endScope===null)throw K("endScope must be object"),be;ot(e,e.end,{key:"endScope"}),e.end=Re(e.end,{joinWith:""})}}function ln(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function dn(e){ln(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),an(e),cn(e)}function un(e){function t(s,o){return new RegExp(oe(s),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(o?"g":""))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(o,d){d.position=this.position++,this.matchIndexes[this.matchAt]=d,this.regexes.push([d,o]),this.matchAt+=Qe(o)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const o=this.regexes.map(d=>d[1]);this.matcherRe=t(Re(o,{joinWith:"|"}),!0),this.lastIndex=0}exec(o){this.matcherRe.lastIndex=this.lastIndex;const d=this.matcherRe.exec(o);if(!d)return null;const m=d.findIndex((C,T)=>T>0&&C!==void 0),_=this.matchIndexes[m];return d.splice(0,m),Object.assign(d,_)}}class i{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(o){if(this.multiRegexes[o])return this.multiRegexes[o];const d=new n;return this.rules.slice(o).forEach(([m,_])=>d.addRule(m,_)),d.compile(),this.multiRegexes[o]=d,d}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(o,d){this.rules.push([o,d]),d.type==="begin"&&this.count++}exec(o){const d=this.getMatcher(this.regexIndex);d.lastIndex=this.lastIndex;let m=d.exec(o);if(this.resumingScanAtSamePosition()&&!(m&&m.index===this.lastIndex)){const _=this.getMatcher(0);_.lastIndex=this.lastIndex+1,m=_.exec(o)}return m&&(this.regexIndex+=m.position+1,this.regexIndex===this.count&&this.considerAll()),m}}function a(s){const o=new i;return s.contains.forEach(d=>o.addRule(d.begin,{rule:d,type:"begin"})),s.terminatorEnd&&o.addRule(s.terminatorEnd,{type:"end"}),s.illegal&&o.addRule(s.illegal,{type:"illegal"}),o}function l(s,o){const d=s;if(s.isCompiled)return d;[Yt,Vt,dn,tn].forEach(_=>_(s,o)),e.compilerExtensions.forEach(_=>_(s,o)),s.__beforeBegin=null,[Jt,Qt,en].forEach(_=>_(s,o)),s.isCompiled=!0;let m=null;return typeof s.keywords=="object"&&s.keywords.$pattern&&(s.keywords=Object.assign({},s.keywords),m=s.keywords.$pattern,delete s.keywords.$pattern),m=m||/\w+/,s.keywords&&(s.keywords=it(s.keywords,e.case_insensitive)),d.keywordPatternRe=t(m,!0),o&&(s.begin||(s.begin=/\B|\b/),d.beginRe=t(d.begin),!s.end&&!s.endsWithParent&&(s.end=/\B|\b/),s.end&&(d.endRe=t(d.end)),d.terminatorEnd=oe(d.end)||"",s.endsWithParent&&o.terminatorEnd&&(d.terminatorEnd+=(s.end?"|":"")+o.terminatorEnd)),s.illegal&&(d.illegalRe=t(s.illegal)),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map(function(_){return gn(_==="self"?s:_)})),s.contains.forEach(function(_){l(_,d)}),s.starts&&l(s.starts,o),d.matcher=a(d),d}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=P(e.classNameAliases||{}),l(e)}function rt(e){return e?e.endsWithParent||rt(e.starts):!1}function gn(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return P(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:rt(e)?P(e,{starts:e.starts?P(e.starts):null}):Object.isFrozen(e)?P(e):e}var fn="11.11.1";class pn extends Error{constructor(t,n){super(t),this.name="HTMLInjectionError",this.html=n}}const Me=Ye,je=P,Ke=Symbol("nomatch"),hn=7,st=function(e){const t=Object.create(null),n=Object.create(null),i=[];let a=!0;const l="Could not find the language '{}', did you forget to load/include a language module?",s={disableAutodetect:!0,name:"Plain text",contains:[]};let o={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:Mt};function d(r){return o.noHighlightRe.test(r)}function m(r){let g=r.className+" ";g+=r.parentNode?r.parentNode.className:"";const f=o.languageDetectRe.exec(g);if(f){const E=R(f[1]);return E||(Fe(l.replace("{}",f[1])),Fe("Falling back to no-highlight mode for this block.",r)),E?f[1]:"no-highlight"}return g.split(/\s+/).find(E=>d(E)||R(E))}function _(r,g,f){let E="",v="";typeof g=="object"?(E=r,f=g.ignoreIllegals,v=g.language):(X("10.7.0","highlight(lang, code, ...args) has been deprecated."),X("10.7.0",`Please use highlight(code, options) instead.
+https://github.com/highlightjs/highlight.js/issues/2277`),v=r,E=g),f===void 0&&(f=!0);const x={code:E,language:v};q("before:highlight",x);const A=x.result?x.result:C(x.language,x.code,f);return A.code=x.code,q("after:highlight",A),A}function C(r,g,f,E){const v=Object.create(null);function x(c,u){return c.keywords[u]}function A(){if(!p.keywords){N.addText(w);return}let c=0;p.keywordPatternRe.lastIndex=0;let u=p.keywordPatternRe.exec(w),b="";for(;u;){b+=w.substring(c,u.index);const y=L.case_insensitive?u[0].toLowerCase():u[0],M=x(p,y);if(M){const[D,wt]=M;if(N.addText(b),b="",v[y]=(v[y]||0)+1,v[y]<=hn&&(de+=wt),D.startsWith("_"))b+=u[0];else{const _t=L.classNameAliases[D]||D;I(u[0],_t)}}else b+=u[0];c=p.keywordPatternRe.lastIndex,u=p.keywordPatternRe.exec(w)}b+=w.substring(c),N.addText(b)}function F(){if(w==="")return;let c=null;if(typeof p.subLanguage=="string"){if(!t[p.subLanguage]){N.addText(w);return}c=C(p.subLanguage,w,!0,Pe[p.subLanguage]),Pe[p.subLanguage]=c._top}else c=h(w,p.subLanguage.length?p.subLanguage:null);p.relevance>0&&(de+=c.relevance),N.__addSublanguage(c._emitter,c.language)}function O(){p.subLanguage!=null?F():A(),w=""}function I(c,u){c!==""&&(N.startScope(u),N.addText(c),N.endScope())}function Le(c,u){let b=1;const y=u.length-1;for(;b<=y;){if(!c._emit[b]){b++;continue}const M=L.classNameAliases[c[b]]||c[b],D=u[b];M?I(D,M):(w=D,A(),w=""),b++}}function De(c,u){return c.scope&&typeof c.scope=="string"&&N.openNode(L.classNameAliases[c.scope]||c.scope),c.beginScope&&(c.beginScope._wrap?(I(w,L.classNameAliases[c.beginScope._wrap]||c.beginScope._wrap),w=""):c.beginScope._multi&&(Le(c.beginScope,u),w="")),p=Object.create(c,{parent:{value:p}}),p}function Be(c,u,b){let y=At(c.endRe,b);if(y){if(c["on:end"]){const M=new ze(c);c["on:end"](u,M),M.isMatchIgnored&&(y=!1)}if(y){for(;c.endsParent&&c.parent;)c=c.parent;return c}}if(c.endsWithParent)return Be(c.parent,u,b)}function ht(c){return p.matcher.regexIndex===0?(w+=c[0],1):(xe=!0,0)}function bt(c){const u=c[0],b=c.rule,y=new ze(b),M=[b.__beforeBegin,b["on:begin"]];for(const D of M)if(D&&(D(c,y),y.isMatchIgnored))return ht(u);return b.skip?w+=u:(b.excludeBegin&&(w+=u),O(),!b.returnBegin&&!b.excludeBegin&&(w=u)),De(b,c),b.returnBegin?0:u.length}function mt(c){const u=c[0],b=g.substring(c.index),y=Be(p,c,b);if(!y)return Ke;const M=p;p.endScope&&p.endScope._wrap?(O(),I(u,p.endScope._wrap)):p.endScope&&p.endScope._multi?(O(),Le(p.endScope,c)):M.skip?w+=u:(M.returnEnd||M.excludeEnd||(w+=u),O(),M.excludeEnd&&(w=u));do p.scope&&N.closeNode(),!p.skip&&!p.subLanguage&&(de+=p.relevance),p=p.parent;while(p!==y.parent);return y.starts&&De(y.starts,c),M.returnEnd?0:u.length}function Et(){const c=[];for(let u=p;u!==L;u=u.parent)u.scope&&c.unshift(u.scope);c.forEach(u=>N.openNode(u))}let le={};function Ue(c,u){const b=u&&u[0];if(w+=c,b==null)return O(),0;if(le.type==="begin"&&u.type==="end"&&le.index===u.index&&b===""){if(w+=g.slice(u.index,u.index+1),!a){const y=new Error(`0 width match regex (${r})`);throw y.languageName=r,y.badRule=le.rule,y}return 1}if(le=u,u.type==="begin")return bt(u);if(u.type==="illegal"&&!f){const y=new Error('Illegal lexeme "'+b+'" for mode "'+(p.scope||"")+'"');throw y.mode=p,y}else if(u.type==="end"){const y=mt(u);if(y!==Ke)return y}if(u.type==="illegal"&&b==="")return w+=`
+`,1;if(Ne>1e5&&Ne>u.index*3)throw new Error("potential infinite loop, way more iterations than matches");return w+=b,b.length}const L=R(r);if(!L)throw K(l.replace("{}",r)),new Error('Unknown language: "'+r+'"');const yt=un(L);let Se="",p=E||yt;const Pe={},N=new o.__emitter(o);Et();let w="",de=0,j=0,Ne=0,xe=!1;try{if(L.__emitTokens)L.__emitTokens(g,N);else{for(p.matcher.considerAll();;){Ne++,xe?xe=!1:p.matcher.considerAll(),p.matcher.lastIndex=j;const c=p.matcher.exec(g);if(!c)break;const u=g.substring(j,c.index),b=Ue(u,c);j=c.index+b}Ue(g.substring(j))}return N.finalize(),Se=N.toHTML(),{language:r,value:Se,relevance:de,illegal:!1,_emitter:N,_top:p}}catch(c){if(c.message&&c.message.includes("Illegal"))return{language:r,value:Me(g),illegal:!0,relevance:0,_illegalBy:{message:c.message,index:j,context:g.slice(j-100,j+100),mode:c.mode,resultSoFar:Se},_emitter:N};if(a)return{language:r,value:Me(g),illegal:!1,relevance:0,errorRaised:c,_emitter:N,_top:p};throw c}}function T(r){const g={value:Me(r),illegal:!1,relevance:0,_top:s,_emitter:new o.__emitter(o)};return g._emitter.addText(r),g}function h(r,g){g=g||o.languages||Object.keys(t);const f=T(r),E=g.filter(R).filter(ce).map(O=>C(O,r,!1));E.unshift(f);const v=E.sort((O,I)=>{if(O.relevance!==I.relevance)return I.relevance-O.relevance;if(O.language&&I.language){if(R(O.language).supersetOf===I.language)return 1;if(R(I.language).supersetOf===O.language)return-1}return 0}),[x,A]=v,F=x;return F.secondBest=A,F}function S(r,g,f){const E=g&&n[g]||f;r.classList.add("hljs"),r.classList.add(`language-${E}`)}function k(r){let g=null;const f=m(r);if(d(f))return;if(q("before:highlightElement",{el:r,language:f}),r.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",r);return}if(r.children.length>0&&(o.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(r)),o.throwUnescapedHTML))throw new pn("One of your code blocks includes unescaped HTML.",r.innerHTML);g=r;const E=g.textContent,v=f?_(E,{language:f,ignoreIllegals:!0}):h(E);r.innerHTML=v.value,r.dataset.highlighted="yes",S(r,f,v.language),r.result={language:v.language,re:v.relevance,relevance:v.relevance},v.secondBest&&(r.secondBest={language:v.secondBest.language,relevance:v.secondBest.relevance}),q("after:highlightElement",{el:r,result:v,text:E})}function B(r){o=je(o,r)}const W=()=>{H(),X("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function U(){H(),X("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let $=!1;function H(){function r(){H()}if(document.readyState==="loading"){$||window.addEventListener("DOMContentLoaded",r,!1),$=!0;return}document.querySelectorAll(o.cssSelector).forEach(k)}function ee(r,g){let f=null;try{f=g(e)}catch(E){if(K("Language definition for '{}' could not be registered.".replace("{}",r)),a)K(E);else throw E;f=s}f.name||(f.name=r),t[r]=f,f.rawDefinition=g.bind(null,e),f.aliases&&ae(f.aliases,{languageName:r})}function G(r){delete t[r];for(const g of Object.keys(n))n[g]===r&&delete n[g]}function Ee(){return Object.keys(t)}function R(r){return r=(r||"").toLowerCase(),t[r]||t[n[r]]}function ae(r,{languageName:g}){typeof r=="string"&&(r=[r]),r.forEach(f=>{n[f.toLowerCase()]=g})}function ce(r){const g=R(r);return g&&!g.disableAutodetect}function ye(r){r["before:highlightBlock"]&&!r["before:highlightElement"]&&(r["before:highlightElement"]=g=>{r["before:highlightBlock"](Object.assign({block:g.el},g))}),r["after:highlightBlock"]&&!r["after:highlightElement"]&&(r["after:highlightElement"]=g=>{r["after:highlightBlock"](Object.assign({block:g.el},g))})}function we(r){ye(r),i.push(r)}function _e(r){const g=i.indexOf(r);g!==-1&&i.splice(g,1)}function q(r,g){const f=r;i.forEach(function(E){E[f]&&E[f](g)})}function ve(r){return X("10.7.0","highlightBlock will be removed entirely in v12.0"),X("10.7.0","Please use highlightElement now."),k(r)}Object.assign(e,{highlight:_,highlightAuto:h,highlightAll:H,highlightElement:k,highlightBlock:ve,configure:B,initHighlighting:W,initHighlightingOnLoad:U,registerLanguage:ee,unregisterLanguage:G,listLanguages:Ee,getLanguage:R,registerAliases:ae,autoDetection:ce,inherit:je,addPlugin:we,removePlugin:_e}),e.debugMode=function(){a=!1},e.safeMode=function(){a=!0},e.versionString=fn,e.regex={concat:Z,lookahead:Je,either:Ae,optional:Ot,anyNumberOfTimes:Tt};for(const r in ue)typeof ue[r]=="object"&&Xe(ue[r]);return Object.assign(e,ue),e},J=st({});J.newInstance=()=>st({});var bn=J;J.HighlightJS=J;J.default=J;const Q=vt(bn),Ze="[A-Za-z$_][0-9A-Za-z$_]*",mn=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends","using"],En=["true","false","null","undefined","NaN","Infinity"],at=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ct=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],lt=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],yn=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],wn=[].concat(lt,at,ct);function _n(e){const t=e.regex,n=(f,{after:E})=>{const v=""+f[0].slice(1);return f.input.indexOf(v,E)!==-1},i=Ze,a={begin:"<>",end:">"},l=/<[A-Za-z0-9\\._:-]+\s*\/>/,s={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(f,E)=>{const v=f[0].length+f.index,x=f.input[v];if(x==="<"||x===","){E.ignoreMatch();return}x===">"&&(n(f,{after:v})||E.ignoreMatch());let A;const F=f.input.substring(v);if(A=F.match(/^\s*=/)){E.ignoreMatch();return}if((A=F.match(/^\s+extends\s+/))&&A.index===0){E.ignoreMatch();return}}},o={$pattern:Ze,keyword:mn,literal:En,built_in:wn,"variable.language":yn},d="[0-9](_?[0-9])*",m=`\\.(${d})`,_="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",C={className:"number",variants:[{begin:`(\\b(${_})((${m})|\\.)?|(${m}))[eE][+-]?(${d})\\b`},{begin:`\\b(${_})\\b((${m})\\b|\\.)?|(${m})\\b`},{begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{begin:"\\b0[0-7]+n?\\b"}],relevance:0},T={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]},h={begin:".?html`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,T],subLanguage:"xml"}},S={begin:".?css`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,T],subLanguage:"css"}},k={begin:".?gql`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,T],subLanguage:"graphql"}},B={className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,T]},U={className:"comment",variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,excludeBegin:!0,relevance:0},{className:"variable",begin:i+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]},$=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,h,S,k,B,{match:/\$\d+/},C];T.contains=$.concat({begin:/\{/,end:/\}/,keywords:o,contains:["self"].concat($)});const H=[].concat(U,T.contains),ee=H.concat([{begin:/(\s*)\(/,end:/\)/,keywords:o,contains:["self"].concat(H)}]),G={className:"params",begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:ee},Ee={variants:[{match:[/class/,/\s+/,i,/\s+/,/extends/,/\s+/,t.concat(i,"(",t.concat(/\./,i),")*")],scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{match:[/class/,/\s+/,i],scope:{1:"keyword",3:"title.class"}}]},R={relevance:0,match:t.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),className:"title.class",keywords:{_:[...at,...ct]}},ae={label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},ce={variants:[{match:[/function/,/\s+/,i,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],className:{1:"keyword",3:"title.function"},label:"func.def",contains:[G],illegal:/%/},ye={relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"};function we(f){return t.concat("(?!",f.join("|"),")")}const _e={match:t.concat(/\b/,we([...lt,"super","import"].map(f=>`${f}\\s*\\(`)),i,t.lookahead(/\s*\(/)),className:"title.function",relevance:0},q={begin:t.concat(/\./,t.lookahead(t.concat(i,/(?![0-9A-Za-z$_(])/))),end:i,excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},ve={match:[/get|set/,/\s+/,i,/(?=\()/],className:{1:"keyword",3:"title.function"},contains:[{begin:/\(\)/},G]},r="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",g={match:[/const|var|let/,/\s+/,i,/\s*/,/=\s*/,/(async\s*)?/,t.lookahead(r)],keywords:"async",className:{1:"keyword",3:"title.function"},contains:[G]};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:o,exports:{PARAMS_CONTAINS:ee,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),ae,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,h,S,k,B,U,{match:/\$\d+/},C,R,{scope:"attr",match:i+t.lookahead(":"),relevance:0},g,{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",relevance:0,contains:[U,e.REGEXP_MODE,{className:"function",begin:r,returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:ee}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:a.begin,end:a.end},{match:l},{begin:s.begin,"on:begin":s.isTrulyOpeningTag,end:s.end}],subLanguage:"xml",contains:[{begin:s.begin,end:s.end,skip:!0,contains:["self"]}]}]},ce,{beginKeywords:"while if switch catch for"},{begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,label:"func.def",contains:[G,e.inherit(e.TITLE_MODE,{begin:i,className:"title.function"})]},{match:/\.\.\./,relevance:0},q,{match:"\\$"+i,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},contains:[G]},_e,ye,Ee,ve,{match:/\$[(.]/}]}}const vn=e=>({IMPORTANT:{scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}),Sn=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","optgroup","option","p","picture","q","quote","samp","section","select","source","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],Nn=["defs","g","marker","mask","pattern","svg","switch","symbol","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feGaussianBlur","feImage","feMerge","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","linearGradient","radialGradient","stop","circle","ellipse","image","line","path","polygon","polyline","rect","text","use","textPath","tspan","foreignObject","clipPath"],xn=[...Sn,...Nn],Mn=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"].sort().reverse(),Tn=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"].sort().reverse(),On=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"].sort().reverse(),kn=["accent-color","align-content","align-items","align-self","alignment-baseline","all","anchor-name","animation","animation-composition","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-range","animation-range-end","animation-range-start","animation-timeline","animation-timing-function","appearance","aspect-ratio","backdrop-filter","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-position-x","background-position-y","background-repeat","background-size","baseline-shift","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-end-end-radius","border-end-start-radius","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-start-end-radius","border-start-start-radius","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-align","box-decoration-break","box-direction","box-flex","box-flex-group","box-lines","box-ordinal-group","box-orient","box-pack","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","color-scheme","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","contain-intrinsic-block-size","contain-intrinsic-height","contain-intrinsic-inline-size","contain-intrinsic-size","contain-intrinsic-width","container","container-name","container-type","content","content-visibility","counter-increment","counter-reset","counter-set","cue","cue-after","cue-before","cursor","cx","cy","direction","display","dominant-baseline","empty-cells","enable-background","field-sizing","fill","fill-opacity","fill-rule","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flood-color","flood-opacity","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-optical-sizing","font-palette","font-size","font-size-adjust","font-smooth","font-smoothing","font-stretch","font-style","font-synthesis","font-synthesis-position","font-synthesis-small-caps","font-synthesis-style","font-synthesis-weight","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-emoji","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","forced-color-adjust","gap","glyph-orientation-horizontal","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphenate-character","hyphenate-limit-chars","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","initial-letter","initial-letter-align","inline-size","inset","inset-area","inset-block","inset-block-end","inset-block-start","inset-inline","inset-inline-end","inset-inline-start","isolation","justify-content","justify-items","justify-self","kerning","left","letter-spacing","lighting-color","line-break","line-height","line-height-step","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","margin-trim","marker","marker-end","marker-mid","marker-start","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","masonry-auto-flow","math-depth","math-shift","math-style","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","offset","offset-anchor","offset-distance","offset-path","offset-position","offset-rotate","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-anchor","overflow-block","overflow-clip-margin","overflow-inline","overflow-wrap","overflow-x","overflow-y","overlay","overscroll-behavior","overscroll-behavior-block","overscroll-behavior-inline","overscroll-behavior-x","overscroll-behavior-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","paint-order","pause","pause-after","pause-before","perspective","perspective-origin","place-content","place-items","place-self","pointer-events","position","position-anchor","position-visibility","print-color-adjust","quotes","r","resize","rest","rest-after","rest-before","right","rotate","row-gap","ruby-align","ruby-position","scale","scroll-behavior","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scroll-timeline","scroll-timeline-axis","scroll-timeline-name","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","shape-rendering","speak","speak-as","src","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","tab-size","table-layout","text-align","text-align-all","text-align-last","text-anchor","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-skip-ink","text-decoration-style","text-decoration-thickness","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-size-adjust","text-transform","text-underline-offset","text-underline-position","text-wrap","text-wrap-mode","text-wrap-style","timeline-scope","top","touch-action","transform","transform-box","transform-origin","transform-style","transition","transition-behavior","transition-delay","transition-duration","transition-property","transition-timing-function","translate","unicode-bidi","user-modify","user-select","vector-effect","vertical-align","view-timeline","view-timeline-axis","view-timeline-inset","view-timeline-name","view-transition-name","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","white-space-collapse","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","x","y","z-index","zoom"].sort().reverse();function An(e){const t=e.regex,n=vn(e),i={begin:/-(webkit|moz|ms|o)-(?=[a-z])/},a="and or not only",l=/@-?\w[\w]*(-\w+)*/,s="[a-zA-Z-][a-zA-Z0-9_-]*",o=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},contains:[n.BLOCK_COMMENT,i,n.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:"selector-class",begin:"\\."+s,relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{begin:":("+Tn.join("|")+")"},{begin:":(:)?("+On.join("|")+")"}]},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+kn.join("|")+")\\b"},{begin:/:/,end:/[;}{]/,contains:[n.BLOCK_COMMENT,n.HEXCOLOR,n.IMPORTANT,n.CSS_NUMBER_MODE,...o,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"},contains:[...o,{className:"string",begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},n.FUNCTION_DISPATCH]},{begin:t.lookahead(/@/),end:"[{;]",relevance:0,illegal:/:/,contains:[{className:"keyword",begin:l},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:a,attribute:Mn.join(" ")},contains:[{begin:/[a-z-]+(?=:)/,className:"attribute"},...o,n.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"\\b("+xn.join("|")+")\\b"}]}}function Rn(e){const t={variants:[e.COMMENT("--","$"),e.COMMENT(/\{-/,/-\}/,{contains:["self"]})]},n={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},i={begin:"\\(",end:"\\)",illegal:'"',contains:[{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},t]},a={begin:/\{/,end:/\}/,contains:i.contains},l={className:"string",begin:"'\\\\?.",end:"'",illegal:"."};return{name:"Elm",keywords:["let","in","if","then","else","case","of","where","module","import","exposing","type","alias","as","infix","infixl","infixr","port","effect","command","subscription"],contains:[{beginKeywords:"port effect module",end:"exposing",keywords:"port effect module where command subscription exposing",contains:[i,t],illegal:"\\W\\.|;"},{begin:"import",end:"$",keywords:"import as exposing",contains:[i,t],illegal:"\\W\\.|;"},{begin:"type",end:"$",keywords:"type alias",contains:[n,i,a,t]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,t]},{begin:"port",end:"$",keywords:"port",contains:[t]},l,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,n,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),t,{begin:"->|<-"}],illegal:/;/}}function Cn(e){const t=e.regex,n=t.concat(/[\p{L}_]/u,t.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),i=/[\p{L}0-9._:-]+/u,a={className:"symbol",begin:/&[a-z]+;|[0-9]+;|[a-f0-9]+;/},l={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},s=e.inherit(l,{begin:/\(/,end:/\)/}),o=e.inherit(e.APOS_STRING_MODE,{className:"string"}),d=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),m={endsWithParent:!0,illegal:/,relevance:0,contains:[{className:"attr",begin:i,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[a]},{begin:/'/,end:/'/,contains:[a]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[l,d,o,s,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[l,s,d,o]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[d]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",begin:/
+
+
+ SimplyCountdown.js - ${type} Test
+
+
+
+
+
+ ${content}
+
+