diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 00000000..690af28d
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,45 @@
+name: Docs
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Setup
+ uses: wyvox/action@v1
+ - name: Build Docs
+ run: pnpm build:docs
+ - name: Setup Pages
+ uses: actions/configure-pages@v3
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v1
+ with:
+ path: "docs/.vitepress/dist"
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.gitignore b/.gitignore
index 2a953744..1e4179bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,8 @@ node_modules/
/.node_modules.ember-try/
/package.json.ember-try
/yarn.lock.ember-try
+
+#vitepress
+/docs/.vitepress/dist/
+/docs/.vitepress/cache/
+/docs/api
diff --git a/README.md b/README.md
index 0397f06c..7268317a 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,10 @@
[![npm version](https://badge.fury.io/js/ember-link.svg)](http://badge.fury.io/js/ember-link)
[![Download Total](https://img.shields.io/npm/dt/ember-link.svg)](http://badge.fury.io/js/ember-link)
[![Ember Observer Score](https://emberobserver.com/badges/ember-link.svg)](https://emberobserver.com/addons/ember-link)
-[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
-[![Dependabot enabled](https://img.shields.io/badge/dependabot-enabled-blue.svg?logo=dependabot)](https://dependabot.com/)
-[![dependencies Status](https://david-dm.org/buschtoens/ember-link/status.svg)](https://david-dm.org/buschtoens/ember-link)
-[![devDependencies Status](https://david-dm.org/buschtoens/ember-link/dev-status.svg)](https://david-dm.org/buschtoens/ember-link?type=dev)
Introduces a new `Link` primitive to pass around self-contained references to
-routes, like URLs, but with state (`isActive`, ...) and methods (`transitionTo`,
-...). Also brings along an accompanying template helper and component for easy
+routes, like URLs, but with state (`isActive`, ...) and methods (`open`,
+...). Also brings along an accompanying template helper for easy
usage in templates.
> `ember-link` does to routing what `ember-concurrency` did to asynchrony!
@@ -20,633 +16,80 @@ usage in templates.
## Installation
-```
+Install `ember-link` with:
+
+```sh
ember install ember-link
```
## Usage
-- [`{{link}}` helper](#link-helper)
-- [` ` component](#link-component)
-- [`Link` class](#link)
-- [`UILink` class](#uilink)
-- [`LinkManager` service](#linkmanager)
-- [Testing](#testing)
-
-### `{{link}}` Helper
-
-The `{{link}}` helper returns a [`UILink`](#uilink) instance.
-
-#### Invocation Styles
-
-##### Positional Parameters
-
-```hbs
-{{#let
- (link
- "blogs.posts.post"
- @post.blog.id
- @post.id
- (query-params showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-##### Named Parameters
-
-```hbs
-{{#let
- (link
- route="blogs.posts.post"
- models=(array @post.blog.id @post.id)
- query=(hash showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-When passing a single model, you can use `model` instead of `models`:
-
-```hbs
-{{#let
- (link
- route="blogs.posts"
- model=@post.blog.id
- )
- as |l|
-}}
-
- Read more stories in the {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-##### Mix & Match
-
-You can also mix and match the parameter styles, however you like.
-
-```hbs
-{{#let
- (link
- "blogs.posts.post"
- @post.blog.id
- @post.id
- query=(hash showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
+You can use `ember-link` in a declarative form with a [`(link)`
+helper](https://buschtoens.github.io/ember-link/helper.html) or imperatively with the [`LinkManager`
+Service](https://buschtoens.github.io/ember-link/service.html).
-##### `fromURL`
+### `(link)` Helper Example
-Instead of the positional & named link parameters described above, you can also
-create a `Link` instance from a serialized URL.
+Use the `(link)` helper to create a link primitive and attach it to an element.
```hbs
-{{! someURL = "/blogs/tech/posts/dont-break-the-web" }}
-{{#let (link fromURL=this.someURL) as |l|}}
-
- Read the next great post.
+{{#let (link "about") as |l|}}
+
+ About us
{{/let}}
```
-`fromURL` is mutually exclusive with the other link parameters: `route`, `model`
-& `models`, `query`
-
-### Parameters
-
-In addition to the parameters shown above, the `{{link}}` helper also accepts a
-`preventDefault` default parameter. It defaults to `true` and intelligently
-prevents hard browser transitions when clicking `` elements.
-
-See [`@preventDefault`](#preventdefault) and [`UILink`](#uilink).
-
-### 💡 Pro Tips
-
-Instead of using the `{{#let}}` helper, you can use the
-[` ` component](#link-component) to achieve the same scoping effect, with
-subjectively nicer syntax.
-
-Even better yet, make [`Link`](#link) / [`UILink`](#uilink) a first-class
-primitive in your app architecture! Instead of manually wiring up
-[`Link#url`](#url) and [`Link#transitionTo()`](#transitionto) every time, rather
-create your own ready-to-use, style-guide-compliant link and button components
-that accept `@link` as an argument instead of `@href` and `@onClick`.
-
-This is akin to the
-[popular](https://github.com/rwjblue/ember-cli-async-button)
-[async](https://github.com/DockYard/ember-async-button)
-[task](https://github.com/quipuapp/ember-task-button)
-button component concept.
-
-```hbs
-
- Become a Premium member
-
-```
-
-```hbs
-
- {{yield}}
-
-```
-
-### ` ` Component
-
-Similar to the the [`{{link}}` helper](#link-helper), the ` ` component
-yields a [`UILink`](#uilink) instance.
-
-```hbs
-
-
- Click me
-
-
-```
-
-#### Arguments
-
-##### `@route`
-
-Required.
-
-The target route name.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route"}}
- Click me
-{{/link-to}}
-```
-
-##### `@models`
-
-Optional. Mutually exclusive with [`@model`](#model).
-
-An array of models / dynamic segments.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route" someModel someNestedModel}}
- Click me
-{{/link-to}}
-```
-
-##### `@model`
-
-Optional. Mutually exclusive with [`@models`](#models).
-
-Shorthand for providing a single model / dynamic segment. The following two
-invocations are equivalent:
-
-```hbs
-
-
-```
-
-##### `@query`
+### `LinkManager` Service Example
-Optional.
-
-Query Params object.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route" (query-params foo="bar")}}
- Click me
-{{/link-to}}
-```
-
-##### `@fromURL`
-
-Optional. Mutually exclusive with [`@route`](#route), [`@model`](#model) /
-[`@models`](#models), [`@query`](#query).
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-##### `@preventDefault`
-
-Optional. Default: `true`
-
-If enabled, the [`transitionTo`](#transitionto) and
-[`replaceWith`](#replacewith) actions will try to call
-[`event.preventDefault()`][prevent-default] on the first argument, if it is an
-event. This is an anti-foot-gun to make ` ` _just work™️_ with `` and
-``, which would otherwise trigger a native browser navigation / form
-submission.
-
-[prevent-default]: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
-
-#### Yielded Parameters
-
-The ` ` component yields a [`UILink`](#uilink) instance.
-
-##### `url`
-
-`string`
-
-The URL for this link that you can pass to an `` tag as the `href` attribute.
-
-```hbs
-
-
- Click me
-
-
-```
-
-##### `isActive`
-
-`boolean`
-
-Whether this route is currently active, including potentially supplied models
-and query params.
-
-In the following example, only one link will be `is-active` at any time.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-```
-
-##### `isActiveWithoutQueryParams`
-
-`boolean`
-
-Whether this route is currently active, including potentially supplied models,
-but ignoring query params.
-
-In the following example, the first two links will be `is-active` simultaneously.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-
-
-
- Three
-
-
-```
-
-##### `isActiveWithoutModels`
-
-`boolean`
-
-Whether this route is currently active, but ignoring models and query params.
-
-In the following example, both links will be `is-active` simultaneously.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-```
-
-##### `transitionTo()`
-
-`(event?: Event) => Transition`
-
-Transition into the target route.
-
-If [`@preventDefault`](#preventdefault) is enabled, also calls `event.preventDefault()`.
-
-##### `replaceWith()`
-
-`(event?: Event) => Transition`
-
-Transition into the target route while replacing the current URL, if possible.
-
-If [`@preventDefault`](#preventdefault) is enabled, also calls `event.preventDefault()`.
-
-### `Link`
-
-A `Link` is a self-contained reference to a concrete route, including models and
-query params. It's basically like a
-[`` / `{{link-to}}` component][link-to-component] you can pass around.
-
-[link-to-component]: https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/input?anchor=LinkTo
-
-You can create a `Link` via the [`LinkManager` service](#linkmanager).
-
-[`UILink`](#uilink) extends `Link` with some anti-foot-guns and conveniences. It
-can also be created via the [`LinkManager` service](#linkmanager), but also via
-the [`{{link}}` helper](#link-helper) and [` ` component](#link-component).
-
-#### Properties
-
-##### `isActive`
-
-Type: `boolean`
-
-Whether this route is currently active, including potentially supplied models
-and query params.
-
-##### `isActiveWithoutQueryParams`
-
-Type: `boolean`
-
-Whether this route is currently active, including potentially supplied models,
-but ignoring query params.
-
-##### `isActiveWithoutModels`
-
-Type: `boolean`
-
-Whether this route is currently active, but ignoring models and query params.
-
-##### `url`
-
-Type: `string`
-
-The URL for this link that you can pass to an `` tag as the `href` attribute.
-
-##### `routeName`
-
-Type: `string`
-
-The target route name of this link.
-
-##### `models`
-
-Type: `RouteModel[]`
-
-The route models passed in this link.
-
-##### `queryParams`
-
-Type: `Record | undefined`
-
-The query params for this link, if specified.
-
-#### Methods
-
-##### `transitionTo()`
-
-Returns: [`Transition`][transition]
-
-Transition into the target route.
-
-##### `replaceWith()`
-
-Returns: [`Transition`][transition]
-
-Transition into the target route while replacing the current URL, if possible.
-
-[transition]: https://api.emberjs.com/ember/release/classes/Transition
-
-### `UILink`
-
-`UILink` extends [`Link`](#link) with anti-foot-guns and conveniences. This
-class is meant to be used in templates, primarily through `` & ``
-elements.
-
-It wraps `transitionTo()` and `replaceWith()` to optionally accept an `event`
-argument. It will intelligently
-
-- call `event.preventDefault()` to prevent hard page reloads
-- open the page in a new tab, when `Cmd` / `Ctrl` clicking
-
-It can be created via the [`LinkManager` service](#linkmanager), but also via
-the [`{{link}}` helper](#link-helper) and [` ` component](#link-component).
-
-### `LinkManager`
-
-The `LinkManager` service is used by the [`{{link}} helper`](#link-helper) and
-[` ` component](#link-component) to create [`UILink`](#uilink) instances.
-
-You can also use this service directly to programmatically create link
-references.
-
-#### `createLink(linkParams: LinkParams): Link`
-
-Returns: [`Link`](#link)
+Use the `LinkManager.createLink()` method to create a link programmatically.
```ts
-interface LinkParams {
- /**
- * The target route name.
- */
- route: string;
+import Contoller from '@ember/controller';
+import { service } from '@ember/service';
+import type { LinkManagerService } from 'ember-link';
- /**
- * Optional array of models / dynamic segments.
- */
- models?: RouteModel[];
+export default class PageHeader extends Controller {
+ @service declare linkManager: LinkManagerService;
- /**
- * Optional query params object.
- */
- query?: QueryParams;
-}
-```
-
-#### `createUILink(linkParams: LinkParams, uiParams: UILinkParams): UILink`
-
-Returns: [`UILink`](#uilink)
-
-```ts
-interface UILinkParams {
- /**
- * Whether or not to call `event.preventDefault()`, if the first parameter to
- * the `transitionTo` or `replaceWith` action is an `Event`. This is useful to
- * prevent links from accidentally triggering real browser navigation or
- * buttons from submitting a form.
- *
- * Defaults to `true`.
- */
- preventDefault?: boolean;
+ aboutUsLink = this.linkManager.createLink('about');
}
```
-#### `getLinkParamsFromURL(url: string): LinkParams`
+### Working with Primitives
-Returns: [`LinkParams`](#createlinklinkparams-linkparams-link)
+The idea of `ember-link` is to be able to create link primitives, that you can
+pass around. Create links at route level and then pass them into components.
-Use this method to derive `LinkParams` from a serialized, recognizable URL, that
-you can then pass into `createLink` / `createUILink`.
+A more in-depth guide is available at [using primitives](https://buschtoens.github.io/ember-link/using-primitives.html).
-### Testing
+## Testing
-In [acceptance / application tests (`setupApplicationTest(hooks)`)][tests-application]
-your app boots with a fully-fledged router, so `ember-link` just works normally.
-
-In [integration / render tests (`setupRenderingTest(hooks)`)][tests-render] the
-router is not initialized, so `ember-link` can't operate normally. To still
-support using `{{link}}` & friends in render tests, you can use the
-[`setupLink(hooks)` test helper][setup-link].
-
-[tests-application]: https://guides.emberjs.com/release/testing/testing-application/
-[tests-render]: https://guides.emberjs.com/release/testing/testing-components/
-[setup-link]: https://github.com/buschtoens/ember-link/blob/main/addon-test-support/setup-link.ts
+[ember-link has testing support](https://buschtoens.github.io/ember-link/testing.html) on board, preparing the environment with
+`setupLink()` and `linkFor()` to create a link to a route on the fly:
```ts
-import { click, render } from '@ember/test-helpers';
-import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { click, render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
import { setupLink, linkFor, TestLink } from 'ember-link/test-support';
-import hbs from 'htmlbars-inline-precompile';
-
module('`setupLink` example', function (hooks) {
setupRenderingTest(hooks);
setupLink(hooks);
- test('` ` component works in render tests', async function (assert) {
- await render(hbs`
-
-
- Click me
-
-
- `);
-
+ test('`(link)` works in render tests', async function (assert) {
const link = linkFor('some.route');
link.onTransitionTo = assert.step('link clicked');
+ await render(hbs`
+ {{#let (link @route="some.route") as |l|}}
+ Click me
+ {{/let}}
+ `);
+
await click('a');
assert.verifySteps(['link clicked']);
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
new file mode 100644
index 00000000..49eeab58
--- /dev/null
+++ b/docs/.vitepress/config.ts
@@ -0,0 +1,60 @@
+import { defineConfig } from 'vitepress';
+import { getSidebar } from './sidebar-api';
+
+const apiSidebar = getSidebar('api');
+
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+ title: "ember-link",
+ description: "Links as Primitives",
+ base: '/ember-link/',
+ themeConfig: {
+ // https://vitepress.dev/reference/default-theme-config
+ nav: [
+ { text: 'Home', link: '/' },
+ { text: 'Guides', link: '/getting-started' },
+ { text: 'API', link: '/api/modules'}
+ ],
+
+ outline: [2, 3],
+
+ sidebar: {
+ '/': [
+ {
+ text: 'Guides',
+ items: [
+ { text: 'Getting Started', link: '/getting-started' },
+ { text: 'Installation', link: '/installation' },
+ { text: 'Configuration', link: '/configuration' },
+ { text: 'Migration', link: '/migration' }
+ ]
+ },
+ {
+ text: 'Usage',
+ items: [
+ { text: 'Using Primitives', link: '/using-primitives' },
+ { text: 'Params', link: '/params' },
+ { text: 'Behavior', link: '/behavior' },
+ { text: 'Link Helper', link: '/helper' },
+ { text: 'LinkManager Service', link: '/service' },
+ { text: 'Testing', link: '/testing' }
+ ]
+ },
+ {
+ text: 'Advanced',
+ items: [
+ { text: 'Customization', link: '/customization' },
+ { text: 'Using Locales', link: '/using-locales' },
+ { text: 'Link Builder', link: '/link-builder' },
+ { text: 'Commands', link: '/commands' }
+ ]
+ }
+ ],
+ '/api/': apiSidebar
+ },
+
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/buschtoens/ember-link' }
+ ]
+ }
+})
diff --git a/docs/.vitepress/sidebar-api.ts b/docs/.vitepress/sidebar-api.ts
new file mode 100644
index 00000000..2bdf0aa9
--- /dev/null
+++ b/docs/.vitepress/sidebar-api.ts
@@ -0,0 +1,89 @@
+import { DefaultTheme } from 'vitepress';
+import data from '../api/data.json';
+
+enum Kind {
+ Project = 1,
+ Module = 2 << 0,
+ Function = 2 << 5,
+ Class = 2 << 6,
+ Interface = 2 << 7,
+ Type = 2 << 21
+}
+
+const KindToSlugMap = {
+ [Kind.Module]: 'modules',
+ [Kind.Function]: 'modules',
+ [Kind.Class]: 'classes',
+ [Kind.Interface]: 'interfaces',
+ [Kind.Type]: 'modules'
+}
+
+interface Entry {
+ name: string,
+ kind: Kind,
+ module?: string;
+}
+
+function parseSegment(name) {
+ return name.replaceAll('/', '_').replaceAll('-', '_');
+}
+
+function slugForKind(kind: Kind) {
+ return KindToSlugMap[kind];
+}
+
+function slug(path, entry: Entry) {
+ const file = (entry: Entry) => {
+ const parts = [];
+
+ if (entry.module) {
+ parts.push(parseSegment(entry.module) as never);
+ }
+
+ if (slugForKind(entry.kind) !== 'modules' || entry.kind === Kind.Module) {
+ parts.push(parseSegment(entry.name) as never);
+ }
+
+ return parts.join('.');
+ }
+
+ const segments = [path, slugForKind(entry.kind), file(entry)];
+
+ let slug = `/${segments.join('/')}`;
+
+ if (entry.kind === Kind.Function || entry.kind === Kind.Type) {
+ slug += `#${entry.name.toLowerCase()}`;
+ }
+
+ return slug;
+}
+
+function getModuleChildren(data, path, module): DefaultTheme.SidebarItem[] {
+ return data.map(entry => {
+ return {
+ text: entry.name,
+ link: slug(path, { ...entry, module })
+ }
+ });
+}
+
+function getModules(data, path): DefaultTheme.SidebarItem[] {
+ const modules: DefaultTheme.SidebarItem[] = data.children.map(entry => {
+ const item: DefaultTheme.SidebarItem = {
+ text: entry.name,
+ link: slug(path, entry),
+ };
+
+ if (entry.children) {
+ item.items = getModuleChildren(entry.children, path, entry.name);
+ }
+
+ return item;
+ });
+
+ return modules;
+}
+
+export function getSidebar(path): DefaultTheme.SidebarItem[] {
+ return getModules(data, path);
+}
diff --git a/docs/api-examples.md b/docs/api-examples.md
new file mode 100644
index 00000000..6bd8bb5c
--- /dev/null
+++ b/docs/api-examples.md
@@ -0,0 +1,49 @@
+---
+outline: deep
+---
+
+# Runtime API Examples
+
+This page demonstrates usage of some of the runtime APIs provided by VitePress.
+
+The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files:
+
+```md
+
+
+## Results
+
+### Theme Data
+{{ theme }}
+
+### Page Data
+{{ page }}
+
+### Page Frontmatter
+{{ frontmatter }}
+```
+
+
+
+## Results
+
+### Theme Data
+{{ theme }}
+
+### Page Data
+{{ page }}
+
+### Page Frontmatter
+{{ frontmatter }}
+
+## More
+
+Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata).
diff --git a/docs/behavior.md b/docs/behavior.md
new file mode 100644
index 00000000..ba06ba83
--- /dev/null
+++ b/docs/behavior.md
@@ -0,0 +1,45 @@
+# Behavior
+
+[`Behavior`](./api/interfaces/ember_link.Behavior.md) controls the way links are
+opened. This can be [configured globally](./configuration.md) or
+[locally with each link](./helper.md#parameters).
+
+## `open`
+
+When links are opened with [`link.open`](./api/classes/ember_link.Link.md#open)
+it will use
+[`Router.transitionTo()`](https://api.emberjs.com/ember/5.0/classes/RouterService/methods/transitionTo?anchor=transitionTo)
+by default, but you can set it to `replace` to use
+[`Router.replaceWith()`](https://api.emberjs.com/ember/5.0/classes/RouterService/methods/replaceWith?anchor=replaceWith).
+
+## `prevent`
+
+Preventing will stop the browser from natively opening the link. The default
+behavior implemented here is to mimic browser behavior but move control to
+ember's routing system, as you'd expect. However, you can customize rsp. extend
+the default behavior:
+
+```ts
+import { prevent as originalPrevent } from 'ember-link';
+
+function applicationPrevent(event: Event | unknown, link: Link): boolean {
+ // something very specific to the entire application
+}
+
+function preventForLink(link: Link): boolean {
+ // something custom for a given link
+}
+
+function prevent(event: Event | unknown, link: Link) {
+ return (
+ originalPrevent(event)
+ || applicationPrevent(event, link)
+ || preventForLink(link)
+ );
+}
+```
+
+provide global rules in `applicationPrevent()` that address your entire
+application. As `Link` instance is passed as well, there can be a prevent for a
+given link, that is [customized](./customization.md) with application specific
+behavior.
diff --git a/docs/commands.md b/docs/commands.md
new file mode 100644
index 00000000..2cb57b1e
--- /dev/null
+++ b/docs/commands.md
@@ -0,0 +1,41 @@
+# Commands
+
+Sometimes, links are not enough to encode the information you want to pass down
+as primitive, this leads to unelegant situations, such as:
+
+```hbs
+
+```
+
+Information is spread apart and _two_ primitives are passed down for _one_
+action. This is where [`ember-command`](https://github.com/gossi/ember-command)
+helps out. It can run any amount of arbitrary actions and take a link for
+backpack. It is designed to work together with `ember-link`. The example from
+above rewritten with `ember-command`:
+
+```hbs
+
+```
+
+And `ember-command` provides `` component to approprietly render
+the command you pass in.
+
+```hbs
+{{! checkout-reward-screen.hbs}}
+
+Congratulations on your Purchase
+
+
+ Return to Home
+
+```
+
+
diff --git a/docs/configuration.md b/docs/configuration.md
new file mode 100644
index 00000000..6ee4dd2f
--- /dev/null
+++ b/docs/configuration.md
@@ -0,0 +1,38 @@
+# Configuration
+
+The [behavior](./behavior.md) of opening links is very much under your control.
+You can configure it globally or locally and there are reasons for both.
+
+## Global Behavior
+
+Global configuration is happening through the
+[`LinkManagerService`](./api/classes/ember_link.LinkManagerService.md) to match
+the needs for your application:
+
+```ts
+import Route from '@ember/routing/route';
+import { service } from '@ember/service';
+
+export default class ApplicationRoute extends Route {
+ @service declare linkManager: LinkManagerService;
+
+ beforeModel() {
+ this.linkManager.configureBehavior({
+ ...
+ });
+ }
+}
+```
+
+## Local Behavior
+
+Local behavior can be applied for each link instance and _may_ overwrite
+globally configured behavior. Pass the `behavior` parameter to a
+[`Link`](./api/classes/ember_link.Link.md) instance.
+
+## Global vs. Local Behavior
+
+The way it is designed, **application** specific behavior is part of **global**
+configuration.
+
+For addon authors, it is best advised to use **local** behavior.
diff --git a/docs/customization.md b/docs/customization.md
new file mode 100644
index 00000000..432f685d
--- /dev/null
+++ b/docs/customization.md
@@ -0,0 +1,83 @@
+# Customization
+
+While `ember-link` focus on its strength at its core, connecting link primitives
+with embers routing system, it leaves customization to you.
+
+## Custom Attributes
+
+For example, you may want to carry around more attributes than provided out of
+the box. This is a great idea when defining links and using links are two
+separate parties and you want to attach the link to the DOM as the intended on
+definition side.
+
+::: code-group
+
+```gts [post.gts]
+import { link } from 'ember-link';
+import { attachLinkAttributes } from './attributes';
+import AuthorLink from './author-link';
+
+
+
+
+ {{@post.title}}
+
+ {{@post.author.name}}
+
+
+
+ {{@post.body}}
+
+
+```
+
+```gts [author-link.gts]
+import { attributesForLink } from './attributes';
+
+
+
+ {{yield}}
+
+
+```
+
+```ts [attributes.ts]
+import { helper } from '@ember/component/helper';
+import { modifier } from 'ember-modifier';
+import type { Link } from 'ember-link';
+
+const Attributes = Symbol('attributes');
+
+export interface AttachLinkAttributesSignature {
+ Args: {
+ Positional: [Link];
+ Named: HTMLAnchorElement; // yeah, sorta
+ };
+ Return: Link;
+}
+
+const attachLinkAttributes = helper(([link], attributes) => {
+ link[Attributes] = attributes;
+});
+
+
+export interface AttributesForLinkSignature {
+ Element: HTMLAnchorElement;
+ Args: {
+ Positional: [Link];
+ };
+}
+
+const attributesForLink = modifier((element, [link]) => {
+ for (const [attr, val] of Object.entries(link[Attributes])) {
+ element[attr] = val;
+ }
+});
+
+export { attachLinkAttributes, attributesForLink };
+```
+
+:::
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 00000000..54b72225
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,84 @@
+# Getting Started
+
+## Installation
+
+Install `ember-link` with:
+
+```sh
+ember install ember-link
+```
+
+## Usage
+
+You can use `ember-link` in a declarative form with a [`(link)`
+helper](helper.md) or imperatively with the [`LinkManager`
+Service](./service.md).
+
+### `(link)` Helper Example
+
+Use the `(link)` helper to create a link primitive and attach it to an element.
+
+```hbs
+{{#let (link "about") as |l|}}
+
+ About us
+
+{{/let}}
+```
+
+### `LinkManager` Service Example
+
+Use the `LinkManager.createLink()` method to create a link programmatically.
+
+```ts
+import Contoller from '@ember/controller';
+import { service } from '@ember/service';
+import type { LinkManagerService } from 'ember-link';
+
+export default class PageHeader extends Controller {
+ @service declare linkManager: LinkManagerService;
+
+ aboutUsLink = this.linkManager.createLink('about');
+}
+```
+
+### Working with Primitives
+
+The idea of `ember-link` is to be able to create link primitives, that you can
+pass around. Create links at route level and then pass them into components.
+
+A more in-depth guide is available at [using primitives](./using-primitives.md).
+
+## Testing
+
+[ember-link has testing support](./testing.md) on board, preparing the environment with
+`setupLink()` and `linkFor()` to create a link to a route on the fly:
+
+```ts
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { click, render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+import { setupLink, linkFor, TestLink } from 'ember-link/test-support';
+
+module('`setupLink` example', function (hooks) {
+ setupRenderingTest(hooks);
+ setupLink(hooks);
+
+ test('`(link)` works in render tests', async function (assert) {
+ const link = linkFor('some.route');
+ link.onTransitionTo = assert.step('link clicked');
+
+ await render(hbs`
+ {{#let (link @route="some.route") as |l|}}
+ Click me
+ {{/let}}
+ `);
+
+ await click('a');
+
+ assert.verifySteps(['link clicked']);
+ });
+});
+```
diff --git a/docs/helper.md b/docs/helper.md
new file mode 100644
index 00000000..77c79233
--- /dev/null
+++ b/docs/helper.md
@@ -0,0 +1,99 @@
+# `(link)` Helper
+
+The `(link)` helper returns a `Link` instance.
+
+## Invocation Styles
+
+### Positional Parameters
+
+```hbs
+{{#let
+ (link
+ "blogs.posts.post"
+ @post.blog.id
+ @post.id
+ (query-params showFullPost=true)
+ )
+ as |l|
+}}
+
+ Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
+
+{{/let}}
+```
+
+### Named Parameters
+
+```hbs
+{{#let
+ (link
+ route="blogs.posts.post"
+ models=(array @post.blog.id @post.id)
+ query=(hash showFullPost=true)
+ )
+ as |l|
+}}
+
+ Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
+
+{{/let}}
+```
+
+When passing a single model, you can use `model` instead of `models`:
+
+```hbs
+{{#let
+ (link
+ route="blogs.posts"
+ model=@post.blog.id
+ )
+ as |l|
+}}
+
+ Read more stories in the {{@post.blog.name}} blog!
+
+{{/let}}
+```
+
+### Mix & Match
+
+You can also mix and match the parameter styles, however you like.
+
+```hbs
+{{#let
+ (link
+ "blogs.posts.post"
+ @post.blog.id
+ @post.id
+ query=(hash showFullPost=true)
+ )
+ as |l|
+}}
+
+ Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
+
+{{/let}}
+```
+
+### `fromURL`
+
+Instead of the positional & named link parameters described above, you can also
+create a `Link` instance from a serialized URL.
+
+```hbs
+{{! someURL = "/blogs/tech/posts/dont-break-the-web" }}
+{{#let (link fromURL=this.someURL) as |l|}}
+
+ Read the next great post.
+
+{{/let}}
+```
+
+`fromURL` is mutually exclusive with the other link parameters: `route`, `model`
+& `models`, `query`
+
+## Parameters
+
+In addition to the parameters shown above, the `(link)` helper also accepts a
+`behavior` parameter. This gives a chance to use a locally change the
+[behavior](./behavior.md) of a link.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..4e4248e2
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,23 @@
+---
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ name: "ember-link"
+ #text: "A VitePress Site"
+ tagline: Links as Primitives
+ actions:
+ - theme: brand
+ text: Getting Started
+ link: /getting-started
+ - theme: alt
+ text: Using Primitives
+ link: /using-primitives
+
+features:
+ - title: Links as Primitives
+ details: Create links and pass them around as needed
+ - title: Separate of Concerns
+ details: Split defining and attaching links
+---
+
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 00000000..e1aa5646
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,7 @@
+# Installation
+
+Install `ember-link` with:
+
+```sh
+ember install ember-link
+```
diff --git a/docs/link-builder.md b/docs/link-builder.md
new file mode 100644
index 00000000..2c37df34
--- /dev/null
+++ b/docs/link-builder.md
@@ -0,0 +1,98 @@
+# Link Builder
+
+Not always, you have the full information at hand when creating a link, as the last pieces
+of information are missing. For example in list-details routing situations, you
+do have the detail route ready, but the final parameter for the id of that
+particular entity you are looking at is expected to be available _later_.
+
+For such situations link builders are a great way to pass down and postpone the
+construction of the final link, when all information is available.
+
+## Creating a Link Builder
+
+Let's take ember's [super-rental](https://github.com/ember-learn/super-rentals/)
+app as an example. The route for a rental is defined as follows:
+
+```js
+Router.map(function () {
+ // ...
+ this.route('rental', { path: '/rentals/:rental_id' });
+});
+```
+
+The builder is crafted at route level, where other routes are known. This allows
+us to do this in the `model()` hook of a `Route` or within the `Controller`.
+When no controller is present `model()` seems the place:
+
+```ts
+import Route from '@ember/routing/route';
+import { service } from '@ember/service';
+
+export default class IndexRoute extends Route {
+ @service store;
+
+ buildRequestOfferLink = (
+ rentalId: string
+ ): Link => {
+ return this.linkManager.createLink({
+ route: 'rental',
+ models: [rentalId]
+ });
+ };
+
+ async model() {
+ return {
+ rentals: this.store.findAll('rental')
+ buildRentalLink: this.buildRentalLink
+ };
+ }
+}
+```
+
+And using it from the template:
+
+```hbs
+
+```
+
+## Using the Link Builder
+
+At
+[``](https://github.com/ember-learn/super-rentals/blob/cac43c0c7ffa340003bce5b07b6048ee42c59d55/app/components/rentals.hbs)
+we pass down the link builder to
+[``](https://github.com/ember-learn/super-rentals/blob/cac43c0c7ffa340003bce5b07b6048ee42c59d55/app/components/rental.hbs):
+
+```hbs
+
+```
+
+At
+[``](https://github.com/ember-learn/super-rentals/blob/cac43c0c7ffa340003bce5b07b6048ee42c59d55/app/components/rental.hbs)
+accepting the link builder with an appropriate signature:
+
+```ts
+import type { Rental } from '../models/rental';
+import type { Link } from 'ember-link';
+
+interface RentalSignature {
+ Args: {
+ rental: Rental;
+ buildRentalLink: (rentalId) => Link;
+ }
+}
+```
+
+And then use it from the template:
+
+```hbs
+
+ {{#let (@buildRentalLink @rental.id) as |link|}}
+
+ {{@rental.title}}
+
+ {{/let}}
+
+```
diff --git a/docs/markdown-examples.md b/docs/markdown-examples.md
new file mode 100644
index 00000000..8e55eb8a
--- /dev/null
+++ b/docs/markdown-examples.md
@@ -0,0 +1,85 @@
+# Markdown Extension Examples
+
+This page demonstrates some of the built-in markdown extensions provided by VitePress.
+
+## Syntax Highlighting
+
+VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
+
+**Input**
+
+````
+```js{4}
+export default {
+ data () {
+ return {
+ msg: 'Highlighted!'
+ }
+ }
+}
+```
+````
+
+**Output**
+
+```js{4}
+export default {
+ data () {
+ return {
+ msg: 'Highlighted!'
+ }
+ }
+}
+```
+
+## Custom Containers
+
+**Input**
+
+```md
+::: info
+This is an info box.
+:::
+
+::: tip
+This is a tip.
+:::
+
+::: warning
+This is a warning.
+:::
+
+::: danger
+This is a dangerous warning.
+:::
+
+::: details
+This is a details block.
+:::
+```
+
+**Output**
+
+::: info
+This is an info box.
+:::
+
+::: tip
+This is a tip.
+:::
+
+::: warning
+This is a warning.
+:::
+
+::: danger
+This is a dangerous warning.
+:::
+
+::: details
+This is a details block.
+:::
+
+## More
+
+Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown).
diff --git a/docs/migration.md b/docs/migration.md
new file mode 100644
index 00000000..6cf1cf47
--- /dev/null
+++ b/docs/migration.md
@@ -0,0 +1,10 @@
+# Migration
+
+## From v2 to v3
+
+- Search and replace `UILink` with `Link`
+- `preventDefault` parameter for `(link)` helper has changed into:
+ `(link ".." behavior=(hash prevent=true))`
+- ` ` component has been removed, use `(link)` helper instead
+- Instead of `link.transitionTo` you want to switch to `link.open` to give
+ control over how this should be opened to definition side of links
diff --git a/docs/params.md b/docs/params.md
new file mode 100644
index 00000000..5bb48c3a
--- /dev/null
+++ b/docs/params.md
@@ -0,0 +1,120 @@
+# Params
+
+Detailed explanation of parameters for a link, in comparison to a regular ``.
+
+## `route`
+
+Required.
+
+The target route name.
+
+::: code-group
+
+```hbs [Example]
+{{#let (link route="some.route") as |l|}}
+
+ Click me
+
+{{/let}}
+```
+
+:::
+
+::: code-group
+
+```hbs [<LinkTo> equivalent]
+
+ Click me
+
+```
+
+:::
+
+## `models`
+
+Optional. Mutually exclusive with [`model`](#model).
+
+An array of models / dynamic segments.
+
+::: code-group
+
+```hbs [Example]
+{{#let (link route="some.route" models=(array someModel someNestedModel)) as |l|}}
+
+ Click me
+
+{{/let}}
+```
+
+:::
+
+::: code-group
+
+```hbs [<LinkTo> equivalent]
+
+ Click me
+
+```
+
+:::
+
+## `model`
+
+Optional. Mutually exclusive with [`models`](#models).
+
+Shorthand for providing a single model / dynamic segment. The following two
+invocations are equivalent:
+
+```hbs
+(link route="some.route" model={{someModel}})
+(link route="some.route" models={{array someModel}})
+```
+
+## `query`
+
+Optional.
+
+Query Params object.
+
+::: code-group
+
+```hbs [Example]
+{{#let (link route="some.route" query=(hash foo="bar")) as |l|}}
+
+ Click me
+
+{{/let}}
+```
+
+:::
+
+::: code-group
+
+```hbs [<LinkTo> equivalent]
+
+ Click me
+
+```
+
+:::
+
+## `fromURL`
+
+Optional. Mutually exclusive with [`route`](#route), [`model`](#model) /
+[`models`](#models), [`query`](#query).
+
+::: code-group
+
+```hbs [Example]
+{{#let (link fromURL="/blogs/tech/posts/dont-break-the-web") as |l|}}
+
+ Click me
+
+{{/let}}
+```
+
+:::
+
+## `behavior`
+
+Control the way links are opened with [behavior](./behavior.md).
diff --git a/docs/references.md b/docs/references.md
new file mode 100644
index 00000000..e64c73e3
--- /dev/null
+++ b/docs/references.md
@@ -0,0 +1,15 @@
+# References
+
+## Related Projects
+
+- [`ember-command`](https://github.com/gossi/ember-command): Primitives for
+ actions backpacking with links
+- [`ember-engine-router-service`](https://github.com/buschtoens/ember-engine-router-service):
+ Allows you to use `ember-link` inside engines
+- [`ember-router-helpers`](https://github.com/rwjblue/ember-router-helpers)
+
+## Related RFCs
+
+- [RFC 391 "Router Helpers"](https://github.com/emberjs/rfcs/blob/master/text/0391-router-helpers.md)
+- [RFC 339 "Router link component and routing helpers"](https://github.com/emberjs/rfcs/pull/339)
+- [RFC 459 "Angle Bracket Invocations For Built-in Components"](https://github.com/emberjs/rfcs/blob/angle-built-ins/text/0459-angle-bracket-built-in-components.md#linkto)
diff --git a/docs/service.md b/docs/service.md
new file mode 100644
index 00000000..ad402267
--- /dev/null
+++ b/docs/service.md
@@ -0,0 +1,25 @@
+# `LinkManager` Service
+
+The `LinkManager` service is used by the [`(link) helper`](./helper.md) and
+to create a [`Link`](./api/classes/ember_link.Link.md) instances.
+
+You can also use this service directly to programmatically create link
+references.
+
+## `createLink(linkParams: LinkParams): Link`
+
+Will create a [`Link`](./api/classes/ember_link.Link.md) to pass around using
+the same parameters as [`(link) helper`](./helper.md).
+
+::: info
+API Docs: [createLink](./api/classes/ember_link.LinkManagerService.md#createlink)
+:::
+
+## `getLinkParamsFromURL(url: string): LinkParams`
+
+Use this method to derive `LinkParams` from a serialized, recognizable URL, that
+you can then pass into `createLink`.
+
+::: info
+API Docs: [getLinkParamsFromURL](./api/classes/ember_link.LinkManagerService.md#getlinkparamsfromurl)
+:::
diff --git a/docs/testing.md b/docs/testing.md
new file mode 100644
index 00000000..48608213
--- /dev/null
+++ b/docs/testing.md
@@ -0,0 +1,47 @@
+# Testing
+
+ember-link has testing support on board to give you great DX for writing tests.
+
+## Application Tests
+
+In [acceptance / application tests (`setupApplicationTest(hooks)`)](https://guides.emberjs.com/release/testing/testing-application/)
+your app boots with a fully-fledged router, so `ember-link` just works normally.
+
+## Rendering Tests
+
+In [integration / render tests (`setupRenderingTest(hooks)`)](https://guides.emberjs.com/release/testing/testing-components/) the
+router is not initialized, so `ember-link` can't operate normally. To still
+support using `(link)` & friends in render tests, you can use the
+[`setupLink(hooks)` test helper](./api/modules/ember_link_test_support.md#setuplink).
+
+```ts
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { click, render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+import { setupLink, linkFor, TestLink } from 'ember-link/test-support';
+
+module('`setupLink` example', function (hooks) {
+ setupRenderingTest(hooks);
+ setupLink(hooks);
+
+ test('`(link)` works in render tests', async function (assert) {
+ // arrange
+ const link = linkFor('some.route');
+ link.onTransitionTo = assert.step('link clicked');
+
+ await render(hbs`
+ {{#let (link @route="some.route") as |l|}}
+ Click me
+ {{/let}}
+ `);
+
+ // act
+ await click('a');
+
+ // assert
+ assert.verifySteps(['link clicked']);
+ });
+});
+```
diff --git a/docs/using-locales.md b/docs/using-locales.md
new file mode 100644
index 00000000..e5817a22
--- /dev/null
+++ b/docs/using-locales.md
@@ -0,0 +1,82 @@
+# Using Locales
+
+Using links in locales with [`ember-intl`](https://ember-intl.github.io) is
+still a hard problem today and `ember-link` allows for a decent solution.
+
+At first define a locale and pass it the url from a link:
+
+```yaml
+terms:
+| Our Terms and Conditions apply. Also find out our
+| Privacy guidelines.
+```
+
+then use the link:
+
+```hbs
+{{#let (link "terms") (link "privacy") as |termsLink privacyLink|}}
+ {{t "terms" htmlSafe=true termsHref=termsLink.url privacyHref=privacyLink.url}}
+{{/let}}
+```
+
+that so far is not enough. So wrap it in a modifier to intercept the browser
+default behavior for links and use embers router system.
+
+```ts [open-links.ts]
+import Modifier from 'ember-modifier';
+import type { LinkManagerService } from 'ember-link';
+
+export interface OpenLinksSignature {
+ Element: HTMLElement;
+}
+
+export default class OpenLinks extends Modifier {
+ @service declare linkManager: LinkManagerService;
+
+ handleClick(event: MouseEvent) => {
+ const anchor = (event.target as HTMLElement | undefined)?.closest('a');
+ if (!anchor) return;
+
+ const url = anchor.getAttribute('href');
+ event.preventDefault();
+
+ const params = this.linkManager.getLinkParamsFromURL(url);
+ const link = this.linkManager.createLink(params);
+
+ link.open();
+ };
+
+ modify(element: HTMLElement) {
+ element.addEventListener('click', handleClick);
+
+ return () => {
+ element.removeEventListener('click', handleClick);
+ };
+ }
+}
+```
+
+which then be used in a footer for a page:
+
+```gts
+import { link } from 'ember-link';
+import { t } from 'ember-intl/helpers/t';
+import openLinks from ./open-links.ts
+
+
+
+ {{#let (link "terms") (link "privacy") as |termsLink privacyLink|}}
+ {{t "terms" htmlSafe=true termsHref=termsLink.url privacyHref=privacyLink.url}}
+ {{/let}}
+
+
+```
+
+That's schematic usage of an `openLinks` modifier in combination. Unfortunately
+this is not using the original link instance created in the template, but this
+assures the URL is correct, which we can pick up again from the modifier.
+
+An extension of the usage might include:
+
+- Using the apps in your in-app browser (when used in a mobile app)
+- Add tracking events
diff --git a/docs/using-primitives.md b/docs/using-primitives.md
new file mode 100644
index 00000000..906cbcc7
--- /dev/null
+++ b/docs/using-primitives.md
@@ -0,0 +1,72 @@
+# Using Primitives
+
+Routes are known to other routes within a given host application, that is
+especially relevant in engines, where the same route may have a different name
+in different engines. Hardcoding a route in a component that is used in multiple
+engines is a very error prone concept.
+
+`ember-link` separates the two from each other, allowing link creation and
+attaching them to elements be handled by different parties.
+
+## Creating Links
+
+Creating links happens at best at route level, either in the route template
+using the [`(link)` helper](./helper.md) or in the controller using the
+[`LinkManager` serivice](./service.md). Then pass it down into components to
+attach them.
+
+Here is an idea for a route template, passing a link to the home screen down to
+a component managing the entire screen.
+
+```hbs
+
+```
+
+You can use [customizations](./customization.md) if you want pass more
+information along with the link.
+
+## Components for Accepting Links
+
+From the checkout reward screen this links is passed down and down until it
+reaches it final destination to be attached to an element. Tailor your
+components to work with links as arguments.
+
+```ts
+import type { Link } from 'ember-link';
+
+interface CheckoutRewardScreenSignature {
+ Args: {
+ home: Link;
+ }
+}
+```
+
+That also prepares them to properly work with [testing](./testing.md).
+
+## Low Level Components
+
+Make [`Link`](./api/classes/ember_link.Link.md) a first-class
+primitive in your app architecture! Instead of manually wiring up
+[`Link#url`](./api/classes/ember_link.Link.md#url) and
+[`Link#open()`](./api/classes/ember_link.Link.md#open) every time, rather
+create your own ready-to-use, style-guide-compliant link and button components
+that accept `@link` as an argument.
+
+```hbs
+
+ Become a Premium member
+
+```
+
+```hbs
+
+ {{yield}}
+
+```
+
+Works even better with [commands](./commands.md).
diff --git a/ember-link/README.md b/ember-link/README.md
index 0397f06c..7268317a 100644
--- a/ember-link/README.md
+++ b/ember-link/README.md
@@ -4,14 +4,10 @@
[![npm version](https://badge.fury.io/js/ember-link.svg)](http://badge.fury.io/js/ember-link)
[![Download Total](https://img.shields.io/npm/dt/ember-link.svg)](http://badge.fury.io/js/ember-link)
[![Ember Observer Score](https://emberobserver.com/badges/ember-link.svg)](https://emberobserver.com/addons/ember-link)
-[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
-[![Dependabot enabled](https://img.shields.io/badge/dependabot-enabled-blue.svg?logo=dependabot)](https://dependabot.com/)
-[![dependencies Status](https://david-dm.org/buschtoens/ember-link/status.svg)](https://david-dm.org/buschtoens/ember-link)
-[![devDependencies Status](https://david-dm.org/buschtoens/ember-link/dev-status.svg)](https://david-dm.org/buschtoens/ember-link?type=dev)
Introduces a new `Link` primitive to pass around self-contained references to
-routes, like URLs, but with state (`isActive`, ...) and methods (`transitionTo`,
-...). Also brings along an accompanying template helper and component for easy
+routes, like URLs, but with state (`isActive`, ...) and methods (`open`,
+...). Also brings along an accompanying template helper for easy
usage in templates.
> `ember-link` does to routing what `ember-concurrency` did to asynchrony!
@@ -20,633 +16,80 @@ usage in templates.
## Installation
-```
+Install `ember-link` with:
+
+```sh
ember install ember-link
```
## Usage
-- [`{{link}}` helper](#link-helper)
-- [` ` component](#link-component)
-- [`Link` class](#link)
-- [`UILink` class](#uilink)
-- [`LinkManager` service](#linkmanager)
-- [Testing](#testing)
-
-### `{{link}}` Helper
-
-The `{{link}}` helper returns a [`UILink`](#uilink) instance.
-
-#### Invocation Styles
-
-##### Positional Parameters
-
-```hbs
-{{#let
- (link
- "blogs.posts.post"
- @post.blog.id
- @post.id
- (query-params showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-##### Named Parameters
-
-```hbs
-{{#let
- (link
- route="blogs.posts.post"
- models=(array @post.blog.id @post.id)
- query=(hash showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-When passing a single model, you can use `model` instead of `models`:
-
-```hbs
-{{#let
- (link
- route="blogs.posts"
- model=@post.blog.id
- )
- as |l|
-}}
-
- Read more stories in the {{@post.blog.name}} blog!
-
-{{/let}}
-```
-
-##### Mix & Match
-
-You can also mix and match the parameter styles, however you like.
-
-```hbs
-{{#let
- (link
- "blogs.posts.post"
- @post.blog.id
- @post.id
- query=(hash showFullPost=true)
- )
- as |l|
-}}
-
- Read the full "{{@post.title}}" story on our {{@post.blog.name}} blog!
-
-{{/let}}
-```
+You can use `ember-link` in a declarative form with a [`(link)`
+helper](https://buschtoens.github.io/ember-link/helper.html) or imperatively with the [`LinkManager`
+Service](https://buschtoens.github.io/ember-link/service.html).
-##### `fromURL`
+### `(link)` Helper Example
-Instead of the positional & named link parameters described above, you can also
-create a `Link` instance from a serialized URL.
+Use the `(link)` helper to create a link primitive and attach it to an element.
```hbs
-{{! someURL = "/blogs/tech/posts/dont-break-the-web" }}
-{{#let (link fromURL=this.someURL) as |l|}}
-
- Read the next great post.
+{{#let (link "about") as |l|}}
+
+ About us
{{/let}}
```
-`fromURL` is mutually exclusive with the other link parameters: `route`, `model`
-& `models`, `query`
-
-### Parameters
-
-In addition to the parameters shown above, the `{{link}}` helper also accepts a
-`preventDefault` default parameter. It defaults to `true` and intelligently
-prevents hard browser transitions when clicking `` elements.
-
-See [`@preventDefault`](#preventdefault) and [`UILink`](#uilink).
-
-### 💡 Pro Tips
-
-Instead of using the `{{#let}}` helper, you can use the
-[` ` component](#link-component) to achieve the same scoping effect, with
-subjectively nicer syntax.
-
-Even better yet, make [`Link`](#link) / [`UILink`](#uilink) a first-class
-primitive in your app architecture! Instead of manually wiring up
-[`Link#url`](#url) and [`Link#transitionTo()`](#transitionto) every time, rather
-create your own ready-to-use, style-guide-compliant link and button components
-that accept `@link` as an argument instead of `@href` and `@onClick`.
-
-This is akin to the
-[popular](https://github.com/rwjblue/ember-cli-async-button)
-[async](https://github.com/DockYard/ember-async-button)
-[task](https://github.com/quipuapp/ember-task-button)
-button component concept.
-
-```hbs
-
- Become a Premium member
-
-```
-
-```hbs
-
- {{yield}}
-
-```
-
-### ` ` Component
-
-Similar to the the [`{{link}}` helper](#link-helper), the ` ` component
-yields a [`UILink`](#uilink) instance.
-
-```hbs
-
-
- Click me
-
-
-```
-
-#### Arguments
-
-##### `@route`
-
-Required.
-
-The target route name.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route"}}
- Click me
-{{/link-to}}
-```
-
-##### `@models`
-
-Optional. Mutually exclusive with [`@model`](#model).
-
-An array of models / dynamic segments.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route" someModel someNestedModel}}
- Click me
-{{/link-to}}
-```
-
-##### `@model`
-
-Optional. Mutually exclusive with [`@models`](#models).
-
-Shorthand for providing a single model / dynamic segment. The following two
-invocations are equivalent:
-
-```hbs
-
-
-```
-
-##### `@query`
+### `LinkManager` Service Example
-Optional.
-
-Query Params object.
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-**`{{link-to}}` equivalent**
-
-```hbs
-{{#link-to "some.route" (query-params foo="bar")}}
- Click me
-{{/link-to}}
-```
-
-##### `@fromURL`
-
-Optional. Mutually exclusive with [`@route`](#route), [`@model`](#model) /
-[`@models`](#models), [`@query`](#query).
-
-**Example**
-
-```hbs
-
-
- Click me
-
-
-```
-
-##### `@preventDefault`
-
-Optional. Default: `true`
-
-If enabled, the [`transitionTo`](#transitionto) and
-[`replaceWith`](#replacewith) actions will try to call
-[`event.preventDefault()`][prevent-default] on the first argument, if it is an
-event. This is an anti-foot-gun to make ` ` _just work™️_ with `` and
-``, which would otherwise trigger a native browser navigation / form
-submission.
-
-[prevent-default]: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
-
-#### Yielded Parameters
-
-The ` ` component yields a [`UILink`](#uilink) instance.
-
-##### `url`
-
-`string`
-
-The URL for this link that you can pass to an `` tag as the `href` attribute.
-
-```hbs
-
-
- Click me
-
-
-```
-
-##### `isActive`
-
-`boolean`
-
-Whether this route is currently active, including potentially supplied models
-and query params.
-
-In the following example, only one link will be `is-active` at any time.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-```
-
-##### `isActiveWithoutQueryParams`
-
-`boolean`
-
-Whether this route is currently active, including potentially supplied models,
-but ignoring query params.
-
-In the following example, the first two links will be `is-active` simultaneously.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-
-
-
- Three
-
-
-```
-
-##### `isActiveWithoutModels`
-
-`boolean`
-
-Whether this route is currently active, but ignoring models and query params.
-
-In the following example, both links will be `is-active` simultaneously.
-
-```hbs
-
-
- One
-
-
-
-
-
- Two
-
-
-```
-
-##### `transitionTo()`
-
-`(event?: Event) => Transition`
-
-Transition into the target route.
-
-If [`@preventDefault`](#preventdefault) is enabled, also calls `event.preventDefault()`.
-
-##### `replaceWith()`
-
-`(event?: Event) => Transition`
-
-Transition into the target route while replacing the current URL, if possible.
-
-If [`@preventDefault`](#preventdefault) is enabled, also calls `event.preventDefault()`.
-
-### `Link`
-
-A `Link` is a self-contained reference to a concrete route, including models and
-query params. It's basically like a
-[`` / `{{link-to}}` component][link-to-component] you can pass around.
-
-[link-to-component]: https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/input?anchor=LinkTo
-
-You can create a `Link` via the [`LinkManager` service](#linkmanager).
-
-[`UILink`](#uilink) extends `Link` with some anti-foot-guns and conveniences. It
-can also be created via the [`LinkManager` service](#linkmanager), but also via
-the [`{{link}}` helper](#link-helper) and [` ` component](#link-component).
-
-#### Properties
-
-##### `isActive`
-
-Type: `boolean`
-
-Whether this route is currently active, including potentially supplied models
-and query params.
-
-##### `isActiveWithoutQueryParams`
-
-Type: `boolean`
-
-Whether this route is currently active, including potentially supplied models,
-but ignoring query params.
-
-##### `isActiveWithoutModels`
-
-Type: `boolean`
-
-Whether this route is currently active, but ignoring models and query params.
-
-##### `url`
-
-Type: `string`
-
-The URL for this link that you can pass to an `` tag as the `href` attribute.
-
-##### `routeName`
-
-Type: `string`
-
-The target route name of this link.
-
-##### `models`
-
-Type: `RouteModel[]`
-
-The route models passed in this link.
-
-##### `queryParams`
-
-Type: `Record | undefined`
-
-The query params for this link, if specified.
-
-#### Methods
-
-##### `transitionTo()`
-
-Returns: [`Transition`][transition]
-
-Transition into the target route.
-
-##### `replaceWith()`
-
-Returns: [`Transition`][transition]
-
-Transition into the target route while replacing the current URL, if possible.
-
-[transition]: https://api.emberjs.com/ember/release/classes/Transition
-
-### `UILink`
-
-`UILink` extends [`Link`](#link) with anti-foot-guns and conveniences. This
-class is meant to be used in templates, primarily through `` & ``
-elements.
-
-It wraps `transitionTo()` and `replaceWith()` to optionally accept an `event`
-argument. It will intelligently
-
-- call `event.preventDefault()` to prevent hard page reloads
-- open the page in a new tab, when `Cmd` / `Ctrl` clicking
-
-It can be created via the [`LinkManager` service](#linkmanager), but also via
-the [`{{link}}` helper](#link-helper) and [` ` component](#link-component).
-
-### `LinkManager`
-
-The `LinkManager` service is used by the [`{{link}} helper`](#link-helper) and
-[` ` component](#link-component) to create [`UILink`](#uilink) instances.
-
-You can also use this service directly to programmatically create link
-references.
-
-#### `createLink(linkParams: LinkParams): Link`
-
-Returns: [`Link`](#link)
+Use the `LinkManager.createLink()` method to create a link programmatically.
```ts
-interface LinkParams {
- /**
- * The target route name.
- */
- route: string;
+import Contoller from '@ember/controller';
+import { service } from '@ember/service';
+import type { LinkManagerService } from 'ember-link';
- /**
- * Optional array of models / dynamic segments.
- */
- models?: RouteModel[];
+export default class PageHeader extends Controller {
+ @service declare linkManager: LinkManagerService;
- /**
- * Optional query params object.
- */
- query?: QueryParams;
-}
-```
-
-#### `createUILink(linkParams: LinkParams, uiParams: UILinkParams): UILink`
-
-Returns: [`UILink`](#uilink)
-
-```ts
-interface UILinkParams {
- /**
- * Whether or not to call `event.preventDefault()`, if the first parameter to
- * the `transitionTo` or `replaceWith` action is an `Event`. This is useful to
- * prevent links from accidentally triggering real browser navigation or
- * buttons from submitting a form.
- *
- * Defaults to `true`.
- */
- preventDefault?: boolean;
+ aboutUsLink = this.linkManager.createLink('about');
}
```
-#### `getLinkParamsFromURL(url: string): LinkParams`
+### Working with Primitives
-Returns: [`LinkParams`](#createlinklinkparams-linkparams-link)
+The idea of `ember-link` is to be able to create link primitives, that you can
+pass around. Create links at route level and then pass them into components.
-Use this method to derive `LinkParams` from a serialized, recognizable URL, that
-you can then pass into `createLink` / `createUILink`.
+A more in-depth guide is available at [using primitives](https://buschtoens.github.io/ember-link/using-primitives.html).
-### Testing
+## Testing
-In [acceptance / application tests (`setupApplicationTest(hooks)`)][tests-application]
-your app boots with a fully-fledged router, so `ember-link` just works normally.
-
-In [integration / render tests (`setupRenderingTest(hooks)`)][tests-render] the
-router is not initialized, so `ember-link` can't operate normally. To still
-support using `{{link}}` & friends in render tests, you can use the
-[`setupLink(hooks)` test helper][setup-link].
-
-[tests-application]: https://guides.emberjs.com/release/testing/testing-application/
-[tests-render]: https://guides.emberjs.com/release/testing/testing-components/
-[setup-link]: https://github.com/buschtoens/ember-link/blob/main/addon-test-support/setup-link.ts
+[ember-link has testing support](https://buschtoens.github.io/ember-link/testing.html) on board, preparing the environment with
+`setupLink()` and `linkFor()` to create a link to a route on the fly:
```ts
-import { click, render } from '@ember/test-helpers';
-import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { click, render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
import { setupLink, linkFor, TestLink } from 'ember-link/test-support';
-import hbs from 'htmlbars-inline-precompile';
-
module('`setupLink` example', function (hooks) {
setupRenderingTest(hooks);
setupLink(hooks);
- test('` ` component works in render tests', async function (assert) {
- await render(hbs`
-
-
- Click me
-
-
- `);
-
+ test('`(link)` works in render tests', async function (assert) {
const link = linkFor('some.route');
link.onTransitionTo = assert.step('link clicked');
+ await render(hbs`
+ {{#let (link @route="some.route") as |l|}}
+ Click me
+ {{/let}}
+ `);
+
await click('a');
assert.verifySteps(['link clicked']);
diff --git a/ember-link/package.json b/ember-link/package.json
index daeb27c3..b706374e 100644
--- a/ember-link/package.json
+++ b/ember-link/package.json
@@ -44,7 +44,8 @@
"lint:js:fix": "eslint . --fix",
"lint:types": "tsc --noEmit",
"prepack": "rollup --config",
- "start": "rollup --config --watch"
+ "start": "rollup --config --watch",
+ "api": "typedoc"
},
"dependencies": {
"@embroider/addon-shim": "^1.8.5",
@@ -79,6 +80,8 @@
"rollup": "3.25.1",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-ts": "^3.2.0",
+ "typedoc": "^0.24.8",
+ "typedoc-plugin-markdown": "^3.15.3",
"typescript": "^5.1.3"
},
"engines": {
diff --git a/ember-link/src/helpers/link.ts b/ember-link/src/helpers/link.ts
index d87155b5..69ebd528 100644
--- a/ember-link/src/helpers/link.ts
+++ b/ember-link/src/helpers/link.ts
@@ -9,9 +9,9 @@ import type { QueryParams } from '../-params';
import type Link from '../link';
import type LinkManagerService from '../services/link-manager';
-type PositionalParams = [] | RouteArgs;
+export type PositionalParams = [] | RouteArgs;
-interface NamedParams extends Partial {
+export interface NamedParams extends Partial {
/**
* Optional shortcut for `models={{array model}}`.
*/
@@ -24,23 +24,6 @@ interface NamedParams extends Partial {
* This is mutually exclusive with any other `LinkParams`.
*/
fromURL?: string;
-
- /**
- * An optional callback that will be fired when the Link is transitioned to.
- *
- * The callback is only fired if the Link is explicitly invoked, not if the
- * app transitions to the Link through other means.
- */
- onTransitionTo?: () => void;
-
- /**
- * An optional callback that will be fired when the current route is replaced
- * with the Link.
- *
- * The callback is only fired if the Link is explicitly invoked, not if the
- * app transitions to the Link through other means.
- */
- onReplaceWith?: () => void;
}
export interface LinkSignature {
diff --git a/ember-link/src/index.ts b/ember-link/src/index.ts
index c67e3c02..ccde2649 100644
--- a/ember-link/src/index.ts
+++ b/ember-link/src/index.ts
@@ -1,5 +1,15 @@
+/**
+ * Create links as primitives, pass them around and attach them to elements.
+ *
+ * @see https://buschtoens.github.io/ember-link
+ * @module ember-link
+ */
+
+export type { Behavior } from './-behavior';
export { prevent } from './-behavior';
export type { LinkParams } from './-params';
+// `NamedParams` breaks vitepress when parsing the markdown ... :(
+export type { LinkSignature, /*NamedParams,*/ PositionalParams } from './helpers/link';
export { default as link } from './helpers/link';
export { default as Link } from './link';
export type { default as LinkManagerService } from './services/link-manager';
diff --git a/ember-link/src/test-support/index.ts b/ember-link/src/test-support/index.ts
index 90c93e02..5c1f2f21 100644
--- a/ember-link/src/test-support/index.ts
+++ b/ember-link/src/test-support/index.ts
@@ -1,3 +1,10 @@
+/**
+ * Test support for `ember-link` containing:
+ *
+ * @see https://buschtoens.github.io/ember-link/testing
+ * @module ember-link/test-support
+ */
+
export { default as TestInstrumentedLinkManagerService } from './-services/test-instrumented-link-manager';
export { default as linkFor } from './link-for';
export { default as setupLink } from './setup-link';
diff --git a/ember-link/typedoc.json b/ember-link/typedoc.json
new file mode 100644
index 00000000..61609b8b
--- /dev/null
+++ b/ember-link/typedoc.json
@@ -0,0 +1,16 @@
+{
+ "entryPoints": [
+ "src/index.ts",
+ "src/test-support/index.ts"
+ ],
+ "out": "../docs/api",
+ "json": "../docs/api/data.json",
+ "plugin": [
+ "typedoc-plugin-markdown"
+ ],
+ "excludePrivate": true,
+ "excludeProtected": true,
+ "excludeExternals": true,
+ // typedoc-plugin-markdown
+ "hideBreadcrumbs": true
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 9d7d0c1e..f2755a43 100644
--- a/package.json
+++ b/package.json
@@ -11,12 +11,26 @@
"lint:fix": "pnpm --filter '*' lint:fix",
"start": "concurrently 'npm:start:*' --restart-after 5000 --prefix-colors cyan,white,yellow",
"start:addon": "pnpm --filter ember-link start",
- "start:test-app": "pnpm --filter test-app start"
+ "start:test-app": "pnpm --filter test-app start",
+ "build:docs": "pnpm docs:api && pnpm docs:build",
+ "docs:api": "pnpm --filter ember-link api",
+ "docs:dev": "vitepress dev docs",
+ "docs:build": "vitepress build docs",
+ "docs:preview": "vitepress preview docs"
},
"devDependencies": {
- "concurrently": "^7.6.0"
+ "concurrently": "^7.6.0",
+ "vitepress": "^1.0.0-beta.3"
},
"volta": {
"node": "16.20.0"
+ },
+ "pnpm": {
+ "peerDependencyRules": {
+ "ignoreMissing": [
+ "@algolia/client-search",
+ "search-insights"
+ ]
+ }
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 10aa56f8..2ab75c03 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,6 +7,9 @@ importers:
concurrently:
specifier: ^7.6.0
version: 7.6.0
+ vitepress:
+ specifier: ^1.0.0-beta.3
+ version: 1.0.0-beta.3
ember-link:
dependencies:
@@ -92,6 +95,12 @@ importers:
rollup-plugin-ts:
specifier: ^3.2.0
version: 3.2.0(@babel/core@7.22.5)(@babel/preset-typescript@7.22.5)(@babel/runtime@7.22.5)(rollup@3.25.1)(typescript@5.1.3)
+ typedoc:
+ specifier: ^0.24.8
+ version: 0.24.8(typescript@5.1.3)
+ typedoc-plugin-markdown:
+ specifier: ^3.15.3
+ version: 3.15.3(typedoc@0.24.8)
typescript:
specifier: ^5.1.3
version: 5.1.3
@@ -243,6 +252,146 @@ importers:
packages:
+ /@algolia/autocomplete-core@1.9.3(algoliasearch@4.18.0):
+ resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==}
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(algoliasearch@4.18.0)
+ '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.18.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+ dev: true
+
+ /@algolia/autocomplete-plugin-algolia-insights@1.9.3(algoliasearch@4.18.0):
+ resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==}
+ peerDependencies:
+ search-insights: '>= 1 < 3'
+ peerDependenciesMeta:
+ search-insights:
+ optional: true
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.18.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ dev: true
+
+ /@algolia/autocomplete-preset-algolia@1.9.3(algoliasearch@4.18.0):
+ resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+ peerDependenciesMeta:
+ '@algolia/client-search':
+ optional: true
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.18.0)
+ algoliasearch: 4.18.0
+ dev: true
+
+ /@algolia/autocomplete-shared@1.9.3(algoliasearch@4.18.0):
+ resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+ peerDependenciesMeta:
+ '@algolia/client-search':
+ optional: true
+ dependencies:
+ algoliasearch: 4.18.0
+ dev: true
+
+ /@algolia/cache-browser-local-storage@4.18.0:
+ resolution: {integrity: sha512-rUAs49NLlO8LVLgGzM4cLkw8NJLKguQLgvFmBEe3DyzlinoqxzQMHfKZs6TSq4LZfw/z8qHvRo8NcTAAUJQLcw==}
+ dependencies:
+ '@algolia/cache-common': 4.18.0
+ dev: true
+
+ /@algolia/cache-common@4.18.0:
+ resolution: {integrity: sha512-BmxsicMR4doGbeEXQu8yqiGmiyvpNvejYJtQ7rvzttEAMxOPoWEHrWyzBQw4x7LrBY9pMrgv4ZlUaF8PGzewHg==}
+ dev: true
+
+ /@algolia/cache-in-memory@4.18.0:
+ resolution: {integrity: sha512-evD4dA1nd5HbFdufBxLqlJoob7E2ozlqJZuV3YlirNx5Na4q1LckIuzjNYZs2ddLzuTc/Xd5O3Ibf7OwPskHxw==}
+ dependencies:
+ '@algolia/cache-common': 4.18.0
+ dev: true
+
+ /@algolia/client-account@4.18.0:
+ resolution: {integrity: sha512-XsDnlROr3+Z1yjxBJjUMfMazi1V155kVdte6496atvBgOEtwCzTs3A+qdhfsAnGUvaYfBrBkL0ThnhMIBCGcew==}
+ dependencies:
+ '@algolia/client-common': 4.18.0
+ '@algolia/client-search': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
+ /@algolia/client-analytics@4.18.0:
+ resolution: {integrity: sha512-chEUSN4ReqU7uRQ1C8kDm0EiPE+eJeAXiWcBwLhEynfNuTfawN9P93rSZktj7gmExz0C8XmkbBU19IQ05wCNrQ==}
+ dependencies:
+ '@algolia/client-common': 4.18.0
+ '@algolia/client-search': 4.18.0
+ '@algolia/requester-common': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
+ /@algolia/client-common@4.18.0:
+ resolution: {integrity: sha512-7N+soJFP4wn8tjTr3MSUT/U+4xVXbz4jmeRfWfVAzdAbxLAQbHa0o/POSdTvQ8/02DjCLelloZ1bb4ZFVKg7Wg==}
+ dependencies:
+ '@algolia/requester-common': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
+ /@algolia/client-personalization@4.18.0:
+ resolution: {integrity: sha512-+PeCjODbxtamHcPl+couXMeHEefpUpr7IHftj4Y4Nia1hj8gGq4VlIcqhToAw8YjLeCTfOR7r7xtj3pJcYdP8A==}
+ dependencies:
+ '@algolia/client-common': 4.18.0
+ '@algolia/requester-common': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
+ /@algolia/client-search@4.18.0:
+ resolution: {integrity: sha512-F9xzQXTjm6UuZtnsLIew6KSraXQ0AzS/Ee+OD+mQbtcA/K1sg89tqb8TkwjtiYZ0oij13u3EapB3gPZwm+1Y6g==}
+ dependencies:
+ '@algolia/client-common': 4.18.0
+ '@algolia/requester-common': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
+ /@algolia/logger-common@4.18.0:
+ resolution: {integrity: sha512-46etYgSlkoKepkMSyaoriSn2JDgcrpc/nkOgou/lm0y17GuMl9oYZxwKKTSviLKI5Irk9nSKGwnBTQYwXOYdRg==}
+ dev: true
+
+ /@algolia/logger-console@4.18.0:
+ resolution: {integrity: sha512-3P3VUYMl9CyJbi/UU1uUNlf6Z8N2ltW3Oqhq/nR7vH0CjWv32YROq3iGWGxB2xt3aXobdUPXs6P0tHSKRmNA6g==}
+ dependencies:
+ '@algolia/logger-common': 4.18.0
+ dev: true
+
+ /@algolia/requester-browser-xhr@4.18.0:
+ resolution: {integrity: sha512-/AcWHOBub2U4TE/bPi4Gz1XfuLK6/7dj4HJG+Z2SfQoS1RjNLshZclU3OoKIkFp8D2NC7+BNsPvr9cPLyW8nyQ==}
+ dependencies:
+ '@algolia/requester-common': 4.18.0
+ dev: true
+
+ /@algolia/requester-common@4.18.0:
+ resolution: {integrity: sha512-xlT8R1qYNRBCi1IYLsx7uhftzdfsLPDGudeQs+xvYB4sQ3ya7+ppolB/8m/a4F2gCkEO6oxpp5AGemM7kD27jA==}
+ dev: true
+
+ /@algolia/requester-node-http@4.18.0:
+ resolution: {integrity: sha512-TGfwj9aeTVgOUhn5XrqBhwUhUUDnGIKlI0kCBMdR58XfXcfdwomka+CPIgThRbfYw04oQr31A6/95ZH2QVJ9UQ==}
+ dependencies:
+ '@algolia/requester-common': 4.18.0
+ dev: true
+
+ /@algolia/transporter@4.18.0:
+ resolution: {integrity: sha512-xbw3YRUGtXQNG1geYFEDDuFLZt4Z8YNKbamHPkzr3rWc6qp4/BqEeXcI2u/P/oMq2yxtXgMxrCxOPA8lyIe5jw==}
+ dependencies:
+ '@algolia/cache-common': 4.18.0
+ '@algolia/logger-common': 4.18.0
+ '@algolia/requester-common': 4.18.0
+ dev: true
+
/@ampproject/remapping@2.2.1:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
engines: {node: '>=6.0.0'}
@@ -1447,6 +1596,46 @@ packages:
minimist: 1.2.7
dev: true
+ /@docsearch/css@3.5.1:
+ resolution: {integrity: sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA==}
+ dev: true
+
+ /@docsearch/js@3.5.1:
+ resolution: {integrity: sha512-EXi8de5njxgP6TV3N9ytnGRLG9zmBNTEZjR4VzwPcpPLbZxxTLG2gaFyJyKiFVQxHW/DPlMrDJA3qoRRGEkgZw==}
+ dependencies:
+ '@docsearch/react': 3.5.1
+ preact: 10.15.1
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - react
+ - react-dom
+ - search-insights
+ dev: true
+
+ /@docsearch/react@3.5.1:
+ resolution: {integrity: sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ==}
+ peerDependencies:
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ dependencies:
+ '@algolia/autocomplete-core': 1.9.3(algoliasearch@4.18.0)
+ '@algolia/autocomplete-preset-algolia': 1.9.3(algoliasearch@4.18.0)
+ '@docsearch/css': 3.5.1
+ algoliasearch: 4.18.0
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - search-insights
+ dev: true
+
/@ember-data/rfc395-data@0.0.4:
resolution: {integrity: sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ==}
@@ -1636,6 +1825,204 @@ packages:
resolve: 1.22.3
dev: true
+ /@esbuild/android-arm64@0.17.19:
+ resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-arm@0.17.19:
+ resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-x64@0.17.19:
+ resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-arm64@0.17.19:
+ resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-x64@0.17.19:
+ resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-arm64@0.17.19:
+ resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-x64@0.17.19:
+ resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm64@0.17.19:
+ resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm@0.17.19:
+ resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ia32@0.17.19:
+ resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-loong64@0.17.19:
+ resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-mips64el@0.17.19:
+ resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ppc64@0.17.19:
+ resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-riscv64@0.17.19:
+ resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-s390x@0.17.19:
+ resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-x64@0.17.19:
+ resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/netbsd-x64@0.17.19:
+ resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/openbsd-x64@0.17.19:
+ resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/sunos-x64@0.17.19:
+ resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-arm64@0.17.19:
+ resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-ia32@0.17.19:
+ resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-x64@0.17.19:
+ resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@eslint-community/eslint-utils@4.4.0(eslint@8.43.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -1961,7 +2348,7 @@ packages:
fs-extra: 9.1.0
proper-lockfile: 4.1.2
slash: 3.0.0
- tslib: 2.4.1
+ tslib: 2.6.0
upath: 2.0.1
dev: true
@@ -2255,6 +2642,10 @@ packages:
resolution: {integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==}
dev: true
+ /@types/web-bluetooth@0.0.17:
+ resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==}
+ dev: true
+
/@typescript-eslint/eslint-plugin@5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3):
resolution: {integrity: sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -2385,6 +2776,179 @@ packages:
eslint-visitor-keys: 3.4.1
dev: true
+ /@vitejs/plugin-vue@4.2.3(vite@4.3.9)(vue@3.3.4):
+ resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.0.0
+ vue: ^3.2.25
+ dependencies:
+ vite: 4.3.9
+ vue: 3.3.4
+ dev: true
+
+ /@vue/compiler-core@3.3.4:
+ resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
+ dependencies:
+ '@babel/parser': 7.22.5
+ '@vue/shared': 3.3.4
+ estree-walker: 2.0.2
+ source-map-js: 1.0.2
+ dev: true
+
+ /@vue/compiler-dom@3.3.4:
+ resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
+ dependencies:
+ '@vue/compiler-core': 3.3.4
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/compiler-sfc@3.3.4:
+ resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==}
+ dependencies:
+ '@babel/parser': 7.22.5
+ '@vue/compiler-core': 3.3.4
+ '@vue/compiler-dom': 3.3.4
+ '@vue/compiler-ssr': 3.3.4
+ '@vue/reactivity-transform': 3.3.4
+ '@vue/shared': 3.3.4
+ estree-walker: 2.0.2
+ magic-string: 0.30.0
+ postcss: 8.4.24
+ source-map-js: 1.0.2
+ dev: true
+
+ /@vue/compiler-ssr@3.3.4:
+ resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==}
+ dependencies:
+ '@vue/compiler-dom': 3.3.4
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/devtools-api@6.5.0:
+ resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
+ dev: true
+
+ /@vue/reactivity-transform@3.3.4:
+ resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
+ dependencies:
+ '@babel/parser': 7.22.5
+ '@vue/compiler-core': 3.3.4
+ '@vue/shared': 3.3.4
+ estree-walker: 2.0.2
+ magic-string: 0.30.0
+ dev: true
+
+ /@vue/reactivity@3.3.4:
+ resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
+ dependencies:
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/runtime-core@3.3.4:
+ resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==}
+ dependencies:
+ '@vue/reactivity': 3.3.4
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/runtime-dom@3.3.4:
+ resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==}
+ dependencies:
+ '@vue/runtime-core': 3.3.4
+ '@vue/shared': 3.3.4
+ csstype: 3.1.2
+ dev: true
+
+ /@vue/server-renderer@3.3.4(vue@3.3.4):
+ resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==}
+ peerDependencies:
+ vue: 3.3.4
+ dependencies:
+ '@vue/compiler-ssr': 3.3.4
+ '@vue/shared': 3.3.4
+ vue: 3.3.4
+ dev: true
+
+ /@vue/shared@3.3.4:
+ resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
+ dev: true
+
+ /@vueuse/core@10.2.1(vue@3.3.4):
+ resolution: {integrity: sha512-c441bfMbkAwTNwVRHQ0zdYZNETK//P84rC01aP2Uy/aRFCiie9NE/k9KdIXbno0eDYP5NPUuWv0aA/I4Unr/7w==}
+ dependencies:
+ '@types/web-bluetooth': 0.0.17
+ '@vueuse/metadata': 10.2.1
+ '@vueuse/shared': 10.2.1(vue@3.3.4)
+ vue-demi: 0.14.5(vue@3.3.4)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: true
+
+ /@vueuse/integrations@10.2.1(focus-trap@7.4.3)(vue@3.3.4):
+ resolution: {integrity: sha512-FDP5lni+z9FjHE9H3xuvwSjoRV9U8jmDvJpmHPCBjUgPGYRynwb60eHWXCFJXLUtb4gSIHy0e+iaEbrKdalCkQ==}
+ peerDependencies:
+ async-validator: '*'
+ axios: '*'
+ change-case: '*'
+ drauu: '*'
+ focus-trap: '*'
+ fuse.js: '*'
+ idb-keyval: '*'
+ jwt-decode: '*'
+ nprogress: '*'
+ qrcode: '*'
+ sortablejs: '*'
+ universal-cookie: '*'
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+ dependencies:
+ '@vueuse/core': 10.2.1(vue@3.3.4)
+ '@vueuse/shared': 10.2.1(vue@3.3.4)
+ focus-trap: 7.4.3
+ vue-demi: 0.14.5(vue@3.3.4)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: true
+
+ /@vueuse/metadata@10.2.1:
+ resolution: {integrity: sha512-3Gt68mY/i6bQvFqx7cuGBzrCCQu17OBaGWS5JdwISpMsHnMKKjC2FeB5OAfMcCQ0oINfADP3i9A4PPRo0peHdQ==}
+ dev: true
+
+ /@vueuse/shared@10.2.1(vue@3.3.4):
+ resolution: {integrity: sha512-QWHq2bSuGptkcxx4f4M/fBYC3Y8d3M2UYyLsyzoPgEoVzJURQ0oJeWXu79OiLlBb8gTKkqe4mO85T/sf39mmiw==}
+ dependencies:
+ vue-demi: 0.14.5(vue@3.3.4)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: true
+
/@webassemblyjs/ast@1.11.5:
resolution: {integrity: sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==}
dependencies:
@@ -2628,6 +3192,25 @@ packages:
uri-js: 4.4.1
dev: true
+ /algoliasearch@4.18.0:
+ resolution: {integrity: sha512-pCuVxC1SVcpc08ENH32T4sLKSyzoU7TkRIDBMwSLfIiW+fq4znOmWDkAygHZ6pRcO9I1UJdqlfgnV7TRj+MXrA==}
+ dependencies:
+ '@algolia/cache-browser-local-storage': 4.18.0
+ '@algolia/cache-common': 4.18.0
+ '@algolia/cache-in-memory': 4.18.0
+ '@algolia/client-account': 4.18.0
+ '@algolia/client-analytics': 4.18.0
+ '@algolia/client-common': 4.18.0
+ '@algolia/client-personalization': 4.18.0
+ '@algolia/client-search': 4.18.0
+ '@algolia/logger-common': 4.18.0
+ '@algolia/logger-console': 4.18.0
+ '@algolia/requester-browser-xhr': 4.18.0
+ '@algolia/requester-common': 4.18.0
+ '@algolia/requester-node-http': 4.18.0
+ '@algolia/transporter': 4.18.0
+ dev: true
+
/amd-name-resolver@1.3.1:
resolution: {integrity: sha512-26qTEWqZQ+cxSYygZ4Cf8tsjDBLceJahhtewxtKZA3SRa4PluuqYCuheemDQD+7Mf5B7sr+zhTDWAHDh02a1Dw==}
engines: {node: 6.* || 8.* || >= 10.*}
@@ -2683,6 +3266,10 @@ packages:
engines: {node: '>=8'}
dev: true
+ /ansi-sequence-parser@1.1.0:
+ resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==}
+ dev: true
+
/ansi-styles@2.2.1:
resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==}
engines: {node: '>=0.10.0'}
@@ -3149,6 +3736,10 @@ packages:
- supports-color
dev: true
+ /body-scroll-lock@4.0.0-beta.0:
+ resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==}
+ dev: true
+
/body@5.1.0:
resolution: {integrity: sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==}
dependencies:
@@ -4535,6 +5126,10 @@ packages:
cssom: 0.3.8
dev: true
+ /csstype@3.1.2:
+ resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+ dev: true
+
/dag-map@2.0.2:
resolution: {integrity: sha512-xnsprIzYuDeiyu5zSKwilV/ajRHxnoMlAhEREfyfTgTSViMVY2fGP1ZcHJbtwup26oCkofySU/m6oKJ3HrkW7w==}
dev: true
@@ -4766,7 +5361,7 @@ packages:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
dependencies:
no-case: 3.0.4
- tslib: 2.4.1
+ tslib: 2.6.0
dev: true
/dot-prop@5.3.0:
@@ -5661,6 +6256,36 @@ packages:
is-symbol: 1.0.4
dev: true
+ /esbuild@0.17.19:
+ resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.17.19
+ '@esbuild/android-arm64': 0.17.19
+ '@esbuild/android-x64': 0.17.19
+ '@esbuild/darwin-arm64': 0.17.19
+ '@esbuild/darwin-x64': 0.17.19
+ '@esbuild/freebsd-arm64': 0.17.19
+ '@esbuild/freebsd-x64': 0.17.19
+ '@esbuild/linux-arm': 0.17.19
+ '@esbuild/linux-arm64': 0.17.19
+ '@esbuild/linux-ia32': 0.17.19
+ '@esbuild/linux-loong64': 0.17.19
+ '@esbuild/linux-mips64el': 0.17.19
+ '@esbuild/linux-ppc64': 0.17.19
+ '@esbuild/linux-riscv64': 0.17.19
+ '@esbuild/linux-s390x': 0.17.19
+ '@esbuild/linux-x64': 0.17.19
+ '@esbuild/netbsd-x64': 0.17.19
+ '@esbuild/openbsd-x64': 0.17.19
+ '@esbuild/sunos-x64': 0.17.19
+ '@esbuild/win32-arm64': 0.17.19
+ '@esbuild/win32-ia32': 0.17.19
+ '@esbuild/win32-x64': 0.17.19
+ dev: true
+
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@@ -6541,6 +7166,12 @@ packages:
resolution: {integrity: sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==}
dev: true
+ /focus-trap@7.4.3:
+ resolution: {integrity: sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==}
+ dependencies:
+ tabbable: 6.2.0
+ dev: true
+
/follow-redirects@1.14.5:
resolution: {integrity: sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==}
engines: {node: '>=4.0'}
@@ -8252,7 +8883,7 @@ packages:
/lower-case@2.0.2:
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
dependencies:
- tslib: 2.4.1
+ tslib: 2.6.0
dev: true
/lowercase-keys@1.0.1:
@@ -8281,6 +8912,10 @@ packages:
engines: {node: '>=12'}
dev: true
+ /lunr@2.3.9:
+ resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==}
+ dev: true
+
/magic-string@0.25.7:
resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
dependencies:
@@ -8333,6 +8968,10 @@ packages:
object-visit: 1.0.1
dev: true
+ /mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+ dev: true
+
/markdown-it-terminal@0.4.0(markdown-it@13.0.1):
resolution: {integrity: sha512-NeXtgpIK6jBciHTm9UhiPnyHDdqyVIdRPJ+KdQtZaf/wR74gvhCNbw5li4TYsxRp5u3ZoHEF4DwpECeZqyCw+w==}
peerDependencies:
@@ -8356,6 +8995,12 @@ packages:
uc.micro: 1.0.6
dev: true
+ /marked@4.3.0:
+ resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
+ engines: {node: '>= 12'}
+ hasBin: true
+ dev: true
+
/matcher-collection@1.1.2:
resolution: {integrity: sha512-YQ/teqaOIIfUHedRam08PB3NK7Mjct6BvzRnJmpGDm8uFXpNr1sbY4yuflI5JcEs6COpYA0FpRQhSDBf1tT95g==}
dependencies:
@@ -8513,6 +9158,13 @@ packages:
brace-expansion: 2.0.1
dev: true
+ /minimatch@9.0.2:
+ resolution: {integrity: sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ brace-expansion: 2.0.1
+ dev: true
+
/minimist@0.2.1:
resolution: {integrity: sha512-GY8fANSrTMfBVfInqJAY41QkOM+upUTytK1jZ0c8+3HdHrJxBJ3rF5i9moClXTE8uUSnUo8cAsCoxDXvSY4DHg==}
dev: true
@@ -8527,6 +9179,10 @@ packages:
yallist: 3.1.1
dev: true
+ /minisearch@6.1.0:
+ resolution: {integrity: sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==}
+ dev: true
+
/mixin-deep@1.3.2:
resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==}
engines: {node: '>=0.10.0'}
@@ -8591,8 +9247,8 @@ packages:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
dev: true
- /nanoid@3.1.30:
- resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==}
+ /nanoid@3.3.6:
+ resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
dev: true
@@ -8651,7 +9307,7 @@ packages:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
dependencies:
lower-case: 2.0.2
- tslib: 2.4.1
+ tslib: 2.6.0
dev: true
/node-fetch@2.6.7:
@@ -9272,11 +9928,24 @@ packages:
resolution: {integrity: sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
- nanoid: 3.1.30
+ nanoid: 3.3.6
picocolors: 1.0.0
source-map-js: 0.6.2
dev: true
+ /postcss@8.4.24:
+ resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.6
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+ dev: true
+
+ /preact@10.15.1:
+ resolution: {integrity: sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==}
+ dev: true
+
/prelude-ls@1.1.2:
resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
engines: {node: '>= 0.8.0'}
@@ -9850,13 +10519,13 @@ packages:
/rxjs@7.8.0:
resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==}
dependencies:
- tslib: 2.4.1
+ tslib: 2.6.0
dev: true
/rxjs@7.8.1:
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
dependencies:
- tslib: 2.4.1
+ tslib: 2.6.0
dev: true
/safe-buffer@5.1.2:
@@ -10082,6 +10751,15 @@ packages:
resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==}
dev: true
+ /shiki@0.14.3:
+ resolution: {integrity: sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==}
+ dependencies:
+ ansi-sequence-parser: 1.1.0
+ jsonc-parser: 3.2.0
+ vscode-oniguruma: 1.7.0
+ vscode-textmate: 8.0.0
+ dev: true
+
/side-channel@1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
dependencies:
@@ -10537,6 +11215,10 @@ packages:
- supports-color
dev: true
+ /tabbable@6.2.0:
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+ dev: true
+
/tap-parser@7.0.0:
resolution: {integrity: sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==}
hasBin: true
@@ -10889,6 +11571,10 @@ packages:
resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}
dev: true
+ /tslib@2.6.0:
+ resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
+ dev: true
+
/tsutils@3.21.0(typescript@5.1.3):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
@@ -10947,6 +11633,29 @@ packages:
is-typedarray: 1.0.0
dev: true
+ /typedoc-plugin-markdown@3.15.3(typedoc@0.24.8):
+ resolution: {integrity: sha512-idntFYu3vfaY3eaD+w9DeRd0PmNGqGuNLKihPU9poxFGnATJYGn9dPtEhn2QrTdishFMg7jPXAhos+2T6YCWRQ==}
+ peerDependencies:
+ typedoc: '>=0.24.0'
+ dependencies:
+ handlebars: 4.7.7
+ typedoc: 0.24.8(typescript@5.1.3)
+ dev: true
+
+ /typedoc@0.24.8(typescript@5.1.3):
+ resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==}
+ engines: {node: '>= 14.14'}
+ hasBin: true
+ peerDependencies:
+ typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x
+ dependencies:
+ lunr: 2.3.9
+ marked: 4.3.0
+ minimatch: 9.0.2
+ shiki: 0.14.3
+ typescript: 5.1.3
+ dev: true
+
/typescript-memoize@1.1.0:
resolution: {integrity: sha512-LQPKVXK8QrBBkL/zclE6YgSWn0I8ew5m0Lf+XL00IwMhlotqRLlzHV+BRrljVQIc+NohUAuQP7mg4HQwrx5Xbg==}
@@ -11156,6 +11865,81 @@ packages:
engines: {node: '>= 0.8'}
dev: true
+ /vite@4.3.9:
+ resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>= 14'
+ less: '*'
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ dependencies:
+ esbuild: 0.17.19
+ postcss: 8.4.24
+ rollup: 3.25.1
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
+ /vitepress@1.0.0-beta.3:
+ resolution: {integrity: sha512-GR5Pvr/o343NN1M4Na1shhDYZRrQbjmLq7WE0lla0H8iDPAsHE8agTHLWfu3FWx+3q2KA29sv16+0O9RQKGjlA==}
+ hasBin: true
+ dependencies:
+ '@docsearch/css': 3.5.1
+ '@docsearch/js': 3.5.1
+ '@vitejs/plugin-vue': 4.2.3(vite@4.3.9)(vue@3.3.4)
+ '@vue/devtools-api': 6.5.0
+ '@vueuse/core': 10.2.1(vue@3.3.4)
+ '@vueuse/integrations': 10.2.1(focus-trap@7.4.3)(vue@3.3.4)
+ body-scroll-lock: 4.0.0-beta.0
+ focus-trap: 7.4.3
+ mark.js: 8.11.1
+ minisearch: 6.1.0
+ shiki: 0.14.3
+ vite: 4.3.9
+ vue: 3.3.4
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/node'
+ - '@types/react'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - fuse.js
+ - idb-keyval
+ - jwt-decode
+ - less
+ - nprogress
+ - qrcode
+ - react
+ - react-dom
+ - sass
+ - search-insights
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - universal-cookie
+ dev: true
+
/vscode-json-languageservice@4.2.1:
resolution: {integrity: sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==}
dependencies:
@@ -11178,10 +11962,43 @@ packages:
resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==}
dev: true
+ /vscode-oniguruma@1.7.0:
+ resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
+ dev: true
+
+ /vscode-textmate@8.0.0:
+ resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==}
+ dev: true
+
/vscode-uri@3.0.7:
resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==}
dev: true
+ /vue-demi@0.14.5(vue@3.3.4):
+ resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+ dependencies:
+ vue: 3.3.4
+ dev: true
+
+ /vue@3.3.4:
+ resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
+ dependencies:
+ '@vue/compiler-dom': 3.3.4
+ '@vue/compiler-sfc': 3.3.4
+ '@vue/runtime-dom': 3.3.4
+ '@vue/server-renderer': 3.3.4(vue@3.3.4)
+ '@vue/shared': 3.3.4
+ dev: true
+
/w3c-hr-time@1.0.2:
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
deprecated: Use your platform's native performance.now() and performance.timeOrigin.