commit dc96e8570cd97935865d7dcda67c6a3c20f41579 Author: Eric Woodward Date: Sat Sep 6 17:22:25 2025 -0400 Initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f44002c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true + +[*.md] +indent_style = tab diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..af3ad12 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +/.yarn/** linguist-vendored +/.yarn/releases/* binary +/.yarn/plugins/**/* binary +/.pnp.* binary linguist-generated diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f03eaec --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Whether you use PnP or not, the node_modules folder is often used to store +# build artifacts that should be gitignored +node_modules + +# Swap the comments on the following lines if you wish to use zero-installs +# In that case, don't forget to run `yarn config set enableGlobalCache false`! +# Documentation here: https://yarnpkg.com/features/caching#zero-installs + +#!.yarn/cache +.pnp.* diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5a938ce --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 4, + "useTabs": false +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7add88d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "cSpell.words": [ + "btih", + "Hocevar", + "ohtml", + "unlisten", + "unplugin" + ] +} \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5c93f45 --- /dev/null +++ b/COPYING @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ed88681 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright © 2025 Eric Woodward + +This program is free software. It comes without any warranty, +to the extent permitted by applicable law. You can redistribute +it and/or modify it under the terms of the Do What The Fuck You +Want To Public License, Version 2, as published by Sam Hocevar. +See the COPYING file for more details. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcd9e1a --- /dev/null +++ b/README.md @@ -0,0 +1,140 @@ +# fluent-dom-esm + +A remarkably simple but surprisingly powerful DOM element creation library with an easy-to-use syntax inspired by the classic JS libraries of yesterday. + +When you don't need a whole framework (or JSX), but also don't want to spend all day typing `document.createElement` or `document.getElementById`, **fluent-dom-esm** may just be the thing you need. + +## Installation + +1. Grab the latest copy of the `fluent-dom-esm.js` file, either by [downloading it](./dist/fluent-dom-esm.js) or doing a `git clone` and pulling it out of the `dist` folder. +2. Add the newly acquired file to your static site / progressive web app / over-engineered blog. +3. Import it as an ESM module (`import $d from "./src/fluent-dom-esm.js"`). +4. Profit! + +### Occasionally Asked Questions + +- _How can I use this in Node?_ You can't, AFAIK. It requires access to the HTML `Document` object from the browser. +- _How can I minify or bundle this?_ You shouldn't, IMHO. JavaScript is meant to be read by humans _AND_ machines. + +## Building / Modifying + +The source exists as a couple of TypeScript files which are "bundled" into a traditional JS file (along with TS definitions). + +### Building + +To build new versions of the `fluent-dom-esm.js` file: + +1. `git clone` this project. +2. `cd fluent-dom-esm` +3. `yarn` +4. `yarn build` + +If everything goes as expected, you should have a newly built `fluent-dom-esm.js` file in the `dist` folder. + +### Modifying + +To edit the source of the `fluent-dom-esm.js` file: + +1. `git clone` this project. +2. `cd fluent-dom-esm` +3. `yarn` +4. `yarn dev` +5. Make your changes to `fluent-dom-esm.ts`. +6. When you're happy with it, do a `yarn build`. + +If everything goes as expected, you should have a newly built `fluent-dom-esm.js` file in the `dist` folder with your changes. + +## Examples + +All assume that `$d` is the default function from `fluent-dom-esm` (`import $d from './fluent-dom-esm.js'`); + +- For more examples, see the `demo.html` file in the `dist` folder. + +### Create a Paragraph + +``` +$(document.body).app($d + .c("p") + .s("background-color", "yellow") + .s("color", "black") + .t("The quick brown fox jumped over the lazy, sleeping dog.") +); + +``` + +renders (with added spaces) as + +``` +... + +

+ The quick brown fox jumped over the lazy, sleeping dog. +

+ + +``` + +### Create a List + +``` +const $ul = $d + .c("ul") + .id("example-list") + .cls("example-list"); + [ + "List Item 1", + "List Item 2", + "List Item 3", + ].forEach((reason, idx) => { + $ul.app( + $d + .c("li") + .id(`fluentDom-example-list-item${idx + 1}`) + .t(reason), + ); + }); + +$(document.body).app($ul); + +``` + +renders (with added spaces) as + +``` + + + + +``` + +## License + +Copyright © 2025 Eric Woodward + +Based on [original source](https://glacius.tmont.com/articles/fluent-dom-manipulation-in-javascript), copyright © 2009 Tommy Montgomery. + +``` +This program is free software. It comes without any warranty, to the +extent permitted by applicable law. You can redistribute it and/or +modify it under the terms of the Do What The Fuck You Want To Public +License, Version 2, as published by Sam Hocevar. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + +``` diff --git a/dist/demo.html b/dist/demo.html new file mode 100644 index 0000000..9634ab1 --- /dev/null +++ b/dist/demo.html @@ -0,0 +1,170 @@ + + + + + + fluent-dom-esm Demo + + + + + + + + + diff --git a/dist/fluent-dom-esm.js b/dist/fluent-dom-esm.js new file mode 100644 index 0000000..16f15d5 --- /dev/null +++ b/dist/fluent-dom-esm.js @@ -0,0 +1,165 @@ +// @license magnet:?xt=urn:btih:723febf9f6185544f57f0660a41489c7d6b4931b&dn=wtfpl.txt +const version = "1.1.0"; +const isFluentDomObject = (value) => !!value.fluentDom; +const isHTMLElement = (value) => !!value.nodeType; +const isNumber = (value) => typeof value === "number"; +const isString = (value) => typeof value === "string"; +/** + * fluent-dom-esm v1.1.0 + * + * Fluent DOM Manipulation, adapted to ESM and cranked up to v1.1(.0). + * + * https://git.itsericwoodward.com/eric/fluent-dom-esm + * + * v1.1.0 Copyright (c) 2025 Eric Woodward + * Original copyright (c) 2009 Tommy Montgomery (https://glacius.tmont.com/articles/fluent-dom-manipulation-in-javascript) + * + * Released under the WTFPL (Do What the Fuck You Want to Public License) + * + * @author Eric Woodward (v1.1.0 update) + * @author Tommy Montgomery (original) + * @license http://sam.zoy.org/wtfpl/ + */ +const fluentDomEsm = (function() { + const FluentDom = function(node) { + return new FluentDomInternal(node); + }; + FluentDom.create = FluentDom.c = function(tagName) { + const f = new FluentDomInternal(); + f.create(tagName); + return f; + }; + const FluentDomInternal = function(node) { + let root = node || null; + this.fluentDom = version; + this.a = this.attr = function(name, value) { + if (!root || value && !root.setAttribute) { + throw new Error("Cannot set an attribute on a non-element"); + } + if (!value) return root.getAttribute(name); + root.setAttribute(name, value); + return this; + }; + this.app = this.append = function(value) { + if (!root || !root?.appendChild) { + throw new Error("Cannot append to a non-element"); + } + const type = typeof value; + if (type === "object") { + if (isFluentDomObject(value)) { + const domVal = value.toDom(); + if (domVal !== null) root.appendChild(domVal); + } else if (isHTMLElement(value)) { + root.appendChild(value); + } else { + throw new Error( + "Invalid argument: not an HTMLElement or FluentDom object" + ); + } + } else if (isNumber(value) || isString(value)) { + root.appendChild(document.createTextNode(`${value}`)); + } else { + throw new Error( + `Invalid argument: not a valid type (${typeof value})` + ); + } + return this; + }; + this.c = this.create = function(tagName) { + root = document.createElement(tagName); + return this; + }; + this.className = this.cls = function(value) { + return this.attr("class", value); + }; + this.clear = function() { + root = null; + return this; + }; + this.h = this.href = function(link) { + return this.attr("href", link); + }; + this.html = function(content) { + if (!root) { + throw new Error( + "Cannot get or set innerHTML for a non-element" + ); + } + if (!content) return root.innerHTML; + root.innerHTML = content; + return this; + }; + this.id = function(value) { + return this.attr("id", value); + }; + this.l = this.listen = function(...props) { + if (!root || !root.addEventListener) { + throw new Error("Cannot addEventListener to a non-element"); + } + root.addEventListener(...props); + return this; + }; + this.ohtml = function(content) { + if (!root) { + throw new Error( + "Cannot get or set outerHTML for a non-element" + ); + } + if (!content) return root.outerHTML; + root.outerHTML = content; + return this; + }; + this.s = this.style = function(prop, value) { + if (!root) { + throw new Error("Cannot get or set style for a non-element"); + } + if (typeof prop === "undefined") return root.style; + if (typeof value !== "undefined") { + root.style[prop] = value; + return this; + } + if (typeof prop === "string") return root.style[prop]; + if (typeof prop !== "object") { + throw new Error( + `Invalid argument: "prop" must be string or object (found ${typeof prop})` + ); + } + Object.keys(prop).forEach((key) => { + root.style[key] = prop[key]; + }); + return this; + }; + this.t = this.text = function(text) { + if (!root) { + throw new Error( + "Cannot get or set innerText for a non-element" + ); + } + if (typeof text === "undefined") return root.innerText; + return this.append(text); + }; + this.title = function(value) { + if (!root) { + throw new Error( + "Cannot get or set outerHTML for a non-element" + ); + } + return this.attr("title", value); + }; + this.toDom = function() { + return root; + }; + this.unlisten = function(...props) { + if (!root || !root.removeEventListener) { + throw new Error("Cannot removeEventListener on a non-element"); + } + root.removeEventListener(...props); + return this; + }; + }; + return FluentDom; +})(); +export { + fluentDomEsm as default +}; +// @license-end diff --git a/dist/package.json.d.ts b/dist/package.json.d.ts new file mode 100644 index 0000000..e46fab8 --- /dev/null +++ b/dist/package.json.d.ts @@ -0,0 +1,35 @@ +declare const _default: { + "name": "fluent-dom-esm", + "version": "1.1.0", + "description": "", + "license": "WTFPL", + "exports": { + ".": { + "import": "./dist/fluent-dom-esm.js" + } + }, + "type": "module", + "files": [ + "dist" + ], + "module": "./dist/fluent-dom-esm.js", + "scripts": { + "add-license": "cat ./src/license-begin.txt ./dist/fluent-dom-esm.js ./src/license-end.txt > .temp && mv .temp ./dist/fluent-dom-esm.js", + "build": "tsc && vite build && yarn add-license", + "ci": "yarn build", + "dev": "vite", + "preview": "vite preview", + "prepublishOnly": "yarn build", + "postpublish": "git push && git push --tags", + "test": "echo 'No tests yet!'" + }, + "devDependencies": { + "prettier": "^3.6.2", + "typescript": "^5.9.2", + "unplugin-dts": "1.0.0-beta.6", + "vite": "^7.1.4" + } +} +; + +export default _default; diff --git a/dist/src/fluent-dom-esm.d.ts b/dist/src/fluent-dom-esm.d.ts new file mode 100644 index 0000000..b3aff2a --- /dev/null +++ b/dist/src/fluent-dom-esm.d.ts @@ -0,0 +1,28 @@ +/** + * fluent-dom-esm v1.1.0 + * + * Fluent DOM Manipulation, adapted to ESM and cranked up to v1.1(.0). + * + * https://git.itsericwoodward.com/eric/fluent-dom-esm + * + * v1.1.0 Copyright (c) 2025 Eric Woodward + * Original copyright (c) 2009 Tommy Montgomery (https://glacius.tmont.com/articles/fluent-dom-manipulation-in-javascript) + * + * Released under the WTFPL (Do What the Fuck You Want to Public License) + * + * @author Eric Woodward (v1.1.0 update) + * @author Tommy Montgomery (original) + * @license http://sam.zoy.org/wtfpl/ + */ +/** + * IIFE that creates the FluentDomObject as default export + */ +declare const _default: { + (node: HTMLElement): any; + /** + * Creates a new HTML element which is wrapped in a FluentDomObject and returned + */ + create: (tagName: string) => any; + c(tagName: string): any; +}; +export default _default; diff --git a/dist/src/fluent-dom-esm.type-guards.d.ts b/dist/src/fluent-dom-esm.type-guards.d.ts new file mode 100644 index 0000000..060974a --- /dev/null +++ b/dist/src/fluent-dom-esm.type-guards.d.ts @@ -0,0 +1,5 @@ +import { FluentDomObject } from './fluent-dom-esm.types'; +export declare const isFluentDomObject: (value: any) => value is FluentDomObject; +export declare const isHTMLElement: (value: any) => value is HTMLElement; +export declare const isNumber: (value: any) => value is number; +export declare const isString: (value: any) => value is string; diff --git a/dist/src/fluent-dom-esm.types.d.ts b/dist/src/fluent-dom-esm.types.d.ts new file mode 100644 index 0000000..ba1341d --- /dev/null +++ b/dist/src/fluent-dom-esm.types.d.ts @@ -0,0 +1,27 @@ +export interface FluentDomObject { + fluentDom: string; + a: (name: string, value?: string) => FluentDomObject | string | null; + app: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject; + append: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject; + attr: (name: string, value?: string) => FluentDomObject | string | null; + c: (tagName: string) => FluentDomObject; + create: (tagName: string) => FluentDomObject; + className: (className?: string) => FluentDomObject | string | null; + clear: () => FluentDomObject; + cls: (className?: string) => FluentDomObject | string | null; + clr: () => FluentDomObject; + h: (url?: string) => FluentDomObject | string | null; + href: (url?: string) => FluentDomObject | string | null; + html: (content?: string) => string | FluentDomObject; + id: (id?: string) => FluentDomObject | string | null; + l: (type: keyof HTMLElementEventMap, listener: () => {}, optionsOrUseCapture?: boolean | object) => FluentDomObject; + listen: (type: keyof HTMLElementEventMap, listener: () => {}, optionsOrUseCapture?: boolean | object) => FluentDomObject; + ohtml: (content?: string) => string | FluentDomObject; + s: (prop?: CSSStyleDeclaration | string, value?: string) => FluentDomObject | CSSStyleDeclaration | string | undefined; + style: (prop?: CSSStyleDeclaration | string, value?: string) => FluentDomObject | CSSStyleDeclaration | string | undefined; + t: (text?: string) => FluentDomObject | string; + text: (text?: string) => FluentDomObject | string; + title: (title?: string) => FluentDomObject | string | null; + toDom: () => HTMLElement | null; + unlisten: (type: keyof HTMLElementEventMap, listener: () => {}, optionsOrUseCapture?: boolean | object) => FluentDomObject; +} diff --git a/dist/styles/main.css b/dist/styles/main.css new file mode 100644 index 0000000..c6682b7 --- /dev/null +++ b/dist/styles/main.css @@ -0,0 +1,140 @@ +* { + box-sizing: content-box; +} + +:root { + --main-light: #4f9a97; + --main-dark: #1a2737; + + --gray-light: #eee; + --gray-bg-60: rgba(10, 10, 10, .6); + --gray-bg-80: rgba(10, 10, 10, .8); +} + +body { + background-color: var(--main-dark); + color: var(--main-light); + font-size: 18px; + transition: color .5s; +} + +h2 { + margin-top: 1rem; +} + +hr { + margin: 2rem 0; +} + +figcaption { + border-bottom: 1px dashed var(--main-light); + font-style: italic; + font-weight: bold; + margin: -1rem -1rem 1rem -1rem; + padding: 0.5rem 1rem; +} + +figure { + background-color: var(--gray-bg-60); + border: 1px solid var(--main-light); + color: #285559; + margin: 1rem; + padding: 1rem; + max-width: 100%; +} + +.code-cmd { + color: #347c7a; +} + +.code-dom { + color: var(--main-light); +} + +.code-func { + color: #db7c17; +} + +.code-str { + color: #c43a19; +} + +.code-var { + color: var(--main-light); +} + +.themeToggle-button { + background-color: #5d27a1; + border: 1px solid var(--gray-light); + border-radius: 1rem; + color: var(--gray-light); + display: flex; + font-size: 1.5rem; + padding: .5rem; + position: absolute; + right: 1rem; + top: 1rem; + z-index: 100; +} + +.themeToggle-svgIndicator { + rotate: 180deg; + transition: rotate .5s; +} + + +body.invertedTheme { + background-color: var(--main-light); + color: var(--main-dark); +} + +body.invertedTheme figcaption { + border-color: var(--main-dark); +} + +body.invertedTheme figure { + background-color: var(--gray-bg-80); + border-color: var(--main-dark); +} + +body.invertedTheme .themeToggle-svgIndicator { + rotate: 0deg; +} + + +@media (prefers-color-scheme: light) { + body { + background-color: var(--main-light); + color: var(--main-dark); + } + + figure { + background-color: var(--gray-bg-80); + border-color: var(--main-dark); + color: var(--main-light); + } + + .themeToggle-svgIndicator { + rotate: 0deg; + } + + body.invertedTheme { + background-color: var(--main-dark); + color: var(--main-light); + } + + body.invertedTheme figcaption { + border-color: var(--main-light); + } + + body.invertedTheme figure { + background-color: var(--gray-bg-60); + border-color: var(--main-light); + } + + body.invertedTheme .themeToggle-svgIndicator { + rotate: 180deg; + } + +} + diff --git a/index.html b/index.html new file mode 100644 index 0000000..1237703 --- /dev/null +++ b/index.html @@ -0,0 +1,170 @@ + + + + + + fluent-dom-esm Demo + + + + + + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..d880c0b --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "fluent-dom-esm", + "version": "1.1.0", + "description": "", + "license": "WTFPL", + "exports": { + ".": { + "import": "./dist/fluent-dom-esm.js" + } + }, + "type": "module", + "files": [ + "dist" + ], + "module": "./dist/fluent-dom-esm.js", + "scripts": { + "add-license": "cat ./src/license-begin.txt ./dist/fluent-dom-esm.js ./src/license-end.txt > .temp && mv .temp ./dist/fluent-dom-esm.js", + "build": "tsc && vite build && yarn add-license", + "ci": "yarn build", + "dev": "vite", + "preview": "vite preview", + "prepublishOnly": "yarn build", + "postpublish": "git push && git push --tags", + "test": "echo 'No tests yet!'" + }, + "devDependencies": { + "prettier": "^3.6.2", + "typescript": "^5.9.2", + "unplugin-dts": "1.0.0-beta.6", + "vite": "^7.1.4" + } +} diff --git a/public/demo.html b/public/demo.html new file mode 100644 index 0000000..9634ab1 --- /dev/null +++ b/public/demo.html @@ -0,0 +1,170 @@ + + + + + + fluent-dom-esm Demo + + + + + + + + + diff --git a/public/styles/main.css b/public/styles/main.css new file mode 100644 index 0000000..c6682b7 --- /dev/null +++ b/public/styles/main.css @@ -0,0 +1,140 @@ +* { + box-sizing: content-box; +} + +:root { + --main-light: #4f9a97; + --main-dark: #1a2737; + + --gray-light: #eee; + --gray-bg-60: rgba(10, 10, 10, .6); + --gray-bg-80: rgba(10, 10, 10, .8); +} + +body { + background-color: var(--main-dark); + color: var(--main-light); + font-size: 18px; + transition: color .5s; +} + +h2 { + margin-top: 1rem; +} + +hr { + margin: 2rem 0; +} + +figcaption { + border-bottom: 1px dashed var(--main-light); + font-style: italic; + font-weight: bold; + margin: -1rem -1rem 1rem -1rem; + padding: 0.5rem 1rem; +} + +figure { + background-color: var(--gray-bg-60); + border: 1px solid var(--main-light); + color: #285559; + margin: 1rem; + padding: 1rem; + max-width: 100%; +} + +.code-cmd { + color: #347c7a; +} + +.code-dom { + color: var(--main-light); +} + +.code-func { + color: #db7c17; +} + +.code-str { + color: #c43a19; +} + +.code-var { + color: var(--main-light); +} + +.themeToggle-button { + background-color: #5d27a1; + border: 1px solid var(--gray-light); + border-radius: 1rem; + color: var(--gray-light); + display: flex; + font-size: 1.5rem; + padding: .5rem; + position: absolute; + right: 1rem; + top: 1rem; + z-index: 100; +} + +.themeToggle-svgIndicator { + rotate: 180deg; + transition: rotate .5s; +} + + +body.invertedTheme { + background-color: var(--main-light); + color: var(--main-dark); +} + +body.invertedTheme figcaption { + border-color: var(--main-dark); +} + +body.invertedTheme figure { + background-color: var(--gray-bg-80); + border-color: var(--main-dark); +} + +body.invertedTheme .themeToggle-svgIndicator { + rotate: 0deg; +} + + +@media (prefers-color-scheme: light) { + body { + background-color: var(--main-light); + color: var(--main-dark); + } + + figure { + background-color: var(--gray-bg-80); + border-color: var(--main-dark); + color: var(--main-light); + } + + .themeToggle-svgIndicator { + rotate: 0deg; + } + + body.invertedTheme { + background-color: var(--main-dark); + color: var(--main-light); + } + + body.invertedTheme figcaption { + border-color: var(--main-light); + } + + body.invertedTheme figure { + background-color: var(--gray-bg-60); + border-color: var(--main-light); + } + + body.invertedTheme .themeToggle-svgIndicator { + rotate: 180deg; + } + +} + diff --git a/src/fluent-dom-esm.ts b/src/fluent-dom-esm.ts new file mode 100644 index 0000000..802aa5f --- /dev/null +++ b/src/fluent-dom-esm.ts @@ -0,0 +1,264 @@ +/** + * fluent-dom-esm v1.1.0 + * + * Fluent DOM Manipulation, adapted to ESM and cranked up to v1.1(.0). + * + * https://git.itsericwoodward.com/eric/fluent-dom-esm + * + * v1.1.0 Copyright (c) 2025 Eric Woodward + * Original copyright (c) 2009 Tommy Montgomery (https://glacius.tmont.com/articles/fluent-dom-manipulation-in-javascript) + * + * Released under the WTFPL (Do What the Fuck You Want to Public License) + * + * @author Eric Woodward (v1.1.0 update) + * @author Tommy Montgomery (original) + * @license http://sam.zoy.org/wtfpl/ + */ + +import type { FluentDomObject } from "./fluent-dom-esm.types"; + +import { version } from "../package.json"; +import { + isFluentDomObject, + isHTMLElement, + isNumber, + isString, +} from "./fluent-dom-esm.type-guards"; + +/** + * IIFE that creates the FluentDomObject as default export + */ +export default (function () { + /** + * Wraps provided element in a FluentDomObject which is then returned + */ + const FluentDom = function (node: HTMLElement) { + return new (FluentDomInternal as any)(node); + }; + + /** + * Creates a new HTML element which is wrapped in a FluentDomObject and returned + */ + FluentDom.create = FluentDom.c = function (tagName: string) { + const f = new (FluentDomInternal as any)(); + f.create(tagName); + return f; + }; + + /** + * The internal representation of the FluentDomObject + */ + const FluentDomInternal = function ( + this: FluentDomObject, + node?: HTMLElement, + ) { + let root = node || null; + + // adds several new features + this.fluentDom = version; + + /** + * Gets or sets the named attribute on the wrapped HTMLElement + */ + this.a = this.attr = function (name, value) { + if (!root || (value && !root.setAttribute)) { + throw new Error("Cannot set an attribute on a non-element"); + } + + if (!value) return root.getAttribute(name); + + root.setAttribute(name, value); + return this; + }; + + /** + * Appends value to wrapped HTMLElement + */ + this.app = this.append = function (value) { + if (!root || !root?.appendChild) { + throw new Error("Cannot append to a non-element"); + } + + const type = typeof value; + if (type === "object") { + if (isFluentDomObject(value)) { + const domVal = value.toDom(); + if (domVal !== null) root.appendChild(domVal); + } else if (isHTMLElement(value)) { + root.appendChild(value); + } else { + throw new Error( + "Invalid argument: not an HTMLElement or FluentDom object", + ); + } + } else if (isNumber(value) || isString(value)) { + root.appendChild(document.createTextNode(`${value}`)); + } else { + throw new Error( + `Invalid argument: not a valid type (${typeof value})`, + ); + } + + return this; + }; + + /** + * Creates a new wrapped HTMLElement of the indicated tag + */ + this.c = this.create = function (tagName) { + root = document.createElement(tagName); + return this; + }; + + /** + * Gets or sets the "class" attribute on the wrapped HTMLElement + */ + this.className = this.cls = function (value) { + return this.attr("class", value); + }; + + /** + * Sets the wrapped HTMLElement to null + */ + this.clear = function () { + root = null; + return this; + }; + + /** + * Gets or sets the "href" attribute on the wrapped HTMLElement + */ + this.h = this.href = function (link) { + return this.attr("href", link); + }; + + /** + * Gets or sets the wrapped HTMLElement's "innerHTML" property + */ + this.html = function (content) { + if (!root) { + throw new Error( + "Cannot get or set innerHTML for a non-element", + ); + } + + if (!content) return root.innerHTML; + + root.innerHTML = content; + return this; + }; + + /** + * Gets or sets the "id" attribute on the wrapped HTMLElement + */ + this.id = function (value) { + return this.attr("id", value); + }; + + /** + * Passes props to the "addEventListener" function on the wrapped HTMLElement + */ + this.l = this.listen = function (...props) { + if (!root || !root.addEventListener) { + throw new Error("Cannot addEventListener to a non-element"); + } + + root.addEventListener(...props); + return this; + }; + + /** + * Gets or sets the wrapped HTMLElement's "outerHTML" property + */ + this.ohtml = function (content) { + if (!root) { + throw new Error( + "Cannot get or set outerHTML for a non-element", + ); + } + + if (!content) return root.outerHTML; + + root.outerHTML = content; + return this; + }; + + /** + * Gets or sets a one or more style attributes on the wrapped HTMLElement + */ + this.s = this.style = function (prop, value) { + if (!root) { + throw new Error("Cannot get or set style for a non-element"); + } + + if (typeof prop === "undefined") return root.style; + + if (typeof value !== "undefined") { + root.style[prop as any] = value; + return this; + } + + if (typeof prop === "string") return root.style[prop as any]; + + if (typeof prop !== "object") { + throw new Error( + `Invalid argument: "prop" must be string or object (found ${typeof prop})`, + ); + } + + Object.keys(prop).forEach((key) => { + (root as HTMLElement).style[key as any] = prop[key as any]; + }); + return this; + }; + + /** + * Gets or sets the wrapped HTMLElement's "innerText" property + */ + this.t = this.text = function (text) { + if (!root) { + throw new Error( + "Cannot get or set innerText for a non-element", + ); + } + + if (typeof text === "undefined") return root.innerText; + + return this.append(text); + }; + + /** + * Gets or sets the "title" attribute on the wrapped HTMLElement + */ + this.title = function (value) { + if (!root) { + throw new Error( + "Cannot get or set outerHTML for a non-element", + ); + } + + return this.attr("title", value); + }; + + /** + * Gets the wrapped HTMLElement itself + */ + this.toDom = function () { + return root; + }; + + /** + * Passes props to the "removeEventListener" function on the wrapped HTMLElement + */ + this.unlisten = function (...props) { + if (!root || !root.removeEventListener) { + throw new Error("Cannot removeEventListener on a non-element"); + } + + root.removeEventListener(...props); + return this; + }; + }; + + return FluentDom; +})(); diff --git a/src/fluent-dom-esm.type-guards.ts b/src/fluent-dom-esm.type-guards.ts new file mode 100644 index 0000000..e8c627b --- /dev/null +++ b/src/fluent-dom-esm.type-guards.ts @@ -0,0 +1,13 @@ +import type { FluentDomObject } from "./fluent-dom-esm.types"; + +export const isFluentDomObject = (value: any): value is FluentDomObject => + !!value.fluentDom; + +export const isHTMLElement = (value: any): value is HTMLElement => + !!value.nodeType; + +export const isNumber = (value: any): value is number => + typeof value === "number"; + +export const isString = (value: any): value is string => + typeof value === "string"; diff --git a/src/fluent-dom-esm.types.ts b/src/fluent-dom-esm.types.ts new file mode 100644 index 0000000..fb19a97 --- /dev/null +++ b/src/fluent-dom-esm.types.ts @@ -0,0 +1,46 @@ +export interface FluentDomObject { + fluentDom: string; + + a: (name: string, value?: string) => FluentDomObject | string | null; + app: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject; + append: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject; + attr: (name: string, value?: string) => FluentDomObject | string | null; + c: (tagName: string) => FluentDomObject; + create: (tagName: string) => FluentDomObject; + className: (className?: string) => FluentDomObject | string | null; + clear: () => FluentDomObject; + cls: (className?: string) => FluentDomObject | string | null; + clr: () => FluentDomObject; + h: (url?: string) => FluentDomObject | string | null; + href: (url?: string) => FluentDomObject | string | null; + html: (content?: string) => string | FluentDomObject; + id: (id?: string) => FluentDomObject | string | null; + l: ( + type: keyof HTMLElementEventMap, + listener: () => {}, + optionsOrUseCapture?: boolean | object, + ) => FluentDomObject; + listen: ( + type: keyof HTMLElementEventMap, + listener: () => {}, + optionsOrUseCapture?: boolean | object, + ) => FluentDomObject; + ohtml: (content?: string) => string | FluentDomObject; + s: ( + prop?: CSSStyleDeclaration | string, + value?: string, + ) => FluentDomObject | CSSStyleDeclaration | string | undefined; + style: ( + prop?: CSSStyleDeclaration | string, + value?: string, + ) => FluentDomObject | CSSStyleDeclaration | string | undefined; + t: (text?: string) => FluentDomObject | string; + text: (text?: string) => FluentDomObject | string; + title: (title?: string) => FluentDomObject | string | null; + toDom: () => HTMLElement | null; + unlisten: ( + type: keyof HTMLElementEventMap, + listener: () => {}, + optionsOrUseCapture?: boolean | object, + ) => FluentDomObject; +} diff --git a/src/license-begin.txt b/src/license-begin.txt new file mode 100644 index 0000000..77a923a --- /dev/null +++ b/src/license-begin.txt @@ -0,0 +1 @@ +// @license magnet:?xt=urn:btih:723febf9f6185544f57f0660a41489c7d6b4931b&dn=wtfpl.txt diff --git a/src/license-end.txt b/src/license-end.txt new file mode 100644 index 0000000..c2db98d --- /dev/null +++ b/src/license-end.txt @@ -0,0 +1 @@ +// @license-end diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..af8313b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..471fb65 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,27 @@ +import dts from 'unplugin-dts/vite' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vite'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineConfig({ + plugins: [dts()], + build: { + lib: { + entry: resolve(__dirname, 'src/fluent-dom-esm.ts'), + name: 'fluent-dom-esm', + fileName: 'fluent-dom-esm', + formats: ['es'] + }, + minify: false, + rollupOptions: { + output: { + banner: '/* my-library version banner */', + footer: '/* follow me on Twitter! @rich_harris footer */', + intro: '/* my-library version intro*/', + outro: '/* follow me on Twitter! @rich_harris outro */', + } + } + } +}); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..ae0defb --- /dev/null +++ b/yarn.lock @@ -0,0 +1,585 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/aix-ppc64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz#bef96351f16520055c947aba28802eede3c9e9a9" + integrity sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== + +"@esbuild/android-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz#d2e70be7d51a529425422091e0dcb90374c1546c" + integrity sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== + +"@esbuild/android-arm@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.9.tgz#d2a753fe2a4c73b79437d0ba1480e2d760097419" + integrity sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== + +"@esbuild/android-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.9.tgz#5278836e3c7ae75761626962f902a0d55352e683" + integrity sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== + +"@esbuild/darwin-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz#f1513eaf9ec8fa15dcaf4c341b0f005d3e8b47ae" + integrity sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== + +"@esbuild/darwin-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz#e27dbc3b507b3a1cea3b9280a04b8b6b725f82be" + integrity sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== + +"@esbuild/freebsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz#364e3e5b7a1fd45d92be08c6cc5d890ca75908ca" + integrity sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== + +"@esbuild/freebsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz#7c869b45faeb3df668e19ace07335a0711ec56ab" + integrity sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== + +"@esbuild/linux-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz#48d42861758c940b61abea43ba9a29b186d6cb8b" + integrity sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== + +"@esbuild/linux-arm@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz#6ce4b9cabf148274101701d112b89dc67cc52f37" + integrity sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== + +"@esbuild/linux-ia32@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz#207e54899b79cac9c26c323fc1caa32e3143f1c4" + integrity sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== + +"@esbuild/linux-loong64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz#0ba48a127159a8f6abb5827f21198b999ffd1fc0" + integrity sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== + +"@esbuild/linux-mips64el@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz#a4d4cc693d185f66a6afde94f772b38ce5d64eb5" + integrity sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== + +"@esbuild/linux-ppc64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz#0f5805c1c6d6435a1dafdc043cb07a19050357db" + integrity sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== + +"@esbuild/linux-riscv64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz#6776edece0f8fca79f3386398b5183ff2a827547" + integrity sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== + +"@esbuild/linux-s390x@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz#3f6f29ef036938447c2218d309dc875225861830" + integrity sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== + +"@esbuild/linux-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz#831fe0b0e1a80a8b8391224ea2377d5520e1527f" + integrity sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== + +"@esbuild/netbsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz#06f99d7eebe035fbbe43de01c9d7e98d2a0aa548" + integrity sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== + +"@esbuild/netbsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz#db99858e6bed6e73911f92a88e4edd3a8c429a52" + integrity sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== + +"@esbuild/openbsd-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz#afb886c867e36f9d86bb21e878e1185f5d5a0935" + integrity sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== + +"@esbuild/openbsd-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz#30855c9f8381fac6a0ef5b5f31ac6e7108a66ecf" + integrity sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== + +"@esbuild/openharmony-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz#2f2144af31e67adc2a8e3705c20c2bd97bd88314" + integrity sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== + +"@esbuild/sunos-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz#69b99a9b5bd226c9eb9c6a73f990fddd497d732e" + integrity sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== + +"@esbuild/win32-arm64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz#d789330a712af916c88325f4ffe465f885719c6b" + integrity sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== + +"@esbuild/win32-ia32@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz#52fc735406bd49688253e74e4e837ac2ba0789e3" + integrity sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== + +"@esbuild/win32-x64@0.25.9": + version "0.25.9" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz#585624dc829cfb6e7c0aa6c3ca7d7e6daa87e34f" + integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.24": + version "0.3.30" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz#4a76c4daeee5df09f5d3940e087442fb36ce2b99" + integrity sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@rollup/pluginutils@^5.1.4": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz#57ba1b0cbda8e7a3c597a4853c807b156e21a7b4" + integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^4.0.2" + +"@rollup/rollup-android-arm-eabi@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz#939c1be9625d428d8513e4ab60d406fe8db23718" + integrity sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ== + +"@rollup/rollup-android-arm64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.0.tgz#b74005775903f7a8f4e363d2840c1dcef3776ff3" + integrity sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw== + +"@rollup/rollup-darwin-arm64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.0.tgz#8c04603cdcf1ec0cd6b27152b3827e49295f2962" + integrity sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg== + +"@rollup/rollup-darwin-x64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.0.tgz#19ec976f1cc663def2692cd7ffb32981f2b0b733" + integrity sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw== + +"@rollup/rollup-freebsd-arm64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.0.tgz#a96b4ad8346229f6fcbd9d57f1c53040b037c2da" + integrity sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ== + +"@rollup/rollup-freebsd-x64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.0.tgz#fa565a282bc57967ee6668607b181678bdd74e4a" + integrity sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA== + +"@rollup/rollup-linux-arm-gnueabihf@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.0.tgz#dfc88f7295e1f98d77f25296be787e8a5d6ced75" + integrity sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w== + +"@rollup/rollup-linux-arm-musleabihf@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.0.tgz#32cd70c87455ca031f0361090cf17da5a2ef66d5" + integrity sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg== + +"@rollup/rollup-linux-arm64-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.0.tgz#0e7e1fe7241e3384f6c6b4ccdbcfa8ad8c78b869" + integrity sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g== + +"@rollup/rollup-linux-arm64-musl@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.0.tgz#5d421f2f3e4a84786c4dfd9ce97e595c9b59e7f4" + integrity sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ== + +"@rollup/rollup-linux-loongarch64-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.0.tgz#a0fb5c7d0e88319e18acfd9436f19ee39354b027" + integrity sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ== + +"@rollup/rollup-linux-ppc64-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.0.tgz#a65b598af12f25210c3295da551a6e3616ea488d" + integrity sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg== + +"@rollup/rollup-linux-riscv64-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.0.tgz#10ba776214ae2857c5bf4389690dabb2fbaf7d98" + integrity sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA== + +"@rollup/rollup-linux-riscv64-musl@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.0.tgz#c2a46cbaa329d5f21e5808f5a66bb9c78cf68aac" + integrity sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ== + +"@rollup/rollup-linux-s390x-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.0.tgz#a07447be069d64462e30c66611be20c4513963ed" + integrity sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ== + +"@rollup/rollup-linux-x64-gnu@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.0.tgz#8887c58bd51242754ae9c56947d6e883332dcc74" + integrity sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA== + +"@rollup/rollup-linux-x64-musl@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.0.tgz#6403fda72a2b3b9fbbeeff93d14f1c45ef9775f3" + integrity sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw== + +"@rollup/rollup-openharmony-arm64@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.0.tgz#52809afccaff47e731b965a0c16e5686be819d5f" + integrity sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q== + +"@rollup/rollup-win32-arm64-msvc@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.0.tgz#23fe00ddbb40b27a3889bc1e99e6310d97353ad5" + integrity sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg== + +"@rollup/rollup-win32-ia32-msvc@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.0.tgz#520b588076b593413d919912d69dfd5728a1f305" + integrity sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw== + +"@rollup/rollup-win32-x64-msvc@4.50.0": + version "4.50.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz#d81efe6a12060c7feddf9805e2a94c3ab0679f48" + integrity sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg== + +"@types/estree@1.0.8", "@types/estree@^1.0.0": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@volar/language-core@2.4.23": + version "2.4.23" + resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.23.tgz#deb6dbc5fdbafa9bb7ba691fc59cb196cdb856d3" + integrity sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ== + dependencies: + "@volar/source-map" "2.4.23" + +"@volar/source-map@2.4.23": + version "2.4.23" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.23.tgz#d476e11a3a669d89858a5eb38b02342be39b0e44" + integrity sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q== + +"@volar/typescript@^2.4.17": + version "2.4.23" + resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.23.tgz#b9b114ea01ad0ad977139edda0239fdafdb21ad7" + integrity sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag== + dependencies: + "@volar/language-core" "2.4.23" + path-browserify "^1.0.1" + vscode-uri "^3.0.8" + +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +compare-versions@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9" + integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg== + +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + +confbox@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110" + integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ== + +debug@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== + dependencies: + ms "^2.1.3" + +esbuild@^0.25.0: + version "0.25.9" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.9.tgz#15ab8e39ae6cdc64c24ff8a2c0aef5b3fd9fa976" + integrity sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.9" + "@esbuild/android-arm" "0.25.9" + "@esbuild/android-arm64" "0.25.9" + "@esbuild/android-x64" "0.25.9" + "@esbuild/darwin-arm64" "0.25.9" + "@esbuild/darwin-x64" "0.25.9" + "@esbuild/freebsd-arm64" "0.25.9" + "@esbuild/freebsd-x64" "0.25.9" + "@esbuild/linux-arm" "0.25.9" + "@esbuild/linux-arm64" "0.25.9" + "@esbuild/linux-ia32" "0.25.9" + "@esbuild/linux-loong64" "0.25.9" + "@esbuild/linux-mips64el" "0.25.9" + "@esbuild/linux-ppc64" "0.25.9" + "@esbuild/linux-riscv64" "0.25.9" + "@esbuild/linux-s390x" "0.25.9" + "@esbuild/linux-x64" "0.25.9" + "@esbuild/netbsd-arm64" "0.25.9" + "@esbuild/netbsd-x64" "0.25.9" + "@esbuild/openbsd-arm64" "0.25.9" + "@esbuild/openbsd-x64" "0.25.9" + "@esbuild/openharmony-arm64" "0.25.9" + "@esbuild/sunos-x64" "0.25.9" + "@esbuild/win32-arm64" "0.25.9" + "@esbuild/win32-ia32" "0.25.9" + "@esbuild/win32-x64" "0.25.9" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +exsolve@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.7.tgz#3b74e4c7ca5c5f9a19c3626ca857309fa99f9e9e" + integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw== + +fdir@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +local-pkg@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.2.tgz#c03d208787126445303f8161619dc701afa4abb5" + integrity sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A== + dependencies: + mlly "^1.7.4" + pkg-types "^2.3.0" + quansync "^0.2.11" + +magic-string@^0.30.17: + version "0.30.18" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.18.tgz#905bfbbc6aa5692703a93db26a9edcaa0007d2bb" + integrity sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.5" + +mlly@^1.7.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.8.0.tgz#e074612b938af8eba1eaf43299cbc89cb72d824e" + integrity sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g== + dependencies: + acorn "^8.15.0" + pathe "^2.0.3" + pkg-types "^1.3.1" + ufo "^1.6.1" + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +pathe@^2.0.1, pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^4.0.2, picomatch@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + +pkg-types@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== + dependencies: + confbox "^0.1.8" + mlly "^1.7.4" + pathe "^2.0.1" + +pkg-types@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.3.0.tgz#037f2c19bd5402966ff6810e32706558cb5b5726" + integrity sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig== + dependencies: + confbox "^0.2.2" + exsolve "^1.0.7" + pathe "^2.0.3" + +postcss@^8.5.6: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +prettier@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" + integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== + +quansync@^0.2.11: + version "0.2.11" + resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.11.tgz#f9c3adda2e1272e4f8cf3f1457b04cbdb4ee692a" + integrity sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA== + +rollup@^4.43.0: + version "4.50.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.50.0.tgz#6f237f598b7163ede33ce827af8534c929aaa186" + integrity sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw== + dependencies: + "@types/estree" "1.0.8" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.50.0" + "@rollup/rollup-android-arm64" "4.50.0" + "@rollup/rollup-darwin-arm64" "4.50.0" + "@rollup/rollup-darwin-x64" "4.50.0" + "@rollup/rollup-freebsd-arm64" "4.50.0" + "@rollup/rollup-freebsd-x64" "4.50.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.50.0" + "@rollup/rollup-linux-arm-musleabihf" "4.50.0" + "@rollup/rollup-linux-arm64-gnu" "4.50.0" + "@rollup/rollup-linux-arm64-musl" "4.50.0" + "@rollup/rollup-linux-loongarch64-gnu" "4.50.0" + "@rollup/rollup-linux-ppc64-gnu" "4.50.0" + "@rollup/rollup-linux-riscv64-gnu" "4.50.0" + "@rollup/rollup-linux-riscv64-musl" "4.50.0" + "@rollup/rollup-linux-s390x-gnu" "4.50.0" + "@rollup/rollup-linux-x64-gnu" "4.50.0" + "@rollup/rollup-linux-x64-musl" "4.50.0" + "@rollup/rollup-openharmony-arm64" "4.50.0" + "@rollup/rollup-win32-arm64-msvc" "4.50.0" + "@rollup/rollup-win32-ia32-msvc" "4.50.0" + "@rollup/rollup-win32-x64-msvc" "4.50.0" + fsevents "~2.3.2" + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +tinyglobby@^0.2.14: + version "0.2.15" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" + integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== + dependencies: + fdir "^6.5.0" + picomatch "^4.0.3" + +typescript@^5.9.2: + version "5.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" + integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== + +ufo@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" + integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== + +unplugin-dts@1.0.0-beta.6: + version "1.0.0-beta.6" + resolved "https://registry.yarnpkg.com/unplugin-dts/-/unplugin-dts-1.0.0-beta.6.tgz#a40589970e3c862f59ac082f0163d96aa47d8be6" + integrity sha512-+xbFv5aVFtLZFNBAKI4+kXmd2h+T42/AaP8Bsp0YP/je/uOTN94Ame2Xt3e9isZS+Z7/hrLCLbsVJh+saqFMfQ== + dependencies: + "@rollup/pluginutils" "^5.1.4" + "@volar/typescript" "^2.4.17" + compare-versions "^6.1.1" + debug "^4.4.0" + kolorist "^1.8.0" + local-pkg "^1.1.1" + magic-string "^0.30.17" + unplugin "^2.3.2" + +unplugin@^2.3.2: + version "2.3.10" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-2.3.10.tgz#15e75fec9384743335be7e54e5c88b5c187a3e94" + integrity sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw== + dependencies: + "@jridgewell/remapping" "^2.3.5" + acorn "^8.15.0" + picomatch "^4.0.3" + webpack-virtual-modules "^0.6.2" + +vite@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.4.tgz#354944affb55e1aff0157406b74e0d0a3232df9a" + integrity sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw== + dependencies: + esbuild "^0.25.0" + fdir "^6.5.0" + picomatch "^4.0.3" + postcss "^8.5.6" + rollup "^4.43.0" + tinyglobby "^0.2.14" + optionalDependencies: + fsevents "~2.3.3" + +vscode-uri@^3.0.8: + version "3.1.0" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c" + integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ== + +webpack-virtual-modules@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" + integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==