aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarv <rotrobmin@gmail.com>2024-02-02 20:44:14 -0800
committerGitHub <noreply@github.com>2024-02-03 04:44:14 +0000
commit97c5c741137ecc363630c58797901f1eb829c1bb (patch)
tree050bd42fc633d728d1687d51db93714efabbfe81
parente598a97f27747bef0f850dcce2ad7bdeab89e0cd (diff)
Add Prettier Formatting for Markdown Files and Pre-Commit Hook (#543)
* Install prettier, add prettierignore * Add precommit hook for md * Prettier format md files
-rw-r--r--.husky/.gitignore1
-rw-r--r--.husky/pre-commit4
-rw-r--r--.prettierignore5
-rw-r--r--README.md6
-rw-r--r--dev/lib/handlebars/README.md1
-rw-r--r--docs/browser-bugs.md154
-rw-r--r--docs/permissions.md16
-rw-r--r--docs/templates.md506
-rw-r--r--package-lock.json919
-rw-r--r--package.json9
10 files changed, 1332 insertions, 289 deletions
diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 00000000..31354ec1
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 00000000..36af2198
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx lint-staged
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..a501e2ca
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,5 @@
+# Ignore Everything
+**/**.*
+
+# Except for markdown
+!**/*.md \ No newline at end of file
diff --git a/README.md b/README.md
index c260180a..4ef50741 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
-# Yomitan <!-- omit from toc -->
+# Yomitan <!-- omit from toc -->
+
[![Chrome Release](<https://img.shields.io/chrome-web-store/v/likgccmbimhjbgkjambclfkhldnlhbnn?logo=Google%20Chrome&logoColor=lightblue&color=lightblue&label=chrome%20release%20(stable)>)](https://chrome.google.com/webstore/detail/yomitan/likgccmbimhjbgkjambclfkhldnlhbnn)
[![Firefox Release](<https://img.shields.io/amo/v/yomitan?logo=Firefox&color=orange&label=firefox%20release%20(stable)>)](https://addons.mozilla.org/en-US/firefox/addon/yomitan/)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/themoeway/yomitan/badge)](https://securityscorecards.dev/viewer/?uri=github.com/themoeway/yomitan)
-[![Discord](https://dcbadge.vercel.app/api/server/UGNPMDE7zC?style=flat)](https://discord.gg/UGNPMDE7zC)
+[![Discord](https://dcbadge.vercel.app/api/server/UGNPMDE7zC?style=flat)](https://discord.gg/UGNPMDE7zC)
:wave: **This project is a community fork of Yomichan** (which was [sunset](https://foosoft.net/posts/sunsetting-the-yomichan-project/) by its owner on Feb 26 2023). We have made a number of foundational changes to ensure **the project stays alive, works on latest browser versions, and is easy to contribute to**:
@@ -57,6 +58,7 @@ Yomitan provides advanced features not available in other browser-based dictiona
Yomitan comes in two flavors: _stable_ and _testing_. New changes are initially introduced into the _testing_ version, and after some time spent ensuring that they are relatively bug free, they will be promoted to the _stable_ version. If you are technically savvy and don't mind submitting issues on GitHub, try the _testing_ version; otherwise, the _stable_ version will be your best bet.
- **Google Chrome**
+
- [stable](https://chrome.google.com/webstore/detail/yomitan/likgccmbimhjbgkjambclfkhldnlhbnn)
- [testing](https://chrome.google.com/webstore/detail/yomitan-development-build/glnaenfapkkecknnmginabpmgkenenml)
diff --git a/dev/lib/handlebars/README.md b/dev/lib/handlebars/README.md
index cc151645..1ec14ef4 100644
--- a/dev/lib/handlebars/README.md
+++ b/dev/lib/handlebars/README.md
@@ -5,6 +5,7 @@ A custom version of the handlebars package which, to improve security, does not
## Limitations
- Only the following compile options are supported:
+
- `data`
- `knownHelpers`
- `knownHelpersOnly`
diff --git a/docs/browser-bugs.md b/docs/browser-bugs.md
index 2b7b3bad..6e4912b5 100644
--- a/docs/browser-bugs.md
+++ b/docs/browser-bugs.md
@@ -3,111 +3,133 @@
This page lists several of the browser bugs that have affected Yomichan over the years.
## Audio doesn't work when autoplay=false
-* **Browser**: Firefox
-* **Date**: 2018-06-17
-* **Issue**: [#129](https://github.com/FooSoft/yomichan/issues/129), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1466926)
+
+- **Browser**: Firefox
+- **Date**: 2018-06-17
+- **Issue**: [#129](https://github.com/FooSoft/yomichan/issues/129), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1466926)
## Ruby text layouts don't always work correctly for certain fonts
-* **Browser**: Chrome
-* **Date**: 2019-08-11
-* **Links**: [#178](https://github.com/FooSoft/yomichan/issues/178), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1045755), [Demo](https://github.com/toasted-nutbread/chrome-layout-bug)
+
+- **Browser**: Chrome
+- **Date**: 2019-08-11
+- **Links**: [#178](https://github.com/FooSoft/yomichan/issues/178), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1045755), [Demo](https://github.com/toasted-nutbread/chrome-layout-bug)
## document.execCommand('paste') doesn't work correctly on web extension background page
-* **Browser**: Firefox
-* **Date**: 2019-12-14
-* **Links**: [#307](https://github.com/FooSoft/yomichan/pull/307), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1603985), [Demo](https://github.com/toasted-nutbread/firefox-clipboard-paste-bug)
+
+- **Browser**: Firefox
+- **Date**: 2019-12-14
+- **Links**: [#307](https://github.com/FooSoft/yomichan/pull/307), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1603985), [Demo](https://github.com/toasted-nutbread/firefox-clipboard-paste-bug)
## Touch events can have incorrect position
-* **Browser**: Firefox
-* **Date**: 2020-01-18
-* **Links**: [#316](https://github.com/FooSoft/yomichan/pull/316), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1610145), [Demo](https://github.com/toasted-nutbread/firefox-touch-position-bug)
+
+- **Browser**: Firefox
+- **Date**: 2020-01-18
+- **Links**: [#316](https://github.com/FooSoft/yomichan/pull/316), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1610145), [Demo](https://github.com/toasted-nutbread/firefox-touch-position-bug)
## Triple click doesn't select text properly
-* **Browser**: Firefox
-* **Date**: 2020-01-30
-* **Issue**: [#340](https://github.com/FooSoft/yomichan/pull/340), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1612236), [Demo](https://github.com/toasted-nutbread/firefox-text-selection-bug)
+
+- **Browser**: Firefox
+- **Date**: 2020-01-30
+- **Issue**: [#340](https://github.com/FooSoft/yomichan/pull/340), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1612236), [Demo](https://github.com/toasted-nutbread/firefox-text-selection-bug)
## unhandledrejection event doesn't work correctly in content scripts
-* **Browser**: Firefox
-* **Date**: 2020-04-12
-* **Issue**: [#454](https://github.com/FooSoft/yomichan/pull/454), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1632270)
+
+- **Browser**: Firefox
+- **Date**: 2020-04-12
+- **Issue**: [#454](https://github.com/FooSoft/yomichan/pull/454), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1632270)
## chrome.tabs.sendMessage doesn't work correctly
-* **Browser**: Firefox (Nightly)
-* **Date**: 2020-06-04
-* **Links**: [#588](https://github.com/FooSoft/yomichan/issues/588), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1643649), [Demo](https://github.com/toasted-nutbread/firefox-web-extension-send-message-bug)
+
+- **Browser**: Firefox (Nightly)
+- **Date**: 2020-06-04
+- **Links**: [#588](https://github.com/FooSoft/yomichan/issues/588), [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1643649), [Demo](https://github.com/toasted-nutbread/firefox-web-extension-send-message-bug)
## CSS animations don't work correctly when using an attribute on the root
-* **Browser**: Chrome
-* **Date**: 2020-06-05
-* **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1087188), [Demo](https://github.com/toasted-nutbread/chrome-animated-text-color-bug)
+
+- **Browser**: Chrome
+- **Date**: 2020-06-05
+- **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1087188), [Demo](https://github.com/toasted-nutbread/chrome-animated-text-color-bug)
## Pen pointer events have various issues
-* **Browser**: Firefox
-* **Date**: 2020-09-12
-* **Links**: [#819](https://github.com/FooSoft/yomichan/pull/819), [#820](https://github.com/FooSoft/yomichan/pull/820), [#821](https://github.com/FooSoft/yomichan/pull/821), [#824](https://github.com/FooSoft/yomichan/pull/824), [Report 1](https://bugzilla.mozilla.org/show_bug.cgi?id=1449660), [Report 2](https://bugzilla.mozilla.org/show_bug.cgi?id=1487509), [Report 3](https://bugzilla.mozilla.org/show_bug.cgi?id=1583480), [Report 4](https://bugzilla.mozilla.org/show_bug.cgi?id=1583519), [Report 5](https://bugzilla.mozilla.org/show_bug.cgi?id=1631377)
+
+- **Browser**: Firefox
+- **Date**: 2020-09-12
+- **Links**: [#819](https://github.com/FooSoft/yomichan/pull/819), [#820](https://github.com/FooSoft/yomichan/pull/820), [#821](https://github.com/FooSoft/yomichan/pull/821), [#824](https://github.com/FooSoft/yomichan/pull/824), [Report 1](https://bugzilla.mozilla.org/show_bug.cgi?id=1449660), [Report 2](https://bugzilla.mozilla.org/show_bug.cgi?id=1487509), [Report 3](https://bugzilla.mozilla.org/show_bug.cgi?id=1583480), [Report 4](https://bugzilla.mozilla.org/show_bug.cgi?id=1583519), [Report 5](https://bugzilla.mozilla.org/show_bug.cgi?id=1631377)
## Cannot read clipboard from service worker in a MV3 chrome extension
-* **Browser**: Chrome
-* **Date**: 2020-12-18
-* **Links**: [#455](https://github.com/FooSoft/yomichan/issues/455), [#1247](https://github.com/FooSoft/yomichan/issues/1247), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1160302)
+
+- **Browser**: Chrome
+- **Date**: 2020-12-18
+- **Links**: [#455](https://github.com/FooSoft/yomichan/issues/455), [#1247](https://github.com/FooSoft/yomichan/issues/1247), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1160302)
## Textareas display incorrectly when they have an animated CSS transform
-* **Browser**: Chrome
-* **Date**: 2021-01-30
-* **Links**: [Demo](https://toasted-nutbread.github.io/chrome-textarea-transform-bug/), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1172666)
+
+- **Browser**: Chrome
+- **Date**: 2021-01-30
+- **Links**: [Demo](https://toasted-nutbread.github.io/chrome-textarea-transform-bug/), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1172666)
## Chrome extensions using port connections can crash the browser using manifest version 3
-* **Browser**: Chrome
-* **Date**: 2021-02-13
-* **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-port-connect-crash), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1178179)
+
+- **Browser**: Chrome
+- **Date**: 2021-02-13
+- **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-port-connect-crash), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1178179)
## Chrome extension Port.onDisconnect event does not always fire in content scripts
-* **Browser**: Chrome
-* **Date**: 2021-02-13
-* **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-port-disconnect-bug), [Report 1](https://bugs.chromium.org/p/chromium/issues/detail?id=1178188) (MV2), [Report 2](https://bugs.chromium.org/p/chromium/issues/detail?id=1178189) (MV3)
+
+- **Browser**: Chrome
+- **Date**: 2021-02-13
+- **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-port-disconnect-bug), [Report 1](https://bugs.chromium.org/p/chromium/issues/detail?id=1178188) (MV2), [Report 2](https://bugs.chromium.org/p/chromium/issues/detail?id=1178189) (MV3)
## Ruby elements with padding have incorrect layout
-* **Browser**: Firefox
-* **Date**: 2021-03-05
-* **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1696721)
+
+- **Browser**: Firefox
+- **Date**: 2021-03-05
+- **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1696721)
## Focus changes don't preserve caret position for caret browsing
-* **Browser**: Chrome
-* **Date**: 2021-05-19
-* **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1211175)
+
+- **Browser**: Chrome
+- **Date**: 2021-05-19
+- **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1211175)
## CSS :active state on &lt;label&gt; element doesn't match state on inner element
-* **Browser**: Chrome
-* **Date**: 2021-05-19
-* **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1211182)
+
+- **Browser**: Chrome
+- **Date**: 2021-05-19
+- **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1211182)
## Caret browsing doesn't work properly for certain display:none elements
-* **Browser**: Firefox
-* **Date**: 2021-06-06
-* **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1714883)
+
+- **Browser**: Firefox
+- **Date**: 2021-06-06
+- **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1714883)
## IndexedDB writes from a Worker thread do not persist if worker is terminated
-* **Browser**: ~~Chrome~~, Firefox _(warning only)_
-* **Date**: 2021-08-07
-* **Links**: ~~[Chrome Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1237686)~~, [Firefox Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1724602)
+
+- **Browser**: ~~Chrome~~, Firefox _(warning only)_
+- **Date**: 2021-08-07
+- **Links**: ~~[Chrome Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1237686)~~, [Firefox Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1724602)
## Web extension content scripts don't run on certain about:blank popups
-* **Browser**: Firefox
-* **Date**: 2021-08-16
-* **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1726068)
+
+- **Browser**: Firefox
+- **Date**: 2021-08-16
+- **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1726068)
## Touch events report incorrect clientX on wide pages with writing-mode:vertical-rl
-* **Browser**: Chrome
-* **Date**: 2022-01-31
-* **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1292815)
+
+- **Browser**: Chrome
+- **Date**: 2022-01-31
+- **Links**: [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1292815)
## Chrome extensions can't auto-play media from an embedded extension frame
-* **Browser**: Chrome
-* **Date**: 2022-04-03
-* **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-audio-autoplay-bug), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1312816)
+
+- **Browser**: Chrome
+- **Date**: 2022-04-03
+- **Links**: [Demo](https://github.com/toasted-nutbread/chrome-extension-audio-autoplay-bug), [Report](https://bugs.chromium.org/p/chromium/issues/detail?id=1312816)
## DOMException.data sometimes throws error on assignment
-* **Browser**: Firefox
-* **Date**: 2022-06-25
-* **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1776555)
+
+- **Browser**: Firefox
+- **Date**: 2022-06-25
+- **Links**: [Report](https://bugzilla.mozilla.org/show_bug.cgi?id=1776555)
diff --git a/docs/permissions.md b/docs/permissions.md
index 92d5e06f..d20d25f9 100644
--- a/docs/permissions.md
+++ b/docs/permissions.md
@@ -1,39 +1,39 @@
# Yomitan Permissions
-* `<all_urls>` <br>
+- `<all_urls>` <br>
Yomitan requires access to all URLs in order to run scripts to scan text and show the definitions popup,
request audio for playback and download, and connect with Anki.
-* `storage` and `unlimitedStorage` <br>
+- `storage` and `unlimitedStorage` <br>
Yomitan uses storage permissions in order to save extension settings and dictionary data.
`unlimitedStorage` is used to help prevent web browsers from unexpectedly
deleting dictionary data.
-* `declarativeNetRequest` <br>
+- `declarativeNetRequest` <br>
Yomitan uses this permission to ensure certain requests have valid and secure headers.
This sometimes involves removing or changing the `Origin` request header,
as this can be used to fingerprint browser configuration.
-* `scripting` <br>
+- `scripting` <br>
Yomitan needs to inject content scripts and stylesheets into webpages in order to
properly display the search popup.
-* `offscreen` _(Chrome only)_ <br>
+- `offscreen` _(Chrome only)_ <br>
Yomitan uses this permission to create a secondary backend document that has DOM access, given that Manifest v3
service workers do not. Service workers can then reach out to out to this document in order to complete
actions that require access to DOM APIs, such as any that require clipboard access.
-* `clipboardWrite` <br>
+- `clipboardWrite` <br>
Yomitan supports simulating the `Ctrl+C` (copy to clipboard) keyboard shortcut
when a definitions popup is open and focused.
-* `clipboardRead` _(optional)_ <br>
+- `clipboardRead` _(optional)_ <br>
Yomitan supports automatically opening a search window when Japanese text is copied to the clipboard
while the browser is running, depending on how certain settings are configured.
This allows Yomitan to support scanning text from external applications, provided there is a way
to copy text from those applications to the clipboard.
-* `nativeMessaging` _(optional, unavailable on Firefox for Android)_ <br>
+- `nativeMessaging` _(optional, unavailable on Firefox for Android)_ <br>
Yomitan has the ability to communicate with an optional native messaging component in order to support
parsing large blocks of Japanese text using
[MeCab](https://en.wikipedia.org/wiki/MeCab).
diff --git a/docs/templates.md b/docs/templates.md
index ddab4390..3f51dc98 100644
--- a/docs/templates.md
+++ b/docs/templates.md
@@ -5,7 +5,6 @@
Yomitan supports several custom Handlebars helpers for rendering templates.
The source code for these templates can be found [here](../ext/js/templates/sandbox/anki-template-renderer.js).
-
### `dumpObject`
Converts an object to a pretty-printed JSON string.
@@ -14,33 +13,38 @@ This function can be helpful for debugging values when creating templates.
<details>
<summary>Syntax:</summary>
- <code>{{dumpObject <i>object</i>}}</code>
+<code>{{dumpObject <i>object</i>}}</code>
- * _`object`_ <br>
- The object to convert.
+- _`object`_ <br>
+The object to convert.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
<pre>{{dumpObject .}}</pre>
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
<pre>{
"key": "value"
}</pre>
```
- Preview:
+Preview:
+
+<!-- prettier-ignore -->
```html
{
"key": "value"
}
```
-</details>
+</details>
### `furigana`
@@ -49,34 +53,37 @@ Converts a definition or expression/reading pair to its furigana representation.
<details>
<summary>Syntax:</summary>
- <code>{{furigana <i>definition</i>}}</code><br>
- <code>{{furigana <i>expression</i> <i>reading</i>}}</code><br>
+<code>{{furigana <i>definition</i>}}</code><br>
+<code>{{furigana <i>expression</i> <i>reading</i>}}</code><br>
- * _`definition`_ <br>
- The definition to convert.
- * _`expression`_ <br>
- The expression to convert.
- * _`reading`_ <br>
- The reading to convert.
+- _`definition`_ <br>
+ The definition to convert.
+- _`expression`_ <br>
+ The expression to convert.
+- _`reading`_ <br>
+The reading to convert.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{furigana .}}
{{furigana "読む" "よむ"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
<ruby>読<rt>よ</rt></ruby>む
```
- Preview
+Preview
+
<pre><ruby>読<rt>よ</rt></ruby>む</pre>
</details>
-
### `furiganaPlain`
Converts a definition or expression/reading pair to its simplified furigana representation.
@@ -84,30 +91,33 @@ Converts a definition or expression/reading pair to its simplified furigana repr
<details>
<summary>Syntax:</summary>
- <code>{{furiganaPlain <i>definition</i>}}</code>
- <code>{{furiganaPlain <i>expression</i> <i>reading</i>}}</code><br>
+<code>{{furiganaPlain <i>definition</i>}}</code>
+<code>{{furiganaPlain <i>expression</i> <i>reading</i>}}</code><br>
- * _`definition`_ <br>
- The definition to convert.
- * _`expression`_ <br>
- The expression to convert.
- * _`reading`_ <br>
- The reading to convert.
+- _`definition`_ <br>
+ The definition to convert.
+- _`expression`_ <br>
+ The expression to convert.
+- _`reading`_ <br>
+The reading to convert.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{~furiganaPlain .~}}
{{furiganaPlain "読む" "よむ"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
読[よ]む
```
-</details>
+</details>
### `multiLine`
@@ -116,11 +126,13 @@ Replaces newline characters with a forced HTML line break `<br>`.
<details>
<summary>Syntax:</summary>
- <code>{{#multiLine}}<i>text with multiple lines</i>{{/multiLine}}</code>
+<code>{{#multiLine}}<i>text with multiple lines</i>{{/multiLine}}</code>
+
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#multiLine~}}
some
@@ -129,16 +141,18 @@ Replaces newline characters with a forced HTML line break `<br>`.
{{~/multiLine}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
some<br>multiline<br>text
```
- Preview:
+Preview:
+
<pre>some<br>multiline<br>text</pre>
</details>
-
### `regexReplace`
Uses a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to replace a pattern with the specified text.
@@ -146,32 +160,35 @@ Uses a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScr
<details>
<summary>Syntax:</summary>
- <code>{{#regexReplace <i>regex</i> <i>replacement</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexReplace}}</code><br>
- <code>{{regexReplace <i>regex</i> <i>replacement</i> <i>[flags]</i> <i>[text-to-modify]...</i>}}</code><br>
+<code>{{#regexReplace <i>regex</i> <i>replacement</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexReplace}}</code><br>
+<code>{{regexReplace <i>regex</i> <i>replacement</i> <i>[flags]</i> <i>[text-to-modify]...</i>}}</code><br>
- * _`regex`_ <br>
- The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
- * _`replacement`_ <br>
- The text used to replace pattern matches. This supports the standard [special capture group replacements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) as supported by the web browser.
- * _`flags`_ _(optional)_ <br>
- Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
- * _`text-to-modify`_ <br>
- The text that the regular expression is applied to.
- If multiple arguments are present, they are all concatenated.
+- _`regex`_ <br>
+ The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
+- _`replacement`_ <br>
+ The text used to replace pattern matches. This supports the standard [special capture group replacements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) as supported by the web browser.
+- _`flags`_ _(optional)_ <br>
+ Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
+- _`text-to-modify`_ <br>
+The text that the regular expression is applied to.
+If multiple arguments are present, they are all concatenated.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#regexReplace "\(([^)]*)\)" "$1" "g"~}}Here is (some) (text) (in) (parentheses){{~/regexReplace}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
Here is some text in parentheses
```
-</details>
+</details>
### `regexMatch`
@@ -180,30 +197,33 @@ Uses a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScr
<details>
<summary>Syntax:</summary>
- <code>{{#regexMatch <i>regex</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexMatch}}</code><br>
- <code>{{regexMatch <i>regex</i> <i>[flags]</i> <i>[text-to-modify]...</i>}}</code><br>
+<code>{{#regexMatch <i>regex</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexMatch}}</code><br>
+<code>{{regexMatch <i>regex</i> <i>[flags]</i> <i>[text-to-modify]...</i>}}</code><br>
- * _`regex`_ <br>
- The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
- * _`flags`_ _(optional)_ <br>
- Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
- * _`text-to-modify`_ <br>
- The text that the regular expression is applied to.
- If multiple arguments are present, they are all concatenated.
+- _`regex`_ <br>
+ The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
+- _`flags`_ _(optional)_ <br>
+ Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
+- _`text-to-modify`_ <br>
+The text that the regular expression is applied to.
+If multiple arguments are present, they are all concatenated.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#regexMatch "\(([^)]*)\)" "g"~}}Here is (some) (text) (in) (parentheses){{~/regexMatch}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
(some)(text)(in)(parentheses)
```
-</details>
+</details>
### `mergeTags`
@@ -212,28 +232,31 @@ Creates a set of all unique tags for the definition and returns a text represent
<details>
<summary>Syntax:</summary>
- <code>{{mergeTags <i>definition</i> <i>isGroupMode</i> <i>isMergeMode</i>}}</code>
+<code>{{mergeTags <i>definition</i> <i>isGroupMode</i> <i>isMergeMode</i>}}</code>
- * _`definition`_ <br>
- The root definition object.
- * _`isGroupMode`_ _(optional)_ <br>
- Whether or not the display mode is the 'group' mode.
- * _`isMergeMode`_ <br>
- Whether or not the display mode is the 'merge' mode.
+- _`definition`_ <br>
+ The root definition object.
+- _`isGroupMode`_ _(optional)_ <br>
+ Whether or not the display mode is the 'group' mode.
+- _`isMergeMode`_ <br>
+Whether or not the display mode is the 'merge' mode.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{~mergeTags definition group merge~}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
v5m, vt, JMdict (English)
```
-</details>
+</details>
### `#eachUpTo`
@@ -243,34 +266,37 @@ If the iterable is falsy or empty, the `else` condition will be used.
<details>
<summary>Syntax:</summary>
- <code>{{#eachUpTo <i>iterable</i> <i>maxCount</i>}}<i>(modification)</i>{{else}}<i>(else-modification)</i>{{/eachUpTo}}</code>
+<code>{{#eachUpTo <i>iterable</i> <i>maxCount</i>}}<i>(modification)</i>{{else}}<i>(else-modification)</i>{{/eachUpTo}}</code>
- * _`iterable`_ <br>
- The object that should be looped over. A JavaScript [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop is used, so the object only needs to be iterable.
- * _`maxCount`_ _(optional)_ <br>
- The maximum number of entries to loop over.
- * _`modification`_ <br>
- The template used to modify the value. The context is changed to the current item of iteration.
- * _`else-modification`_ <br>
- The template used in case the iterable is falsy or empty. The context is unchanged.
+- _`iterable`_ <br>
+ The object that should be looped over. A JavaScript [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop is used, so the object only needs to be iterable.
+- _`maxCount`_ _(optional)_ <br>
+ The maximum number of entries to loop over.
+- _`modification`_ <br>
+ The template used to modify the value. The context is changed to the current item of iteration.
+- _`else-modification`_ <br>
+The template used in case the iterable is falsy or empty. The context is unchanged.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{~#eachUpTo someArray 5}}{{{.}}}<br>{{else}}Empty{{/mergeTags~}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
someArray[0]<br>someArray[1]<br>someArray[2]<br>someArray[3]<br>someArray[4]<br>
```
- Preview:
+Preview:
+
<pre>someArray[0]<br>someArray[1]<br>someArray[2]<br>someArray[3]<br>someArray[4]<br></pre>
</details>
-
### `spread`
Uses the JavaScript [spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) operator to convert one or more iterables into a single array.
@@ -279,71 +305,77 @@ This allows it to be used similar to an [`Array.concat`](https://developer.mozil
<details>
<summary>Syntax:</summary>
- <code>{{spread <i>iterable1</i> <i>iterable2</i> <i>...</i> <i>iterableN</i>}}</code>
+<code>{{spread <i>iterable1</i> <i>iterable2</i> <i>...</i> <i>iterableN</i>}}</code>
- * _`iterableN`_ <br>
- A variable amount of iterable objects to combine into a single array.
+- _`iterableN`_ <br>
+A variable amount of iterable objects to combine into a single array.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#each (spread array1 array2)}}{{{.}}}<br>{{/each}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
array1[0]<br>array1[1]<br>array2[0]<br>array2[1]<br>
```
- Preview:
+Preview:
+
<pre>array1[0]<br>array1[1]<br>array2[0]<br>array2[1]<br></pre>
</details>
-
### `op`
Performs a simple operation on one, two, or three arguments. The operations available are:
-* Unary operators: `+`, `-`, `~`, `!`
-* Binary operators: `+`, `-`, `/`, `*`, `%`, `**`, `==`, `!=`, `===`, `!==`, `<`, `<=`, `>`, `>=`, `<<`, `>>`, `>>>`, `&`, `|`, `^`, `&&`, `||`
-* Ternary operators: `?:`
+- Unary operators: `+`, `-`, `~`, `!`
+- Binary operators: `+`, `-`, `/`, `*`, `%`, `**`, `==`, `!=`, `===`, `!==`, `<`, `<=`, `>`, `>=`, `<<`, `>>`, `>>>`, `&`, `|`, `^`, `&&`, `||`
+- Ternary operators: `?:`
If an unknown operator is specified, the `undefined` value is returned.
<details>
<summary>Syntax:</summary>
- <code>{{op <i>operator</i> <i>operand1</i> <i>[operand2]</i> <i>[operand3]</i>}}</code>
+<code>{{op <i>operator</i> <i>operand1</i> <i>[operand2]</i> <i>[operand3]</i>}}</code>
- * _`operator`_ <br>
- One of the unary, binary, or ternary operators.
- * _`operand1`_ <br>
- The first operand of the operation.
- * _`operand2`_ _(Optional)_<br>
- The second operand of the operation.
- * _`operand3`_ _(Optional)_<br>
- The third operand of the operation.
+- _`operator`_ <br>
+ One of the unary, binary, or ternary operators.
+- _`operand1`_ <br>
+ The first operand of the operation.
+- _`operand2`_ _(Optional)_<br>
+ The second operand of the operation.
+- _`operand3`_ _(Optional)_<br>
+The third operand of the operation.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#if (op "===" value1 value2)}}Values are equal{{/if~}}<br>
{{~#op "-" value1}}{{/op~}}<br>
{{~op "?:" value1 "a" "b"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
Values are equal<br>-32<br>a
```
- Preview:
+Preview:
+
<pre>Values are equal<br>-32<br>a</pre>
</details>
-
### `get`
Gets a value from the custom state stack.
@@ -351,24 +383,27 @@ Gets a value from the custom state stack.
<details>
<summary>Syntax:</summary>
- <code>{{get <i>name</i>}}</code>
+<code>{{get <i>name</i>}}</code>
- * _`name`_ <br>
- The name of the variable to get.
+- _`name`_ <br>
+The name of the variable to get.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{get "some-text"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
This is the value of some-text!
```
-</details>
+</details>
### `set`
@@ -377,27 +412,30 @@ Assigns a value to the custom state stack.
<details>
<summary>Syntax:</summary>
- <code>{{#set <i>name</i>}}<i>value</i>{{/get}}</code><br>
- <code>{{set <i>name</i> <i>value</i>}}</code><br>
+<code>{{#set <i>name</i>}}<i>value</i>{{/get}}</code><br>
+<code>{{set <i>name</i> <i>value</i>}}</code><br>
- * _`name`_ <br>
- The name of the variable to assign.
- * _`value`_ <br>
- The value of the variable.
+- _`name`_ <br>
+ The name of the variable to assign.
+- _`value`_ <br>
+The value of the variable.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#set "some-text"}}This is the value of some-text!{{/set~}}
{{~set "some-number" 32}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
```
-</details>
+</details>
### `#scope`
@@ -408,16 +446,17 @@ and variable lookups will start from the most recent scope and work backwards un
<details>
<summary>Syntax:</summary>
- <code>{{#scope}}<i>content</i>{{/scope}}</code>
+<code>{{#scope}}<i>content</i>{{/scope}}</code>
- * _`name`_ <br>
- The name of the variable to assign.
- * _`value`_ <br>
- The value of the variable.
+- _`name`_ <br>
+ The name of the variable to assign.
+- _`value`_ <br>
+The value of the variable.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{~set "key" 32~}}
{{~get "key"~}},
@@ -429,12 +468,14 @@ and variable lookups will start from the most recent scope and work backwards un
{{~get "key"~}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
32,32,64,32
```
-</details>
+</details>
### `property`
@@ -443,26 +484,29 @@ Repeatedly gets a property of an object.
<details>
<summary>Syntax:</summary>
- <code>{{property <i>object</i> <i>property1</i> <i>property2</i> <i>...</i> <i>propertyN</i>}}</code>
+<code>{{property <i>object</i> <i>property1</i> <i>property2</i> <i>...</i> <i>propertyN</i>}}</code>
- * _`object`_ <br>
- The initial object to use.
- * _`propertyN`_ <br>
- A chain of property names to get on the object.
+- _`object`_ <br>
+ The initial object to use.
+- _`propertyN`_ <br>
+A chain of property names to get on the object.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{property someObject "field" 0 "toString"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
function toString() { [native code] }
```
-</details>
+</details>
### `noop`
@@ -471,21 +515,25 @@ No-op. Returns the inner contents of the template.
<details>
<summary>Syntax:</summary>
- <code>{{#noop}}<i>content</i>{{/noop}}</code>
+<code>{{#noop}}<i>content</i>{{/noop}}</code>
+
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{noop}}Unchanged content{{/noop}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
Unchanged content
```
-</details>
+</details>
### `isMoraPitchHigh`
@@ -494,21 +542,25 @@ Returns whether or not a mora will have a high pitch, given the index of the mor
<details>
<summary>Syntax:</summary>
- <code>{{isMoraPitchHigh <i>index</i> <i>position</i>}}</code>
+<code>{{isMoraPitchHigh <i>index</i> <i>position</i>}}</code>
+
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#if (isMoraPitchHigh 1 2)}}High pitch{{else}}Low pitch{{/if}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
High pitch
```
-</details>
+</details>
### `getKanaMorae`
@@ -517,25 +569,29 @@ Returns an array of the mora for a kana string.
<details>
<summary>Syntax:</summary>
- <code>{{getKanaMorae <i>kana-string</i>}}</code>
+<code>{{getKanaMorae <i>kana-string</i>}}</code>
+
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#each (getKanaMorae "よみたん")}}{{{.}}}<br>{{/each}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
よ<br>み<br>た<br>ん<br>
```
- Preview:
+Preview:
+
<pre>よ<br>み<br>た<br>ん<br></pre>
</details>
-
### `typeof`
Returns the type of a value. `#typeof` in the block form will always return `'string'`.
@@ -543,29 +599,32 @@ Returns the type of a value. `#typeof` in the block form will always return `'st
<details>
<summary>Syntax:</summary>
- <code>{{typeof <i>value</i>}}</code><br>
- <code>{{#typeof}}<i>value</i>{{/typeof}}</code><br>
+<code>{{typeof <i>value</i>}}</code><br>
+<code>{{#typeof}}<i>value</i>{{/typeof}}</code><br>
- * _`value`_ <br>
- The value to check.
+- _`value`_ <br>
+The value to check.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{typeof "よみたん"}}
{{typeof 1}}
{{#typeof}}よみたん{{/typeof}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
string
number
string
```
-</details>
+</details>
### `join`
@@ -574,27 +633,30 @@ Joins the arguments to a single string with a separator, flattening any argument
<details>
<summary>Syntax:</summary>
- <code>{{join <i>separator</i> <i>value1</i> <i>value2</i> <i>valueN</i>...}}</code><br>
+<code>{{join <i>separator</i> <i>value1</i> <i>value2</i> <i>valueN</i>...}}</code><br>
- * _`separator`_ <br>
- The separator string to use between values.
- * _`valueN`_ <br>
- An individual value to join into the resulting string
+- _`separator`_ <br>
+ The separator string to use between values.
+- _`valueN`_ <br>
+An individual value to join into the resulting string
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{set "index" 32~}}
{{~join "_" "yomitan" (get "index") "value"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
yomitan_32_value
```
-</details>
+</details>
### `concat`
@@ -603,25 +665,28 @@ Joins the arguments to a single string, without flattening arguments that are ar
<details>
<summary>Syntax:</summary>
- <code>{{concat <i>value1</i> <i>value1</i> <i>valueN</i>...}}</code><br>
+<code>{{concat <i>value1</i> <i>value1</i> <i>valueN</i>...}}</code><br>
- * _`valueN`_ <br>
- A value to join into the resulting string
+- _`valueN`_ <br>
+A value to join into the resulting string
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{set "index" 32~}}
{{~concat "yomitan_" (get "index") "_value"}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
yomitan_32_value
```
-</details>
+</details>
### `pitchCategories`
@@ -630,24 +695,27 @@ Returns an array representing the different pitch categories for a specific term
<details>
<summary>Syntax:</summary>
- <code>{{pitchCategories @root}}</code><br>
+<code>{{pitchCategories @root}}</code><br>
- * _`@root`_ <br>
- The argument passed should always be the root data object.
+- _`@root`_ <br>
+The argument passed should always be the root data object.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
[{{#each (pitchCategories @root)}}{{.}}{{#unless @last}}, {{/unless}}{{/each}}]
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
[heiban, kifuku]
```
-</details>
+</details>
### `formatGlossary`
@@ -657,26 +725,29 @@ structured-content generation.
<details>
<summary>Syntax:</summary>
- <code>{{formatGlossary <i>dictionary</i> <i>definitionEntry</i>}}</code><br>
+<code>{{formatGlossary <i>dictionary</i> <i>definitionEntry</i>}}</code><br>
- * _`dictionary`_ <br>
- The dictionary that the glossary entry belongs to.
- * _`definitionEntry`_ <br>
- The definition entry object in raw form.
+- _`dictionary`_ <br>
+ The dictionary that the glossary entry belongs to.
+- _`definitionEntry`_ <br>
+The definition entry object in raw form.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
Here is the content of a gloss, which may include formatted HTML.
```
-</details>
+</details>
### `hasMedia` & `getMedia`
@@ -686,29 +757,30 @@ These functions are used together in order to request media and other types of o
<details>
<summary>Syntax:</summary>
- <code>{{hasMedia <i>type</i> <i>args</i>...}}</code><br>
- <code>{{getMedia <i>type</i> <i>args</i>... <i>[escape=true|false]</i>}}</code><br>
+<code>{{hasMedia <i>type</i> <i>args</i>...}}</code><br>
+<code>{{getMedia <i>type</i> <i>args</i>... <i>[escape=true|false]</i>}}</code><br>
- * _`type`_ <br>
- The type of media to check for.
- * _`args`_ <br>
- Additional arguments for the media. The arguments depend on the media type.
- * _`escape`_ _(optional)_ <br>
- Whether or not the resulting text should be HTML-escaped. If omitted, defaults to `true`.
+- _`type`_ <br>
+ The type of media to check for.
+- _`args`_ <br>
+ Additional arguments for the media. The arguments depend on the media type.
+- _`escape`_ _(optional)_ <br>
+ Whether or not the resulting text should be HTML-escaped. If omitted, defaults to `true`.
- **Available media types and arguments**
+**Available media types and arguments**
- * <code>"audio"</code>
- * <code>"screenshot"</code>
- * <code>"clipboardImage"</code>
- * <code>"clipboardText"</code>
- * <code>"selectionText"</code>
- * <code>"textFurigana" <i>japaneseText</i> <i>readingMode="default|hiragana|katakana"</i></code>
- * <code>"dictionaryMedia" <i>fileName</i> <i>dictionary="Dictionary Name"</i></code>
+- <code>"audio"</code>
+- <code>"screenshot"</code>
+- <code>"clipboardImage"</code>
+- <code>"clipboardText"</code>
+- <code>"selectionText"</code>
+- <code>"textFurigana" <i>japaneseText</i> <i>readingMode="default|hiragana|katakana"</i></code>
+- <code>"dictionaryMedia" <i>fileName</i> <i>dictionary="Dictionary Name"</i></code>
</details>
<details>
<summary>Examples:</summary>
+<!-- prettier-ignore -->
```handlebars
{{#if (hasMedia "audio")}}The audio file name is: {{getMedia "audio"}}{{/if}}
@@ -725,7 +797,9 @@ These functions are used together in order to request media and other types of o
{{#if (hasMedia "dictionaryMedia" "image.png" dictionary="Example Dictionary")}}The remapped file name for image.png is: {{getMedia "dictionaryMedia" "image.png" dictionary="Example Dictionary"}}{{/if}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
The audio file name is: yomitan_audio_にほんご_日本語.mp3
@@ -743,8 +817,8 @@ These functions are used together in order to request media and other types of o
The remapped file name for image.png is: yomitan_dictionary_media_1_にほんご_日本語.png
```
-</details>
+</details>
### `pronunciation`
@@ -754,30 +828,31 @@ same as the system used for generating popup and search page dictionary entries.
<details>
<summary>Syntax:</summary>
- <code>{{pronunciation <i>format=string</i> <i>reading=string</i> <i>downstepPosition=integer</i> <i>[nasalPositions=array]</i> <i>[devoicePositions=array]</i>}}</code><br>
+<code>{{pronunciation <i>format=string</i> <i>reading=string</i> <i>downstepPosition=integer</i> <i>[nasalPositions=array]</i> <i>[devoicePositions=array]</i>}}</code><br>
- * _`format`_ <br>
- The format of the HTML to generate. This can be any of the following values:
- * `'text'`
- * `'graph'`
- * `'position'`
- * _`reading`_ <br>
- The kana reading of the term.
- * _`downstepPosition`_ <br>
- The mora position of the downstep in the reading.
- * _`nasalPositions`_ _(optional)_ <br>
- An array of indices of mora that have a nasal pronunciation.
- * _`devoicePositions`_ _(optional)_ <br>
- An array of indices of mora that are devoiced.
+- _`format`_ <br>
+ The format of the HTML to generate. This can be any of the following values:
+ - `'text'`
+ - `'graph'`
+ - `'position'`
+- _`reading`_ <br>
+ The kana reading of the term.
+- _`downstepPosition`_ <br>
+ The mora position of the downstep in the reading.
+- _`nasalPositions`_ _(optional)_ <br>
+ An array of indices of mora that have a nasal pronunciation.
+- _`devoicePositions`_ _(optional)_ <br>
+An array of indices of mora that are devoiced.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{~pronunciation format='text' reading='よむ' downstepPosition=1~}}
```
-</details>
+</details>
### `hiragana`
@@ -786,18 +861,19 @@ Converts katakana text to hiragana.
<details>
<summary>Syntax:</summary>
- <code>{{hiragana <i>value</i> <i>[keepProlongedSoundMarks=true|false]</i>}}</code><br>
- <code>{{#hiragana <i>[keepProlongedSoundMarks=true|false]</i>}}<i>value</i>{{/hiragana}}</code><br>
+<code>{{hiragana <i>value</i> <i>[keepProlongedSoundMarks=true|false]</i>}}</code><br>
+<code>{{#hiragana <i>[keepProlongedSoundMarks=true|false]</i>}}<i>value</i>{{/hiragana}}</code><br>
- * _`value`_ <br>
- The text to convert.
- * _`keepProlongedSoundMarks`_ _(optional)_ <br>
- Whether or not the `ー` character should be kept or converted to a vowel character.
- Defaults to `false` if not specified.
+- _`value`_ <br>
+ The text to convert.
+- _`keepProlongedSoundMarks`_ _(optional)_ <br>
+Whether or not the `ー` character should be kept or converted to a vowel character.
+Defaults to `false` if not specified.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{hiragana "よみたん ヨミたん ヨミタン"}}
{{#hiragana}}よみたん ヨミたん ヨミタン{{/hiragana}}
@@ -805,15 +881,17 @@ Converts katakana text to hiragana.
{{#hiragana keepProlongedSoundMarks=true}}ローマ字{{/hiragana}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
よみたん よみたん よみたん
よみたん よみたん よみたん
ろうま字
ろーま字
```
-</details>
+</details>
### `katakana`
@@ -822,23 +900,27 @@ Converts hiragana text to katakana.
<details>
<summary>Syntax:</summary>
- <code>{{katakana <i>text</i>}}</code><br>
- <code>{{#katakana}}<i>text</i>{{/katakana}}</code><br>
+<code>{{katakana <i>text</i>}}</code><br>
+<code>{{#katakana}}<i>text</i>{{/katakana}}</code><br>
- * _`text`_ <br>
- The text to convert.
+- _`text`_ <br>
+The text to convert.
</details>
<details>
<summary>Example:</summary>
+<!-- prettier-ignore -->
```handlebars
{{katakana "よみたん ヨミたん ヨミタン"}}
{{#katakana}}よみたん ヨミたん ヨミタン{{/katakana}}
```
- Output:
+Output:
+
+<!-- prettier-ignore -->
```html
ヨミタン ヨミタン ヨミタン
ヨミタン ヨミタン ヨミタン
```
+
</details>
diff --git a/package-lock.json b/package-lock.json
index 114a0cb1..1473fe65 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,9 +47,12 @@
"eslint-plugin-vitest": "^0.3.20",
"fake-indexeddb": "^5.0.2",
"html-validate": "^8.8.0",
+ "husky": "^9.0.10",
"jsdom": "^24.0.0",
"jszip": "^3.10.1",
"license-report": "^6.5.0",
+ "lint-staged": "^15.2.1",
+ "prettier": "^3.2.4",
"stylelint": "^16.1.0",
"stylelint-config-recommended": "^14.0.0",
"ts-json-schema-generator": "^1.5.0",
@@ -1895,6 +1898,33 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ansi-escapes": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz",
+ "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2110,6 +2140,127 @@
"node": "*"
}
},
+ "node_modules/cli-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
+ "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2134,6 +2285,12 @@
"integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
"dev": true
},
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2894,6 +3051,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "dev": true
+ },
"node_modules/execa": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
@@ -3121,6 +3284,18 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/get-east-asian-width": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
+ "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/get-func-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
@@ -3477,6 +3652,21 @@
"node": ">=16.17.0"
}
},
+ "node_modules/husky": {
+ "version": "9.0.10",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.10.tgz",
+ "integrity": "sha512-TQGNknoiy6bURzIO77pPRu+XHi6zI7T93rX+QnJsoYFf3xdjKOur+IlfqzJGMHIK/wXrLg+GsvMs8Op7vI2jVA==",
+ "dev": true,
+ "bin": {
+ "husky": "bin.mjs"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -3944,12 +4134,156 @@
"immediate": "~3.0.5"
}
},
+ "node_modules/lilconfig": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz",
+ "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
+ "node_modules/lint-staged": {
+ "version": "15.2.1",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.1.tgz",
+ "integrity": "sha512-dhwAPnM85VdshybV9FWI/9ghTvMLoQLEXgVMx+ua2DN7mdfzd/tRfoU2yhMcBac0RHkofoxdnnJUokr8s4zKmQ==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "5.3.0",
+ "commander": "11.1.0",
+ "debug": "4.3.4",
+ "execa": "8.0.1",
+ "lilconfig": "3.0.0",
+ "listr2": "8.0.1",
+ "micromatch": "4.0.5",
+ "pidtree": "0.6.0",
+ "string-argv": "0.3.2",
+ "yaml": "2.3.4"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz",
+ "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==",
+ "dev": true,
+ "dependencies": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.0.0",
+ "rfdc": "^1.3.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/listr2/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/listr2/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/listr2/node_modules/emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "node_modules/listr2/node_modules/string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/listr2/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/listr2/node_modules/wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/local-pkg": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
@@ -3993,6 +4327,135 @@
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
"dev": true
},
+ "node_modules/log-update": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
+ "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^6.2.0",
+ "cli-cursor": "^4.0.0",
+ "slice-ansi": "^7.0.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
+ "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
+ "dev": true,
+ "dependencies": {
+ "get-east-asian-width": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
+ "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/loupe": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
@@ -4523,6 +4986,18 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/pkg-types": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz",
@@ -4652,6 +5127,21 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
+ "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
@@ -4849,6 +5339,52 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/restore-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
+ "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -4859,6 +5395,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/rfdc": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
+ "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
+ "dev": true
+ },
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -5187,6 +5729,15 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -6326,6 +6877,15 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/yaml": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
+ "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -7516,6 +8076,23 @@
"uri-js": "^4.2.2"
}
},
+ "ansi-escapes": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz",
+ "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^3.0.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
+ "dev": true
+ }
+ }
+ },
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -7671,6 +8248,81 @@
"get-func-name": "^2.0.2"
}
},
+ "cli-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
+ "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^4.0.0"
+ }
+ },
+ "cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "requires": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ }
+ },
+ "string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^6.0.1"
+ }
+ }
+ }
+ },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -7692,6 +8344,12 @@
"integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
"dev": true
},
+ "colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -8225,6 +8883,12 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
+ "eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "dev": true
+ },
"execa": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
@@ -8398,6 +9062,12 @@
"dev": true,
"optional": true
},
+ "get-east-asian-width": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
+ "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
+ "dev": true
+ },
"get-func-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
@@ -8643,6 +9313,12 @@
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
"dev": true
},
+ "husky": {
+ "version": "9.0.10",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.10.tgz",
+ "integrity": "sha512-TQGNknoiy6bURzIO77pPRu+XHi6zI7T93rX+QnJsoYFf3xdjKOur+IlfqzJGMHIK/wXrLg+GsvMs8Op7vI2jVA==",
+ "dev": true
+ },
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -9001,12 +9677,109 @@
"immediate": "~3.0.5"
}
},
+ "lilconfig": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz",
+ "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==",
+ "dev": true
+ },
"lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
+ "lint-staged": {
+ "version": "15.2.1",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.1.tgz",
+ "integrity": "sha512-dhwAPnM85VdshybV9FWI/9ghTvMLoQLEXgVMx+ua2DN7mdfzd/tRfoU2yhMcBac0RHkofoxdnnJUokr8s4zKmQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "5.3.0",
+ "commander": "11.1.0",
+ "debug": "4.3.4",
+ "execa": "8.0.1",
+ "lilconfig": "3.0.0",
+ "listr2": "8.0.1",
+ "micromatch": "4.0.5",
+ "pidtree": "0.6.0",
+ "string-argv": "0.3.2",
+ "yaml": "2.3.4"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true
+ }
+ }
+ },
+ "listr2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz",
+ "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==",
+ "dev": true,
+ "requires": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.0.0",
+ "rfdc": "^1.3.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^6.0.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ }
+ }
+ }
+ },
"local-pkg": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
@@ -9038,6 +9811,89 @@
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
"dev": true
},
+ "log-update": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
+ "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^6.2.0",
+ "cli-cursor": "^4.0.0",
+ "slice-ansi": "^7.0.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
+ "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
+ "dev": true,
+ "requires": {
+ "get-east-asian-width": "^1.0.0"
+ }
+ },
+ "slice-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
+ "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ }
+ },
+ "string-width": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
+ "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^6.0.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ }
+ }
+ }
+ },
"loupe": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
@@ -9413,6 +10269,12 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
+ "pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true
+ },
"pkg-types": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz",
@@ -9486,6 +10348,12 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
+ "prettier": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
+ "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+ "dev": true
+ },
"pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
@@ -9633,12 +10501,51 @@
"lowercase-keys": "^3.0.0"
}
},
+ "restore-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
+ "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "dependencies": {
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ }
+ }
+ },
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
+ "rfdc": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
+ "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
+ "dev": true
+ },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -9890,6 +10797,12 @@
"safe-buffer": "~5.1.0"
}
},
+ "string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true
+ },
"string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -10683,6 +11596,12 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "yaml": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
+ "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+ "dev": true
+ },
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 094fb05c..0f8e82cd 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,8 @@
"test-code-write": "vitest run --config test/data/vitest.write.config.json",
"test-build": "node ./dev/bin/build.js --dryRun --all",
"license-report": "license-report --output=html --only=prod --fields=name --fields=installedVersion --fields=licenseType --fields=link --html.cssFile=dev/data/legal-npm.css > ext/legal-npm.html",
- "license-report-markdown": "license-report --output=markdown --only=prod --fields=name --fields=installedVersion --fields=licenseType --fields=link"
+ "license-report-markdown": "license-report --output=markdown --only=prod --fields=name --fields=installedVersion --fields=licenseType --fields=link",
+ "prepare": "husky install"
},
"repository": {
"type": "git",
@@ -75,9 +76,12 @@
"eslint-plugin-vitest": "^0.3.20",
"fake-indexeddb": "^5.0.2",
"html-validate": "^8.8.0",
+ "husky": "^9.0.10",
"jsdom": "^24.0.0",
"jszip": "^3.10.1",
"license-report": "^6.5.0",
+ "lint-staged": "^15.2.1",
+ "prettier": "^3.2.4",
"stylelint": "^16.1.0",
"stylelint-config-recommended": "^14.0.0",
"ts-json-schema-generator": "^1.5.0",
@@ -91,5 +95,8 @@
"handlebars": "^4.7.8",
"parse5": "^7.1.2",
"wanakana": "^5.3.1"
+ },
+ "lint-staged": {
+ "*.md": "prettier --write"
}
}