diff --git a/.babelrc b/.babelrc deleted file mode 100644 index bea32a4a7..000000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": [ "es2015" ] -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..56278952d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,124 @@ +name: CI + +on: + push: + branches: + - main + - staging + pull_request: + branches: + - main + - staging + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [22, 24] + steps: + - uses: actions/checkout@v6 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm test + - run: npm run build + - run: npm run doc + - name: Save build + if: matrix.node-version == 22 + uses: actions/upload-artifact@v7 + with: + name: build + path: | + . + !node_modules + retention-days: 1 + + gh-pages: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/staging' + steps: + - uses: actions/download-artifact@v8 + with: + name: build + - uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: . + + dependabot: + name: 'Dependabot' + needs: build # After the E2E and build jobs, if one of them fails, it won't merge the PR. + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}} # Detect that the PR author is dependabot + permissions: + contents: write + pull-requests: write + steps: + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --merge "$PR_URL" # Use Github CLI to merge automatically the PR + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + npm-publish-dev: + needs: build + uses: SolidOS/solidos/.github/workflows/publish-prerelease.yml@main + with: + node_version: 22 + + npm-publish-latest: + needs: [build] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + permissions: + id-token: write # Required for OIDC + contents: read + steps: + - uses: actions/download-artifact@v8 + with: + name: build + - uses: actions/setup-node@v6 + with: + node-version: 22 # required for OIDC npm@latest + registry-url: 'https://registry.npmjs.org' + - name: Update npm to latest (required for OIDC) + run: npm install -g npm@latest + - name: Disable pre- and post-publish actions + run: 'sed -i -E "s/\"((pre|post)publish)/\"ignore:\1/" package.json' + - name: Publish to npm + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + run: npm publish --tag latest + + github-release: + needs: [npm-publish-latest] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + permissions: + contents: write + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Create GitHub release with generated notes + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="v$(node -p 'require("./package.json").version')" + + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists. Skipping." + exit 0 + fi + + if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists on origin. Creating release from existing tag." + gh release create "$TAG" --verify-tag --generate-notes + else + echo "Creating tag and release $TAG from commit $GITHUB_SHA." + gh release create "$TAG" --target "$GITHUB_SHA" --generate-notes + fi diff --git a/.gitignore b/.gitignore index 468bb8912..9b1a4436b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ node_modules dist lib +src/versionInfo.ts +.idea +.vscode +coverage +docs/api +examples/storybook +.history/ +docs/form-examples/solid-ui.js +.tsbuildinfo diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..1d24c91bd --- /dev/null +++ b/.nojekyll @@ -0,0 +1,6 @@ +It is now possible to completely bypass Jekyll processing on GitHub Pages by creating a file named .nojekyll in the +root of your pages repo and pushing it to GitHub. This should only be necessary if your site uses files or directories +that start with underscores since Jekyll considers these to be special resources and does not copy them to the final +site. + +https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..42a1c98ac --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v22.22.0 diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 000000000..a80bd7872 --- /dev/null +++ b/.storybook/main.js @@ -0,0 +1,42 @@ +export default { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-mdx-gfm', + '@storybook/addon-webpack5-compiler-swc' + ], + + framework: { + name: '@storybook/html-webpack5', + options: {} + }, + + docs: { + autodocs: true + }, + webpackFinal: async (config) => { + // For Storybook, we DON'T externalize rdflib and solid-logic + // Instead, we let webpack bundle them from node_modules + + // Handle Node.js modules for browser + config.resolve.fallback = { + ...config.resolve.fallback, + path: false, + fs: false, + crypto: false, + stream: false, + util: false, + buffer: false + } + + // Alias $rdf to rdflib for solid-logic compatibility + config.resolve.alias = { + ...config.resolve.alias, + $rdf: 'rdflib' + } + + return config + } +} diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 000000000..996229f9d --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,11 @@ +// For backward compatibility, provide rdflib and solid-logic as globals +import * as rdflib from 'rdflib' +import * as solidLogic from 'solid-logic' + +// Some legacy code might expect these as globals +if (typeof window !== 'undefined') { + window.$rdf = rdflib + window.SolidLogic = solidLogic +} + +export const parameters = {} diff --git a/.web_base b/.web_base new file mode 100644 index 000000000..664c7c143 --- /dev/null +++ b/.web_base @@ -0,0 +1 @@ +https://solidos.github.io/solid-ui diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..307ecf861 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,8 @@ +MIT License + +Copyright (c) 2019 Solid + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index c0f202734..c34a97fb8 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,432 @@ # solid-ui -User Interface widgets and utilities for Solid -These are HTML5 widgets which connect to a solid store. Building blocks for solid-based apps. +[![NPM Package](https://img.shields.io/npm/v/solid-ui.svg)](https://www.npmjs.com/package/solid-ui) -A selection -``` - var UI = require('solid-ui') +User Interface widgets and utilities for Solid (solid-ui) - var acl = require('solid-ui').acl -``` -The submodules at the moment include log, acl, acl-control, messageArea, etc +These are HTML5 widgets which connect to a solid store. Building blocks for solid-based apps. +Vanilla JS. Includes large widgets like chat, table, matrix, form fields, and small widgets. -- A login widget -- A chat widget: add discussion to any object. -- A people picker widget for choosing a set of people or an existing group -- A form system: Forms are defined in RDF, and create/edit RDF data, including form definitions -- A general purpose table display with built-in facetted browsing -- An Access Control List widget for Solid ACL system -- A two-dimentional matrix of editable live data -- A notepad of shared notes for real-time collaboration. -- Drag and drop code for linking things and uploading files -- A set of tabs for holding other widgets and arbitrary UI elements -- A collection of shortcut namespace objects for a selection of relevant RDF vocabularies. +See [Solid-Ui Storybook](http://solidos.github.io/solid-ui/examples/storybook/) for UI widgets. +See [Solid-UI API](https://solidos.github.io/solid-ui/docs/api/) for UI functions. +See [Forms introduction](./docs/FormsReadme.md) for UI vocabulary implementation. -The typical style of the widgets is to know what data it has been derived from, -allow users to edit it, and to automatically sync with data as it changes in the future. -TO see how these are used, see the panes which use them within the solid-app-set +## Table of Contents +- [Getting Started](#getting-started) +- [Install via npm](#install-via-npm) +- [Use Directly in Browser](#use-directly-in-a-browser) + - [UMD Bundle](#umd-bundle-global-variable) + - [ESM Bundle](#esm-bundle-import-as-module) +- [Web Components](#web-components) + - [solid-ui-header](#solid-ui-header) +- [Development](#development) +- [Testing](#adding-tests) +- [Further Documentation](#further-documentation) +- [Generative AI usage](#generative-ai-usage) -The level of support for this varies. + +## Getting started Contributions of bug fixes and new functionality, documentation, and tests are always appreciated. + +## Install via npm + +```sh +npm install solid-ui rdflib solid-logic +``` + +Then import in your JavaScript/TypeScript code: + +```js +import * as UI from 'solid-ui' +import * as $rdf from 'rdflib' +import * as SolidLogic from 'solid-logic' + +// Example: Create a button +const button = UI.widgets.button( + document, + 'https://solidproject.org/assets/img/solid-emblem.svg', + 'Click me', + () => alert('Button clicked!') +) +document.body.appendChild(button) +``` + +## Use Directly in a Browser + +Solid-UI provides both **UMD** and **ESM** bundles for direct browser usage. Both bundles externalize `rdflib` and `solid-logic`, which must be loaded separately. + +### Available Files + +- **UMD (Universal Module Definition)**: + - Development: `dist/solid-ui.js` (exposes global `window.UI`) + - Production: `dist/solid-ui.min.js` (minified) + +- **ESM (ES Modules)**: + - Development: `dist/solid-ui.esm.js` + - Production: `dist/solid-ui.esm.min.js` (minified) + +### UMD Bundle (Global Variable) + +If you use the legacy UMD bundle (`solid-ui.js` / `solid-ui.min.js`), `rdflib` must define `window.$rdf` before `solid-ui` loads. If `rdflib` is missing, `solid-ui` will throw `ReferenceError: $rdf is not defined`. + +Load via ` + + + + + + + + +``` + +### ESM Bundle (Import as Module) + +Use modern JavaScript modules with `import` statements. + +```html + + + + Solid-UI ESM Example + + +
+ + + + +``` + +### ESM Bundle with Import Maps + +Use import maps for cleaner module specifiers: + +```html + + + + Solid-UI ESM with Import Maps + + +
+ + + + + + + +``` + +## Web Components + +solid-ui ships self-contained Lit-based custom elements as subpath exports. Each component is independently importable, registers its custom element on import, and ships its own styles encapsulated in a Shadow DOM. + +> Component UMD bundles do not export a shared global like `window.UI`. They only register the custom element on import, while the legacy main bundle still provides the `UI` global. + +### solid-ui-header + +A header bar with branding, auth state (logged-out / logged-in), an account dropdown, an optional logout icon, and a desktop-only help menu. + +**Subpath export:** `solid-ui/components/header` + +```typescript +import { Header } from 'solid-ui/components/header' +import type { HeaderMenuItem, HeaderAccountMenuItem, HeaderAuthState } from 'solid-ui/components/header' +``` + +```html + + Help + +``` + +Importing this module automatically registers `` as a custom element. + +### solid-ui-login-button + +A standalone login button that encapsulates the Solid OIDC login flow and emits `login-success` when authentication succeeds. + +**Subpath export:** `solid-ui/components/login-button` + +```typescript +import { LoginButton } from 'solid-ui/components/login-button' +``` + +```html + +``` + +```typescript +const loginButton = document.querySelector('solid-ui-login-button') as LoginButton +loginButton.addEventListener('login-success', (event: CustomEvent) => { + console.log('Logged in as', event.detail.webId) +}) +``` + +### solid-ui-signup-button + +A standalone sign-up button that opens a signup URL in a new browser tab. + +**Subpath export:** `solid-ui/components/signup-button` + +```typescript +import { SignupButton } from 'solid-ui/components/signup-button' +``` + +```html + +``` + +### Component build pipeline + +Web components use a two-stage build to produce a clean public runtime layout while keeping internal TypeScript artifacts separate: + +1. **`scripts/component-manifest.mjs`** is the source of truth for v2 web components. It defines the component entrypoints used by webpack and the public subpath names exposed from the package. +2. **webpack** (`npm run build-dist`) bundles each component entrypoint from the manifest and emits the runtime files to `dist/components//index.js` and `dist/components//index.esm.js`. +3. **tsc** (`npm run build-js`) emits internal declaration and JS artifacts mirroring the source tree under `dist/v2/components//`. +4. **`scripts/build-component-dts.mjs`** (runs automatically after tsc as part of `postbuild-js`) writes thin public declaration wrappers at `dist/components//index.d.ts`, re-exporting from the internal `dist/v2/components//` output. +5. **`scripts/sync-component-exports.mjs`** keeps the `package.json` `exports` map aligned with the manifest. It runs automatically as part of `npm run build` and `npm version` workflows. + +The legacy main bundle remains a special case. In [webpack.config.mjs](webpack.config.mjs) only the `main` entry keeps the UMD `UI` global export; component entries are generated from the manifest and built as standalone scripts so they do not clobber one another when loaded directly. + +This keeps the `package.json` subpath export fully aligned while exposing only the public `dist/components/...` layout: + +```json +"./components/header": { + "types": "./dist/components/header/index.d.ts", + "import": "./dist/components/header/index.esm.js", + "require": "./dist/components/header/index.js" +} +``` + +Consumers never import from `dist/v2/components/...`; that path is an internal build artifact only. + +### Adding a new web component + +When adding a new v2 component: + +1. Create the component folder under `src/v2/components/` with its `index.ts` entrypoint. Components can be grouped in nested directories such as `src/v2/components/forms/select/`, `src/v2/components/auth/loginButton/`, or `src/v2/components/layout/header/`. +2. Add one record to `scripts/component-manifest.mjs`. If the component lives in a nested directory, set its `sourcePath` in the manifest to match that grouped path. +3. Run `npm run sync-component-exports` if you want to update `package.json` immediately, or just run `npm run build` and let the build do it automatically. + +You should not need to hand-edit the webpack component entry list or the `package.json` component export map anymore. + +## Development + +When developing a component in solid-ui you can test it in isolation using storybook + +``` +npm run build +npm run storybook +``` + +If there is no story for the component yet, add a new one to `./src/stories`. + +When you want to test the component within a solid-pane, you can use the [development mode of solid-panes](https://github.com/solidos/solid-panes#development). + +## Adding Tests + +One can run extisting tests with: +``` +npm run test +``` +or with coverage +``` +npm run test-coverage +``` +The following document gives guidance on how to add and perform testing in solid-ui. +[Testing in solid-ui](https://github.com/SolidOS/solid-ui/blob/18070a02fa8159a2b83d9503ee400f8e046bf1f6/test/unit/README.md) + +## GitHub Pages + +* The github pages should contain the storybook and further documentation. In order to make sure it is deployed there is a step in the CI (gh-pages). This depends on the previous `build` step. It MUST contain `build-storybook` otherwise the storybook is not being published. + +## Further documentation + +- [Some code know-how](https://github.com/SolidOS/solidos/wiki/2.-Solid-UI-know-how) + +## Generative AI usage +The SolidOS team is using GitHub Copilot integrated in Visual Studio Code. +We have added comments in the code to make it explicit which parts are 100% written by AI. + +### Prompt usage history: + +* Raptor mini: If I want to make the header a web component with a self contained CSS which only consumes CSS variables from a theme, how would I do this? + +* Raptor mini: Go ahead and create a header web component, for backward compatibility keep the current code too. +In the new header component I need to be flexible and receive from consumer - the layout (mobile or desktop) and the theme (light or dark) and its according CSS variables for light to dark. + +* Raptor mini: Propose code. how about webpack config for distribution? + +* Raptor mini: pls add a readme in the component documenting it usage and test and all + +* Raptor mini: the helpMenuList should be menu items inside the help icon drop down menu + +* Raptor mini: When I am not logged in I want the header to display: Log in button and Sign Up button. +When the user is logged in, there is only one button, a drop down button called Accounts. The icon of the button is the avatar of the profile and it displays a list of available accounts of the user. +I want this all to be presented flexible in the component. + +* Claude Sonnet 4.6: create a LitElement also for the signupButton in the SignupButton.ts based on the signup.js code and wire it into the header like you did the loginButton. + +* Raptor mini: when we are on layout mobile we do not want to display the help menu at all. + +* Raptor mini: Create for me a footer Lit Component in tsy style of the components I have and under v2. Take the code from this index.ts to start with. + +* Raptor mini: Good. Now, I want the footer to be a rectangular with round corners, grey background and it should have an adjustable position. + +* Raptor mini: The content of the footer should be different upon loggedin or not. +If not logged in, it should say: +Title Public View +You are viewving this profile as a guest, +And if logged in: +Title: Logged in View +You are logged in as nameOfLoggedIn user. + +* Raptor mini: add a readme to the Footer component with example. + +* Claude Sonnet 4.6: Make the drop down as a list under the input field and enlarge the pop up, make it higher, adjustable to fit the drop down. And make the drop down arrow area larger + +* GPT-5.4 Model: can you wire up the keyboard interactions and aria attributes for Select? + +* GPT-5.4 Model: Take the code from /Users/sharon/2025Dev/solid-ui/src/media/media-capture.ts and make it a web component. Make it work in forms as well as not. Make it configurable and follow LoginButton. diff --git a/__mocks__/rdflib.ts b/__mocks__/rdflib.ts new file mode 100644 index 000000000..dbf997ae0 --- /dev/null +++ b/__mocks__/rdflib.ts @@ -0,0 +1,98 @@ +// @@ TODO: Remove currently untyped methods as they are added + +import { IndexedFormula } from 'rdflib' + +export { + BlankNode, + Collection, + convert, + DataFactory, + Empty, + Formula, + // Store, // Not currently supported in @types/rdflib + // jsonParser, // Not currently supported in @types/rdflib + Literal, + log, + // N3Parser, // Not currently supported in @types/rdflib + NamedNode, + Namespace, + Node, + parse, + Query, + // queryToSPARQL, // Not currently supported in @types/rdflib + // RDFaProcessor, // Not currently supported in @types/rdflib + // RDFParser, // Not currently supported in @types/rdflib + // serialize, // Not currently supported in @types/rdflib + // Serializer, // Not currently supported in @types/rdflib + // SPARQLToQuery, // Not currently supported in @types/rdflib + // sparqlUpdateParser, // Not currently supported in @types/rdflib + Statement, + term, + // UpdatesSocket, // Not currently supported in @types/rdflib + // UpdatesVia, // Not currently supported in @types/rdflib + uri, + Util, + Variable, + NextId, + fromNT, + graph, + lit, + st, + namedNode as sym, + blankNode, + defaultGraph, + literal, + namedNode, + quad, + triple, + variable +} from 'rdflib' + +export function fetcher (store: any) { + const fetcher = new Fetcher() + store.fetcher = fetcher + return fetcher +} + +export class Fetcher { + requested: any + nonexistent = {} + + constructor () { + this.requested = {} + } + + load () { + return Promise.resolve() + } + + nowOrWhenFetched () { + return Promise.resolve() + } +} + +export class UpdateManager { + // mock as needed + updated: boolean = false + reportSuccess: boolean = true + + editable (uri: string) { + if (uri === 'http://not.editable/') { + return false + } + return true + } + + put () { + return Promise.resolve() + } + + update (_deletes, _inserts, onDone: (uri: string, ok: boolean, body: string) => void) { + this.updated = true + onDone('uri', this.reportSuccess, 'body') + return Promise.resolve() + } + + addDownstreamChangeListener () { + } +} diff --git a/__mocks__/solid-auth-client.ts b/__mocks__/solid-auth-client.ts new file mode 100644 index 000000000..508524c1f --- /dev/null +++ b/__mocks__/solid-auth-client.ts @@ -0,0 +1,5 @@ +export default { + currentSession: function () { + return Promise.resolve('http://w.e/b#id') + } +} diff --git a/__mocks__/styleMock.js b/__mocks__/styleMock.js new file mode 100644 index 000000000..7ef57ffcf --- /dev/null +++ b/__mocks__/styleMock.js @@ -0,0 +1,2 @@ +// Jest mock for CSS imports +module.exports = {} diff --git a/babel.config.mjs b/babel.config.mjs new file mode 100644 index 000000000..8f7dc3a86 --- /dev/null +++ b/babel.config.mjs @@ -0,0 +1,13 @@ +export default { + presets: [ + ['@babel/preset-env', { + targets: { + browsers: ['> 1%', 'last 3 versions', 'not dead'] + } + }], + ['@babel/preset-typescript', { allowDeclareFields: true }], + ], + plugins: [ + '@babel/plugin-transform-runtime' + ] +} diff --git a/build.sh b/build.sh deleted file mode 100755 index 0197b1171..000000000 --- a/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# Build the dist file based on individual modules -# TODO: minify dist file - -npm run build diff --git a/declarations.d.ts b/declarations.d.ts new file mode 100644 index 000000000..d16cbef41 --- /dev/null +++ b/declarations.d.ts @@ -0,0 +1,4 @@ +declare module '*.sparql' { + const content: string + export default content +} diff --git a/dependencies/InternalDependencies.svg b/dependencies/InternalDependencies.svg new file mode 100644 index 000000000..b7aa235a2 --- /dev/null +++ b/dependencies/InternalDependencies.svg @@ -0,0 +1,1195 @@ + + + + + + +InternalDependencies + + + +media_capture + +media_capture + + + +debug + +debug + + + +media_capture->debug + + + + + +store + +store + + + +media_capture->store + + + + + +iconBase + +iconBase + + + +media_capture->iconBase + + + + + +rdflib + +rdflib + + + +media_capture->rdflib + + + + + +ns + +ns + + + +media_capture->ns + + + + + +pad + +pad + + + +media_capture->pad + + + + + +utils + +utils + + + +media_capture->utils + + + + + +widgets + +widgets + + + +media_capture->widgets + + + + + +message + +message + + + +message->media_capture + + + + + +messageTools + +messageTools + + + +message->messageTools + + + + + +message->store + + + + + +message->iconBase + + + + + +message->rdflib + + + + + +message->ns + + + + + +message->pad + + + + + +message->utils + + + + + +message->widgets + + + + + +authn + +authn + + + +message->authn + + + + + +style + +style + + + +message->style + + + + + +messageTools->media_capture + + + + + +bookmarks + +bookmarks + + + +messageTools->bookmarks + + + + + +messageTools->store + + + + + +messageTools->iconBase + + + + + +messageTools->rdflib + + + + + +messageTools->ns + + + + + +messageTools->pad + + + + + +messageTools->utils + + + + + +messageTools->widgets + + + + + +messageTools->authn + + + + + +messageTools->style + + + + + +infinite + +infinite + + + +infinite->media_capture + + + + + +infinite->debug + + + + + +infinite->message + + + + + +infinite->bookmarks + + + + + +dateFolder + +dateFolder + + + +infinite->dateFolder + + + + + +infinite->store + + + + + +infinite->iconBase + + + + + +infinite->rdflib + + + + + +infinite->rdflib + + + + + +infinite->ns + + + + + +infinite->pad + + + + + +infinite->utils + + + + + +infinite->widgets + + + + + +infinite->authn + + + + + +infinite->style + + + + + +bookmarks->media_capture + + + + + +bookmarks->debug + + + + + +bookmarks->store + + + + + +bookmarks->iconBase + + + + + +bookmarks->rdflib + + + + + +bookmarks->ns + + + + + +bookmarks->pad + + + + + +bookmarks->utils + + + + + +bookmarks->widgets + + + + + +bookmarks->authn + + + + + +bookmarks->style + + + + + +dateFolder->debug + + + + + +dateFolder->store + + + + + +dateFolder->rdflib + + + + + +dateFolder->ns + + + + + +preferences + +preferences + + + +preferences->debug + + + + + +preferences->store + + + + + +preferences->ns + + + + + +preferences->pad + + + + + +preferences->widgets + + + + + +preferences->authn + + + + + +participation + +participation + + + +preferences->participation + + + + + +store->debug + + + + + +solid_auth_client + +solid_auth_client + + + +store->solid_auth_client + + + + + +store->rdflib + + + + + +create + +create + + + +create->debug + + + + + +create->store + + + + + +create->iconBase + + + + + +create->ns + + + + + +create->utils + + + + + +create->widgets + + + + + +create->authn + + + + + +create->style + + + + + +folders + +folders + + + +folders->debug + + + + + +folders->store + + + + + +folders->iconBase + + + + + +folders->rdflib + + + + + +folders->ns + + + + + +folders->utils + + + + + +folders->widgets + + + + + +iconBase->debug + + + + + +table + +table + + + +table->debug + + + + + +table->store + + + + + +table->iconBase + + + + + +table->rdflib + + + + + +table->ns + + + + + +table->utils + + + + + +table->widgets + + + + + +log + +log + + + +table->log + + + + + +peoplePicker + +peoplePicker + + + +peoplePicker->debug + + + + + +peoplePicker->store + + + + + +peoplePicker->iconBase + + + + + +escape_html + +escape_html + + + +peoplePicker->escape_html + + + + + +node_uuid + +node_uuid + + + +peoplePicker->node_uuid + + + + + +peoplePicker->rdflib + + + + + +dragAndDrop + +dragAndDrop + + + +peoplePicker->dragAndDrop + + + + + +error + +error + + + +peoplePicker->error + + + + + +peoplePicker->ns + + + + + +dragAndDrop->debug + + + + + +mime_types + +mime_types + + + +dragAndDrop->mime_types + + + + + +ns->rdflib + + + + + +index + +index + + + +index->debug + + + + + +index->peoplePicker + + + + + +forms + +forms + + + +index->forms + + + + + +buttons + +buttons + + + +index->buttons + + + + + +forms->debug + + + + + +forms->store + + + + + +forms->iconBase + + + + + +forms->rdflib + + + + + +forms->error + + + + + +forms->ns + + + + + +forms->ns + + + + + +fieldParams + +fieldParams + + + +forms->fieldParams + + + + + +fieldFunction + +fieldFunction + + + +forms->fieldFunction + + + + + +basic + +basic + + + +forms->basic + + + + + +forms->utils + + + + + +forms->style + + + + + +forms->log + + + + + +forms->buttons + + + + + +utils->store + + + + + +utils->rdflib + + + + + +utils->ns + + + + + +utils->log + + + + + +test_acl + +test_acl + + + +test_acl->index + + + + + +acl + +acl + + + +test_acl->acl + + + + + +thread + +thread + + + +thread->store + + + + + +thread->iconBase + + + + + +thread->rdflib + + + + + +thread->rdflib + + + + + +thread->ns + + + + + +thread->utils + + + + + +thread->widgets + + + + + +thread->authn + + + + + +thread->style + + + + + +matrix + +matrix + + + +matrix->store + + + + + +matrix->iconBase + + + + + +matrix->rdflib + + + + + +matrix->ns + + + + + +matrix->utils + + + + + +matrix->widgets + + + + + +signup + +signup + + + +config_default + +config_default + + + +signup->config_default + + + + + +messageArea + +messageArea + + + +messageArea->store + + + + + +messageArea->iconBase + + + + + +messageArea->rdflib + + + + + +messageArea->rdflib + + + + + +messageArea->ns + + + + + +messageArea->utils + + + + + +messageArea->widgets + + + + + +messageArea->authn + + + + + +messageArea->style + + + + + diff --git a/dependencies/Makefile b/dependencies/Makefile new file mode 100644 index 000000000..279890a0a --- /dev/null +++ b/dependencies/Makefile @@ -0,0 +1,31 @@ +# Make dependency diagram of js functions +# https://graphviz.readthedocs.io/en/stable/manual.html +# https://www.graphviz.org/pdf/dotguide.pdf + +# Where to find source files +S=../src +# Where to put files? +D=. + +InternalDependencies.svg: $D/dependencies.dot + dot -Tsvg -oInternalDependencies.svg $D/dependencies.dot +$D/dependencies.dot : $D/all.ttl ttl2dot.sed + sed -f ttl2dot.sed < $< > $@ +$D/all.ttl : $D/imports.ttl $D/requires.ttl + cat $D/imports.ttl $D/requires.ttl > $@ +$D/imports.ttl : $D/imports.txt + sed -e 's/^\([^:]*\):.*from .\(.*\)./<\1> :dependsOn <\2>./' < $D/imports.txt > $@ +$D/requires.ttl : convert-dependency.sed $D/requires.txt + sed -f convert-dependency.sed < $D/requires.txt > $@ +$D/imports.txt : $D/source-file-list.txt + cat $D/source-file-list.txt | xargs grep "import.*from " > $D/imports.txt +$D/requires.txt : $D/source-file-list.txt + cat $D/source-file-list.txt | xargs grep "require(" > $D/requires.txt +# $D/imports-list.txt : $D/ +# grep -e "^import.*from " > $@ +$D/source-file-list.txt : + find $S -name "*.js" > $@ + +clean: + rm imports.* requires.* source-file-list.txt dependencies.dot +# ends diff --git a/dependencies/Old-InternalDependencies.svg b/dependencies/Old-InternalDependencies.svg new file mode 100644 index 000000000..34850c626 --- /dev/null +++ b/dependencies/Old-InternalDependencies.svg @@ -0,0 +1,1273 @@ + + + + + + +G + + + +media_capture + +media_capture + + + +debug + +debug + + + +media_capture->debug + + + + + +store + +store + + + +media_capture->store + + + + + +iconBase + +iconBase + + + +media_capture->iconBase + + + + + +pad + +pad + + + +media_capture->pad + + + + + +rdflib + +rdflib + + + +media_capture->rdflib + + + + + +ns + +ns + + + +media_capture->ns + + + + + +utils + +utils + + + +media_capture->utils + + + + + +widgets + +widgets + + + +media_capture->widgets + + + + + +noun_Camera_1618446_000000 + +noun_Camera_1618446_000000 + + + +media_capture->noun_Camera_1618446_000000 + + + + + +message + +message + + + +message->media_capture + + + + + +messageTools + +messageTools + + + +message->messageTools + + + + + +message->messageTools + + + + + +message->store + + + + + +message->iconBase + + + + + +message->pad + + + + + +message->rdflib + + + + + +message->ns + + + + + +message->utils + + + + + +message->widgets + + + + + +authn + +authn + + + +message->authn + + + + + +style + +style + + + +message->style + + + + + +messageTools->media_capture + + + + + +bookmarks + +bookmarks + + + +messageTools->bookmarks + + + + + +messageTools->store + + + + + +messageTools->iconBase + + + + + +messageTools->pad + + + + + +messageTools->rdflib + + + + + +messageTools->ns + + + + + +messageTools->utils + + + + + +messageTools->widgets + + + + + +messageTools->authn + + + + + +messageTools->style + + + + + +infinite + +infinite + + + +infinite->media_capture + + + + + +infinite->debug + + + + + +infinite->message + + + + + +infinite->bookmarks + + + + + +dateFolder + +dateFolder + + + +infinite->dateFolder + + + + + +infinite->store + + + + + +infinite->iconBase + + + + + +infinite->pad + + + + + +infinite->rdflib + + + + + +infinite->rdflib + + + + + +infinite->ns + + + + + +infinite->utils + + + + + +infinite->utils + + + + + +infinite->widgets + + + + + +infinite->authn + + + + + +infinite->style + + + + + +bookmarks->media_capture + + + + + +bookmarks->debug + + + + + +bookmarks->store + + + + + +bookmarks->iconBase + + + + + +bookmarks->pad + + + + + +bookmarks->rdflib + + + + + +bookmarks->ns + + + + + +bookmarks->utils + + + + + +bookmarks->widgets + + + + + +bookmarks->authn + + + + + +bookmarks->style + + + + + +dateFolder->debug + + + + + +dateFolder->store + + + + + +dateFolder->rdflib + + + + + +dateFolder->ns + + + + + +preferences + +preferences + + + +preferences->debug + + + + + +preferences->store + + + + + +preferences->pad + + + + + +preferences->ns + + + + + +preferences->widgets + + + + + +preferences->authn + + + + + +store->debug + + + + + +store->rdflib + + + + + +create + +create + + + +create->debug + + + + + +create->store + + + + + +create->iconBase + + + + + +error + +error + + + +create->error + + + + + +create->ns + + + + + +index + +index + + + +create->index + + + + + +create->utils + + + + + +create->utils + + + + + +create->widgets + + + + + +create->authn + + + + + +create->style + + + + + +solid_ui + +solid_ui + + + +create->solid_ui + + + + + +folders + +folders + + + +folders->debug + + + + + +folders->store + + + + + +folders->iconBase + + + + + +folders->rdflib + + + + + +folders->ns + + + + + +folders->utils + + + + + +folders->widgets + + + + + +iconBase->debug + + + + + +table + +table + + + +table->debug + + + + + +table->store + + + + + +table->iconBase + + + + + +table->rdflib + + + + + +table->ns + + + + + +table->utils + + + + + +table->widgets + + + + + +log + +log + + + +table->log + + + + + +pad->debug + + + + + +pad->store + + + + + +pad->iconBase + + + + + +pad->rdflib + + + + + +pad->ns + + + + + +pad->utils + + + + + +pad->widgets + + + + + +pad->authn + + + + + +peoplePicker + +peoplePicker + + + +peoplePicker->debug + + + + + +peoplePicker->store + + + + + +peoplePicker->iconBase + + + + + +escape_html + +escape_html + + + +peoplePicker->escape_html + + + + + +node_uuid + +node_uuid + + + +peoplePicker->node_uuid + + + + + +peoplePicker->rdflib + + + + + +dragAndDrop + +dragAndDrop + + + +peoplePicker->dragAndDrop + + + + + +peoplePicker->error + + + + + +peoplePicker->ns + + + + + +dragAndDrop->debug + + + + + +dragAndDrop->index + + + + + +mime_types + +mime_types + + + +dragAndDrop->mime_types + + + + + +ns->rdflib + + + + + +solid_namespace + +solid_namespace + + + +ns->solid_namespace + + + + + +index->debug + + + + + +index->peoplePicker + + + + + +index->dragAndDrop + + + + + +index->error + + + + + +forms + +forms + + + +index->forms + + + + + +acl + +acl + + + +index->acl + + + + + +buttons + +buttons + + + +index->buttons + + + + + +forms->debug + + + + + +forms->store + + + + + +forms->iconBase + + + + + +forms->rdflib + + + + + +forms->error + + + + + +forms->ns + + + + + +forms->ns + + + + + +fieldParams + +fieldParams + + + +forms->fieldParams + + + + + +fieldFunction + +fieldFunction + + + +forms->fieldFunction + + + + + +basic + +basic + + + +forms->basic + + + + + +forms->utils + + + + + +forms->style + + + + + +forms->log + + + + + +forms->buttons + + + + + +utils->store + + + + + +utils->rdflib + + + + + +utils->ns + + + + + +utils->log + + + + + +thread + +thread + + + +thread->store + + + + + +thread->iconBase + + + + + +thread->rdflib + + + + + +thread->rdflib + + + + + +thread->ns + + + + + +thread->utils + + + + + +thread->widgets + + + + + +thread->authn + + + + + +thread->style + + + + + +matrix + +matrix + + + +matrix->store + + + + + +matrix->iconBase + + + + + +matrix->rdflib + + + + + +matrix->ns + + + + + +matrix->utils + + + + + +matrix->widgets + + + + + +messageArea + +messageArea + + + +messageArea->store + + + + + +messageArea->iconBase + + + + + +messageArea->rdflib + + + + + +messageArea->rdflib + + + + + +messageArea->ns + + + + + +messageArea->utils + + + + + +messageArea->widgets + + + + + +messageArea->authn + + + + + +messageArea->style + + + + + diff --git a/dependencies/all.ttl b/dependencies/all.ttl new file mode 100644 index 000000000..0e4f513f9 --- /dev/null +++ b/dependencies/all.ttl @@ -0,0 +1,169 @@ +<../src/media-capture.js> :dependsOn <./debug>. +<../src/chat/message.js> :dependsOn <./messageTools>. +<../src/chat/infinite.js> :dependsOn <../debug>. +<../src/chat/bookmarks.js> :dependsOn <../debug>. +<../src/chat/dateFolder.js> :dependsOn <../debug>. +<../src/preferences.js> :dependsOn <./debug>. +<../src/store.js> :dependsOn <./debug>. +<../src/store.js> :dependsOn . +<../src/create.js> :dependsOn <./debug>. +<../src/folders.js> :dependsOn <./debug>. +<../src/iconBase.js> :dependsOn <./debug>. +<../src/table.js> :dependsOn <./debug>. +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn <../debug>. +<../src/widgets/peoplePicker.js> :dependsOn <./dragAndDrop>. +<../src/widgets/peoplePicker.js> :dependsOn <./error>. +<../src/widgets/peoplePicker.js> :dependsOn <../iconBase>. +<../src/widgets/peoplePicker.js> :dependsOn <../ns>. +<../src/widgets/peoplePicker.js> :dependsOn <../store>. +<../src/widgets/index.js> :dependsOn <../debug>. +<../src/widgets/dragAndDrop.js> :dependsOn <../debug>. +<../src/widgets/forms.js> :dependsOn <./forms/fieldParams>. +<../src/widgets/forms.js> :dependsOn <./forms/fieldFunction>. +<../src/widgets/forms.js> :dependsOn <../debug>. +<../src/widgets/forms.js> :dependsOn <./forms/basic>. + :dependsOn . + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn <./pad>. + :dependsOn <./store>. + :dependsOn <./utils>. + :dependsOn <./widgets>. + + + :dependsOn . + :dependsOn <../acl>. + :dependsOn <../../../../linkeddata/rdflib.js/index.js>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + + :dependsOn . + :dependsOn <./dateFolder>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + + :dependsOn <./message>. + :dependsOn <./bookmarks>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../widgets>. + :dependsOn <../utils>. + :dependsOn . + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + :dependsOn <../store.js>. + :dependsOn <../ns.js>. + :dependsOn . + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + :dependsOn <./bookmarks>. + :dependsOn <./store>. + :dependsOn <./ns>. + :dependsOn <./authn/authn>. + :dependsOn <./widgets>. + :dependsOn <./pad>. + :dependsOn <./participation>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn . + + + + + :dependsOn <./authn/authn>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn <./store>. + :dependsOn <./style>. + :dependsOn <./utils>. + :dependsOn <./widgets>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn <./iconBase>. + :dependsOn <./log>. + :dependsOn <./ns>. + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn . + :dependsOn <./log>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./config-default>. + + + :dependsOn <./peoplePicker>. + + + :dependsOn <./buttons>. + :dependsOn <./forms>. + :dependsOn . + + :dependsOn <../iconBase>. + :dependsOn <../log>. + :dependsOn <../ns>. + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn . + :dependsOn <./error>. + :dependsOn <./buttons>. + :dependsOn <../ns>. + :dependsOn <../utils>. + :dependsOn <./authn/authn>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./style>. + :dependsOn <./widgets>. + :dependsOn . + :dependsOn <./utils>. diff --git a/dependencies/convert-dependency.sed b/dependencies/convert-dependency.sed new file mode 100644 index 000000000..8acefe63d --- /dev/null +++ b/dependencies/convert-dependency.sed @@ -0,0 +1,6 @@ +# A comment // deleted the whole line +s?^.*//.*$??g +# Strip path to filename +s?../src/??g +# Convert syntax to turtle +s/^\([^:]*\):.*require(.\(.*\).).*/<\1> :dependsOn <\2>./ diff --git a/dependencies/dependencies.dot b/dependencies/dependencies.dot new file mode 100644 index 000000000..28d08f661 --- /dev/null +++ b/dependencies/dependencies.dot @@ -0,0 +1,170 @@ +digraph InternalDependencies { +media_capture -> debug; +message -> messageTools; +infinite -> debug; +bookmarks -> debug; +dateFolder -> debug; +preferences -> debug; +store -> debug; +store -> solid_auth_client; +create -> debug; +folders -> debug; +iconBase -> debug; +table -> debug; +peoplePicker -> escape_html; +peoplePicker -> node_uuid; +peoplePicker -> rdflib; +peoplePicker -> debug; +peoplePicker -> dragAndDrop; +peoplePicker -> error; +peoplePicker -> iconBase; +peoplePicker -> ns; +peoplePicker -> store; +index -> debug; +dragAndDrop -> debug; +forms -> fieldParams; +forms -> fieldFunction; +forms -> debug; +forms -> basic; +media_capture -> rdflib; +media_capture -> iconBase; +media_capture -> ns; +media_capture -> pad; +media_capture -> store; +media_capture -> utils; +media_capture -> widgets; + + +ns -> rdflib; +test_acl -> acl; +test_acl -> index; +message -> authn; +message -> iconBase; +message -> ns; +message -> media_capture; +message -> pad; +message -> rdflib; +message -> store; +message -> style; +message -> utils; +message -> widgets; + +infinite -> rdflib; +infinite -> dateFolder; +infinite -> authn; +infinite -> iconBase; +infinite -> ns; +infinite -> media_capture; +infinite -> pad; +infinite -> rdflib; +infinite -> store; +infinite -> style; +infinite -> utils; +infinite -> widgets; + +infinite -> message; +infinite -> bookmarks; +thread -> authn; +thread -> iconBase; +thread -> ns; +thread -> rdflib; +thread -> store; +thread -> style; +thread -> widgets; +thread -> utils; +thread -> rdflib; +bookmarks -> authn; +bookmarks -> iconBase; +bookmarks -> ns; +bookmarks -> media_capture; +bookmarks -> pad; +bookmarks -> rdflib; +bookmarks -> store; +bookmarks -> style; +bookmarks -> utils; +bookmarks -> widgets; +dateFolder -> store; +dateFolder -> ns; +dateFolder -> rdflib; +messageTools -> authn; +messageTools -> iconBase; +messageTools -> ns; +messageTools -> media_capture; +messageTools -> pad; +messageTools -> rdflib; +messageTools -> store; +messageTools -> style; +messageTools -> utils; +messageTools -> widgets; +messageTools -> bookmarks; +preferences -> store; +preferences -> ns; +preferences -> authn; +preferences -> widgets; +preferences -> pad; +preferences -> participation; +matrix -> iconBase; +matrix -> ns; +matrix -> rdflib; +matrix -> store; +matrix -> widgets; +matrix -> utils; +store -> rdflib; + + + + +create -> authn; +create -> iconBase; +create -> ns; +create -> store; +create -> style; +create -> utils; +create -> widgets; +folders -> iconBase; +folders -> ns; +folders -> rdflib; +folders -> store; +folders -> widgets; +folders -> utils; +table -> iconBase; +table -> log; +table -> ns; +table -> store; +table -> widgets; +table -> utils; +table -> rdflib; +utils -> log; +utils -> ns; +utils -> rdflib; +utils -> store; +signup -> config_default; + + +index -> peoplePicker; + + +index -> buttons; +index -> forms; +dragAndDrop -> mime_types; + +forms -> iconBase; +forms -> log; +forms -> ns; +forms -> store; +forms -> style; +forms -> rdflib; +forms -> error; +forms -> buttons; +forms -> ns; +forms -> utils; +messageArea -> authn; +messageArea -> iconBase; +messageArea -> ns; +messageArea -> rdflib; +messageArea -> store; +messageArea -> style; +messageArea -> widgets; +messageArea -> rdflib; +messageArea -> utils; +} diff --git a/dependencies/imports.ttl b/dependencies/imports.ttl new file mode 100644 index 000000000..59929526d --- /dev/null +++ b/dependencies/imports.ttl @@ -0,0 +1,27 @@ +<../src/media-capture.js> :dependsOn <./debug>. +<../src/chat/message.js> :dependsOn <./messageTools>. +<../src/chat/infinite.js> :dependsOn <../debug>. +<../src/chat/bookmarks.js> :dependsOn <../debug>. +<../src/chat/dateFolder.js> :dependsOn <../debug>. +<../src/preferences.js> :dependsOn <./debug>. +<../src/store.js> :dependsOn <./debug>. +<../src/store.js> :dependsOn . +<../src/create.js> :dependsOn <./debug>. +<../src/folders.js> :dependsOn <./debug>. +<../src/iconBase.js> :dependsOn <./debug>. +<../src/table.js> :dependsOn <./debug>. +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn . +<../src/widgets/peoplePicker.js> :dependsOn <../debug>. +<../src/widgets/peoplePicker.js> :dependsOn <./dragAndDrop>. +<../src/widgets/peoplePicker.js> :dependsOn <./error>. +<../src/widgets/peoplePicker.js> :dependsOn <../iconBase>. +<../src/widgets/peoplePicker.js> :dependsOn <../ns>. +<../src/widgets/peoplePicker.js> :dependsOn <../store>. +<../src/widgets/index.js> :dependsOn <../debug>. +<../src/widgets/dragAndDrop.js> :dependsOn <../debug>. +<../src/widgets/forms.js> :dependsOn <./forms/fieldParams>. +<../src/widgets/forms.js> :dependsOn <./forms/fieldFunction>. +<../src/widgets/forms.js> :dependsOn <../debug>. +<../src/widgets/forms.js> :dependsOn <./forms/basic>. diff --git a/dependencies/imports.txt b/dependencies/imports.txt new file mode 100644 index 000000000..51fc711d9 --- /dev/null +++ b/dependencies/imports.txt @@ -0,0 +1,27 @@ +../src/media-capture.js:import * as debug from './debug' +../src/chat/message.js:import { messageToolbar, sentimentStripLinked } from './messageTools' +../src/chat/infinite.js:import * as debug from '../debug' +../src/chat/bookmarks.js:import * as debug from '../debug' +../src/chat/dateFolder.js:// import * as debug from '../debug' +../src/preferences.js:import * as debug from './debug' +../src/store.js:import * as debug from './debug' +../src/store.js:import { fetch } from 'solid-auth-client' +../src/create.js:import * as debug from './debug' +../src/folders.js:import * as debug from './debug' +../src/iconBase.js:import * as debug from './debug' +../src/table.js:import * as debug from './debug' +../src/widgets/peoplePicker.js:import escape from 'escape-html' +../src/widgets/peoplePicker.js:import uuid from 'node-uuid' +../src/widgets/peoplePicker.js:import * as rdf from 'rdflib' +../src/widgets/peoplePicker.js:import * as debug from '../debug' +../src/widgets/peoplePicker.js:import { makeDropTarget } from './dragAndDrop' +../src/widgets/peoplePicker.js:import { errorMessageBlock } from './error' +../src/widgets/peoplePicker.js:import { iconBase } from '../iconBase' +../src/widgets/peoplePicker.js:import ns from '../ns' +../src/widgets/peoplePicker.js:import kb from '../store' +../src/widgets/index.js:import * as debug from '../debug' +../src/widgets/dragAndDrop.js:import * as debug from '../debug' +../src/widgets/forms.js:import { fieldParams } from './forms/fieldParams' +../src/widgets/forms.js:import { field, mostSpecificClassURI, fieldFunction } from './forms/fieldFunction' +../src/widgets/forms.js:import * as debug from '../debug' +../src/widgets/forms.js:import { basicField } from './forms/basic' diff --git a/dependencies/requires.ttl b/dependencies/requires.ttl new file mode 100644 index 000000000..d63eee77f --- /dev/null +++ b/dependencies/requires.ttl @@ -0,0 +1,142 @@ + :dependsOn . + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn <./pad>. + :dependsOn <./store>. + :dependsOn <./utils>. + :dependsOn <./widgets>. + + + :dependsOn . + :dependsOn <../acl>. + :dependsOn <../../../../linkeddata/rdflib.js/index.js>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + + :dependsOn . + :dependsOn <./dateFolder>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + + :dependsOn <./message>. + :dependsOn <./bookmarks>. + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../widgets>. + :dependsOn <../utils>. + :dependsOn . + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + :dependsOn <../store.js>. + :dependsOn <../ns.js>. + :dependsOn . + :dependsOn <../authn/authn>. + :dependsOn <../iconBase>. + :dependsOn <../ns>. + :dependsOn <../media-capture>. + :dependsOn <../pad>. + :dependsOn . + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn <../utils>. + :dependsOn <../widgets>. + :dependsOn <./bookmarks>. + :dependsOn <./store>. + :dependsOn <./ns>. + :dependsOn <./authn/authn>. + :dependsOn <./widgets>. + :dependsOn <./pad>. + :dependsOn <./participation>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn . + + + + + :dependsOn <./authn/authn>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn <./store>. + :dependsOn <./style>. + :dependsOn <./utils>. + :dependsOn <./widgets>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn <./iconBase>. + :dependsOn <./log>. + :dependsOn <./ns>. + :dependsOn <./store>. + :dependsOn <./widgets>. + :dependsOn <./utils>. + :dependsOn . + :dependsOn <./log>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./config-default>. + + + :dependsOn <./peoplePicker>. + + + :dependsOn <./buttons>. + :dependsOn <./forms>. + :dependsOn . + + :dependsOn <../iconBase>. + :dependsOn <../log>. + :dependsOn <../ns>. + :dependsOn <../store>. + :dependsOn <../style>. + :dependsOn . + :dependsOn <./error>. + :dependsOn <./buttons>. + :dependsOn <../ns>. + :dependsOn <../utils>. + :dependsOn <./authn/authn>. + :dependsOn <./iconBase>. + :dependsOn <./ns>. + :dependsOn . + :dependsOn <./store>. + :dependsOn <./style>. + :dependsOn <./widgets>. + :dependsOn . + :dependsOn <./utils>. diff --git a/dependencies/requires.txt b/dependencies/requires.txt new file mode 100644 index 000000000..d9f335cc9 --- /dev/null +++ b/dependencies/requires.txt @@ -0,0 +1,142 @@ +../src/media-capture.js:var $rdf = require('rdflib') +../src/media-capture.js: icons: require('./iconBase'), +../src/media-capture.js: ns: require('./ns'), +../src/media-capture.js: pad: require('./pad'), +../src/media-capture.js: store: require('./store'), +../src/media-capture.js: utils: require('./utils'), +../src/media-capture.js: widgets: require('./widgets') +../src/media-capture.js:// const cameraIcon = require('./noun_Camera_1618446_000000') // load it in JS +../src/ns.js:const solidNamespace = require('solid-namespace') // Delegate to this which takes RDFlib as param. +../src/ns.js:const $rdf = require('rdflib') +../src/test/test-acl.js:const acl = require('../acl') +../src/test/test-acl.js:const rdf = require('../../../../linkeddata/rdflib.js/index.js') +../src/chat/message.js: authn: require('../authn/authn'), +../src/chat/message.js: icons: require('../iconBase'), +../src/chat/message.js: ns: require('../ns'), +../src/chat/message.js: media: require('../media-capture'), +../src/chat/message.js: pad: require('../pad'), +../src/chat/message.js: rdf: require('rdflib'), +../src/chat/message.js: store: require('../store'), +../src/chat/message.js: style: require('../style'), +../src/chat/message.js: utils: require('../utils'), +../src/chat/message.js: widgets: require('../widgets') +../src/chat/message.js:// const { messageToolbar, sentimentStripLinked } = require('./messageTools') +../src/chat/infinite.js:const $rdf = require('rdflib') +../src/chat/infinite.js:const DateFolder = require('./dateFolder') +../src/chat/infinite.js: authn: require('../authn/authn'), +../src/chat/infinite.js: icons: require('../iconBase'), +../src/chat/infinite.js: ns: require('../ns'), +../src/chat/infinite.js: media: require('../media-capture'), +../src/chat/infinite.js: pad: require('../pad'), +../src/chat/infinite.js: rdf: require('rdflib'), +../src/chat/infinite.js: store: require('../store'), +../src/chat/infinite.js: style: require('../style'), +../src/chat/infinite.js: utils: require('../utils'), +../src/chat/infinite.js: widgets: require('../widgets') +../src/chat/infinite.js:// const utils = require('./utils') +../src/chat/infinite.js:const { renderMessage, creatorAndDate } = require('./message') +../src/chat/infinite.js:const bookmarks = require('./bookmarks') +../src/chat/thread.js: authn: require('../authn/authn'), +../src/chat/thread.js: icons: require('../iconBase'), +../src/chat/thread.js: ns: require('../ns'), +../src/chat/thread.js: pad: require('../'), +../src/chat/thread.js: rdf: require('rdflib'), +../src/chat/thread.js: store: require('../store'), +../src/chat/thread.js: style: require('../style'), +../src/chat/thread.js: widgets: require('../widgets') +../src/chat/thread.js:const utils = require('../utils') +../src/chat/thread.js:const $rdf = require('rdflib') +../src/chat/bookmarks.js: authn: require('../authn/authn'), +../src/chat/bookmarks.js: icons: require('../iconBase'), +../src/chat/bookmarks.js: ns: require('../ns'), +../src/chat/bookmarks.js: media: require('../media-capture'), +../src/chat/bookmarks.js: pad: require('../pad'), +../src/chat/bookmarks.js: rdf: require('rdflib'), +../src/chat/bookmarks.js: store: require('../store'), +../src/chat/bookmarks.js: style: require('../style'), +../src/chat/bookmarks.js: utils: require('../utils'), +../src/chat/bookmarks.js: widgets: require('../widgets') +../src/chat/dateFolder.js:const kb = require('../store.js') +../src/chat/dateFolder.js:const ns = require('../ns.js') +../src/chat/dateFolder.js:const $rdf = require('rdflib') +../src/chat/messageTools.js: authn: require('../authn/authn'), +../src/chat/messageTools.js: icons: require('../iconBase'), +../src/chat/messageTools.js: ns: require('../ns'), +../src/chat/messageTools.js: media: require('../media-capture'), +../src/chat/messageTools.js: pad: require('../pad'), +../src/chat/messageTools.js: rdf: require('rdflib'), +../src/chat/messageTools.js: store: require('../store'), +../src/chat/messageTools.js: style: require('../style'), +../src/chat/messageTools.js: utils: require('../utils'), +../src/chat/messageTools.js: widgets: require('../widgets') +../src/chat/messageTools.js:const bookmarks = require('./bookmarks') +../src/preferences.js:const kb = require('./store') +../src/preferences.js:const ns = require('./ns') +../src/preferences.js:const authn = require('./authn/authn') +../src/preferences.js:const widgets = require('./widgets') +../src/preferences.js:const pad = require('./pad') +../src/preferences.js:const participation = require('./participation') +../src/matrix.js: icons: require('./iconBase'), +../src/matrix.js: ns: require('./ns'), +../src/matrix.js: rdf: require('rdflib'), +../src/matrix.js: store: require('./store'), +../src/matrix.js: widgets: require('./widgets') +../src/matrix.js:const utils = require('./utils') +../src/store.js:var rdf = require('rdflib') +../src/create.js:// const error = require('./widgets/error') +../src/create.js:// const widgets = require('./widgets/index') +../src/create.js:// const utils = require('./utils') +../src/create.js:// const UI = require('solid-ui') +../src/create.js: authn: require('./authn/authn'), +../src/create.js: icons: require('./iconBase'), +../src/create.js: ns: require('./ns'), +../src/create.js: store: require('./store'), +../src/create.js: style: require('./style'), +../src/create.js: utils: require('./utils'), +../src/create.js: widgets: require('./widgets') +../src/folders.js: icons: require('./iconBase'), +../src/folders.js: ns: require('./ns'), +../src/folders.js: rdf: require('rdflib'), +../src/folders.js: store: require('./store'), +../src/folders.js: widgets: require('./widgets'), +../src/folders.js: utils: require('./utils') +../src/table.js: icons: require('./iconBase'), +../src/table.js: log: require('./log'), +../src/table.js: ns: require('./ns'), +../src/table.js: store: require('./store'), +../src/table.js: widgets: require('./widgets') +../src/table.js:const utils = require('./utils') +../src/table.js:const $rdf = require('rdflib') +../src/utils.js: log: require('./log'), +../src/utils.js: ns: require('./ns'), +../src/utils.js: rdf: require('rdflib'), +../src/utils.js: store: require('./store') +../src/authn/signup.js:var defaultConfig = require('./config-default') +../src/widgets/peoplePicker.js:// const webClient = require('solid-web-client')(rdf) +../src/widgets/index.js:// var aclModule = require('./acl.js') +../src/widgets/index.js: require('./peoplePicker'), +../src/widgets/index.js: require('./dragAndDrop'), // uploadFiles etc +../src/widgets/index.js: require('./error'), // UI.widgets.errorMessageBlock +../src/widgets/index.js: require('./buttons'), +../src/widgets/index.js: require('./forms') +../src/widgets/dragAndDrop.js:const mime = require('mime-types') +../src/widgets/dragAndDrop.js:// const UI = require('../index.js') // this package +../src/widgets/forms.js: icons: require('../iconBase'), +../src/widgets/forms.js: log: require('../log'), +../src/widgets/forms.js: ns: require('../ns'), +../src/widgets/forms.js: store: require('../store'), +../src/widgets/forms.js: style: require('../style'), +../src/widgets/forms.js:const $rdf = require('rdflib') +../src/widgets/forms.js:const error = require('./error') +../src/widgets/forms.js:const buttons = require('./buttons') +../src/widgets/forms.js:const ns = require('../ns') +../src/widgets/forms.js:const utils = require('../utils') +../src/messageArea.js: authn: require('./authn/authn'), +../src/messageArea.js: icons: require('./iconBase'), +../src/messageArea.js: ns: require('./ns'), +../src/messageArea.js: rdf: require('rdflib'), +../src/messageArea.js: store: require('./store'), +../src/messageArea.js: style: require('./style'), +../src/messageArea.js: widgets: require('./widgets') +../src/messageArea.js:const $rdf = require('rdflib') +../src/messageArea.js:const utils = require('./utils') diff --git a/dependencies/source-file-list.txt b/dependencies/source-file-list.txt new file mode 100644 index 000000000..eb0732eda --- /dev/null +++ b/dependencies/source-file-list.txt @@ -0,0 +1,27 @@ +../src/media-capture.js +../src/ns.js +../src/test/test-acl.js +../src/chat/message.js +../src/chat/infinite.js +../src/chat/thread.js +../src/chat/bookmarks.js +../src/chat/dateFolder.js +../src/chat/messageTools.js +../src/preferences.js +../src/matrix.js +../src/store.js +../src/style.js +../src/create.js +../src/folders.js +../src/iconBase.js +../src/stories/decorators.js +../src/table.js +../src/utils.js +../src/authn/config-default.js +../src/authn/signup.js +../src/noun_Camera_1618446_000000.js +../src/widgets/peoplePicker.js +../src/widgets/index.js +../src/widgets/dragAndDrop.js +../src/widgets/forms.js +../src/messageArea.js diff --git a/dependencies/ttl2dot.sed b/dependencies/ttl2dot.sed new file mode 100644 index 000000000..6995aefdf --- /dev/null +++ b/dependencies/ttl2dot.sed @@ -0,0 +1,14 @@ +1i\ +digraph InternalDependencies { +$a\ +} +s?<[^<]*/\([a-zA-Z_\.0-9-]*\)>?<\1>?g +s/\.$/;/g +s///g +s/:dependsOn/ -> /g +s/\.js//g +s/\.ts//g +s/\([a-zA-Z_\.0-9-]\)-\([a-zA-Z_\.0-9-]\)/\1_\2/g +/ ;$/d +# ends diff --git a/docs/FormsReadme.md b/docs/FormsReadme.md new file mode 100644 index 000000000..15275bac0 --- /dev/null +++ b/docs/FormsReadme.md @@ -0,0 +1,67 @@ +# Welcome to solidUI Forms + +`Forms` are what we call the code part of solid-ui which takes the User Interface ontology at and makes it usable for developers. As its name suggests, `Forms` are used for rendering WebApp Frontend elements. For example, will translate to something like the following: +``` + +``` + +## A few starting points + +There are different documentation entry points for the topic. + +To get you started with Forms, we have the [forms-intro](./forms-intro.html). +If you're asking yourself how Forms fit into the Solid ecosystem, head over to [form-ecosystem](./form-ecosystem.html). + +Sir Tim Berners-Lee gave a talk about Forms to the SolidOS team end of 2021. His slides are online [here](./talks/FormsTalk.html), while a recording of the talk is on the [SolidOS pod](https://solidos.solidcommunity.net/public/SolidOS%20team%20meetings/SolidOS_team_videos.html). + + +## Creating your own Form using Turtle + +In the [form-playground](https://solidos.github.io/form-playground/playground.html) (code [here](https://github.com/SolidOS/form-playground)), you can create your own Form to render a frontend for some given Turtle. + +## Code examples + +To make use of Forms, you need to use solid-ui. Head over to the [solid-ui readme](https://github.com/SolidOS/solid-ui/blob/main/README.md#getting-started) for some how-to guides on how to use it in `npm` or as a `html + + + + + + + + + + + +

Role Types in preference - Classifier

+
+    @prefix foaf:  <http://xmlns.com/foaf/0.1/>.
+    @prefix sched: <http://www.w3.org/ns/pim/schedule#>.
+    @prefix cal:   <http://www.w3.org/2002/12/cal/ical#>.
+    @prefix dc:    <http://purl.org/dc/elements/1.1/>.
+    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>.
+    @prefix ui:    <http://www.w3.org/ns/ui#>.
+
+    @prefix schema: <http://schema.org/>.
+
+    @prefix trip:  <http://www.w3.org/ns/pim/trip#>.
+    @prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
+    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#>.
+    @prefix ex: <#>.  # Things in the examples
+    @prefix : <#>.
+
+ +
+ + + + + + + + + + + + + +
Form data for ui:ChoiceRaw dataForm
+ +
+
+ + + \ No newline at end of file diff --git a/docs/form-examples/backupData/profile-demo_profile_rawData.ttl b/docs/form-examples/backupData/profile-demo_profile_rawData.ttl new file mode 100644 index 000000000..39cd94578 --- /dev/null +++ b/docs/form-examples/backupData/profile-demo_profile_rawData.ttl @@ -0,0 +1,160 @@ +########### used for https://solidos.github.io/solid-ui/docs/form-examples/profile-demo.html ##### + +@prefix : <#>. +@prefix acl: . +@prefix foaf: . +@prefix ldp: . +@prefix org: . +@prefix schema: . +@prefix solid: . +@prefix space: . +@prefix vcard: . +@prefix xsd: . +@prefix pro: <./>. +@prefix inbox: . +@prefix tes: . +@prefix l: . +@prefix ent: . +@prefix not: . +@prefix www: . +@prefix ww: . +@prefix occup: . +@prefix c: . +@prefix skill: . + +occup:50af07f0-7a75-424e-a66d-5a9deea10f4c + schema:name + "testeur d\u2019accessibilit\u00e9/testeuse d\u2019accessibilit\u00e9". +occup:6b0ad7c0-a37f-45c6-a486-ee943a11429e schema:name "astrologue". + +occup:807a1ac3-4f56-41f3-a68c-d653d558eb0a schema:name "copilote". + +occup:88990bdf-4f6b-4411-82c9-9eecad1db8fb +schema:name "professeur de musique/professeure de musique". +skill:aec4c9bf-9c44-4f9d-99f1-70011cebe1a8 +schema:name "tester du mat\u00e9riel d\u2019instrumentation". +skill:b805f989-14d5-46ad-80b0-755634b66dba +schema:name "travailler dans de mauvaises conditions m\u00e9t\u00e9orologiques". +ent:Q23548 schema:name "NASA"@yo. + +ent:Q312 schema:name "Apple"@fr. + +pro:card a foaf:PersonalProfileDocument; foaf:maker :me; foaf:primaryTopic :me. + +:id1621179872094 solid:publicId l:fr. + +:id1621182189397 solid:publicId l:de. + +:id1621182208190 + a solid:CurrentRole; + schema:startDate "2021-04-01"^^xsd:date; + vcard:role "Testeuse des Apps Solid"; + org:member :me; + org:organization :id1621182234226; + org:role occup:50af07f0-7a75-424e-a66d-5a9deea10f4c. +:id1621182234226 + a schema:Corporation; + schema:name "Apple"; + schema:uri not:; + solid:publicId ent:Q312 . +:id1621182452881 + a solid:PastRole; + schema:description "This was an imaginary but fun gig."; + schema:endDate "1963-04-01"^^xsd:date; + schema:startDate "1960-04-01"^^xsd:date; + vcard:role "Directed the white album"; + org:member :me; + org:organization :id1621182460879; + org:role occup:88990bdf-4f6b-4411-82c9-9eecad1db8fb. +:id1621182460879 a schema:MusicGroup; schema:name "The Beatles"; schema:uri www: . + +:id1621183757035 + a solid:CurrentRole; + schema:description "Imaginary future roles are sometimes the best"; + schema:endDate "1993-04-01"^^xsd:date; + schema:startDate "1990-05-01"^^xsd:date; + vcard:role "Dream: Fly a couple of missions"; + org:member :me; + org:organization :id1621183860447, :id1652992302194; + org:role occup:807a1ac3-4f56-41f3-a68c-d653d558eb0a. +:id1621183860447 + a schema:GovernmentOrganization; + schema:name "National Aeronautical and Space Administration"; + schema:uri ww:; + solid:publicId ent:Q23548 . +:id1621184812427 + a solid:FutureRole; + schema:description "Second future role"; + schema:startDate "2023-12-25"^^xsd:date; + vcard:role "Mission a Mars"; + org:member :me; + org:organization :id1621184844320; + org:role occup:6b0ad7c0-a37f-45c6-a486-ee943a11429e. +:id1621184844320 + a schema:GovernmentOrganization; + schema:name "NASA"; + schema:uri ww:; + solid:publicId ent:Q23548 . +:id1622021411833 + vcard:country-name "USA"; + vcard:locality "Testingville"; + vcard:region "Texas"; + vcard:street-address "The testing tree house". +:id1622021761923 solid:publicId skill:aec4c9bf-9c44-4f9d-99f1-70011cebe1a8 . + +:id1622021775187 solid:publicId skill:b805f989-14d5-46ad-80b0-755634b66dba. + +:id1629201755476 solid:publicId l:el. + +:id1629201830484 solid:publicId l:el. + +:id1652992302194 a schema:NGO, vcard:Organization; schema:name "Some name". + +:me + a schema:Person, foaf:Person; + schema:knowsLanguage + ( :id1629201755476 ), ( :id1629201755476 ), + ( :id1629201755476 :id1629201806315 ); + schema:skills :id1622021761923, :id1622021775187; + vcard:bday "2021-05-14"^^xsd:date; + vcard:fn "Testing SolidOS Test"; + vcard:hasAddress :id1622021411833; + vcard:hasPhoto ; + vcard:note + "This is a test account for testing versions of the SolidOS operating system for solid."; + vcard:organization-name "Solid"; + vcard:role "foobar"; + acl:trustedApp + [ + acl:mode acl:Append, acl:Control, acl:Read, acl:Write; + acl:origin + ], + [ + acl:mode acl:Append, acl:Read, acl:Write; + acl:origin + ], + [ + acl:mode acl:Append, acl:Read, acl:Write; + acl:origin + ]; + ldp:inbox inbox:; + space:preferencesFile ; + space:storage tes:; + solid:account tes:; + solid:preferredObjectPronoun "them"; + solid:preferredRelativePronoun "theirs"; + solid:preferredSubjectPronoun "they"; + solid:privateTypeIndex ; + solid:profileBackgroundColor "#f4f5c2"^^xsd:color; + solid:profileHighlightColor "#06b74a"^^xsd:color; + solid:publicTypeIndex ; + foaf:knows c:me; + foaf:name "Testing SolidOS"; + foaf:nick "tester1". +l:de schema:name "germano"@ia. + +l:el + schema:name + "Modern Greek"@en, + "\u039d\u03ad\u03b1 \u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ae \u03b3\u03bb\u03ce\u03c3\u03c3\u03b1"@el. +l:fr schema:name "French"@en. diff --git a/docs/form-examples/backupData/structures2_organisations_form.ttl b/docs/form-examples/backupData/structures2_organisations_form.ttl new file mode 100644 index 000000000..5555d4abc --- /dev/null +++ b/docs/form-examples/backupData/structures2_organisations_form.ttl @@ -0,0 +1,186 @@ +########### used for https://solidos.github.io/solid-ui/docs/form-examples/structures2.html ##### +######## THIS IS PART OF THE PRODUCTION PROFILE FORM ########### + +@prefix rdf: . +@prefix rdfs: . +@prefix foaf: . +@prefix owl: . +@prefix solid: . +@prefix ui: . +@prefix schema: . +@prefix vcard: . + +@prefix org: . +@prefix esco: . +@prefix wd: . +@prefix wdt: . + +@prefix : <#>. + +:this + "Profile form" ; + a ui:Form ; + ui:parts ( + :OrganizationCreationForm + ). + +############ Organizations ################# + +:OrganizationCreationForm a ui:Form; + schema:name "Form for editing an organization using public data" ; + ui:parts ( :OrgClassifier :OrgSwitch :OrganizationNameField :homePageURIField ) . + + + :OrgClassifier a ui:Classifier; ui:label "What sort of organization?"@en; + ui:category solid:InterestingOrganization . + + # Ontology data to drive the classifier + + solid:InterestingOrganization owl:disjointUnionOf ( + schema:Corporation + schema:EducationalOrganization + schema:ResearchOrganization # Proposed. https://github.com/schemaorg/schemaorg/issues/2877 + schema:GovernmentOrganization + schema:NGO + schema:PerformingGroup # a band + schema:Project # like Solid + schema:SportsOrganization # a Team + solid:OtherOrganization + ) . + + # This until the schema.org ontology adopts it + schema:ResearchOrganization a rdfs:Class; + rdfs:label "Research Organization"@en, "Organization de Recherche"@fr , + "organización de investigación"@es, "منظمة البحث"@ar, "अनुसंधान संगठन"@hi, "Forschungsorganisation"@de, "shirika la utafiti"@sw . + + :OrganizationNameField + a ui:SingleLineTextField ; + ui:label "Organization Name"; + ui:maxLength "200" ; + ui:property schema:name ; + ui:size 80 . + + :homePageURIField a ui:NamedNodeURIField; ui:size 80; + ui:label "Home page URI"@en; + ui:property schema:uri . # @@ ?? + +# Depending on the type of org, chose a different form + + :OrgSwitch a ui:Options; ui:dependingOn rdf:type; + ui:case + [ ui:for schema:Corporation; ui:use :CorporationForm ], + [ ui:for schema:GovernmentOrganization; ui:use :GovernmentOrganizationForm ], + [ ui:for schema:PerformingGroup; ui:use :PerformingGroupForm ], + [ ui:for schema:Project; ui:use :ProjectForm ], + [ ui:for schema:NGO; ui:use :NGOForm ], + [ ui:for schema:EducationalOrganization; ui:use :EducationalOrganizationForm ], + [ ui:for schema:ResearchOrganization; ui:use :ResearchOrganizationForm ], + [ ui:for :SportsOrganization; ui:use :SportsOrganizationForm ], + [ ui:for solid:OtherOrganization; ui:use :OtherOrganizationForm ]. + + + :CorporationForm a ui:Group; ui:weight 0; ui:parts ( :CorporationPrompt :CorporationAutocomplete ) . + + :CorporationPrompt a ui:Comment; ui:contents "Which corporation?". + + :CorporationAutocomplete a ui:AutocompleteField; + a ui:AutocompleteField; ui:label "Corporation in wikidata"; + ui:size 60; + ui:targetClass ; # Enterprise + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + :WikidataInstancesByName a ui:DataSource ; + schema:name "Wikidata instances by name"; + ui:endpoint "https://query.wikidata.org/sparql" ; + ui:searchByNameQuery """SELECT ?subject ?name + WHERE { + ?klass wdt:P279* $(targetClass) . + ?subject wdt:P31 ?klass . + ?subject rdfs:label ?name. + FILTER regex(?name, "$(name)", "i") + } LIMIT $(limit) """ ; + + # Note this form of the query is very experimental + ui:searchByName [ ui:construct { ?subject schema:name ?name } ; + ui:where { ?klass wdt:P279 ?targetClass . + ?subject wdt:P31 ?klass; rdfs:label ?name . + }; + ]. + + :GovernmentOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :GovernmentOrganizationPrompt :GovernmentOrganizationAutocomplete ) . + + :GovernmentOrganizationPrompt a ui:Comment; ui:contents "Which GovernmentOrganization?". + + :GovernmentOrganizationAutocomplete + a ui:AutocompleteField; ui:label "GovernmentOrganization in wikidata"; + ui:size 60; + ui:targetClass ; # GovernmentOrganization + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + :EducationalOrganizationForm a ui:Group; ui:weight 1; ui:parts ( :EducationalOrganizationPrompt :EducationalOrganizationAutocomplete ) . + + :EducationalOrganizationPrompt a ui:Comment; ui:contents "Which Educational Organization?". + + :EducationalOrganizationAutocomplete + a ui:AutocompleteField; ui:label "Educational Organization in wikidata"; + ui:size 60; + ui:targetClass ; # EducationalOrganization + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + + :ResearchOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :ResearchOrganizationPrompt :ResearchOrganizationAutocomplete ) . + + :ResearchOrganizationPrompt a ui:Comment; ui:contents "Which Research Organization?". + + :ResearchOrganizationAutocomplete + a ui:AutocompleteField; ui:label "Research Insitute in wikidata"; + ui:size 60; + ui:targetClass ; # research institute + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + + :NGOForm a ui:Group; ui:weight 0; ui:parts ( :NGOPrompt :NGOAutocomplete ) . + + :NGOPrompt a ui:Comment; ui:contents "Which NGO?". + + :NGOAutocomplete + a ui:AutocompleteField; ui:label "NGO in wikidata"; + ui:size 60; + ui:targetClass ; # Non-profit org + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + :PerformingGroupForm a ui:Group; ui:weight 0; ui:parts ( :PerformingGroupPrompt :PerformingGroupAutocomplete ) . + + :PerformingGroupPrompt a ui:Comment; ui:contents "Which PerformingGroup?". + + :PerformingGroupAutocomplete + a ui:AutocompleteField; ui:label "PerformingGroup in wikidata"; + ui:size 60; + ui:targetClass ; # Music Org + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + + :ProjectForm a ui:Group; ui:weight 0; ui:parts ( :ProjectPrompt :ProjectAutocomplete ) . # :ProjectAutocomplete - no: supress, as not in WD + + :ProjectPrompt a ui:Comment; ui:contents "Which Project?". + + :ProjectAutocomplete + a ui:AutocompleteField; ui:label "Project in wikidata"; + ui:size 60; + ui:targetClass ; # Project + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + :SportsOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :SportsOrganizationPrompt :SportsOrganizationAutocomplete ) . + + :SportsOrganizationPrompt a ui:Comment; ui:contents "Which Sports Organization?". + + :SportsOrganizationAutocomplete + a ui:AutocompleteField; ui:label "SportsOrganization in wikidata"; + ui:size 60; + ui:targetClass ; # SportsOrganization + ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. + + :OtherOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :OrganizationNameField :homePageURIField ) . + + +# ENDS \ No newline at end of file diff --git a/docs/form-examples/backupData/structures2_organisations_rawData.ttl b/docs/form-examples/backupData/structures2_organisations_rawData.ttl new file mode 100644 index 000000000..6a71eaa53 --- /dev/null +++ b/docs/form-examples/backupData/structures2_organisations_rawData.ttl @@ -0,0 +1,15 @@ +########### used for https://solidos.github.io/solid-ui/docs/form-examples/structures2.html ##### + +@prefix : <#>. +@prefix schema: . +@prefix solid: . +@prefix wikidata: . + +wikidata:Q875914 schema:name "Kreischberg"@en. + +:org1 + a schema:Corporation, wikidata:Q6881511; + schema:name "Kreischberg", "kreischberg"; + schema:uri ; + solid:publicId wikidata:Q875914 . + diff --git a/docs/form-examples/backupData/structures3_SolidApps_rawData.ttl b/docs/form-examples/backupData/structures3_SolidApps_rawData.ttl new file mode 100644 index 000000000..5b560ecc6 --- /dev/null +++ b/docs/form-examples/backupData/structures3_SolidApps_rawData.ttl @@ -0,0 +1,258 @@ +########### used for https://solidos.github.io/solid-ui/docs/form-examples/structures3.html ##### + +@prefix : <#>. +@prefix dct: . +@prefix skos: . +@prefix dbpedia: . +@prefix So: . +@prefix hel: . +@prefix n1: . +@prefix he: . +@prefix wko: . +@prefix r: . +@prefix no: . +@prefix g0: . +@prefix Vir: . +@prefix blog: . +@prefix pu: . +@prefix Mel: . + +:0data-Solid-Hello-World + a skos:Concept, So:Example-Application; + skos:definition "Task Manager in Solid, Fission and remoteStorage"@en; + skos:prefLabel "0data Solid Hello World"@en; + skos:topConceptOf :Examples; + So:author "Noel De Martin"; + So:linkToDemo hel:; + So:linkToRepo n1:hello; + So:showcasesUseCase + :Authentication-on-Solid-using-library, :CRUD-operations-on-Solid; + So:usesCodeStack :CSS, :HTML, :JavaScript, :Simple-CSS; + So:usesFullCodeStack + :CSS, :HTML, :Inrupt-solid-client-authn, :JavaScript, :N3-rdfjs, + :Simple-CSS; + So:usesSemWebLibrary :N3-rdfjs; + So:usesSolidLibrary :Inrupt-solid-client-authn. +:Authentication-on-Solid-using-library + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Authentication on Solid using library"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication + :0data-Solid-Hello-World, :Hello-Solid, :Ramen, :Svelte-Solid-App. +:Authentication-using-React-library + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Authentication using React library"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication :Solid-To-Do-App-with-React. +:Bulma-CSS + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:prefLabel "Bulma CSS"@en; + So:usedInApplication :Hello-Solid. +:Code-stack + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:narrower + :Bulma-CSS, :CSS, :HTML, :JavaScript, :JQuery, :Nodejs, :React, + :Simple-CSS, :Svelte, :Vuejs; + skos:prefLabel "Code stack"@en; + skos:topConceptOf :Full-Code-stack. +:CRUD-operations-on-Solid + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "CRUD operations on Solid"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication + :0data-Solid-Hello-World, :Solid-To-Do-App-with-React. +:CSS + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:prefLabel "CSS"@en; + So:usedInApplication :Solid-To-Do-App-with-React. +:Examples + a skos:ConceptScheme; + dct:title "Examples"@en; + skos:hasTopConcept + :0data-Solid-Hello-World, :Hello-Solid, :Ramen, + :Solid-To-Do-App-with-React, :Svelte-Solid-App. +:Full-code-stack + a skos:ConceptScheme, So:Full-code-stack; + dct:title "Full code stack"@en; + skos:hasTopConcept :Code-stack, :Semantic-Web, :Solid. +:Hello-Solid + a skos:Concept, So:Example-Application; + skos:definition "Solid tutorial with links"@en; + skos:prefLabel "Hello Solid"@en; + skos:topConceptOf :Examples; + So:author "Wouter Kok"; + So:linkToDemo he:; + So:linkToRepo wko:hellosolid; + So:showcasesUseCase + :Authentication-on-Solid-using-library, :Read-from-Solid-Pod, + :Update-on-Solid-Pod, :Write-to-Solid-Pod; + So:usesCodeStack :Bulma-CSS, :CSS, :HTML, :JavaScript, :JQuery; + So:usesFullCodeStack + :Bulma-CSS, :CSS, :HTML, :JavaScript, :JQuery, :rdflib, + :Solid-query-ldflex, :Solid-solid-auth-client; + So:usesSemWebLibrary :rdflib; + So:usesSolidLibrary :Solid-query-ldflex, :Solid-solid-auth-client. +:HTML + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:prefLabel "HTML"@en; + So:usedInApplication :0data-Solid-Hello-World, :Hello-Solid. +:Inrupt-solid-client-authn + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "@Inrupt/solid-client-authn"@en. +:Inrupt-solid-client-js + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "@Inrupt/solid-client-js"@en. +:Inrupt-solid-ui-react + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "@Inrupt/solid-ui-react"@en. +:JavaScript + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:exactMatch dbpedia:JavaScript; + skos:prefLabel "JavaScript"@en; + So:usedInApplication :0data-Solid-Hello-World, :Hello-Solid. +:JQuery + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:exactMatch dbpedia:JQuery; + skos:prefLabel "JQuery"@en; + So:usedInApplication :Hello-Solid. +:N3-rdfjs + a skos:Concept, So:Full-code-stack, So:Semantic-Web-Library; + skos:broader :Semantic-Web; + skos:prefLabel "N3 rdfjs"@en; + So:linkToRepo . +:Nodejs + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:prefLabel "Nodejs"@en; + So:usedInApplication :Svelte-Solid-App. +:Ramen + a skos:Concept, So:Example-Application; + skos:definition "Adds a recipe for Ramen to your POD"@en; + skos:prefLabel "Ramen new"; + skos:topConceptOf :Examples; + So:author "Noel De Martin"; + So:linkToDemo r:; + So:linkToRepo no:ramen; + So:showcasesUseCase + :Authentication-on-Solid-using-library, :Usage-of-typeIndex, + :Write-to-Solid-Pod; + So:usesCodeStack :Vuejs; + So:usesFullCodeStack + :Inrupt-solid-client-authn, :Solid-solid-auth-client, :Soukai-Solid, :Vuejs; + So:usesSolidLibrary + :Inrupt-solid-client-authn, :Solid-solid-auth-client, :Soukai-Solid. +:rdflib + a skos:Concept, So:Full-code-stack, So:Semantic-Web-Library; + skos:broader :Semantic-Web; + skos:prefLabel "rdflib"@en. +:React + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:prefLabel "React"@en; + So:usedInApplication :Solid-To-Do-App-with-React. +:Read-from-Solid-Pod + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Read from Solid Pod"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication :Hello-Solid, :Svelte-Solid-App. +:Semantic-Web + a skos:Concept, So:Full-code-stack, So:Semantic-Web-Library; + skos:narrower :N3-rdfjs, :rdflib; + skos:prefLabel "Semantic web library"@en; + skos:topConceptOf :Full-Code-stack. +:Simple-CSS + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:prefLabel "Simple CSS"@en; + So:usedInApplication :0data-Solid-Hello-World. +:Solid + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:narrower + :Inrupt-solid-client-authn, :Inrupt-solid-client-js, + :Inrupt-solid-ui-react, :Solid-query-ldflex, :Solid-solid-auth-client, + :Soukai-Solid; + skos:prefLabel "Solid library"@en; + skos:topConceptOf :Full-Code-stack. +:Solid-query-ldflex + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "Solid/query-ldflex"@en. +:Solid-solid-auth-client + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "Solid/solid-auth-client"@en. +:Solid-To-Do-App-with-React + a skos:Concept, So:Example-Application; + skos:definition "To-Do app"@en; + skos:prefLabel "Solid To-Do App with React"@en; + skos:topConceptOf :Examples; + So:author "Virginia Balseiro"; + So:linkToDemo g0:; + So:linkToRepo Vir:solid-todo-tutorial; + So:linkToTutorial blog:tutorial; + So:showcasesUseCase + :Authentication-using-React-library, :CRUD-operations-on-Solid; + So:usesCodeStack :CSS, :React; + So:usesFullCodeStack + :CSS, :Inrupt-solid-client-authn, :Inrupt-solid-client-js, + :Inrupt-solid-ui-react, :React; + So:usesSolidLibrary + :Inrupt-solid-client-authn, :Inrupt-solid-client-js, :Inrupt-solid-ui-react. +:Soukai-Solid + a skos:Concept, So:Full-code-stack, So:Solid-Library; + skos:broader :Solid; + skos:prefLabel "Soukai-Solid"@en. +:Svelte + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:exactMatch dbpedia:Svelte; + skos:prefLabel "Svelte"@en; + So:usedInApplication :Svelte-Solid-App. +:Svelte-Solid-App + a skos:Concept, So:Example-Application; + skos:definition "Read/Write on a Pod with Svelte"@en; + skos:prefLabel "Svelte Solid App"@en; + skos:topConceptOf :Examples; + So:author "Patrick Hochstenbach"; + So:linkToDemo pu:; + So:linkToRepo Mel:Svelte-Solid-Authn; + So:showcasesUseCase + :Authentication-on-Solid-using-library, :Read-from-Solid-Pod, + :Write-to-Solid-Pod; + So:usesCodeStack :Nodejs, :Svelte; + So:usesFullCodeStack + :Inrupt-solid-client-authn, :Inrupt-solid-client-js, :Nodejs, :Svelte; + So:usesSolidLibrary :Inrupt-solid-client-authn, :Inrupt-solid-client-js. +:Technical-use-case + a skos:ConceptScheme, So:Technical-Use-Case; + dct:title "Technical use case"@en; + skos:hasTopConcept + :Authentication-on-Solid-using-library, + :Authentication-using-React-library, :CRUD-operations-on-Solid, + :Read-from-Solid-Pod, :Update-on-Solid-Pod, :Usage-of-typeIndex, + :Write-to-Solid-Pod. +:Update-on-Solid-Pod + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Update on Solid Pod"@en; + skos:topConceptOf :Technical-use-case. +:Usage-of-typeIndex + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Usage of typeIndex"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication :Ramen. +:Vuejs + a skos:Concept, So:Code-Stack, So:Full-code-stack; + skos:broader :Code-stack; + skos:prefLabel "Vuejs"@en; + So:usedInApplication :Ramen. +:Write-to-Solid-Pod + a skos:Concept, So:Technical-Use-Case; + skos:prefLabel "Write to Solid Pod"@en; + skos:topConceptOf :Technical-use-case; + So:exemplifiedInApplication :Hello-Solid, :Ramen, :Svelte-Solid-App. diff --git a/docs/form-examples/backupData/structures3_uiChoice_form.ttl b/docs/form-examples/backupData/structures3_uiChoice_form.ttl new file mode 100644 index 000000000..1f71f6450 --- /dev/null +++ b/docs/form-examples/backupData/structures3_uiChoice_form.ttl @@ -0,0 +1,114 @@ +########### used for https://solidos.github.io/solid-ui/docs/form-examples/structures3.html ##### + +@prefix ui: . +@prefix skos: . +@prefix So: . +@prefix schema: . +@prefix rdf: . + +@prefix : <#>. + +:this + schema:name "Solid example applications form" ; + a ui:Form ; + ui:parts ( + :projects + ). + +:projects a ui:Choice; + ui:label "Select project:"@en; + ui:canMintNew :true; + ui:use :projectCreationForm; + ui:property skos:hasTopConcept; + ui:from So:Example-Application . + + +:projectCreationForm a ui:Form; + schema:name "Form for creating a new Project" ; + ui:parts ( + :projectName + :projectDescription + :projectAuthor + :linksHeading + :linkToDemo + :linkToRepo + :linkToTutorial + :techStackHeading + :solidTechStack + :semWebTechStack + :genericTechStack + :useCaseHeading + :showcasesUseCase + ). + +# Project Name +:projectName a ui:SingleLineTextField; + ui:size 12; + ui:property skos:prefLabel; + ui:label "Name of project"@en. + +# Project Description +:projectDescription a ui:SingleLineTextField; + ui:size 100; + ui:property skos:definition; + ui:label "Short description"@en. + +# Project Author +:projectAuthor a ui:SingleLineTextField; + ui:size 100; + ui:property So:author; + ui:label "Author"@en. + +# ------------ project links ------------- # +:linksHeading a ui:Heading; ui:contents "Project links"@en. + +# Link to where the Demo is working/deployed +:linkToDemo a ui:SingleLineTextField; + ui:size 100; + ui:property So:linkToDemo; + ui:label "Link to demo"@en. + +# Link to repository +:linkToRepo a ui:SingleLineTextField; + ui:size 100; + ui:property So:linkToRepo; + ui:label "Link to repository"@en. + +# Link to tutorial +:linkToTutorial a ui:SingleLineTextField; + ui:size 100; + ui:property So:linkToTutorial; + ui:label "Link to tutorial"@en. + + +# ------------ project tech stack ------------- # +:techStackHeading a ui:Heading; ui:contents "Technical stack"@en. + +# drop down for solid tech stack +:solidTechStack a ui:Choice; + ui:label "Solid libraries used:"@en; + ui:property So:usesSolidLibrary; + ui:from So:Solid-Library. + +# drop down for semantic web tech stack +:semWebTechStack a ui:Choice; + ui:label "Semantic Web libraries used:"@en; + ui:property So:usesSemWebLibrary; + ui:from So:Semantic-Web-Library. + +# drop down for tech stack +:genericTechStack a ui:Choice; + ui:label "Generic technical stack used:"@en; + ui:property So:usesCodeStack; + ui:from So:Code-Stack. + +# ------------ project use cases -------------- # +:useCaseHeading a ui:Heading; ui:contents "Use cases"@en. + +# drop down for use cases +:showcasesUseCase a ui:Choice; + ui:label "Select use case:"@en; + ui:property So:showcasesUseCase; + ui:from So:Technical-Use-Case. + +# END \ No newline at end of file diff --git a/docs/form-examples/demo.html b/docs/form-examples/demo.html new file mode 100644 index 000000000..6c8ea8089 --- /dev/null +++ b/docs/form-examples/demo.html @@ -0,0 +1,272 @@ + + + + + + + + Form fields + + + + + + + + + + + + + + + + + +

Form fields

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+# A simple form with one text field
+
+ex:form
+    a ui:SingleLineTextField; ui:label "name";
+    ui:property vcard:fn .
+
+
+
+ex:this vcard:fn  "Alice" .
+
+
+
+# A simple form with one text field
+
+ex:form
+   a ui:MultiLineTextField ;
+   ui:property rdfs:comment .
+
+
+
+ex:this rdfs:comment "Here we made a comment" .
+          
+
+
+# A simple form with one boolean field
+
+ ex:form
+   a ui:BooleanField ;
+   ui:property ex:allDay .
+
+
+
+ex:this ex:allDay true .
+
+
+
+# one Tristate field
+
+ex:form
+     a ui:TristateField ;
+     ui:property ex:allDay .
+  
+
+
+# Commented oout so there is no value true or false:
+# ex:this ex:allDay true .
+
+
+# A simple form with one integer field
+
+ ex:form
+   a ui:IntegerField ;
+   ui:property foaf:age .
+
+
ex:this foaf:age 6 .
+
+# A simple form with one decimal field
+
+ ex:form
+   a ui:DecimalField ;
+   ui:property ex:price .
+
+
ex:this ex:price 12.47 .
+
+# A simple form with one floating point field
+
+ex:form
+   a ui:FloatField ;
+   ui:property ex:weight .
+        
+
 ex:this ex:weight  1.56769e23 .
+
+    # A simple form with one color field
+ ex:form
+   a ui:ColorField ;
+   ui:property ui:backgroundColor .
+  
+
ex:this ui:backgroundColor "#ffccff" .
+
+# A simple form with one date field
+
+ex:form
+   a ui:DateField;
+   ui:property cal:starts .
+    
+
ex:this cal:starts "2021-10-12"^^xsd:date .
+
+# A  date-time field
+ ex:form
+     a ui:DateTimeField ;
+     ui:property cal:starts .
+
+
+
 ex:this cal:starts "2021-10-12T12:34:23Z"^^xsd:dateTime .
+
+
+  # A simple form with one phone field
+
+ex:form
+   a ui:PhoneField ;
+   ui:property vcard:hasPhone . # @@ check
+    
+
ex:this vcard:hasPhone  <tel:+1-55-555-1212> .
+
+    # A simple form with one email address field
+
+ex:form
+   a ui:EmailField ;
+   ui:property vcard:hasEmail . # @@ chcek
+
+
+
ex:this vcard:hasEmail  <mailto:info@example.com> .
+
+
+# A field for entering a URI as a named node
+# (stores as RDF resource, not string literal)
+
+ex:form
+   a ui:NamedNodeURIField ;
+   ui:label "Homepage" ;
+   ui:property foaf:homepage .
+
+
+
ex:this foaf:homepage <https://example.org/alice> .
+
+
+ + diff --git a/docs/form-examples/edit-form-form.html b/docs/form-examples/edit-form-form.html new file mode 100644 index 000000000..22bacd76d --- /dev/null +++ b/docs/form-examples/edit-form-form.html @@ -0,0 +1,42 @@ + + + + + Edit the Form Form with the Form Form + + + + + + + + + + + + + + + + + + + + +

Edit the Form Form with the Form Form

+
+ + + + + + + + +
+
+ + diff --git a/docs/form-examples/edit-form.html b/docs/form-examples/edit-form.html new file mode 100644 index 000000000..d33ae0b14 --- /dev/null +++ b/docs/form-examples/edit-form.html @@ -0,0 +1,58 @@ + + + + + Edit a form with the Form Form + + + + + + + + + + + + + + + + + + + + +

Edit a form with the Form Form

+
+ + + + + + + + +
+
+  ex:this a ui:Form;
+   dc:title "Basic details";
+    ui:parts (ex:part1 ex:part2).
+
+        ex:part1 a ui:SingleLineTextField ;
+        ui:property vcard:fn;
+        ui:label "name" .
+
+        ex:part2 a ui:EmailField ;
+        ui:property vcard:hasEmail;
+        ui:label "email" .
+
+
+
+
+ + diff --git a/docs/form-examples/profile-demo.html b/docs/form-examples/profile-demo.html new file mode 100644 index 000000000..5d197d79c --- /dev/null +++ b/docs/form-examples/profile-demo.html @@ -0,0 +1,48 @@ + + + + + Profile form demo + + + + + + + + + + + + + + + + + + + + +

Profile form

+
+ + + + + + + + +
+
+ + diff --git a/docs/form-examples/structures.html b/docs/form-examples/structures.html new file mode 100644 index 000000000..c8578f15e --- /dev/null +++ b/docs/form-examples/structures.html @@ -0,0 +1,157 @@ + + + + + + + + Form structures + + + + + + + + + + + + + + + + +

Form structures

+
+    @prefix foaf:  <http://xmlns.com/foaf/0.1/>.
+    @prefix sched: <http://www.w3.org/ns/pim/schedule#>.
+    @prefix cal:   <http://www.w3.org/2002/12/cal/ical#>.
+    @prefix dc:    <http://purl.org/dc/elements/1.1/>.
+    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>.
+    @prefix ui:    <http://www.w3.org/ns/ui#>.
+    @prefix trip:  <http://www.w3.org/ns/pim/trip#>.
+    @prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
+    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#>.
+    @prefix : <#>.
+
+ +
+ + + + + + + + + + + + + + + + ___________ + +
Form dataRaw dataForm
+
+# A simple group with two fields
+
+:form a ui:Group;
+  ui:parts (:part1 :part2).
+
+      :part1 a ui:SingleLineTextField ;
+      ui:property vcard:fn;
+      ui:label "name" .
+
+      :part2 a ui:EmailField ;
+      ui:property vcard:hasEmail; # @@ chcek
+      ui:label "email" .
+
+
+
+:this vcard:fn "Alice";
+               vcard:hasEmail  <mailto:alice@example.com> .
+
+
+# A group with two fields and a nested subgroup
+
+:form a ui:Group;
+  ui:parts (:nameField :emailField :addresses) .
+
+      :nameField a ui:SingleLineTextField ;
+      ui:property vcard:fn;
+      ui:label "name" .
+
+      :emailField a ui:EmailField ;
+      ui:property vcard:hasEmail; # @@ chcek
+      ui:label "email" .
+
+      :addresses
+          a ui:Multiple ;  # -- Allows zero or one or more
+          ui:part :oneAddress ;
+          ui:property vcard:hasAddress .
+
+          :oneAddress
+              a ui:Group ;  # A subgroup of the main form
+              ui:parts ( :street :locality :postcode :region :country ).
+
+              :street
+                  a ui:SingleLineTextField ;
+                  ui:maxLength "128" ;
+                  ui:property vcard:street-address ;
+                  ui:size "40" .
+
+              :locality
+                  a ui:SingleLineTextField ;
+                  ui:maxLength "128" ;
+                  ui:property vcard:locality ;
+                  ui:size "40" .
+
+              :postcode
+                  a ui:SingleLineTextField ;
+                  ui:maxLength "25" ;
+                  ui:property vcard:postal-code ;
+                  ui:size "25" .
+
+      :region
+          a ui:SingleLineTextField ;
+          ui:maxLength "128" ;
+          ui:property vcard:region ;
+          ui:size "40" .
+
+      :country
+          a ui:SingleLineTextField ;
+          ui:maxLength "128" ;
+          ui:property vcard:country-name ;
+          ui:size "40" .
+
+
+
+
+##### Data:
+
+:this vcard:fn "Alice";
+   vcard:hasEmail  <mailto:alice@example.com>  ;
+   vcard:hasAddress [
+        vcard:street-address "111 Accacia Avennue";
+        vcard:country-name "UK"
+      ],
+      [
+         vcard:street-address "101 Autumn Ave";
+         vcard:country-name "USA"
+      ] .
+
+
+
+ + diff --git a/docs/form-examples/structures2.html b/docs/form-examples/structures2.html new file mode 100644 index 000000000..f18304928 --- /dev/null +++ b/docs/form-examples/structures2.html @@ -0,0 +1,71 @@ + + + + + + + + Form structures 2 - Classifier and Choice + + + + + + + + + + + + + + + + + +

Form structures 2 - Classifier and Options

+
+    @prefix foaf:  <http://xmlns.com/foaf/0.1/>.
+    @prefix sched: <http://www.w3.org/ns/pim/schedule#>.
+    @prefix cal:   <http://www.w3.org/2002/12/cal/ical#>.
+    @prefix dc:    <http://purl.org/dc/elements/1.1/>.
+    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>.
+    @prefix ui:    <http://www.w3.org/ns/ui#>.
+
+          @prefix schema: <http://schema.org/>.
+
+    @prefix trip:  <http://www.w3.org/ns/pim/trip#>.
+    @prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
+    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#>.
+    @prefix ex: <#>.  # Things in the examples
+    @prefix : <#>.
+
+ +
+ + + + + + + + + + + + + + ___________ + +
Form data example for ui:Classifier and ui:Options Raw dataForm
+ +
+
+ + diff --git a/docs/form-examples/structures3.html b/docs/form-examples/structures3.html new file mode 100644 index 000000000..9ddd66e2b --- /dev/null +++ b/docs/form-examples/structures3.html @@ -0,0 +1,68 @@ + + + + + + + + + Form structures 3 - Choice + + + + + + + + + + + + + + + + +

Form structures 3 - Choice

+
+    @prefix foaf:  <http://xmlns.com/foaf/0.1/>.
+    @prefix sched: <http://www.w3.org/ns/pim/schedule#>.
+    @prefix cal:   <http://www.w3.org/2002/12/cal/ical#>.
+    @prefix dc:    <http://purl.org/dc/elements/1.1/>.
+    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>.
+    @prefix ui:    <http://www.w3.org/ns/ui#>.
+
+    @prefix schema: <http://schema.org/>.
+
+    @prefix trip:  <http://www.w3.org/ns/pim/trip#>.
+    @prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
+    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#>.
+    @prefix ex: <#>.  # Things in the examples
+    @prefix : <#>.
+
+ +
+ + + + + + + + + + + + + +
Form data for ui:ChoiceRaw dataForm
+ +
+
+ + + \ No newline at end of file diff --git a/docs/form-examples/test-form.js b/docs/form-examples/test-form.js new file mode 100644 index 000000000..06047718f --- /dev/null +++ b/docs/form-examples/test-form.js @@ -0,0 +1,155 @@ + + +document.addEventListener('DOMContentLoaded', async function () { + /// /////////////////////////////////////////// + + var kb = SolidLogic.store + + kb.updater.editable = // uri => true // Force modifyable UX // @@@ + function (uri) { + console.log(' @@ fudging editable for ' + uri) + return 'SPARQL' + } + + var dom = document + + var uri = window.location.href + var base = (window.document.title = uri.slice(0, uri.lastIndexOf('/') + 1)) + // var testDocURI = base + 'test.ttl' // imaginary doc - just use its URL + // const testDocURI = 'https://timbl.com/timbl/Public/Test/Forms/exampleData.ttl' + const testDocURI = 'https://solidos.solidcommunity.net/public/2021/solidUiFormTestData/dummyFormTestFile.ttl' + var testDoc = $rdf.sym(testDocURI) + const ex = $rdf.Namespace(testDocURI + "#") + + const defaultProlog = ` + @prefix foaf: . + @prefix sched: . + @prefix cal: . + @prefix dc: . + @prefix rdfs: . + @prefix ui: . + @prefix trip: . + @prefix vcard: . + @prefix xsd: . + @prefix ex: <#>. # Things in the examples + @prefix : <#>. +` + + // var div = dom.getElementById('UITestArea') + + const getOptions = { + credentials: 'omit', withCredentials: false + } + + function output (row) { + return row.children[1] + } + function renderForm (form, subject, container) { + async function callback() { + } + const doc = subject.doc() + + var ele = UI.widgets.appendForm(dom, container, {}, subject, form, doc, callback) + return ele + } + + /* For loading eg ontologies from w3.org + */ + function addStoHTTP (str) { + if (str.startsWith('http:')) { + return 'https:' + str.slice(5) + } + return str + } + + async function doRow (prolog, row) { + + async function loadTextIntoCell (cell) { + const source = cell.getAttribute('source') + if (!source) return + const response = await kb.fetcher.webOperation('GET', addStoHTTP(source), getOptions) + if (!response.ok) { // if HTTP-status is 200-299 + const msg = "HTTP-Error: " + response.status + cell.textContent = msg + cell.style.backgroundColor = '#fee' + alert(msg); + return + } + const text = response.responseText; + const pre = dom.createElement('pre') + cell.appendChild(pre) + pre.textContent = text + } + + const cellForClass = [] + + kb.removeMany(null, null, null, testDoc) // Remove previous test data + + + for (var cell of row.children) { + await loadTextIntoCell(cell) + if (cell.getAttribute('class')) { + for (const c of cell.getAttribute('class').split(' ')) { + cellForClass[c] = cell + console.log(' cellForClass: ' + c) + } + } + } + const inputCell = cellForClass['input'] + const targetCell = cellForClass['target'] + const outputCell = cellForClass['output'] + + const inputText = inputCell.firstElementChild.textContent + if (inputCell.getAttribute('source')) { + form = $rdf.sym(inputCell.getAttribute('source')) + } else { + form = ex('form') + } + if (targetCell.getAttribute('source')) { + subject = $rdf.sym(targetCell.getAttribute('source')) + } else { + subject = ex('this') + } + + try { + $rdf.parse(prolog + inputText, kb, form.doc().uri, 'text/turtle') // str, kb, base, contentType + } catch (e) { + outputCell.textContent = e + console.log('>>>>>>>' + prolog + inputText + '<<<<<<\n') + return + } + + if (true) { + const subjectText = targetCell.firstElementChild.textContent + try { + $rdf.parse(prolog + subjectText, kb, subject.doc().uri, 'text/turtle') // str, kb, base, contentType + } catch (e) { + outputCell.textContent = e + console.log('>>>>>>>' + prolog + subjectText + '<<<<<<\n') + return + } + } + renderForm(form, subject, outputCell) + } + async function showResults () { + var prologEle = dom.getElementById('Prolog') + const prolog = defaultProlog + (prologEle ? prologEle.textContent : "") + + const testRows = dom.getElementsByClassName('form-demo') + for (var row of testRows) { + await doRow(prolog, row) + } + if (dom.getElementById('TestData')) { + for (var row of dom.getElementById('TestData').children) { + await doRow(prolog, row) + } + } + } // showResults + + try { + // await kb.fetcher.load(testDoc) // To fool the form syt + } catch (err) { + console.warn(err) + } + await showResults() +}) diff --git a/docs/forms-intro.html b/docs/forms-intro.html new file mode 100644 index 000000000..58b5fe2c8 --- /dev/null +++ b/docs/forms-intro.html @@ -0,0 +1,725 @@ + + + + + + + solid-ui: Introduction using forms + + + + +

Using Forms in the UI ontology

+ +

+ The User Interface ontology at http://www.w3.org/ns/ui defines + RDF terms for describing forms. The + solid-ui project + provides functions to use these forms within your web application to + create a quick user interface solution. This document describes how. +

+ +

+ The form system allows you to define a user interface declaratively in + RDF. In your web app, you then: +

+ +
    +
  1. make sure the ontology files are loaded
  2. + +
  3. load the file with the form itself
  4. + +
  5. + call + UI.widgets.appendForm(dom, container, {}, subject, form, doc, + callback) +
  6. +
+ +

where

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
domis the DOM HTMLDocument object, a/k/a document
containeris a DOM element to contain the form
{}are unused at present
subjectis the RDF thing about which data will be stored
formis the RDF object in the store for the form
doc + is the RDF document on the web where the data will be stored. Often, + subject.doc() +
callback + is a function taking an error flag and a message (if the error flag is + true) +
+ + If the form is a complex form, as the user adds more data, more form UI will + be created. The data in each field is saved back to the web the moment the + user has entered it. There is no general Save Button. + +

+ There is a form form for editing forms. It is in the form ontology itself. +

+ +

+ You can of course go and write other implementations of the form system + using your favorite user interface language. +

+ +

Go to the source

+ + + +

Form field types

+ +

+ Form fields may be named or blank nodes in your file; the form system does + not care. It is often useful to name them to keep track of them. +

+ +

+ Below, all Field Classes and Properties are in the UI namespace, + http://www.w3.org/ns/ui#, except the data types, like Integer, which are in the normal + XSD + namespace. +

+ +

+ Here are some properties which you can use with any field (except the + documentation fields). +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
labelString + A label for the form field. This is the prompt for the user, e.g., + "Name", "Employer". If the label is not given in the form, the + system will make one from a label of the property in the ontology. +
propertyrdf:Property + When the user enters the data, it is stored in the web as a triple + with this property as its predicate. +
default[according to field type] Optional + The input control is set to this value by default. It is easiest for + the user to enter this value. (This value is not automatically + stored by the form system if the user does not select or enter it in + some way. +
suppressEmptyUneditableBoolean + Setting this flag (on a single form field not a structure) means that when the user is just reading the data, not + editing it, the fields with blank data will be removed completely. + This avoid things like a blank field for a region in an address when there isn't one given. + This can make the UX much cleaner. Defaults to false. +
+ +

+ Other properties are given for each field type. +

+ +

Form

+ +

+ The form itself has a collection of fields. The parts property + gives an order list of the fields in each form. +

+ + + + + + + + + + + + + + + + + +
partsrdf:Collection (aka List, Array) of FieldThe parts of the form in the order in which they are
partField (Obsolete) + A field which is a part of the form or group. This property is + obsolete. Use parts. +
+ + If you use the obsolete "part" method for listing the parts of a form, then + each field needs an additional property: + + + + + + + + + +
sequenceIntegerThe parts of the form in the order in which they are
+ + For each part, declare its type, and the extra data that type requires, as + below. + +

Group

+ +

+ Group is a field which is just a collection of other fields. It is in fact + interchangeable with Form. +

+ +

Single Value fields - Numeric

+ These prompt the user for a single value. They typically take default + values, and min and max values. + +

BooleanField

+ +

A checkbox on the form, stored an RDF boolean true or false value.

+ +

TriStateField

+ +

+ A checkbox on the form, stores an RDF boolean true or false value, or no + value if the box is left in its third, blank state. +

+ +

IntegerField

+ +

An RDF integer value

+ +

DecimalField

+ +

An RDF decimal value. Useful for monetary amounts

+ +

FloatField

+ +

A floating point number

+ +

Single Value fields: Special Types

+ +

ColorField

+ +

+ A color picker is used, and generates a string which is a CSS_compatible + color in a string like #ffeebb +

+ +

DateField

+ +

+ Uses a date picker on a good browser. Leaves an RDF date literal as its + value. +

+ +

DateTimeField

+ +

Leaves an RDF dateTime literal as its value.

+ +

PhoneField

+ +

Leaves as its value a named node with a tel: scheme URI

+ +

EmailField

+ +

Leaves as its value a named node with a 'mailto:' scheme URI

+ +

Single Value fields - Text

+ +

SingleLineTextField

+ +

NamedNodeURIField

+ +

+ A NamedNodeURIField is like a SingleLineTextField, except that the + value it generates is not a literal string but an RDF named node with + the given URI. Use this when users need to provide explicit URIs to things, + storing them as proper RDF resources rather than text values. +

+ +

+ Unlike PhoneField or EmailField which add URI scheme prefixes (tel: + or mailto:), the NamedNodeURIField stores the URI exactly as + entered by the user. +

+ +

MultiLineTextField

+ +

Complex fields

+ +

Group

+ +

+ A group is simply a static set of fields of any type. Its properties are + the same as for Form. +

+ + + + + + + + + + + + + +
weightxsd:integer0:lighter than normal, 1: Normal, 2,3: heavier than normal
partsrdf:Collection + The form fields, forms, in the group +
+ + + +

Choice

+ +

The user choses an item from a class.

+ + + + + + + + + + + + + + + + + + + + + + + +
fromrdfs:ClassThe selected thing must be a member of this class, e.g., Person.
propertyrdf:Property + When the item is found, the new data links it from the subject with + this property, e.g., friend. +
canMintNewxsd:Boolean + If the user doesn't find the thing they want, can they introduce an + item of that class by filling in a form about it? [Boolean] +
+ +

If a new thing is minted, that will be done with a form which is a + ui:creationForm for the class.

+ +

Multiple

+ +

+ When the subject can have several of the same thing, like friends or + phone numbers, then the Multiple field allows this. The user clicks on the + green plus icon, and is prompted for a subform for the related thing. The + user can also delete existing ones. +

+ +

+ For each new thing, the system generates an arbitrary (timestamp) URI + within the file where the data is being stored. The subform is then about + that thing; the subject of the subform is not the subject of the original + form. It is the field, or the address, and so on. +

+ + + + + + + + + + + + + + + + + + + + + + + +
orderedBooleanIf true, the user has an ordered array of things, and the data is in an RDF collection. + If false, the UI is irrelevant and the data is a series of arcs.
propertyrdf:PropertyThe API details or query endpoint and query details to be used to search the item in + the databasse.
reverseBooleanIf set, the form will write data triple like X P S instead of the normal S P X. +
partFormThe form to be used for each one. +
+ + + + +

Classifier

+ + + + + + + + + +
categoryrdfs:Class + The object will already be in this class. The user will select + subclasses of this class. +
+

+ This form field leverages the ontology heavily. It pulls the subclasses of + the given class, and makes a pop-up menu for the user to chose one. If and + only if the ontology says that the class is a disjoint union + (owl:disjointUnionOf) of the subclasses, then the user interface will only + allow the user to pick one. If the user picks a subclass, and the ontology + shows that that subclass has its own subclasses, then the user will be + prompted to pick one of those, to (if they like) further refine the + selection. And so on. +

+

+ The classifier pops a menu to allow the user to select a set of values to + classify the subject. +

+ +

Options

+ +

+ An Options field is the 'case statement' of the form system. It will + choose at runtime a subfield depending on a property, often the type, of + the subject. Often used after a classifier. +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Options propertyrangesignificance
dependingOnrdf:PropertyThe predicate in the data used to select the case.
caseCaseA case object, with for x use y. (2 or more cases)
+ +

and for each case:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Case propertyrangesignificance
for[The range of the dependingOn property]The value this case applies to
useFieldsub form to be used in case the value matches the "for"
+ +

Autocomplete

+ +

The autocomplete field alllows the user to select one + out of a large number of existing choices, by typing enough of its + name to be unambiguous. +

+ +

The field stores two triples,one of the given property linking to the + object the user has selcted, and the other stoting the name of that object, + as seen in the completed feld, using the labelProperty. +

+ +

The field must specify a dataSource which gives the paramters + and form of the query make over the net. +

+ + + + + + + + + + + + + + + + + + + +
labelPropertyrdf:PropertyThe property which will be used to store the name of the selected thing as a separate triple
dataSourceDataSourceThe API details or query endpint and query details to be usde to search of the itemn in + the databasse.
targetClassrdfs:ClassIs tyhis is specified, it be used to replace any occurrences of + "$(targetClass)" in the query template. this allows different instances + of AutocompleteField to share the same DataSource, by specifying different values for targetClass.
+ +

Documentation fields

+ +

Heading

+ +

+ Help the user find parts of a long form, or just for a title of a short + form. +

+ + + + + + + + + + + + + + +
contentsStringThe text content of the heading
suppressIfUneditableBooleanIf data is uneditable,ie read-only mode, hide this comment
+ +

The suppressIfUneditable flag allow you to make a form which + is much cleaner and simpler when the user is just reading information, + not editing it.

+ +

Comment

+ +

+ Use comments in the form to help users understand what is going on, what + their options are, and what the fields mean. +

+ + + + + + + + + + + + + + +
contentsString + The text content of the comment. (This should be displayed by form + systems as pre-wrap mode.) +
suppressIfUneditableBooleanIf data is uneditable,ie read-only mode, hide this comment
+ +

Conclusion

+ +

+ The form language and the form implementation in solid-ui can't do + everything, but it can handle a pretty wide selection of tasks in common + daily life at home and at work. It can be vary efficient as developers can + reuse material between forms. Users can even generate their own forms. +

+

+ Future directions include separate implementations of the form UI code in + for various platforms, and using various UI frameworks. There may also be + extensions of the system with new field types, more options for setting style + from various sources, etc. +

+ + diff --git a/docs/style/demo-style.css b/docs/style/demo-style.css new file mode 100644 index 000000000..1ad815832 --- /dev/null +++ b/docs/style/demo-style.css @@ -0,0 +1,46 @@ + input { + background-color: #eef; + padding: 0.5em; + border: .5em solid white; + font-size: 120%; + } + + table { + + border-collapse: collapse; + border: 0.1em solid gray; + margin: 1em; + + } + + tr.naviMenu { + background-color: white; + } + + tr.naviMenu td { + text-align: middle; + vertical-align: middle; + padding-top: 4em; + } + + table tbody tr td { + padding: 1em; + border: 0.1em solid gray; + } + + td { + vertical-align: top; + } + + td.input { + border-top: 0.1em solid gray; + border-right: 0.1em dotted gray; + padding: 1em; + } + + td.output { + border-top: 0.1em solid gray; + padding: 1em; + } + + td.input pre { padding: 0.5em;} diff --git a/docs/style/solid-purple.css b/docs/style/solid-purple.css new file mode 100644 index 000000000..4c1474a5a --- /dev/null +++ b/docs/style/solid-purple.css @@ -0,0 +1,518 @@ +/* w3c-blue.css + + Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved. + W3C liability, trademark, document use and software licensing + rules apply, see: + + http://www.w3.org/Consortium/Legal/copyright-documents + http://www.w3.org/Consortium/Legal/copyright-software +*/ +body +{ + margin: 0 0 0 0; + padding: 0 0 0 0; + width: 100%; + height: 100%; + color: black; + background-color: white; + font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif; + font-size: 14pt; +} + +div.slide.titlepage { + text-align: center; +} + +div.slide.titlepage h1 { + padding-top: 40%; +} + +div.slide { + z-index: 20; + margin: 0 0 0 0; + padding: 0; + border-width: 0; + top: 0; + bottom: 0; + left: 0; + right: 0; + line-height: 120%; + background-color: transparent; +} + +div.background { + z-index: 1; + position: absolute; + vertical-align: bottom; + left: 0; + right: 0; + top: 0; + bottom: auto; + height: 4.1em; + padding: 0 0 0 0.2em; + margin: 0 0 0 0; + border-width: 0; + background-color: #c28ec2; /* was #c28ec2 */ +} + +div.background img { + height: 4em; +} + +/* this rule is hidden from IE which doesn't support + selector */ +div.slide + div[class].slide { page-break-before: always;} + +div.slide h1 { + padding-left: 3em; + padding-right: 3em; + padding-top: 0.1em; + margin-bottom: 0.8em; + margin-top: -0.05em; + margin-left: 0; + margin-right: 0; + min-height: 2.3em; + color: white; + height: 2.2em; + font-size: 160%; + line-height: 1.1em; +} + +div.slide h1 a { + color: white; + text-decoration: none; +} + +div.slide h1 a:link { + color: white; + text-decoration: none; +} + +div.slide h1 a:visited { + color: white; + text-decoration: none; +} + +div.slide h1 a:hover { + color: white; + text-decoration: underline; +} + +div.slide h1 a:active { + color: red; + text-decoration: underline; +} + +#head-icon { + margin-top: 0.5em; + margin-bottom: 0; + margin-left: 0; + margin-right: 1em; + background: #c28ec2; + border-width: 0; + height: 3em; + max-width: 3em; + z-index: 2; + float: left; +} + +#head-logo { + margin: 0; + margin-top: 0.25em; + padding-top: 0.25em; + padding-bottom: 0.2em; + padding-left: 0; + padding-right: 0; + height: 3.2em; + width: 4.8em; + float: right; + z-index: 2; + background: #c28ec2; +} + +#head-logo-fallback { + margin: 0; + padding: 0; + margin-top: -0.8em; + width: 4.8em; + float: right; + z-index: 2; +} + +/* the next two classes support vertical and horizontal centering */ +div.vbox { + float: left; + height: 40%; + width: 50%; + margin-top: -240px; +} +div.hbox { + width:60%; + margin-top: 0; + margin-left:auto; + margin-right:auto; + height: 60%; + border:1px solid silver; + background:#F0F0F0; + overflow:auto; + text-align:left; + clear:both; +} + +/* styling for named background */ +div.background.slanty { + z-index: 2; + bottom: 0; + height: 100%; + background: transparent; +} + +div.background.slanty img { margin-top: 4em; width: 100%; height: 80% } + +/* the following makes the pre background translucent */ +/* opacity is a CSS3 property but supported by Mozilla family */ +/* filter is an IE specific feature that also requires width */ +div.slide.slanty pre { + width: 93%; /* needed for IE filter to work */ + opacity: .8; + filter: alpha(opacity=80); +} + +img.withBorder { + border: 2px solid #c60; + padding: 4px; +} + +li pre { margin-left: 0; } + +@media print { pre { font-size: 60% } } + +blockquote { font-style: italic } + +img { background-color: transparent } + +p.copyright { font-size: smaller } + +.center { text-align: center } +.footnote { font-size: smaller; margin-left: 2em; } + +a img { border-width: 0; border-style: none } + +a:visited { color: navy } +a:link { color: navy } +a:hover { color: red; text-decoration: underline } +a:active { color: red; text-decoration: underline } + +a {text-decoration: none} +.navbar a:link {color: white} +.navbar a:visited {color: yellow} +.navbar a:active {color: red} +.navbar a:hover {color: red} + +p { margin-left: 0.5em; margin-top: 0.5em; font-size: 150%; line-height: 120%; } + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +li { margin-left: 0.5em; margin-top: 0.5em; } +li li { font-size: 85%; font-style: italic } +li li li { font-size: 85%; font-style: normal } + +div dt +{ + margin-left: 0; + margin-top: 1em; + margin-bottom: 0.5em; + font-weight: bold; +} +div dd +{ + margin-left: 2em; + margin-bottom: 0.5em; +} + + +p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table { + margin-left: 1em; + margin-right: 1em; +} + +p.subhead { font-weight: bold; margin-top: 2em; } + +div.cover p.explanation { + font-style: italic; + margin-top: 3em; +} + + +.smaller { font-size: smaller } + +td,th { padding: 0.2em } + +ul { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ol { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +li { margin-left: 0.5em; margin-top: 0.5em; } +li li { font-size: 85%; font-style: italic } +li li li { font-size: 85%; font-style: normal } + + +ul li { + list-style: none; + margin: 0.1em 0em 0.6em 0; + padding: 0 0 0 40px; + background: transparent url(../graphics/bullet.png) no-repeat 5px 0.3em; + line-height: 140%; +} + +/* workaround IE's failure to support background on li for print media */ +@media print { ul li { list-style: disc; padding-left: 0; background: none; } } + +ol li { + margin: 0.1em 0em 0.6em 1.5em; + padding: 0 0 0 0px; + line-height: 140%; +} + +li li { + font-size: 85%; + font-style: italic; + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} +li li li { + font-size: 85%; + font-style: normal; + list-style-type: circle; + background: transparent; + padding: 0 0 0 0; +} +li li li li { + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} + +/* rectangular blue bullet + unfold/nofold/fold widget */ + +/* + setting class="outline on ol or ul makes it behave as an + ouline list where blocklevel content in li elements is + hidden by default and can be expanded or collapsed with + mouse click. Set class="expand" on li to override default +*/ + +ol.outline li:hover { cursor: pointer } +ol.outline li.nofold:hover { cursor: default } + +ul.outline li:hover { cursor: pointer } +ul.outline li.nofold:hover { cursor: default } + +ol.outline { list-style:decimal; } +ol.outline ol { list-style-type:lower-alpha } + +ol.outline li.nofold { + padding: 0 0 0 20px; + background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.3em; +} +ol.outline li.unfolded { + padding: 0 0 0 20px; + background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.3em; +} +ol.outline li.folded { + padding: 0 0 0 20px; + background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.3em; +} +ol.outline li.unfolded:hover { + padding: 0 0 0 20px; + background: transparent url(../graphics/fold.gif) no-repeat 0px 0.3em; +} +ol.outline li.folded:hover { + padding: 0 0 0 20px; + background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.3em; +} + +ul.outline li.nofold { + padding: 0 0 0 52px; + background: transparent url(../graphics/bullet-nofold-dim.gif) no-repeat 5px 0.3em; +} +ul.outline li.unfolded { + padding: 0 0 0 52px; + background: transparent url(../graphics/bullet-fold-dim.gif) no-repeat 5px 0.3em; +} +ul.outline li.folded { + padding: 0 0 0 52px; + background: transparent url(../graphics/bullet-unfold-dim.gif) no-repeat 5px 0.3em; +} +ul.outline li.unfolded:hover { + padding: 0 0 0 52px; + background: transparent url(../graphics/bullet-fold.gif) no-repeat 5px 0.3em; +} +ul.outline li.folded:hover { + padding: 0 0 0 52px; + background: transparent url(../graphics/bullet-unfold.gif) no-repeat 5px 0.3em; +} + +li ul.outline li.nofold { + padding: 0 0 0 21px; + background: transparent url(../graphics/nofold-dim.gif) no-repeat 5px 0.3em; +} +li ul.outline li.unfolded { + padding: 0 0 0 21px; + background: transparent url(../graphics/fold-dim.gif) no-repeat 5px 0.3em; +} +li ul.outline li.folded { + padding: 0 0 0 21px; + background: transparent url(../graphics/unfold-dim.gif) no-repeat 5px 0.3em; +} +li ul.outline li.unfolded:hover { + padding: 0 0 0 21px; + background: transparent url(../graphics/fold.gif) no-repeat 5px 0.3em; +} +li ul.outline li.folded:hover { + padding: 0 0 0 21px; + background: transparent url(../graphics/unfold.gif) no-repeat 5px 0.3em; +} + +img { + image-rendering: optimize-quality; +} + +img.withBorder { + border: 2px solid #c60; + padding: 4px; +} + +div.header { + position: absolute; + z-index: 2; + left: 0; + right: 0; + top: 0; + bottom: auto; + height: 2.95em; + width: 100%; + padding: 0 0 0 0; + margin: 0 0 0 0; + border-width: 0; + border-style: solid; + background-color: #005A9C; + border-bottom-width: thick; + border-bottom-color: #95ABD0; +} + +div.footer { + position: absolute; + z-index: 80; + left: 0; + right: 0; + top: auto; + bottom: 0; + height: 3.5em; + margin: 0; + font-size: 80%; + font-weight: bold; + padding-left: 1em; + padding-right: 0; + padding-top: 0.3em; + padding-bottom: 0; + color: #003366; + background-color: #95ABD0; +} + +/* this is a hack to hide property from IE6 and below */ +div[class="footer"] { + position: fixed; +} + +#hidden-bullet { + visibility: hidden; + display: none; +} + +div.slide.cover { + color: white; + background-color: #c28ec2; + padding-top: 0; + padding-right: 0; + padding-left: 3em; + height: 100%; +} + +div.slide.cover h1 { + margin: 0; + padding: 0.5em; + color: white; + height: auto; +} + +div.slide.cover h2 { + color: white; +} + +div.slide.cover a { + color: white; +} + +div.slide.cover a:visited { color: white } +div.slide.cover a:link { color: white } +div.slide.cover a:hover { color: yellow; text-decoration: underline } +div.slide.cover a:active { color: yellow; text-decoration: underline } + +div.slide.cover a:hover, div.slide.cover a:active { + color: yellow; text-decoration: underline; +} + +div.slide.cover img.cover { + margin: 0 0 0 0; + float: right; + padding-bottom: 4em; + width: 50%; + overflow: hidden; +} + +div.slide.cover a:hover, div.slide.cover a:active { + color: yellow; text-decoration: underline; +} + +/* for Bert as an ardent user of the old W3C slidemaker tool */ + +div.comment { display: none; visibility: hidden } + +@media print { + div.slide h1 { background: transparent; color: black } + div.slide.cover { background: transparent; color: black } + div.slide.cover h1 { background: transparent; color: black } + div.comment { display: block; visibility: visible } +} + + + + +table { + border-collapse: collapse; + margin: 1em; + } + table.parameters { + background-color: #dddddd; + } /* background-color: #ddddff; */ + table.properties { + background-color: #ddddff; + } /* background-color: #ddddff; */ + td { + padding: 0.5em; + border: 0.1em solid white; + margin: 0; + } diff --git a/docs/talks/FormsTalk.html b/docs/talks/FormsTalk.html new file mode 100644 index 000000000..7e78bdc30 --- /dev/null +++ b/docs/talks/FormsTalk.html @@ -0,0 +1,421 @@ + + + + +Linked Data Forms + + + + + + + + + + + +
+
+ +
+slanted W3C logo +
+
+ + + + + + + + + + + + + +
+

Declarative User Interface: Forms and Apps in RDF

+ +

Tim BL, +<timbl@w3.org>
+
+
+
+
Hit the space bar or swipe left for next slide

+
+ +
+

Declarative User Interface: Forms and Apps in RDF

+ +
    +
  • Declarative design is good.
  • +
  • The Principle of Least Power
  • +
  • Compose apps and parts of apps out of components
  • +
  • High-level design allows multiple compatible implementations
  • +
  • In Solid, data is in Linked Data graphs
  • +
  • Why not use that for User Interface?
  • +
+
+ +
+

What would that look like?

+ +
+  # A simple group with two fields
+
+  ex:form a ui:Group;
+    ui:parts (ex:part1 ex:part2).
+
+        ex:part1 a ui:SingleLineTextField ;
+        ui:property vcard:fn;
+        ui:label "name" .
+
+        ex:part2 a ui:EmailField ;
+        ui:property vcard:hasEmail;
+        ui:label "email" .
+
+
+ + +
+

Components are form Fields or structures

+

Fields

+
    +
  • BooleanField +
  • +
  • TriStateField +
  • +
  • IntegerField +
  • +
  • DecimalField +
  • +
  • FloatField
  • + +
    + +
  • ColorField +
  • +
  • DateField +
  • +
  • DateTimeField +
  • +
  • PhoneField +
  • +
  • EmailField +
  • +
  • SingleLineTextField +
  • +
  • MultiLineTextField +
  • +
  • Autocomplete
  • +
+

Structures

+
    +
  • Group +
  • +
  • Choice +
  • +
  • Multiple +
  • +
  • Classifier +
  • +
  • Options +
  • +
+

Documentation components

+
    +
  • Heading +
  • +
  • Comment +
  • +
+ +

+ +
+

Single Line Text field

+

Form fields are set up to write linked data into Solid pods.

+

Each one adds (typically) a new edge to the data graph at run time

+

So We give the predicate which will be used in the instance of the field.

+
+# A simple form with one boolean field
+ex:form
+a ui:BooleanField ;
+ui:property ex:allDay .
+
+
+
+ + + + +
+

Common properties of form fields

+ + + + + + + + + + + + + + + + + + + + + + + + + +
labelString + A label for the form field, prompt for the user. +
propertyrdf:Property + Data it is stored in the web as a triple + with this property as its predicate. +
default[according to field type] Optional + The input control is set to this value by default. It is easiest for + the user to enter this value. (This value is not automatically + stored by the form system if the user does not select or enter it in + some way. +
suppressEmptyUneditableBoolean + When the user is just reading the data, not + editing it, the fields with blank data will be hidden. +
+ +
+ + +
+

The Autocomplete field

+

This form field allows users to select things from lists in public databases, things like Languages, Organizations, Occupations, and Skills

+

This is not covered in detail in this talk.

+

(There is a blog +Building Solid Apps which use Public Data, + about this which I could run though for those interested)

+ +
+ +
+

Code: Render a form

+

To put a form in your UI

+
const element = UI.widgets.appendForm(dom, null, {}, subject, form, doc, callback)
+  
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
domis the DOM HTMLDocument object, a/k/a document
nullused to be the is a DOM element to contain the form. If given, the form will be + appended to it. This use is deprecated.
{}are unused at present
subjectis the RDF thing about which data will be stored
formis the RDF object in the store for the form
doc + is the RDF document on the web where the data will be stored. Often, + subject.doc() +
callback + is a function taking an error flag and a message (if the error flag is + true). Called when the form field has been set to a new value. +
+ +
+ +
+

Going meta -- designing forms using the form of forms 1

+

Here is a form for editing a form

+

Users and developers should be able to design and adapt their forms

+ +
+ +

The Form Form

+
+

Going meta -- Editing forms using the form of forms 2

+

Here we are editing the really small form we started with.

+ +

Here we edit the FormForm with itself.

+ + +
+ + + + +
+

Forms and Classes

+
+export function formsFor (subject) {
+  const kb = store
+
+  log.debug('formsFor: subject=' + subject)
+  const t = kb.findTypeURIs(subject)
+  let t1
+  for (t1 in t) {
+    log.debug('   type: ' + t1)
+  }
+  const bottom = kb.bottomTypeURIs(t) // most specific
+  let candidates = []
+  for (const b in bottom) {
+    // Find the most specific
+    log.debug('candidatesFor: trying bottom type =' + b)
+    candidates = candidates.concat(
+      findClosest(kb, b, ns.ui('creationForm'))
+    )
+    candidates = candidates.concat(
+      findClosest(kb, b, ns.ui('annotationForm'))
+    )
+  }
+  return candidates
+}
+
+
+
+ +
+

The Form Pane

+

The Form Pane

+
+  icon: UI.icons.iconBase + 'noun_122196.svg',
+
+  name: 'form',
+
+  audience: [ns.solid('PowerUser')],
+
+  // Does the subject deserve this pane?
+  label: function (subject) {
+    const n = UI.widgets.formsFor(subject).length
+    UI.log.debug('Form pane: forms for ' + subject + ': ' + n)
+    if (!n) return null
+    return '' + n + ' forms'
+  },
+
+  render: function (subject, context) {
+  ...
+  }
+
+ +
+ + + + +
+

Future: A Form registry?

+
    A place to list forms for each class. (by Shape?) +
  • Global one could be say https://solidos.solidcommunity.net/reg/form
  • +
  • Users and Communities could have their own, linked from type index
  • +
  • Idea: Things like global registries are linked from a global community, The Public which is just like a user and controlled by Solid Project
  • +
+
+ + +
+

Future

+
    +
  • Implementations in other platforms - MechanicalUI etc, Native mobile...
  • +
  • Add new form features -- what can you think of? Things we have code for: +
      +
    • Matrix, Tables
    • +
    • Image gallery, collections
    • +
    • Drawers, sidebars
    • + +
    +
  • +
  • Allow entire App top be build from RDF-based declarative components + a la JeffZ +
      +
    • The App
    • +
    • Navigation
    • +
    • Menus
    • +
    • HTML templates
    • +
    • Style themes
    • +
    • etc.
    • +
    +
  • +
      Integrate with Ontologies +
    • Design/Edit Ontologies with forms
    • +
    • Browse and pick for existing ontologies when building a form
    • +
    +
+
+ + + + diff --git a/docs/workingWithSolidUI/solid-logic.min.js b/docs/workingWithSolidUI/solid-logic.min.js new file mode 100644 index 000000000..cbcf0a64a --- /dev/null +++ b/docs/workingWithSolidUI/solid-logic.min.js @@ -0,0 +1,32 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("$rdf")):"function"==typeof define&&define.amd?define("SolidLogic",["$rdf"],t):"object"==typeof exports?exports.SolidLogic=t(require("$rdf")):e.SolidLogic=t(e.$rdf)}(this,e=>(()=>{var t={7:e=>{"use strict";var t,r="object"==typeof Reflect?Reflect:null,n=r&&"function"==typeof r.apply?r.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};t=r&&"function"==typeof r.ownKeys?r.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var i=Number.isNaN||function(e){return e!=e};function o(){o.init.call(this)}e.exports=o,e.exports.once=function(e,t){return new Promise(function(r,n){function i(r){e.removeListener(t,o),n(r)}function o(){"function"==typeof e.removeListener&&e.removeListener("error",i),r([].slice.call(arguments))}g(e,t,o,{once:!0}),"error"!==t&&function(e,t,r){"function"==typeof e.on&&g(e,"error",t,r)}(e,i,{once:!0})})},o.EventEmitter=o,o.prototype._events=void 0,o.prototype._eventsCount=0,o.prototype._maxListeners=void 0;var s=10;function a(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function u(e){return void 0===e._maxListeners?o.defaultMaxListeners:e._maxListeners}function c(e,t,r,n){var i,o,s,c;if(a(r),void 0===(o=e._events)?(o=e._events=Object.create(null),e._eventsCount=0):(void 0!==o.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),o=e._events),s=o[t]),void 0===s)s=o[t]=r,++e._eventsCount;else if("function"==typeof s?s=o[t]=n?[r,s]:[s,r]:n?s.unshift(r):s.push(r),(i=u(e))>0&&s.length>i&&!s.warned){s.warned=!0;var h=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");h.name="MaxListenersExceededWarning",h.emitter=e,h.type=t,h.count=s.length,c=h,console&&console.warn&&console.warn(c)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function l(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},i=h.bind(n);return i.listener=r,n.wrapFn=i,i}function d(e,t,r){var n=e._events;if(void 0===n)return[];var i=n[t];return void 0===i?[]:"function"==typeof i?r?[i.listener||i]:[i]:r?function(e){for(var t=new Array(e.length),r=0;r0&&(s=t[0]),s instanceof Error)throw s;var a=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw a.context=s,a}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)n(u,this,t);else{var c=u.length,h=p(u,c);for(r=0;r=0;o--)if(r[o]===t||r[o].listener===t){s=r[o].listener,i=o;break}if(i<0)return this;0===i?r.shift():function(e,t){for(;t+1=0;n--)this.removeListener(e,t[n]);return this},o.prototype.listeners=function(e){return d(this,e,!0)},o.prototype.rawListeners=function(e){return d(this,e,!1)},o.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):f.call(e,t)},o.prototype.listenerCount=f,o.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},264:t=>{"use strict";t.exports=e},386:e=>{const t={acl:"http://www.w3.org/ns/auth/acl#",arg:"http://www.w3.org/ns/pim/arg#",as:"https://www.w3.org/ns/activitystreams#",bookmark:"http://www.w3.org/2002/01/bookmark#",cal:"http://www.w3.org/2002/12/cal/ical#",cco:"http://www.ontologyrepository.com/CommonCoreOntologies/",cert:"http://www.w3.org/ns/auth/cert#",contact:"http://www.w3.org/2000/10/swap/pim/contact#",dc:"http://purl.org/dc/elements/1.1/",dct:"http://purl.org/dc/terms/",doap:"http://usefulinc.com/ns/doap#",foaf:"http://xmlns.com/foaf/0.1/",geo:"http://www.w3.org/2003/01/geo/wgs84_pos#",gpx:"http://www.w3.org/ns/pim/gpx#",gr:"http://purl.org/goodrelations/v1#",http:"http://www.w3.org/2007/ont/http#",httph:"http://www.w3.org/2007/ont/httph#",icalTZ:"http://www.w3.org/2002/12/cal/icaltzd#",ldp:"http://www.w3.org/ns/ldp#",link:"http://www.w3.org/2007/ont/link#",log:"http://www.w3.org/2000/10/swap/log#",meeting:"http://www.w3.org/ns/pim/meeting#",mo:"http://purl.org/ontology/mo/",org:"http://www.w3.org/ns/org#",owl:"http://www.w3.org/2002/07/owl#",pad:"http://www.w3.org/ns/pim/pad#",patch:"http://www.w3.org/ns/pim/patch#",prov:"http://www.w3.org/ns/prov#",pto:"http://www.productontology.org/id/",qu:"http://www.w3.org/2000/10/swap/pim/qif#",trip:"http://www.w3.org/ns/pim/trip#",rdf:"http://www.w3.org/1999/02/22-rdf-syntax-ns#",rdfs:"http://www.w3.org/2000/01/rdf-schema#",rss:"http://purl.org/rss/1.0/",sched:"http://www.w3.org/ns/pim/schedule#",schema:"http://schema.org/",sioc:"http://rdfs.org/sioc/ns#",skos:"http://www.w3.org/2004/02/skos/core#",solid:"http://www.w3.org/ns/solid/terms#",space:"http://www.w3.org/ns/pim/space#",stat:"http://www.w3.org/ns/posix/stat#",tab:"http://www.w3.org/2007/ont/link#",tabont:"http://www.w3.org/2007/ont/link#",ui:"http://www.w3.org/ns/ui#",vann:"http://purl.org/vocab/vann/",vcard:"http://www.w3.org/2006/vcard/ns#",wf:"http://www.w3.org/2005/01/wf/flow#",xsd:"http://www.w3.org/2001/XMLSchema#"};e.exports=function(e={namedNode:e=>e}){const r={};for(const n in t){const i=t[n];r[n]=function(t=""){return e.namedNode(i+t)}}return r}},516:function(e){var t;t=function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=22)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r=4){for(var e=arguments.length,t=Array(e),r=0;r=3){for(var e=arguments.length,t=Array(e),r=0;r=2){for(var e=arguments.length,t=Array(e),r=0;r=1){for(var e=arguments.length,t=Array(e),r=0;r1&&void 0!==arguments[1]?arguments[1]:o.JsonService;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw i.Log.error("MetadataService: No settings passed to MetadataService"),new Error("settings");this._settings=t,this._jsonService=new r(["application/jwk-set+json"])}return e.prototype.resetSigningKeys=function(){this._settings=this._settings||{},this._settings.signingKeys=void 0},e.prototype.getMetadata=function(){var e=this;return this._settings.metadata?(i.Log.debug("MetadataService.getMetadata: Returning metadata from settings"),Promise.resolve(this._settings.metadata)):this.metadataUrl?(i.Log.debug("MetadataService.getMetadata: getting metadata from",this.metadataUrl),this._jsonService.getJson(this.metadataUrl).then(function(t){i.Log.debug("MetadataService.getMetadata: json received");var r=e._settings.metadataSeed||{};return e._settings.metadata=Object.assign({},r,t),e._settings.metadata})):(i.Log.error("MetadataService.getMetadata: No authority or metadataUrl configured on settings"),Promise.reject(new Error("No authority or metadataUrl configured on settings")))},e.prototype.getIssuer=function(){return this._getMetadataProperty("issuer")},e.prototype.getAuthorizationEndpoint=function(){return this._getMetadataProperty("authorization_endpoint")},e.prototype.getUserInfoEndpoint=function(){return this._getMetadataProperty("userinfo_endpoint")},e.prototype.getTokenEndpoint=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this._getMetadataProperty("token_endpoint",e)},e.prototype.getCheckSessionIframe=function(){return this._getMetadataProperty("check_session_iframe",!0)},e.prototype.getEndSessionEndpoint=function(){return this._getMetadataProperty("end_session_endpoint",!0)},e.prototype.getRevocationEndpoint=function(){return this._getMetadataProperty("revocation_endpoint",!0)},e.prototype.getKeysEndpoint=function(){return this._getMetadataProperty("jwks_uri",!0)},e.prototype._getMetadataProperty=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return i.Log.debug("MetadataService.getMetadataProperty for: "+e),this.getMetadata().then(function(r){if(i.Log.debug("MetadataService.getMetadataProperty: metadata recieved"),void 0===r[e]){if(!0===t)return void i.Log.warn("MetadataService.getMetadataProperty: Metadata does not contain optional property "+e);throw i.Log.error("MetadataService.getMetadataProperty: Metadata does not contain property "+e),new Error("Metadata does not contain property "+e)}return r[e]})},e.prototype.getSigningKeys=function(){var e=this;return this._settings.signingKeys?(i.Log.debug("MetadataService.getSigningKeys: Returning signingKeys from settings"),Promise.resolve(this._settings.signingKeys)):this._getMetadataProperty("jwks_uri").then(function(t){return i.Log.debug("MetadataService.getSigningKeys: jwks_uri received",t),e._jsonService.getJson(t).then(function(t){if(i.Log.debug("MetadataService.getSigningKeys: key set received",t),!t.keys)throw i.Log.error("MetadataService.getSigningKeys: Missing keys on keyset"),new Error("Missing keys on keyset");return e._settings.signingKeys=t.keys,e._settings.signingKeys})})},n(e,[{key:"metadataUrl",get:function(){return this._metadataUrl||(this._settings.metadataUrl?this._metadataUrl=this._settings.metadataUrl:(this._metadataUrl=this._settings.authority,this._metadataUrl&&this._metadataUrl.indexOf(s)<0&&("/"!==this._metadataUrl[this._metadataUrl.length-1]&&(this._metadataUrl+="/"),this._metadataUrl+=s))),this._metadataUrl}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.UrlUtility=void 0;var n=r(0),i=r(1);t.UrlUtility=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)}return e.addQueryParam=function(e,t,r){return e.indexOf("?")<0&&(e+="?"),"?"!==e[e.length-1]&&(e+="&"),e+=encodeURIComponent(t),(e+="=")+encodeURIComponent(r)},e.parseUrlFragment=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"#",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:i.Global;"string"!=typeof e&&(e=r.location.href);var o=e.lastIndexOf(t);o>=0&&(e=e.substr(o+1)),"?"===t&&(o=e.indexOf("#"))>=0&&(e=e.substr(0,o));for(var s,a={},u=/([^&=]+)=([^&]*)/g,c=0;s=u.exec(e);)if(a[decodeURIComponent(s[1])]=decodeURIComponent(s[2].replace(/\+/g," ")),c++>50)return n.Log.error("UrlUtility.parseUrlFragment: response exceeded expected number of parameters",e),{error:"Response exceeded expected number of parameters"};for(var h in a)return a;return{}},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.JoseUtil=void 0;var n=r(26),i=function(e){return e&&e.__esModule?e:{default:e}}(r(33));t.JoseUtil=(0,i.default)({jws:n.jws,KeyUtil:n.KeyUtil,X509:n.X509,crypto:n.crypto,hextob64u:n.hextob64u,b64tohex:n.b64tohex,AllowedSigningAlgs:n.AllowedSigningAlgs})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OidcClientSettings=void 0;var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},r=t.authority,i=t.metadataUrl,o=t.metadata,h=t.signingKeys,l=t.metadataSeed,d=t.client_id,f=t.client_secret,p=t.response_type,g=void 0===p?"id_token":p,y=t.scope,v=void 0===y?"openid":y,m=t.redirect_uri,w=t.post_logout_redirect_uri,_=t.client_authentication,S=void 0===_?"client_secret_post":_,b=t.prompt,E=t.display,F=t.max_age,x=t.ui_locales,A=t.acr_values,k=t.resource,P=t.response_mode,T=t.filterProtocolClaims,I=void 0===T||T,C=t.loadUserInfo,R=void 0===C||C,U=t.staleStateAge,L=void 0===U?900:U,D=t.clockSkew,N=void 0===D?300:D,O=t.clockService,H=void 0===O?new s.ClockService:O,j=t.userInfoJwtIssuer,M=void 0===j?"OP":j,B=t.mergeClaims,K=void 0!==B&&B,V=t.stateStore,q=void 0===V?new a.WebStorageStateStore:V,J=t.ResponseValidatorCtor,W=void 0===J?u.ResponseValidator:J,$=t.MetadataServiceCtor,z=void 0===$?c.MetadataService:$,Y=t.extraQueryParams,G=void 0===Y?{}:Y,X=t.extraTokenParams,Q=void 0===X?{}:X;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),this._authority=r,this._metadataUrl=i,this._metadata=o,this._metadataSeed=l,this._signingKeys=h,this._client_id=d,this._client_secret=f,this._response_type=g,this._scope=v,this._redirect_uri=m,this._post_logout_redirect_uri=w,this._client_authentication=S,this._prompt=b,this._display=E,this._max_age=F,this._ui_locales=x,this._acr_values=A,this._resource=k,this._response_mode=P,this._filterProtocolClaims=!!I,this._loadUserInfo=!!R,this._staleStateAge=L,this._clockSkew=N,this._clockService=H,this._userInfoJwtIssuer=M,this._mergeClaims=!!K,this._stateStore=q,this._validator=new W(this),this._metadataService=new z(this),this._extraQueryParams="object"===(void 0===G?"undefined":n(G))?G:{},this._extraTokenParams="object"===(void 0===Q?"undefined":n(Q))?Q:{}}return e.prototype.getEpochTime=function(){return this._clockService.getEpochTime()},i(e,[{key:"client_id",get:function(){return this._client_id},set:function(e){if(this._client_id)throw o.Log.error("OidcClientSettings.set_client_id: client_id has already been assigned."),new Error("client_id has already been assigned.");this._client_id=e}},{key:"client_secret",get:function(){return this._client_secret}},{key:"response_type",get:function(){return this._response_type}},{key:"scope",get:function(){return this._scope}},{key:"redirect_uri",get:function(){return this._redirect_uri}},{key:"post_logout_redirect_uri",get:function(){return this._post_logout_redirect_uri}},{key:"client_authentication",get:function(){return this._client_authentication}},{key:"prompt",get:function(){return this._prompt}},{key:"display",get:function(){return this._display}},{key:"max_age",get:function(){return this._max_age}},{key:"ui_locales",get:function(){return this._ui_locales}},{key:"acr_values",get:function(){return this._acr_values}},{key:"resource",get:function(){return this._resource}},{key:"response_mode",get:function(){return this._response_mode}},{key:"authority",get:function(){return this._authority},set:function(e){if(this._authority)throw o.Log.error("OidcClientSettings.set_authority: authority has already been assigned."),new Error("authority has already been assigned.");this._authority=e}},{key:"metadataUrl",get:function(){return this._metadataUrl||(this._metadataUrl=this.authority,this._metadataUrl&&this._metadataUrl.indexOf(h)<0&&("/"!==this._metadataUrl[this._metadataUrl.length-1]&&(this._metadataUrl+="/"),this._metadataUrl+=h)),this._metadataUrl}},{key:"metadata",get:function(){return this._metadata},set:function(e){this._metadata=e}},{key:"metadataSeed",get:function(){return this._metadataSeed},set:function(e){this._metadataSeed=e}},{key:"signingKeys",get:function(){return this._signingKeys},set:function(e){this._signingKeys=e}},{key:"filterProtocolClaims",get:function(){return this._filterProtocolClaims}},{key:"loadUserInfo",get:function(){return this._loadUserInfo}},{key:"staleStateAge",get:function(){return this._staleStateAge}},{key:"clockSkew",get:function(){return this._clockSkew}},{key:"userInfoJwtIssuer",get:function(){return this._userInfoJwtIssuer}},{key:"mergeClaims",get:function(){return this._mergeClaims}},{key:"stateStore",get:function(){return this._stateStore}},{key:"validator",get:function(){return this._validator}},{key:"metadataService",get:function(){return this._metadataService}},{key:"extraQueryParams",get:function(){return this._extraQueryParams},set:function(e){"object"===(void 0===e?"undefined":n(e))?this._extraQueryParams=e:this._extraQueryParams={}}},{key:"extraTokenParams",get:function(){return this._extraTokenParams},set:function(e){"object"===(void 0===e?"undefined":n(e))?this._extraTokenParams=e:this._extraTokenParams={}}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.WebStorageStateStore=void 0;var n=r(0),i=r(1);t.WebStorageStateStore=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t.prefix,n=void 0===r?"oidc.":r,o=t.store,s=void 0===o?i.Global.localStorage:o;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),this._store=s,this._prefix=n}return e.prototype.set=function(e,t){return n.Log.debug("WebStorageStateStore.set",e),e=this._prefix+e,this._store.setItem(e,t),Promise.resolve()},e.prototype.get=function(e){n.Log.debug("WebStorageStateStore.get",e),e=this._prefix+e;var t=this._store.getItem(e);return Promise.resolve(t)},e.prototype.remove=function(e){n.Log.debug("WebStorageStateStore.remove",e),e=this._prefix+e;var t=this._store.getItem(e);return this._store.removeItem(e),Promise.resolve(t)},e.prototype.getAllKeys=function(){n.Log.debug("WebStorageStateStore.getAllKeys");for(var e=[],t=0;t0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i.Global.XMLHttpRequest,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),t&&Array.isArray(t)?this._contentTypes=t.slice():this._contentTypes=[],this._contentTypes.push("application/json"),n&&this._contentTypes.push("application/jwt"),this._XMLHttpRequest=r,this._jwtHandler=n}return e.prototype.getJson=function(e,t){var r=this;if(!e)throw n.Log.error("JsonService.getJson: No url passed"),new Error("url");return n.Log.debug("JsonService.getJson, url: ",e),new Promise(function(i,o){var s=new r._XMLHttpRequest;s.open("GET",e);var a=r._contentTypes,u=r._jwtHandler;s.onload=function(){if(n.Log.debug("JsonService.getJson: HTTP response received, status",s.status),200===s.status){var t=s.getResponseHeader("Content-Type");if(t){var r=a.find(function(e){if(t.startsWith(e))return!0});if("application/jwt"==r)return void u(s).then(i,o);if(r)try{return void i(JSON.parse(s.responseText))}catch(e){return n.Log.error("JsonService.getJson: Error parsing JSON response",e.message),void o(e)}}o(Error("Invalid response Content-Type: "+t+", from URL: "+e))}else o(Error(s.statusText+" ("+s.status+")"))},s.onerror=function(){n.Log.error("JsonService.getJson: network error"),o(Error("Network Error"))},t&&(n.Log.debug("JsonService.getJson: token passed, setting Authorization header"),s.setRequestHeader("Authorization","Bearer "+t)),s.send()})},e.prototype.postForm=function(e,t,r){var i=this;if(!e)throw n.Log.error("JsonService.postForm: No url passed"),new Error("url");return n.Log.debug("JsonService.postForm, url: ",e),new Promise(function(o,s){var a=new i._XMLHttpRequest;a.open("POST",e);var u=i._contentTypes;a.onload=function(){if(n.Log.debug("JsonService.postForm: HTTP response received, status",a.status),200!==a.status){if(400===a.status&&(r=a.getResponseHeader("Content-Type"))&&u.find(function(e){if(r.startsWith(e))return!0}))try{var t=JSON.parse(a.responseText);if(t&&t.error)return n.Log.error("JsonService.postForm: Error from server: ",t.error),void s(new Error(t.error))}catch(e){return n.Log.error("JsonService.postForm: Error parsing JSON response",e.message),void s(e)}s(Error(a.statusText+" ("+a.status+")"))}else{var r;if((r=a.getResponseHeader("Content-Type"))&&u.find(function(e){if(r.startsWith(e))return!0}))try{return void o(JSON.parse(a.responseText))}catch(e){return n.Log.error("JsonService.postForm: Error parsing JSON response",e.message),void s(e)}s(Error("Invalid response Content-Type: "+r+", from URL: "+e))}},a.onerror=function(){n.Log.error("JsonService.postForm: network error"),s(Error("Network Error"))};var c="";for(var h in t){var l=t[h];l&&(c.length>0&&(c+="&"),c+=encodeURIComponent(h),c+="=",c+=encodeURIComponent(l))}a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),void 0!==r&&a.setRequestHeader("Authorization","Basic "+btoa(r)),a.send(c)})},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SigninRequest=void 0;var n=r(0),i=r(3),o=r(13);t.SigninRequest=function(){function e(t){var r=t.url,s=t.client_id,a=t.redirect_uri,u=t.response_type,c=t.scope,h=t.authority,l=t.data,d=t.prompt,f=t.display,p=t.max_age,g=t.ui_locales,y=t.id_token_hint,v=t.login_hint,m=t.acr_values,w=t.resource,_=t.response_mode,S=t.request,b=t.request_uri,E=t.extraQueryParams,F=t.request_type,x=t.client_secret,A=t.extraTokenParams,k=t.skipUserInfo;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!r)throw n.Log.error("SigninRequest.ctor: No url passed"),new Error("url");if(!s)throw n.Log.error("SigninRequest.ctor: No client_id passed"),new Error("client_id");if(!a)throw n.Log.error("SigninRequest.ctor: No redirect_uri passed"),new Error("redirect_uri");if(!u)throw n.Log.error("SigninRequest.ctor: No response_type passed"),new Error("response_type");if(!c)throw n.Log.error("SigninRequest.ctor: No scope passed"),new Error("scope");if(!h)throw n.Log.error("SigninRequest.ctor: No authority passed"),new Error("authority");var P=e.isOidc(u),T=e.isCode(u);_||(_=e.isCode(u)?"query":null),this.state=new o.SigninState({nonce:P,data:l,client_id:s,authority:h,redirect_uri:a,code_verifier:T,request_type:F,response_mode:_,client_secret:x,scope:c,extraTokenParams:A,skipUserInfo:k}),r=i.UrlUtility.addQueryParam(r,"client_id",s),r=i.UrlUtility.addQueryParam(r,"redirect_uri",a),r=i.UrlUtility.addQueryParam(r,"response_type",u),r=i.UrlUtility.addQueryParam(r,"scope",c),r=i.UrlUtility.addQueryParam(r,"state",this.state.id),P&&(r=i.UrlUtility.addQueryParam(r,"nonce",this.state.nonce)),T&&(r=i.UrlUtility.addQueryParam(r,"code_challenge",this.state.code_challenge),r=i.UrlUtility.addQueryParam(r,"code_challenge_method","S256"));var I={prompt:d,display:f,max_age:p,ui_locales:g,id_token_hint:y,login_hint:v,acr_values:m,resource:w,request:S,request_uri:b,response_mode:_};for(var C in I)I[C]&&(r=i.UrlUtility.addQueryParam(r,C,I[C]));for(var R in E)r=i.UrlUtility.addQueryParam(r,R,E[R]);this.url=r}return e.isOidc=function(e){return!!e.split(/\s+/g).filter(function(e){return"id_token"===e})[0]},e.isOAuth=function(e){return!!e.split(/\s+/g).filter(function(e){return"token"===e})[0]},e.isCode=function(e){return!!e.split(/\s+/g).filter(function(e){return"code"===e})[0]},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.State=void 0;var n=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},r=t.id,n=t.data,i=t.created,s=t.request_type;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),this._id=r||(0,o.default)(),this._data=n,this._created="number"==typeof i&&i>0?i:parseInt(Date.now()/1e3),this._request_type=s}return e.prototype.toStorageString=function(){return i.Log.debug("State.toStorageString"),JSON.stringify({id:this.id,data:this.data,created:this.created,request_type:this.request_type})},e.fromStorageString=function(t){return i.Log.debug("State.fromStorageString"),new e(JSON.parse(t))},e.clearStaleState=function(t,r){var n=Date.now()/1e3-r;return t.getAllKeys().then(function(r){i.Log.debug("State.clearStaleState: got keys",r);for(var o=[],s=function(s){var a=r[s];u=t.get(a).then(function(r){var o=!1;if(r)try{var s=e.fromStorageString(r);i.Log.debug("State.clearStaleState: got item from key: ",a,s.created),s.created<=n&&(o=!0)}catch(e){i.Log.error("State.clearStaleState: Error parsing state for key",a,e.message),o=!0}else i.Log.debug("State.clearStaleState: no item in storage for key: ",a),o=!0;if(o)return i.Log.debug("State.clearStaleState: removed item for key: ",a),t.remove(a)}),o.push(u)},a=0;a0&&void 0!==arguments[0]?arguments[0]:{};(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),t instanceof o.OidcClientSettings?this._settings=t:this._settings=new o.OidcClientSettings(t)}return e.prototype.createSigninRequest=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t.response_type,n=t.scope,o=t.redirect_uri,s=t.data,u=t.state,c=t.prompt,h=t.display,l=t.max_age,d=t.ui_locales,f=t.id_token_hint,p=t.login_hint,g=t.acr_values,y=t.resource,v=t.request,m=t.request_uri,w=t.response_mode,_=t.extraQueryParams,S=t.extraTokenParams,b=t.request_type,E=t.skipUserInfo,F=arguments[1];i.Log.debug("OidcClient.createSigninRequest");var x=this._settings.client_id;r=r||this._settings.response_type,n=n||this._settings.scope,o=o||this._settings.redirect_uri,c=c||this._settings.prompt,h=h||this._settings.display,l=l||this._settings.max_age,d=d||this._settings.ui_locales,g=g||this._settings.acr_values,y=y||this._settings.resource,w=w||this._settings.response_mode,_=_||this._settings.extraQueryParams,S=S||this._settings.extraTokenParams;var A=this._settings.authority;return a.SigninRequest.isCode(r)&&"code"!==r?Promise.reject(new Error("OpenID Connect hybrid flow is not supported")):this._metadataService.getAuthorizationEndpoint().then(function(t){i.Log.debug("OidcClient.createSigninRequest: Received authorization endpoint",t);var k=new a.SigninRequest({url:t,client_id:x,redirect_uri:o,response_type:r,scope:n,data:s||u,authority:A,prompt:c,display:h,max_age:l,ui_locales:d,id_token_hint:f,login_hint:p,acr_values:g,resource:y,request:v,request_uri:m,extraQueryParams:_,extraTokenParams:S,request_type:b,response_mode:w,client_secret:e._settings.client_secret,skipUserInfo:E}),P=k.state;return(F=F||e._stateStore).set(P.id,P.toStorageString()).then(function(){return k})})},e.prototype.readSigninResponseState=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];i.Log.debug("OidcClient.readSigninResponseState");var n="query"===this._settings.response_mode||!this._settings.response_mode&&a.SigninRequest.isCode(this._settings.response_type)?"?":"#",o=new u.SigninResponse(e,n);return o.state?(t=t||this._stateStore,(r?t.remove.bind(t):t.get.bind(t))(o.state).then(function(e){if(!e)throw i.Log.error("OidcClient.readSigninResponseState: No matching state found in storage"),new Error("No matching state found in storage");return{state:l.SigninState.fromStorageString(e),response:o}})):(i.Log.error("OidcClient.readSigninResponseState: No state in response"),Promise.reject(new Error("No state in response")))},e.prototype.processSigninResponse=function(e,t){var r=this;return i.Log.debug("OidcClient.processSigninResponse"),this.readSigninResponseState(e,t,!0).then(function(e){var t=e.state,n=e.response;return i.Log.debug("OidcClient.processSigninResponse: Received state from storage; validating response"),r._validator.validateSigninResponse(t,n)})},e.prototype.createSignoutRequest=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t.id_token_hint,n=t.data,o=t.state,s=t.post_logout_redirect_uri,a=t.extraQueryParams,u=t.request_type,h=arguments[1];return i.Log.debug("OidcClient.createSignoutRequest"),s=s||this._settings.post_logout_redirect_uri,a=a||this._settings.extraQueryParams,this._metadataService.getEndSessionEndpoint().then(function(t){if(!t)throw i.Log.error("OidcClient.createSignoutRequest: No end session endpoint url returned"),new Error("no end session endpoint");i.Log.debug("OidcClient.createSignoutRequest: Received end session endpoint",t);var l=new c.SignoutRequest({url:t,id_token_hint:r,post_logout_redirect_uri:s,data:n||o,extraQueryParams:a,request_type:u}),d=l.state;return d&&(i.Log.debug("OidcClient.createSignoutRequest: Signout request has state to persist"),(h=h||e._stateStore).set(d.id,d.toStorageString())),l})},e.prototype.readSignoutResponseState=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];i.Log.debug("OidcClient.readSignoutResponseState");var n=new h.SignoutResponse(e);if(!n.state)return i.Log.debug("OidcClient.readSignoutResponseState: No state in response"),n.error?(i.Log.warn("OidcClient.readSignoutResponseState: Response was error: ",n.error),Promise.reject(new s.ErrorResponse(n))):Promise.resolve({state:void 0,response:n});var o=n.state;return t=t||this._stateStore,(r?t.remove.bind(t):t.get.bind(t))(o).then(function(e){if(!e)throw i.Log.error("OidcClient.readSignoutResponseState: No matching state found in storage"),new Error("No matching state found in storage");return{state:d.State.fromStorageString(e),response:n}})},e.prototype.processSignoutResponse=function(e,t){var r=this;return i.Log.debug("OidcClient.processSignoutResponse"),this.readSignoutResponseState(e,t,!0).then(function(e){var t=e.state,n=e.response;return t?(i.Log.debug("OidcClient.processSignoutResponse: Received state from storage; validating response"),r._validator.validateSignoutResponse(t,n)):(i.Log.debug("OidcClient.processSignoutResponse: No state from storage; skipping validating response"),n)})},e.prototype.clearStaleState=function(e){return i.Log.debug("OidcClient.clearStaleState"),e=e||this._stateStore,d.State.clearStaleState(e,this.settings.staleStateAge)},n(e,[{key:"_stateStore",get:function(){return this.settings.stateStore}},{key:"_validator",get:function(){return this.settings.validator}},{key:"_metadataService",get:function(){return this.settings.metadataService}},{key:"settings",get:function(){return this._settings}},{key:"metadataService",get:function(){return this._metadataService}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TokenClient=void 0;var n=r(7),i=r(2),o=r(0);t.TokenClient=function(){function e(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.JsonService,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:i.MetadataService;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw o.Log.error("TokenClient.ctor: No settings passed"),new Error("settings");this._settings=t,this._jsonService=new r,this._metadataService=new s(this._settings)}return e.prototype.exchangeCode=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(t=Object.assign({},t)).grant_type=t.grant_type||"authorization_code",t.client_id=t.client_id||this._settings.client_id,t.client_secret=t.client_secret||this._settings.client_secret,t.redirect_uri=t.redirect_uri||this._settings.redirect_uri;var r=void 0,n=t._client_authentication||this._settings._client_authentication;return delete t._client_authentication,t.code?t.redirect_uri?t.code_verifier?t.client_id?t.client_secret||"client_secret_basic"!=n?("client_secret_basic"==n&&(r=t.client_id+":"+t.client_secret,delete t.client_id,delete t.client_secret),this._metadataService.getTokenEndpoint(!1).then(function(n){return o.Log.debug("TokenClient.exchangeCode: Received token endpoint"),e._jsonService.postForm(n,t,r).then(function(e){return o.Log.debug("TokenClient.exchangeCode: response received"),e})})):(o.Log.error("TokenClient.exchangeCode: No client_secret passed"),Promise.reject(new Error("A client_secret is required"))):(o.Log.error("TokenClient.exchangeCode: No client_id passed"),Promise.reject(new Error("A client_id is required"))):(o.Log.error("TokenClient.exchangeCode: No code_verifier passed"),Promise.reject(new Error("A code_verifier is required"))):(o.Log.error("TokenClient.exchangeCode: No redirect_uri passed"),Promise.reject(new Error("A redirect_uri is required"))):(o.Log.error("TokenClient.exchangeCode: No code passed"),Promise.reject(new Error("A code is required")))},e.prototype.exchangeRefreshToken=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(t=Object.assign({},t)).grant_type=t.grant_type||"refresh_token",t.client_id=t.client_id||this._settings.client_id,t.client_secret=t.client_secret||this._settings.client_secret;var r=void 0,n=t._client_authentication||this._settings._client_authentication;return delete t._client_authentication,t.refresh_token?t.client_id?("client_secret_basic"==n&&(r=t.client_id+":"+t.client_secret,delete t.client_id,delete t.client_secret),this._metadataService.getTokenEndpoint(!1).then(function(n){return o.Log.debug("TokenClient.exchangeRefreshToken: Received token endpoint"),e._jsonService.postForm(n,t,r).then(function(e){return o.Log.debug("TokenClient.exchangeRefreshToken: response received"),e})})):(o.Log.error("TokenClient.exchangeRefreshToken: No client_id passed"),Promise.reject(new Error("A client_id is required"))):(o.Log.error("TokenClient.exchangeRefreshToken: No refresh_token passed"),Promise.reject(new Error("A refresh_token is required")))},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ErrorResponse=void 0;var n=r(0);t.ErrorResponse=function(e){function t(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=r.error,o=r.error_description,s=r.error_uri,a=r.state,u=r.session_state;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),!i)throw n.Log.error("No error passed to ErrorResponse"),new Error("error");var c=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this,o||i));return c.name="ErrorResponse",c.error=i,c.error_description=o,c.error_uri=s,c.state=a,c.session_state=u,c}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(Error)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SigninState=void 0;var n=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},n=r.nonce,i=r.authority,o=r.client_id,u=r.redirect_uri,c=r.code_verifier,h=r.response_mode,l=r.client_secret,d=r.scope,f=r.extraTokenParams,p=r.skipUserInfo;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var g=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this,arguments[0]));if(!0===n?g._nonce=(0,a.default)():n&&(g._nonce=n),!0===c?g._code_verifier=(0,a.default)()+(0,a.default)()+(0,a.default)():c&&(g._code_verifier=c),g.code_verifier){var y=s.JoseUtil.hashString(g.code_verifier,"SHA256");g._code_challenge=s.JoseUtil.hexToBase64Url(y)}return g._redirect_uri=u,g._authority=i,g._client_id=o,g._response_mode=h,g._client_secret=l,g._scope=d,g._extraTokenParams=f,g._skipUserInfo=p,g}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.toStorageString=function(){return i.Log.debug("SigninState.toStorageString"),JSON.stringify({id:this.id,data:this.data,created:this.created,request_type:this.request_type,nonce:this.nonce,code_verifier:this.code_verifier,redirect_uri:this.redirect_uri,authority:this.authority,client_id:this.client_id,response_mode:this.response_mode,client_secret:this.client_secret,scope:this.scope,extraTokenParams:this.extraTokenParams,skipUserInfo:this.skipUserInfo})},t.fromStorageString=function(e){return i.Log.debug("SigninState.fromStorageString"),new t(JSON.parse(e))},n(t,[{key:"nonce",get:function(){return this._nonce}},{key:"authority",get:function(){return this._authority}},{key:"client_id",get:function(){return this._client_id}},{key:"redirect_uri",get:function(){return this._redirect_uri}},{key:"code_verifier",get:function(){return this._code_verifier}},{key:"code_challenge",get:function(){return this._code_challenge}},{key:"response_mode",get:function(){return this._response_mode}},{key:"client_secret",get:function(){return this._client_secret}},{key:"scope",get:function(){return this._scope}},{key:"extraTokenParams",get:function(){return this._extraTokenParams}},{key:"skipUserInfo",get:function(){return this._skipUserInfo}}]),t}(o.State)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){return("undefined"!=n&&null!==n&&void 0!==n.getRandomValues?i:o)().replace(/-/g,"")};var n="undefined"!=typeof window?window.crypto||window.msCrypto:null;function i(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^n.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})}function o(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^16*Math.random()>>e/4).toString(16)})}e.exports=t.default},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.User=void 0;var n=function(){function e(e,t){for(var r=0;r0){var r=parseInt(Date.now()/1e3);this.expires_at=r+t}}},{key:"expired",get:function(){var e=this.expires_in;if(void 0!==e)return e<=0}},{key:"scopes",get:function(){return(this.scope||"").split(" ")}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AccessTokenEvents=void 0;var n=r(0),i=r(46);t.AccessTokenEvents=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t.accessTokenExpiringNotificationTime,n=void 0===r?60:r,o=t.accessTokenExpiringTimer,s=void 0===o?new i.Timer("Access token expiring"):o,a=t.accessTokenExpiredTimer,u=void 0===a?new i.Timer("Access token expired"):a;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),this._accessTokenExpiringNotificationTime=n,this._accessTokenExpiring=s,this._accessTokenExpired=u}return e.prototype.load=function(e){if(e.access_token&&void 0!==e.expires_in){var t=e.expires_in;if(n.Log.debug("AccessTokenEvents.load: access token present, remaining duration:",t),t>0){var r=t-this._accessTokenExpiringNotificationTime;r<=0&&(r=1),n.Log.debug("AccessTokenEvents.load: registering expiring timer in:",r),this._accessTokenExpiring.init(r)}else n.Log.debug("AccessTokenEvents.load: canceling existing expiring timer becase we're past expiration."),this._accessTokenExpiring.cancel();var i=t+1;n.Log.debug("AccessTokenEvents.load: registering expired timer in:",i),this._accessTokenExpired.init(i)}else this._accessTokenExpiring.cancel(),this._accessTokenExpired.cancel()},e.prototype.unload=function(){n.Log.debug("AccessTokenEvents.unload: canceling existing access token timers"),this._accessTokenExpiring.cancel(),this._accessTokenExpired.cancel()},e.prototype.addAccessTokenExpiring=function(e){this._accessTokenExpiring.addHandler(e)},e.prototype.removeAccessTokenExpiring=function(e){this._accessTokenExpiring.removeHandler(e)},e.prototype.addAccessTokenExpired=function(e){this._accessTokenExpired.addHandler(e)},e.prototype.removeAccessTokenExpired=function(e){this._accessTokenExpired.removeHandler(e)},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Event=void 0;var n=r(0);t.Event=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._name=t,this._callbacks=[]}return e.prototype.addHandler=function(e){this._callbacks.push(e)},e.prototype.removeHandler=function(e){var t=this._callbacks.findIndex(function(t){return t===e});t>=0&&this._callbacks.splice(t,1)},e.prototype.raise=function(){n.Log.debug("Event: Raising event: "+this._name);for(var e=0;e1&&void 0!==arguments[1]?arguments[1]:o.CheckSessionIFrame,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:s.Global.timer;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw i.Log.error("SessionMonitor.ctor: No user manager passed to SessionMonitor"),new Error("userManager");this._userManager=t,this._CheckSessionIFrameCtor=n,this._timer=a,this._userManager.events.addUserLoaded(this._start.bind(this)),this._userManager.events.addUserUnloaded(this._stop.bind(this)),Promise.resolve(this._userManager.getUser().then(function(e){e?r._start(e):r._settings.monitorAnonymousSession&&r._userManager.querySessionStatus().then(function(e){var t={session_state:e.session_state};e.sub&&e.sid&&(t.profile={sub:e.sub,sid:e.sid}),r._start(t)}).catch(function(e){i.Log.error("SessionMonitor ctor: error from querySessionStatus:",e.message)})}).catch(function(e){i.Log.error("SessionMonitor ctor: error from getUser:",e.message)}))}return e.prototype._start=function(e){var t=this,r=e.session_state;r&&(e.profile?(this._sub=e.profile.sub,this._sid=e.profile.sid,i.Log.debug("SessionMonitor._start: session_state:",r,", sub:",this._sub)):(this._sub=void 0,this._sid=void 0,i.Log.debug("SessionMonitor._start: session_state:",r,", anonymous user")),this._checkSessionIFrame?this._checkSessionIFrame.start(r):this._metadataService.getCheckSessionIframe().then(function(e){if(e){i.Log.debug("SessionMonitor._start: Initializing check session iframe");var n=t._client_id,o=t._checkSessionInterval,s=t._stopCheckSessionOnError;t._checkSessionIFrame=new t._CheckSessionIFrameCtor(t._callback.bind(t),n,e,o,s),t._checkSessionIFrame.load().then(function(){t._checkSessionIFrame.start(r)})}else i.Log.warn("SessionMonitor._start: No check session iframe found in the metadata")}).catch(function(e){i.Log.error("SessionMonitor._start: Error from getCheckSessionIframe:",e.message)}))},e.prototype._stop=function(){var e=this;if(this._sub=void 0,this._sid=void 0,this._checkSessionIFrame&&(i.Log.debug("SessionMonitor._stop"),this._checkSessionIFrame.stop()),this._settings.monitorAnonymousSession)var t=this._timer.setInterval(function(){e._timer.clearInterval(t),e._userManager.querySessionStatus().then(function(t){var r={session_state:t.session_state};t.sub&&t.sid&&(r.profile={sub:t.sub,sid:t.sid}),e._start(r)}).catch(function(e){i.Log.error("SessionMonitor: error from querySessionStatus:",e.message)})},1e3)},e.prototype._callback=function(){var e=this;this._userManager.querySessionStatus().then(function(t){var r=!0;t?t.sub===e._sub?(r=!1,e._checkSessionIFrame.start(t.session_state),t.sid===e._sid?i.Log.debug("SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:",t.session_state):(i.Log.debug("SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:",t.session_state),e._userManager.events._raiseUserSessionChanged())):i.Log.debug("SessionMonitor._callback: Different subject signed into OP:",t.sub):i.Log.debug("SessionMonitor._callback: Subject no longer signed into OP"),r&&(e._sub?(i.Log.debug("SessionMonitor._callback: SessionMonitor._callback; raising signed out event"),e._userManager.events._raiseUserSignedOut()):(i.Log.debug("SessionMonitor._callback: SessionMonitor._callback; raising signed in event"),e._userManager.events._raiseUserSignedIn()))}).catch(function(t){e._sub&&(i.Log.debug("SessionMonitor._callback: Error calling queryCurrentSigninSession; raising signed out event",t.message),e._userManager.events._raiseUserSignedOut())})},n(e,[{key:"_settings",get:function(){return this._userManager.settings}},{key:"_metadataService",get:function(){return this._userManager.metadataService}},{key:"_client_id",get:function(){return this._settings.client_id}},{key:"_checkSessionInterval",get:function(){return this._settings.checkSessionInterval}},{key:"_stopCheckSessionOnError",get:function(){return this._settings.stopCheckSessionOnError}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CheckSessionIFrame=void 0;var n=r(0);t.CheckSessionIFrame=function(){function e(t,r,n,i){var o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,e),this._callback=t,this._client_id=r,this._url=n,this._interval=i||2e3,this._stopOnError=o;var s=n.indexOf("/",n.indexOf("//")+2);this._frame_origin=n.substr(0,s),this._frame=window.document.createElement("iframe"),this._frame.style.visibility="hidden",this._frame.style.position="absolute",this._frame.style.display="none",this._frame.width=0,this._frame.height=0,this._frame.src=n}return e.prototype.load=function(){var e=this;return new Promise(function(t){e._frame.onload=function(){t()},window.document.body.appendChild(e._frame),e._boundMessageEvent=e._message.bind(e),window.addEventListener("message",e._boundMessageEvent,!1)})},e.prototype._message=function(e){e.origin===this._frame_origin&&e.source===this._frame.contentWindow&&("error"===e.data?(n.Log.error("CheckSessionIFrame: error message from check session op iframe"),this._stopOnError&&this.stop()):"changed"===e.data?(n.Log.debug("CheckSessionIFrame: changed message from check session op iframe"),this.stop(),this._callback()):n.Log.debug("CheckSessionIFrame: "+e.data+" message from check session op iframe"))},e.prototype.start=function(e){var t=this;if(this._session_state!==e){n.Log.debug("CheckSessionIFrame.start"),this.stop(),this._session_state=e;var r=function(){t._frame.contentWindow.postMessage(t._client_id+" "+t._session_state,t._frame_origin)};r(),this._timer=window.setInterval(r,this._interval)}},e.prototype.stop=function(){this._session_state=null,this._timer&&(n.Log.debug("CheckSessionIFrame.stop"),window.clearInterval(this._timer),this._timer=null)},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TokenRevocationClient=void 0;var n=r(0),i=r(2),o=r(1);t.TokenRevocationClient=function(){function e(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o.Global.XMLHttpRequest,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:i.MetadataService;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw n.Log.error("TokenRevocationClient.ctor: No settings provided"),new Error("No settings provided.");this._settings=t,this._XMLHttpRequestCtor=r,this._metadataService=new s(this._settings)}return e.prototype.revoke=function(e,t){var r=this,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"access_token";if(!e)throw n.Log.error("TokenRevocationClient.revoke: No token provided"),new Error("No token provided.");if("access_token"!==i&&"refresh_token"!=i)throw n.Log.error("TokenRevocationClient.revoke: Invalid token type"),new Error("Invalid token type.");return this._metadataService.getRevocationEndpoint().then(function(o){if(o){n.Log.debug("TokenRevocationClient.revoke: Revoking "+i);var s=r._settings.client_id,a=r._settings.client_secret;return r._revoke(o,s,a,e,i)}if(t)throw n.Log.error("TokenRevocationClient.revoke: Revocation not supported"),new Error("Revocation not supported")})},e.prototype._revoke=function(e,t,r,i,o){var s=this;return new Promise(function(a,u){var c=new s._XMLHttpRequestCtor;c.open("POST",e),c.onload=function(){n.Log.debug("TokenRevocationClient.revoke: HTTP response received, status",c.status),200===c.status?a():u(Error(c.statusText+" ("+c.status+")"))},c.onerror=function(){n.Log.debug("TokenRevocationClient.revoke: Network Error."),u("Network Error")};var h="client_id="+encodeURIComponent(t);r&&(h+="&client_secret="+encodeURIComponent(r)),h+="&token_type_hint="+encodeURIComponent(o),h+="&token="+encodeURIComponent(i),c.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),c.send(h)})},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CordovaPopupWindow=void 0;var n=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:o.MetadataService,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:s.UserInfoService,u=arguments.length>3&&void 0!==arguments[3]?arguments[3]:c.JoseUtil,h=arguments.length>4&&void 0!==arguments[4]?arguments[4]:a.TokenClient;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw i.Log.error("ResponseValidator.ctor: No settings passed to ResponseValidator"),new Error("settings");this._settings=t,this._metadataService=new r(this._settings),this._userInfoService=new n(this._settings),this._joseUtil=u,this._tokenClient=new h(this._settings)}return e.prototype.validateSigninResponse=function(e,t){var r=this;return i.Log.debug("ResponseValidator.validateSigninResponse"),this._processSigninParams(e,t).then(function(t){return i.Log.debug("ResponseValidator.validateSigninResponse: state processed"),r._validateTokens(e,t).then(function(t){return i.Log.debug("ResponseValidator.validateSigninResponse: tokens validated"),r._processClaims(e,t).then(function(e){return i.Log.debug("ResponseValidator.validateSigninResponse: claims processed"),e})})})},e.prototype.validateSignoutResponse=function(e,t){return e.id!==t.state?(i.Log.error("ResponseValidator.validateSignoutResponse: State does not match"),Promise.reject(new Error("State does not match"))):(i.Log.debug("ResponseValidator.validateSignoutResponse: state validated"),t.state=e.data,t.error?(i.Log.warn("ResponseValidator.validateSignoutResponse: Response was error",t.error),Promise.reject(new u.ErrorResponse(t))):Promise.resolve(t))},e.prototype._processSigninParams=function(e,t){if(e.id!==t.state)return i.Log.error("ResponseValidator._processSigninParams: State does not match"),Promise.reject(new Error("State does not match"));if(!e.client_id)return i.Log.error("ResponseValidator._processSigninParams: No client_id on state"),Promise.reject(new Error("No client_id on state"));if(!e.authority)return i.Log.error("ResponseValidator._processSigninParams: No authority on state"),Promise.reject(new Error("No authority on state"));if(this._settings.authority){if(this._settings.authority&&this._settings.authority!==e.authority)return i.Log.error("ResponseValidator._processSigninParams: authority mismatch on settings vs. signin state"),Promise.reject(new Error("authority mismatch on settings vs. signin state"))}else this._settings.authority=e.authority;if(this._settings.client_id){if(this._settings.client_id&&this._settings.client_id!==e.client_id)return i.Log.error("ResponseValidator._processSigninParams: client_id mismatch on settings vs. signin state"),Promise.reject(new Error("client_id mismatch on settings vs. signin state"))}else this._settings.client_id=e.client_id;return i.Log.debug("ResponseValidator._processSigninParams: state validated"),t.state=e.data,t.error?(i.Log.warn("ResponseValidator._processSigninParams: Response was error",t.error),Promise.reject(new u.ErrorResponse(t))):e.nonce&&!t.id_token?(i.Log.error("ResponseValidator._processSigninParams: Expecting id_token in response"),Promise.reject(new Error("No id_token in response"))):!e.nonce&&t.id_token?(i.Log.error("ResponseValidator._processSigninParams: Not expecting id_token in response"),Promise.reject(new Error("Unexpected id_token in response"))):e.code_verifier&&!t.code?(i.Log.error("ResponseValidator._processSigninParams: Expecting code in response"),Promise.reject(new Error("No code in response"))):!e.code_verifier&&t.code?(i.Log.error("ResponseValidator._processSigninParams: Not expecting code in response"),Promise.reject(new Error("Unexpected code in response"))):(t.scope||(t.scope=e.scope),Promise.resolve(t))},e.prototype._processClaims=function(e,t){var r=this;if(t.isOpenIdConnect){if(i.Log.debug("ResponseValidator._processClaims: response is OIDC, processing claims"),t.profile=this._filterProtocolClaims(t.profile),!0!==e.skipUserInfo&&this._settings.loadUserInfo&&t.access_token)return i.Log.debug("ResponseValidator._processClaims: loading user info"),this._userInfoService.getClaims(t.access_token).then(function(e){return i.Log.debug("ResponseValidator._processClaims: user info claims received from user info endpoint"),e.sub!==t.profile.sub?(i.Log.error("ResponseValidator._processClaims: sub from user info endpoint does not match sub in id_token"),Promise.reject(new Error("sub from user info endpoint does not match sub in id_token"))):(t.profile=r._mergeClaims(t.profile,e),i.Log.debug("ResponseValidator._processClaims: user info claims received, updated profile:",t.profile),t)});i.Log.debug("ResponseValidator._processClaims: not loading user info")}else i.Log.debug("ResponseValidator._processClaims: response is not OIDC, not processing claims");return Promise.resolve(t)},e.prototype._mergeClaims=function(e,t){var r=Object.assign({},e);for(var i in t){var o=t[i];Array.isArray(o)||(o=[o]);for(var s=0;s1)return i.Log.error("ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata"),Promise.reject(new Error("No kid found in id_token and more than one key found in metadata"));o=r[0]}return Promise.resolve(o)})},e.prototype._getSigningKeyForJwtWithSingleRetry=function(e){var t=this;return this._getSigningKeyForJwt(e).then(function(r){return r?Promise.resolve(r):(t._metadataService.resetSigningKeys(),t._getSigningKeyForJwt(e))})},e.prototype._validateIdToken=function(e,t){var r=this;if(!e.nonce)return i.Log.error("ResponseValidator._validateIdToken: No nonce on state"),Promise.reject(new Error("No nonce on state"));var n=this._joseUtil.parseJwt(t.id_token);return n&&n.header&&n.payload?e.nonce!==n.payload.nonce?(i.Log.error("ResponseValidator._validateIdToken: Invalid nonce in id_token"),Promise.reject(new Error("Invalid nonce in id_token"))):this._metadataService.getIssuer().then(function(o){return i.Log.debug("ResponseValidator._validateIdToken: Received issuer"),r._getSigningKeyForJwtWithSingleRetry(n).then(function(s){if(!s)return i.Log.error("ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys"),Promise.reject(new Error("No key matching kid or alg found in signing keys"));var a=e.client_id,u=r._settings.clockSkew;return i.Log.debug("ResponseValidator._validateIdToken: Validaing JWT; using clock skew (in seconds) of: ",u),r._joseUtil.validateJwt(t.id_token,s,o,a,u).then(function(){return i.Log.debug("ResponseValidator._validateIdToken: JWT validation successful"),n.payload.sub?(t.profile=n.payload,t):(i.Log.error("ResponseValidator._validateIdToken: No sub present in id_token"),Promise.reject(new Error("No sub present in id_token")))})})}):(i.Log.error("ResponseValidator._validateIdToken: Failed to parse id_token",n),Promise.reject(new Error("Failed to parse id_token")))},e.prototype._filterByAlg=function(e,t){var r=null;if(t.startsWith("RS"))r="RSA";else if(t.startsWith("PS"))r="PS";else{if(!t.startsWith("ES"))return i.Log.debug("ResponseValidator._filterByAlg: alg not supported: ",t),[];r="EC"}return i.Log.debug("ResponseValidator._filterByAlg: Looking for keys that match kty: ",r),e=e.filter(function(e){return e.kty===r}),i.Log.debug("ResponseValidator._filterByAlg: Number of keys that match kty: ",r,e.length),e},e.prototype._validateAccessToken=function(e){if(!e.profile)return i.Log.error("ResponseValidator._validateAccessToken: No profile loaded from id_token"),Promise.reject(new Error("No profile loaded from id_token"));if(!e.profile.at_hash)return i.Log.error("ResponseValidator._validateAccessToken: No at_hash in id_token"),Promise.reject(new Error("No at_hash in id_token"));if(!e.id_token)return i.Log.error("ResponseValidator._validateAccessToken: No id_token"),Promise.reject(new Error("No id_token"));var t=this._joseUtil.parseJwt(e.id_token);if(!t||!t.header)return i.Log.error("ResponseValidator._validateAccessToken: Failed to parse id_token",t),Promise.reject(new Error("Failed to parse id_token"));var r=t.header.alg;if(!r||5!==r.length)return i.Log.error("ResponseValidator._validateAccessToken: Unsupported alg:",r),Promise.reject(new Error("Unsupported alg: "+r));var n=r.substr(2,3);if(!n)return i.Log.error("ResponseValidator._validateAccessToken: Unsupported alg:",r,n),Promise.reject(new Error("Unsupported alg: "+r));if(256!==(n=parseInt(n))&&384!==n&&512!==n)return i.Log.error("ResponseValidator._validateAccessToken: Unsupported alg:",r,n),Promise.reject(new Error("Unsupported alg: "+r));var o="sha"+n,s=this._joseUtil.hashString(e.access_token,o);if(!s)return i.Log.error("ResponseValidator._validateAccessToken: access_token hash failed:",o),Promise.reject(new Error("Failed to validate at_hash"));var a=s.substr(0,s.length/2),u=this._joseUtil.hexToBase64Url(a);return u!==e.profile.at_hash?(i.Log.error("ResponseValidator._validateAccessToken: Failed to validate at_hash",u,e.profile.at_hash),Promise.reject(new Error("Failed to validate at_hash"))):(i.Log.debug("ResponseValidator._validateAccessToken: success"),Promise.resolve(e))},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.UserInfoService=void 0;var n=r(7),i=r(2),o=r(0),s=r(4);t.UserInfoService=function(){function e(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.JsonService,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:i.MetadataService,u=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s.JoseUtil;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!t)throw o.Log.error("UserInfoService.ctor: No settings passed"),new Error("settings");this._settings=t,this._jsonService=new r(void 0,void 0,this._getClaimsFromJwt.bind(this)),this._metadataService=new a(this._settings),this._joseUtil=u}return e.prototype.getClaims=function(e){var t=this;return e?this._metadataService.getUserInfoEndpoint().then(function(r){return o.Log.debug("UserInfoService.getClaims: received userinfo url",r),t._jsonService.getJson(r,e).then(function(e){return o.Log.debug("UserInfoService.getClaims: claims received",e),e})}):(o.Log.error("UserInfoService.getClaims: No token passed"),Promise.reject(new Error("A token is required")))},e.prototype._getClaimsFromJwt=function e(t){var r=this;try{var n=this._joseUtil.parseJwt(t.responseText);if(!n||!n.header||!n.payload)return o.Log.error("UserInfoService._getClaimsFromJwt: Failed to parse JWT",n),Promise.reject(new Error("Failed to parse id_token"));var i=n.header.kid,s=void 0;switch(this._settings.userInfoJwtIssuer){case"OP":s=this._metadataService.getIssuer();break;case"ANY":s=Promise.resolve(n.payload.iss);break;default:s=Promise.resolve(this._settings.userInfoJwtIssuer)}return s.then(function(e){return o.Log.debug("UserInfoService._getClaimsFromJwt: Received issuer:"+e),r._metadataService.getSigningKeys().then(function(s){if(!s)return o.Log.error("UserInfoService._getClaimsFromJwt: No signing keys from metadata"),Promise.reject(new Error("No signing keys from metadata"));o.Log.debug("UserInfoService._getClaimsFromJwt: Received signing keys");var a=void 0;if(i)a=s.filter(function(e){return e.kid===i})[0];else{if((s=r._filterByAlg(s,n.header.alg)).length>1)return o.Log.error("UserInfoService._getClaimsFromJwt: No kid found in id_token and more than one key found in metadata"),Promise.reject(new Error("No kid found in id_token and more than one key found in metadata"));a=s[0]}if(!a)return o.Log.error("UserInfoService._getClaimsFromJwt: No key matching kid or alg found in signing keys"),Promise.reject(new Error("No key matching kid or alg found in signing keys"));var u=r._settings.client_id,c=r._settings.clockSkew;return o.Log.debug("UserInfoService._getClaimsFromJwt: Validaing JWT; using clock skew (in seconds) of: ",c),r._joseUtil.validateJwt(t.responseText,a,e,u,c,void 0,!0).then(function(){return o.Log.debug("UserInfoService._getClaimsFromJwt: JWT validation successful"),n.payload})})})}catch(e){return o.Log.error("UserInfoService._getClaimsFromJwt: Error parsing JWT response",e.message),void reject(e)}},e.prototype._filterByAlg=function(e,t){var r=null;if(t.startsWith("RS"))r="RSA";else if(t.startsWith("PS"))r="PS";else{if(!t.startsWith("ES"))return o.Log.debug("UserInfoService._filterByAlg: alg not supported: ",t),[];r="EC"}return o.Log.debug("UserInfoService._filterByAlg: Looking for keys that match kty: ",r),e=e.filter(function(e){return e.kty===r}),o.Log.debug("UserInfoService._filterByAlg: Number of keys that match kty: ",r,e.length),e},e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AllowedSigningAlgs=t.b64tohex=t.hextob64u=t.crypto=t.X509=t.KeyUtil=t.jws=void 0;var n=r(27);t.jws=n.jws,t.KeyUtil=n.KEYUTIL,t.X509=n.X509,t.crypto=n.crypto,t.hextob64u=n.hextob64u,t.b64tohex=n.b64tohex,t.AllowedSigningAlgs=["RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512"]},function(e,t,r){"use strict";(function(e){Object.defineProperty(t,"__esModule",{value:!0});var r,n,i,o,s,a,u,c,h,l,d,f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p={userAgent:!1},g={},y=y||(r=Math,i=(n={}).lib={},o=i.Base=function(){function e(){}return{extend:function(t){e.prototype=this;var r=new e;return t&&r.mixIn(t),r.hasOwnProperty("init")||(r.init=function(){r.$super.init.apply(this,arguments)}),r.init.prototype=r,r.$super=this,r},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),s=i.WordArray=o.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||u).stringify(this)},concat:function(e){var t=this.words,r=e.words,n=this.sigBytes,i=e.sigBytes;if(this.clamp(),n%4)for(var o=0;o>>2]>>>24-o%4*8&255;t[n+o>>>2]|=s<<24-(n+o)%4*8}else for(o=0;o>>2]=r[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,t=this.sigBytes;e[t>>>2]&=4294967295<<32-t%4*8,e.length=r.ceil(t/4)},clone:function(){var e=o.clone.call(this);return e.words=this.words.slice(0),e},random:function(e){for(var t=[],n=0;n>>2]>>>24-i%4*8&255;n.push((o>>>4).toString(16)),n.push((15&o).toString(16))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new s.init(r,t/2)}},c=a.Latin1={stringify:function(e){for(var t=e.words,r=e.sigBytes,n=[],i=0;i>>2]>>>24-i%4*8&255;n.push(String.fromCharCode(o))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new s.init(r,t)}},h=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=i.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new s.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=h.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(e){var t=this._data,n=t.words,i=t.sigBytes,o=this.blockSize,a=i/(4*o),u=(a=e?r.ceil(a):r.max((0|a)-this._minBufferSize,0))*o,c=r.min(4*u,i);if(u){for(var h=0;h>>2]>>>24-i%4*8&255)<<16|(t[i+1>>>2]>>>24-(i+1)%4*8&255)<<8|t[i+2>>>2]>>>24-(i+2)%4*8&255,s=0;4>s&&i+.75*s>>6*(3-s)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var r=e.length,n=this._map;(i=n.charAt(64))&&-1!=(i=e.indexOf(i))&&(r=i);for(var i=[],o=0,s=0;s>>6-s%4*2;i[o>>>2]|=(a|u)<<24-o%4*8,o++}return t.create(i,o)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}}(),function(e){for(var t=y,r=(i=t.lib).WordArray,n=i.Hasher,i=t.algo,o=[],s=[],a=function(e){return 4294967296*(e-(0|e))|0},u=2,c=0;64>c;){var h;e:{h=u;for(var l=e.sqrt(h),d=2;d<=l;d++)if(!(h%d)){h=!1;break e}h=!0}h&&(8>c&&(o[c]=a(e.pow(u,.5))),s[c]=a(e.pow(u,1/3)),c++),u++}var f=[];i=i.SHA256=n.extend({_doReset:function(){this._hash=new r.init(o.slice(0))},_doProcessBlock:function(e,t){for(var r=this._hash.words,n=r[0],i=r[1],o=r[2],a=r[3],u=r[4],c=r[5],h=r[6],l=r[7],d=0;64>d;d++){if(16>d)f[d]=0|e[t+d];else{var p=f[d-15],g=f[d-2];f[d]=((p<<25|p>>>7)^(p<<14|p>>>18)^p>>>3)+f[d-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+f[d-16]}p=l+((u<<26|u>>>6)^(u<<21|u>>>11)^(u<<7|u>>>25))+(u&c^~u&h)+s[d]+f[d],g=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&i^n&o^i&o),l=h,h=c,c=u,u=a+p|0,a=o,o=i,i=n,n=p+g|0}r[0]=r[0]+n|0,r[1]=r[1]+i|0,r[2]=r[2]+o|0,r[3]=r[3]+a|0,r[4]=r[4]+u|0,r[5]=r[5]+c|0,r[6]=r[6]+h|0,r[7]=r[7]+l|0},_doFinalize:function(){var t=this._data,r=t.words,n=8*this._nDataBytes,i=8*t.sigBytes;return r[i>>>5]|=128<<24-i%32,r[14+(i+64>>>9<<4)]=e.floor(n/4294967296),r[15+(i+64>>>9<<4)]=n,t.sigBytes=4*r.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}}),t.SHA256=n._createHelper(i),t.HmacSHA256=n._createHmacHelper(i)}(Math),function(){function e(){return n.create.apply(n,arguments)}for(var t=y,r=t.lib.Hasher,n=(o=t.x64).Word,i=o.WordArray,o=t.algo,s=[e(1116352408,3609767458),e(1899447441,602891725),e(3049323471,3964484399),e(3921009573,2173295548),e(961987163,4081628472),e(1508970993,3053834265),e(2453635748,2937671579),e(2870763221,3664609560),e(3624381080,2734883394),e(310598401,1164996542),e(607225278,1323610764),e(1426881987,3590304994),e(1925078388,4068182383),e(2162078206,991336113),e(2614888103,633803317),e(3248222580,3479774868),e(3835390401,2666613458),e(4022224774,944711139),e(264347078,2341262773),e(604807628,2007800933),e(770255983,1495990901),e(1249150122,1856431235),e(1555081692,3175218132),e(1996064986,2198950837),e(2554220882,3999719339),e(2821834349,766784016),e(2952996808,2566594879),e(3210313671,3203337956),e(3336571891,1034457026),e(3584528711,2466948901),e(113926993,3758326383),e(338241895,168717936),e(666307205,1188179964),e(773529912,1546045734),e(1294757372,1522805485),e(1396182291,2643833823),e(1695183700,2343527390),e(1986661051,1014477480),e(2177026350,1206759142),e(2456956037,344077627),e(2730485921,1290863460),e(2820302411,3158454273),e(3259730800,3505952657),e(3345764771,106217008),e(3516065817,3606008344),e(3600352804,1432725776),e(4094571909,1467031594),e(275423344,851169720),e(430227734,3100823752),e(506948616,1363258195),e(659060556,3750685593),e(883997877,3785050280),e(958139571,3318307427),e(1322822218,3812723403),e(1537002063,2003034995),e(1747873779,3602036899),e(1955562222,1575990012),e(2024104815,1125592928),e(2227730452,2716904306),e(2361852424,442776044),e(2428436474,593698344),e(2756734187,3733110249),e(3204031479,2999351573),e(3329325298,3815920427),e(3391569614,3928383900),e(3515267271,566280711),e(3940187606,3454069534),e(4118630271,4000239992),e(116418474,1914138554),e(174292421,2731055270),e(289380356,3203993006),e(460393269,320620315),e(685471733,587496836),e(852142971,1086792851),e(1017036298,365543100),e(1126000580,2618297676),e(1288033470,3409855158),e(1501505948,4234509866),e(1607167915,987167468),e(1816402316,1246189591)],a=[],u=0;80>u;u++)a[u]=e();o=o.SHA512=r.extend({_doReset:function(){this._hash=new i.init([new n.init(1779033703,4089235720),new n.init(3144134277,2227873595),new n.init(1013904242,4271175723),new n.init(2773480762,1595750129),new n.init(1359893119,2917565137),new n.init(2600822924,725511199),new n.init(528734635,4215389547),new n.init(1541459225,327033209)])},_doProcessBlock:function(e,t){for(var r=(l=this._hash.words)[0],n=l[1],i=l[2],o=l[3],u=l[4],c=l[5],h=l[6],l=l[7],d=r.high,f=r.low,p=n.high,g=n.low,y=i.high,v=i.low,m=o.high,w=o.low,_=u.high,S=u.low,b=c.high,E=c.low,F=h.high,x=h.low,A=l.high,k=l.low,P=d,T=f,I=p,C=g,R=y,U=v,L=m,D=w,N=_,O=S,H=b,j=E,M=F,B=x,K=A,V=k,q=0;80>q;q++){var J=a[q];if(16>q)var W=J.high=0|e[t+2*q],$=J.low=0|e[t+2*q+1];else{W=(($=(W=a[q-15]).high)>>>1|(z=W.low)<<31)^($>>>8|z<<24)^$>>>7;var z=(z>>>1|$<<31)^(z>>>8|$<<24)^(z>>>7|$<<25),Y=(($=(Y=a[q-2]).high)>>>19|(G=Y.low)<<13)^($<<3|G>>>29)^$>>>6,G=(G>>>19|$<<13)^(G<<3|$>>>29)^(G>>>6|$<<26),X=($=a[q-7]).high,Q=(Z=a[q-16]).high,Z=Z.low;W=(W=(W=W+X+(($=z+$.low)>>>0>>0?1:0))+Y+(($+=G)>>>0>>0?1:0))+Q+(($+=Z)>>>0>>0?1:0),J.high=W,J.low=$}X=N&H^~N&M,Z=O&j^~O&B,J=P&I^P&R^I&R;var ee=T&C^T&U^C&U,te=(z=(P>>>28|T<<4)^(P<<30|T>>>2)^(P<<25|T>>>7),Y=(T>>>28|P<<4)^(T<<30|P>>>2)^(T<<25|P>>>7),(G=s[q]).high),re=G.low;Q=K+((N>>>14|O<<18)^(N>>>18|O<<14)^(N<<23|O>>>9))+((G=V+((O>>>14|N<<18)^(O>>>18|N<<14)^(O<<23|N>>>9)))>>>0>>0?1:0),K=M,V=B,M=H,B=j,H=N,j=O,N=L+(Q=(Q=(Q=Q+X+((G+=Z)>>>0>>0?1:0))+te+((G+=re)>>>0>>0?1:0))+W+((G+=$)>>>0<$>>>0?1:0))+((O=D+G|0)>>>0>>0?1:0)|0,L=R,D=U,R=I,U=C,I=P,C=T,P=Q+(J=z+J+(($=Y+ee)>>>0>>0?1:0))+((T=G+$|0)>>>0>>0?1:0)|0}f=r.low=f+T,r.high=d+P+(f>>>0>>0?1:0),g=n.low=g+C,n.high=p+I+(g>>>0>>0?1:0),v=i.low=v+U,i.high=y+R+(v>>>0>>0?1:0),w=o.low=w+D,o.high=m+L+(w>>>0>>0?1:0),S=u.low=S+O,u.high=_+N+(S>>>0>>0?1:0),E=c.low=E+j,c.high=b+H+(E>>>0>>0?1:0),x=h.low=x+B,h.high=F+M+(x>>>0>>0?1:0),k=l.low=k+V,l.high=A+K+(k>>>0>>0?1:0)},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;return t[n>>>5]|=128<<24-n%32,t[30+(n+128>>>10<<5)]=Math.floor(r/4294967296),t[31+(n+128>>>10<<5)]=r,e.sigBytes=4*t.length,this._process(),this._hash.toX32()},clone:function(){var e=r.clone.call(this);return e._hash=this._hash.clone(),e},blockSize:32}),t.SHA512=r._createHelper(o),t.HmacSHA512=r._createHmacHelper(o)}(),function(){var e=y,t=(i=e.x64).Word,r=i.WordArray,n=(i=e.algo).SHA512,i=i.SHA384=n.extend({_doReset:function(){this._hash=new r.init([new t.init(3418070365,3238371032),new t.init(1654270250,914150663),new t.init(2438529370,812702999),new t.init(355462360,4144912697),new t.init(1731405415,4290775857),new t.init(2394180231,1750603025),new t.init(3675008525,1694076839),new t.init(1203062813,3204075428)])},_doFinalize:function(){var e=n._doFinalize.call(this);return e.sigBytes-=16,e}});e.SHA384=n._createHelper(i),e.HmacSHA384=n._createHmacHelper(i)}(); +/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ + */ +var v,m="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function w(e){var t,r,n="";for(t=0;t+3<=e.length;t+=3)r=parseInt(e.substring(t,t+3),16),n+=m.charAt(r>>6)+m.charAt(63&r);for(t+1==e.length?(r=parseInt(e.substring(t,t+1),16),n+=m.charAt(r<<2)):t+2==e.length&&(r=parseInt(e.substring(t,t+2),16),n+=m.charAt(r>>2)+m.charAt((3&r)<<4));(3&n.length)>0;)n+="=";return n}function _(e){var t,r,n,i="",o=0;for(t=0;t>2),r=3&n,o=1):1==o?(i+=k(r<<2|n>>4),r=15&n,o=2):2==o?(i+=k(r),i+=k(n>>2),r=3&n,o=3):(i+=k(r<<2|n>>4),i+=k(15&n),o=0));return 1==o&&(i+=k(r<<2)),i}function S(e){var t,r=_(e),n=new Array;for(t=0;2*t>15;--o>=0;){var u=32767&this[e],c=this[e++]>>15,h=a*u+c*s;i=((u=s*u+((32767&h)<<15)+r[n]+(1073741823&i))>>>30)+(h>>>15)+a*c+(i>>>30),r[n++]=1073741823&u}return i},v=30):"Netscape"!=p.appName?(b.prototype.am=function(e,t,r,n,i,o){for(;--o>=0;){var s=t*this[e++]+r[n]+i;i=Math.floor(s/67108864),r[n++]=67108863&s}return i},v=26):(b.prototype.am=function(e,t,r,n,i,o){for(var s=16383&t,a=t>>14;--o>=0;){var u=16383&this[e],c=this[e++]>>14,h=a*u+c*s;i=((u=s*u+((16383&h)<<14)+r[n]+i)>>28)+(h>>14)+a*c,r[n++]=268435455&u}return i},v=28),b.prototype.DB=v,b.prototype.DM=(1<>>16)&&(e=t,r+=16),0!=(t=e>>8)&&(e=t,r+=8),0!=(t=e>>4)&&(e=t,r+=4),0!=(t=e>>2)&&(e=t,r+=2),0!=(t=e>>1)&&(e=t,r+=1),r}function C(e){this.m=e}function R(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<>=16,t+=16),!(255&e)&&(e>>=8,t+=8),!(15&e)&&(e>>=4,t+=4),!(3&e)&&(e>>=2,t+=2),!(1&e)&&++t,t}function H(e){for(var t=0;0!=e;)e&=e-1,++t;return t}function j(){}function M(e){return e}function B(e){this.r2=E(),this.q3=E(),b.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}C.prototype.convert=function(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e},C.prototype.revert=function(e){return e},C.prototype.reduce=function(e){e.divRemTo(this.m,null,e)},C.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},C.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},R.prototype.convert=function(e){var t=E();return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&t.compareTo(b.ZERO)>0&&this.m.subTo(t,t),t},R.prototype.revert=function(e){var t=E();return e.copyTo(t),this.reduce(t),t},R.prototype.reduce=function(e){for(;e.t<=this.mt2;)e[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;for(e[r=t+this.m.t]+=this.m.am(0,n,e,t,0,this.m.t);e[r]>=e.DV;)e[r]-=e.DV,e[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)},R.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},R.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},b.prototype.copyTo=function(e){for(var t=this.t-1;t>=0;--t)e[t]=this[t];e.t=this.t,e.s=this.s},b.prototype.fromInt=function(e){this.t=1,this.s=e<0?-1:0,e>0?this[0]=e:e<-1?this[0]=e+this.DV:this.t=0},b.prototype.fromString=function(e,t){var r;if(16==t)r=4;else if(8==t)r=3;else if(256==t)r=8;else if(2==t)r=1;else if(32==t)r=5;else{if(4!=t)return void this.fromRadix(e,t);r=2}this.t=0,this.s=0;for(var n=e.length,i=!1,o=0;--n>=0;){var s=8==r?255&e[n]:P(e,n);s<0?"-"==e.charAt(n)&&(i=!0):(i=!1,0==o?this[this.t++]=s:o+r>this.DB?(this[this.t-1]|=(s&(1<>this.DB-o):this[this.t-1]|=s<=this.DB&&(o-=this.DB))}8==r&&!!(128&e[0])&&(this.s=-1,o>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==e;)--this.t},b.prototype.dlShiftTo=function(e,t){var r;for(r=this.t-1;r>=0;--r)t[r+e]=this[r];for(r=e-1;r>=0;--r)t[r]=0;t.t=this.t+e,t.s=this.s},b.prototype.drShiftTo=function(e,t){for(var r=e;r=0;--r)t[r+s+1]=this[r]>>i|a,a=(this[r]&o)<=0;--r)t[r]=0;t[s]=a,t.t=this.t+s+1,t.s=this.s,t.clamp()},b.prototype.rShiftTo=function(e,t){t.s=this.s;var r=Math.floor(e/this.DB);if(r>=this.t)t.t=0;else{var n=e%this.DB,i=this.DB-n,o=(1<>n;for(var s=r+1;s>n;n>0&&(t[this.t-r-1]|=(this.s&o)<>=this.DB;if(e.t>=this.DB;n+=this.s}else{for(n+=this.s;r>=this.DB;n-=e.s}t.s=n<0?-1:0,n<-1?t[r++]=this.DV+n:n>0&&(t[r++]=n),t.t=r,t.clamp()},b.prototype.multiplyTo=function(e,t){var r=this.abs(),n=e.abs(),i=r.t;for(t.t=i+n.t;--i>=0;)t[i]=0;for(i=0;i=0;)e[r]=0;for(r=0;r=t.DV&&(e[r+t.t]-=t.DV,e[r+t.t+1]=1)}e.t>0&&(e[e.t-1]+=t.am(r,t[r],e,2*r,0,1)),e.s=0,e.clamp()},b.prototype.divRemTo=function(e,t,r){var n=e.abs();if(!(n.t<=0)){var i=this.abs();if(i.t0?(n.lShiftTo(u,o),i.lShiftTo(u,r)):(n.copyTo(o),i.copyTo(r));var c=o.t,h=o[c-1];if(0!=h){var l=h*(1<1?o[c-2]>>this.F2:0),d=this.FV/l,f=(1<=0&&(r[r.t++]=1,r.subTo(v,r)),b.ONE.dlShiftTo(c,v),v.subTo(o,o);o.t=0;){var m=r[--g]==h?this.DM:Math.floor(r[g]*d+(r[g-1]+p)*f);if((r[g]+=o.am(0,m,r,y,0,c))0&&r.rShiftTo(u,r),s<0&&b.ZERO.subTo(r,r)}}},b.prototype.invDigit=function(){if(this.t<1)return 0;var e=this[0];if(!(1&e))return 0;var t=3&e;return(t=(t=(t=(t=t*(2-(15&e)*t)&15)*(2-(255&e)*t)&255)*(2-((65535&e)*t&65535))&65535)*(2-e*t%this.DV)%this.DV)>0?this.DV-t:-t},b.prototype.isEven=function(){return 0==(this.t>0?1&this[0]:this.s)},b.prototype.exp=function(e,t){if(e>4294967295||e<1)return b.ONE;var r=E(),n=E(),i=t.convert(this),o=I(e)-1;for(i.copyTo(r);--o>=0;)if(t.sqrTo(r,n),(e&1<0)t.mulTo(n,i,r);else{var s=r;r=n,n=s}return t.revert(r)},b.prototype.toString=function(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(16==e)t=4;else if(8==e)t=3;else if(2==e)t=1;else if(32==e)t=5;else{if(4!=e)return this.toRadix(e);t=2}var r,n=(1<0)for(a>a)>0&&(i=!0,o=k(r));s>=0;)a>(a+=this.DB-t)):(r=this[s]>>(a-=t)&n,a<=0&&(a+=this.DB,--s)),r>0&&(i=!0),i&&(o+=k(r));return i?o:"0"},b.prototype.negate=function(){var e=E();return b.ZERO.subTo(this,e),e},b.prototype.abs=function(){return this.s<0?this.negate():this},b.prototype.compareTo=function(e){var t=this.s-e.s;if(0!=t)return t;var r=this.t;if(0!=(t=r-e.t))return this.s<0?-t:t;for(;--r>=0;)if(0!=(t=this[r]-e[r]))return t;return 0},b.prototype.bitLength=function(){return this.t<=0?0:this.DB*(this.t-1)+I(this[this.t-1]^this.s&this.DM)},b.prototype.mod=function(e){var t=E();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(b.ZERO)>0&&e.subTo(t,t),t},b.prototype.modPowInt=function(e,t){var r;return r=e<256||t.isEven()?new C(t):new R(t),this.exp(e,r)},b.ZERO=T(0),b.ONE=T(1),j.prototype.convert=M,j.prototype.revert=M,j.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r)},j.prototype.sqrTo=function(e,t){e.squareTo(t)},B.prototype.convert=function(e){if(e.s<0||e.t>2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=E();return e.copyTo(t),this.reduce(t),t},B.prototype.revert=function(e){return e},B.prototype.reduce=function(e){for(e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);e.compareTo(this.r2)<0;)e.dAddOffset(1,this.m.t+1);for(e.subTo(this.r2,e);e.compareTo(this.m)>=0;)e.subTo(this.m,e)},B.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},B.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)};var K,V,q,J=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],W=(1<<26)/J[J.length-1]; +/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ + */function $(){this.i=0,this.j=0,this.S=new Array} +/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ + */ +function z(){!function(e){V[q++]^=255&e,V[q++]^=e>>8&255,V[q++]^=e>>16&255,V[q++]^=e>>24&255,q>=256&&(q-=256)}((new Date).getTime())}if(b.prototype.chunkSize=function(e){return Math.floor(Math.LN2*this.DB/Math.log(e))},b.prototype.toRadix=function(e){if(null==e&&(e=10),0==this.signum()||e<2||e>36)return"0";var t=this.chunkSize(e),r=Math.pow(e,t),n=T(r),i=E(),o=E(),s="";for(this.divRemTo(n,i,o);i.signum()>0;)s=(r+o.intValue()).toString(e).substr(1)+s,i.divRemTo(n,i,o);return o.intValue().toString(e)+s},b.prototype.fromRadix=function(e,t){this.fromInt(0),null==t&&(t=10);for(var r=this.chunkSize(t),n=Math.pow(t,r),i=!1,o=0,s=0,a=0;a=r&&(this.dMultiply(n),this.dAddOffset(s,0),o=0,s=0))}o>0&&(this.dMultiply(Math.pow(t,o)),this.dAddOffset(s,0)),i&&b.ZERO.subTo(this,this)},b.prototype.fromNumber=function(e,t,r){if("number"==typeof t)if(e<2)this.fromInt(1);else for(this.fromNumber(e,r),this.testBit(e-1)||this.bitwiseTo(b.ONE.shiftLeft(e-1),L,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(t);)this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(b.ONE.shiftLeft(e-1),this);else{var n=new Array,i=7&e;n.length=1+(e>>3),t.nextBytes(n),i>0?n[0]&=(1<>=this.DB;if(e.t>=this.DB;n+=this.s}else{for(n+=this.s;r>=this.DB;n+=e.s}t.s=n<0?-1:0,n>0?t[r++]=n:n<-1&&(t[r++]=this.DV+n),t.t=r,t.clamp()},b.prototype.dMultiply=function(e){this[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()},b.prototype.dAddOffset=function(e,t){if(0!=e){for(;this.t<=t;)this[this.t++]=0;for(this[t]+=e;this[t]>=this.DV;)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}},b.prototype.multiplyLowerTo=function(e,t,r){var n,i=Math.min(this.t+e.t,t);for(r.s=0,r.t=i;i>0;)r[--i]=0;for(n=r.t-this.t;i=0;)r[n]=0;for(n=Math.max(t-this.t,0);n0)if(0==t)r=this[0]%e;else for(var n=this.t-1;n>=0;--n)r=(t*r+this[n])%e;return r},b.prototype.millerRabin=function(e){var t=this.subtract(b.ONE),r=t.getLowestSetBit();if(r<=0)return!1;var n=t.shiftRight(r);(e=e+1>>1)>J.length&&(e=J.length);for(var i=E(),o=0;o>24},b.prototype.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},b.prototype.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},b.prototype.toByteArray=function(){var e=this.t,t=new Array;t[0]=this.s;var r,n=this.DB-e*this.DB%8,i=0;if(e-- >0)for(n>n)!=(this.s&this.DM)>>n&&(t[i++]=r|this.s<=0;)n<8?(r=(this[e]&(1<>(n+=this.DB-8)):(r=this[e]>>(n-=8)&255,n<=0&&(n+=this.DB,--e)),!!(128&r)&&(r|=-256),0==i&&(128&this.s)!=(128&r)&&++i,(i>0||r!=this.s)&&(t[i++]=r);return t},b.prototype.equals=function(e){return 0==this.compareTo(e)},b.prototype.min=function(e){return this.compareTo(e)<0?this:e},b.prototype.max=function(e){return this.compareTo(e)>0?this:e},b.prototype.and=function(e){var t=E();return this.bitwiseTo(e,U,t),t},b.prototype.or=function(e){var t=E();return this.bitwiseTo(e,L,t),t},b.prototype.xor=function(e){var t=E();return this.bitwiseTo(e,D,t),t},b.prototype.andNot=function(e){var t=E();return this.bitwiseTo(e,N,t),t},b.prototype.not=function(){for(var e=E(),t=0;t=this.t?0!=this.s:!!(this[t]&1<1){var h=E();for(n.sqrTo(s[1],h);a<=c;)s[a]=E(),n.mulTo(h,s[a-2],s[a]),a+=2}var l,d,f=e.t-1,p=!0,g=E();for(i=I(e[f])-1;f>=0;){for(i>=u?l=e[f]>>i-u&c:(l=(e[f]&(1<0&&(l|=e[f-1]>>this.DB+i-u)),a=r;!(1&l);)l>>=1,--a;if((i-=a)<0&&(i+=this.DB,--f),p)s[l].copyTo(o),p=!1;else{for(;a>1;)n.sqrTo(o,g),n.sqrTo(g,o),a-=2;a>0?n.sqrTo(o,g):(d=o,o=g,g=d),n.mulTo(g,s[l],o)}for(;f>=0&&!(e[f]&1<=0?(r.subTo(n,r),t&&i.subTo(s,i),o.subTo(a,o)):(n.subTo(r,n),t&&s.subTo(i,s),a.subTo(o,a))}return 0!=n.compareTo(b.ONE)?b.ZERO:a.compareTo(e)>=0?a.subtract(e):a.signum()<0?(a.addTo(e,a),a.signum()<0?a.add(e):a):a},b.prototype.pow=function(e){return this.exp(e,new j)},b.prototype.gcd=function(e){var t=this.s<0?this.negate():this.clone(),r=e.s<0?e.negate():e.clone();if(t.compareTo(r)<0){var n=t;t=r,r=n}var i=t.getLowestSetBit(),o=r.getLowestSetBit();if(o<0)return t;for(i0&&(t.rShiftTo(o,t),r.rShiftTo(o,r));t.signum()>0;)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=r.getLowestSetBit())>0&&r.rShiftTo(i,r),t.compareTo(r)>=0?(t.subTo(r,t),t.rShiftTo(1,t)):(r.subTo(t,r),r.rShiftTo(1,r));return o>0&&r.lShiftTo(o,r),r},b.prototype.isProbablePrime=function(e){var t,r=this.abs();if(1==r.t&&r[0]<=J[J.length-1]){for(t=0;t>>8,V[q++]=255&Y;q=0,z()}function Z(){if(null==K){for(z(),(K=new $).init(V),q=0;q>24,(16711680&i)>>16,(65280&i)>>8,255&i]))),i+=1;return n}function ne(){this.n=null,this.e=0,this.d=null,this.p=null,this.q=null,this.dmp1=null,this.dmq1=null,this.coeff=null} +/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ + */function ie(e,t){this.x=t,this.q=e}function oe(e,t,r,n){this.curve=e,this.x=t,this.y=r,this.z=null==n?b.ONE:n,this.zinv=null}function se(e,t,r){this.q=e,this.a=this.fromBigInteger(t),this.b=this.fromBigInteger(r),this.infinity=new oe(this,null,null)}ee.prototype.nextBytes=function(e){var t;for(t=0;t0&&t.length>0))throw"Invalid RSA public key";this.n=te(e,16),this.e=parseInt(t,16)}},ne.prototype.encrypt=function(e){var t=function(e,t){if(t=0&&t>0;){var i=e.charCodeAt(n--);i<128?r[--t]=i:i>127&&i<2048?(r[--t]=63&i|128,r[--t]=i>>6|192):(r[--t]=63&i|128,r[--t]=i>>6&63|128,r[--t]=i>>12|224)}r[--t]=0;for(var o=new ee,s=new Array;t>2;){for(s[0]=0;0==s[0];)o.nextBytes(s);r[--t]=s[0]}return r[--t]=2,r[--t]=0,new b(r)}(e,this.n.bitLength()+7>>3);if(null==t)return null;var r=this.doPublic(t);if(null==r)return null;var n=r.toString(16);return 1&n.length?"0"+n:n},ne.prototype.encryptOAEP=function(e,t,r){var n=function(e,t,r,n){var i=ue.crypto.MessageDigest,o=ue.crypto.Util,s=null;if(r||(r="sha1"),"string"==typeof r&&(s=i.getCanonicalAlgName(r),n=i.getHashLength(s),r=function(e){return be(o.hashHex(Ee(e),s))}),e.length+2*n+2>t)throw"Message too long for RSA";var a,u="";for(a=0;a>3,t,r);if(null==n)return null;var i=this.doPublic(n);if(null==i)return null;var o=i.toString(16);return 1&o.length?"0"+o:o},ne.prototype.type="RSA",ie.prototype.equals=function(e){return e==this||this.q.equals(e.q)&&this.x.equals(e.x)},ie.prototype.toBigInteger=function(){return this.x},ie.prototype.negate=function(){return new ie(this.q,this.x.negate().mod(this.q))},ie.prototype.add=function(e){return new ie(this.q,this.x.add(e.toBigInteger()).mod(this.q))},ie.prototype.subtract=function(e){return new ie(this.q,this.x.subtract(e.toBigInteger()).mod(this.q))},ie.prototype.multiply=function(e){return new ie(this.q,this.x.multiply(e.toBigInteger()).mod(this.q))},ie.prototype.square=function(){return new ie(this.q,this.x.square().mod(this.q))},ie.prototype.divide=function(e){return new ie(this.q,this.x.multiply(e.toBigInteger().modInverse(this.q)).mod(this.q))},oe.prototype.getX=function(){return null==this.zinv&&(this.zinv=this.z.modInverse(this.curve.q)),this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q))},oe.prototype.getY=function(){return null==this.zinv&&(this.zinv=this.z.modInverse(this.curve.q)),this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q))},oe.prototype.equals=function(e){return e==this||(this.isInfinity()?e.isInfinity():e.isInfinity()?this.isInfinity():!!e.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(e.z)).mod(this.curve.q).equals(b.ZERO)&&e.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(e.z)).mod(this.curve.q).equals(b.ZERO))},oe.prototype.isInfinity=function(){return null==this.x&&null==this.y||this.z.equals(b.ZERO)&&!this.y.toBigInteger().equals(b.ZERO)},oe.prototype.negate=function(){return new oe(this.curve,this.x,this.y.negate(),this.z)},oe.prototype.add=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;var t=e.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(e.z)).mod(this.curve.q),r=e.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(e.z)).mod(this.curve.q);if(b.ZERO.equals(r))return b.ZERO.equals(t)?this.twice():this.curve.getInfinity();var n=new b("3"),i=this.x.toBigInteger(),o=this.y.toBigInteger(),s=(e.x.toBigInteger(),e.y.toBigInteger(),r.square()),a=s.multiply(r),u=i.multiply(s),c=t.square().multiply(this.z),h=c.subtract(u.shiftLeft(1)).multiply(e.z).subtract(a).multiply(r).mod(this.curve.q),l=u.multiply(n).multiply(t).subtract(o.multiply(a)).subtract(c.multiply(t)).multiply(e.z).add(t.multiply(a)).mod(this.curve.q),d=a.multiply(this.z).multiply(e.z).mod(this.curve.q);return new oe(this.curve,this.curve.fromBigInteger(h),this.curve.fromBigInteger(l),d)},oe.prototype.twice=function(){if(this.isInfinity())return this;if(0==this.y.toBigInteger().signum())return this.curve.getInfinity();var e=new b("3"),t=this.x.toBigInteger(),r=this.y.toBigInteger(),n=r.multiply(this.z),i=n.multiply(r).mod(this.curve.q),o=this.curve.a.toBigInteger(),s=t.square().multiply(e);b.ZERO.equals(o)||(s=s.add(this.z.square().multiply(o)));var a=(s=s.mod(this.curve.q)).square().subtract(t.shiftLeft(3).multiply(i)).shiftLeft(1).multiply(n).mod(this.curve.q),u=s.multiply(e).multiply(t).subtract(i.shiftLeft(1)).shiftLeft(2).multiply(i).subtract(s.square().multiply(s)).mod(this.curve.q),c=n.square().multiply(n).shiftLeft(3).mod(this.curve.q);return new oe(this.curve,this.curve.fromBigInteger(a),this.curve.fromBigInteger(u),c)},oe.prototype.multiply=function(e){if(this.isInfinity())return this;if(0==e.signum())return this.curve.getInfinity();var t,r=e,n=r.multiply(new b("3")),i=this.negate(),o=this,s=this.curve.q.subtract(e),a=s.multiply(new b("3")),u=new oe(this.curve,this.x,this.y),c=u.negate();for(t=n.bitLength()-2;t>0;--t){o=o.twice();var h=n.testBit(t);h!=r.testBit(t)&&(o=o.add(h?this:i))}for(t=a.bitLength()-2;t>0;--t){u=u.twice();var l=a.testBit(t);l!=s.testBit(t)&&(u=u.add(l?u:c))}return o},oe.prototype.multiplyTwo=function(e,t,r){var n;n=e.bitLength()>r.bitLength()?e.bitLength()-1:r.bitLength()-1;for(var i=this.curve.getInfinity(),o=this.add(t);n>=0;)i=i.twice(),e.testBit(n)?i=r.testBit(n)?i.add(o):i.add(this):r.testBit(n)&&(i=i.add(t)),--n;return i},se.prototype.getQ=function(){return this.q},se.prototype.getA=function(){return this.a},se.prototype.getB=function(){return this.b},se.prototype.equals=function(e){return e==this||this.q.equals(e.q)&&this.a.equals(e.a)&&this.b.equals(e.b)},se.prototype.getInfinity=function(){return this.infinity},se.prototype.fromBigInteger=function(e){return new ie(this.q,e)},se.prototype.decodePointHex=function(e){switch(parseInt(e.substr(0,2),16)){case 0:return this.infinity;case 2:case 3:default:return null;case 4:case 6:case 7:var t=(e.length-2)/2,r=e.substr(2,t),n=e.substr(t+2,t);return new oe(this,this.fromBigInteger(new b(r,16)),this.fromBigInteger(new b(n,16)))}}, +/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib + */ +ie.prototype.getByteLength=function(){return Math.floor((this.toBigInteger().bitLength()+7)/8)},oe.prototype.getEncoded=function(e){var t=function(e,t){var r=e.toByteArrayUnsigned();if(tr.length;)r.unshift(0);return r},r=this.getX().toBigInteger(),n=this.getY().toBigInteger(),i=t(r,32);return e?n.isEven()?i.unshift(2):i.unshift(3):(i.unshift(4),i=i.concat(t(n,32))),i},oe.decodeFrom=function(e,t){t[0];var r=t.length-1,n=t.slice(1,1+r/2),i=t.slice(1+r/2,1+r);n.unshift(0),i.unshift(0);var o=new b(n),s=new b(i);return new oe(e,e.fromBigInteger(o),e.fromBigInteger(s))},oe.decodeFromHex=function(e,t){t.substr(0,2);var r=t.length-2,n=t.substr(2,r/2),i=t.substr(2+r/2,r/2),o=new b(n,16),s=new b(i,16);return new oe(e,e.fromBigInteger(o),e.fromBigInteger(s))},oe.prototype.add2D=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;if(this.x.equals(e.x))return this.y.equals(e.y)?this.twice():this.curve.getInfinity();var t=e.x.subtract(this.x),r=e.y.subtract(this.y).divide(t),n=r.square().subtract(this.x).subtract(e.x),i=r.multiply(this.x.subtract(n)).subtract(this.y);return new oe(this.curve,n,i)},oe.prototype.twice2D=function(){if(this.isInfinity())return this;if(0==this.y.toBigInteger().signum())return this.curve.getInfinity();var e=this.curve.fromBigInteger(b.valueOf(2)),t=this.curve.fromBigInteger(b.valueOf(3)),r=this.x.square().multiply(t).add(this.curve.a).divide(this.y.multiply(e)),n=r.square().subtract(this.x.multiply(e)),i=r.multiply(this.x.subtract(n)).subtract(this.y);return new oe(this.curve,n,i)},oe.prototype.multiply2D=function(e){if(this.isInfinity())return this;if(0==e.signum())return this.curve.getInfinity();var t,r=e,n=r.multiply(new b("3")),i=this.negate(),o=this;for(t=n.bitLength()-2;t>0;--t){o=o.twice();var s=n.testBit(t);s!=r.testBit(t)&&(o=o.add2D(s?this:i))}return o},oe.prototype.isOnCurve=function(){var e=this.getX().toBigInteger(),t=this.getY().toBigInteger(),r=this.curve.getA().toBigInteger(),n=this.curve.getB().toBigInteger(),i=this.curve.getQ(),o=t.multiply(t).mod(i),s=e.multiply(e).multiply(e).add(r.multiply(e)).add(n).mod(i);return o.equals(s)},oe.prototype.toString=function(){return"("+this.getX().toBigInteger().toString()+","+this.getY().toBigInteger().toString()+")"},oe.prototype.validate=function(){var e=this.curve.getQ();if(this.isInfinity())throw new Error("Point is at infinity.");var t=this.getX().toBigInteger(),r=this.getY().toBigInteger();if(t.compareTo(b.ONE)<0||t.compareTo(e.subtract(b.ONE))>0)throw new Error("x coordinate out of bounds");if(r.compareTo(b.ONE)<0||r.compareTo(e.subtract(b.ONE))>0)throw new Error("y coordinate out of bounds");if(!this.isOnCurve())throw new Error("Point is not on the curve.");if(this.multiply(e).isInfinity())throw new Error("Point is not a scalar multiple of G.");return!0}; +/*! Mike Samuel (c) 2009 | code.google.com/p/json-sans-eval + */ +var ae=function(){var e=new RegExp('(?:false|true|null|[\\{\\}\\[\\]]|(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)|(?:"(?:[^\\0-\\x08\\x0a-\\x1f"\\\\]|\\\\(?:["/\\\\bfnrt]|u[0-9A-Fa-f]{4}))*"))',"g"),t=new RegExp("\\\\(?:([^u])|u(.{4}))","g"),r={'"':'"',"/":"/","\\":"\\",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};function n(e,t,n){return t?r[t]:String.fromCharCode(parseInt(n,16))}var i=new String(""),o=Object.hasOwnProperty;return function(r,s){var a,u,c=r.match(e),h=c[0],l=!1;"{"===h?a={}:"["===h?a=[]:(a=[],l=!0);for(var d=[a],p=1-l,g=c.length;p=0;)delete n[i[c]]}return s.call(t,r,n)}({"":a},"")),a}}();void 0!==ue&&ue||(t.KJUR=ue={}),void 0!==ue.asn1&&ue.asn1||(ue.asn1={}),ue.asn1.ASN1Util=new function(){this.integerToByteHex=function(e){var t=e.toString(16);return t.length%2==1&&(t="0"+t),t},this.bigIntToMinTwosComplementsHex=function(e){var t=e.toString(16);if("-"!=t.substr(0,1))t.length%2==1?t="0"+t:t.match(/^[0-7]/)||(t="00"+t);else{var r=t.substr(1).length;r%2==1?r+=1:t.match(/^[0-7]/)||(r+=2);for(var n="",i=0;i15)throw"ASN.1 length too long to represent by 8x: n = "+e.toString(16);return(128+r).toString(16)+t},this.getEncodedHex=function(){return(null==this.hTLV||this.isModified)&&(this.hV=this.getFreshValueHex(),this.hL=this.getLengthHexFromValue(),this.hTLV=this.hT+this.hL+this.hV,this.isModified=!1),this.hTLV},this.getValueHex=function(){return this.getEncodedHex(),this.hV},this.getFreshValueHex=function(){return""},this.setByParam=function(e){this.params=e},null!=e&&null!=e.tlv&&(this.hTLV=e.tlv,this.isModified=!1)},ue.asn1.DERAbstractString=function(e){ue.asn1.DERAbstractString.superclass.constructor.call(this),this.getString=function(){return this.s},this.setString=function(e){this.hTLV=null,this.isModified=!0,this.s=e,this.hV=_e(this.s).toLowerCase()},this.setStringHex=function(e){this.hTLV=null,this.isModified=!0,this.s=null,this.hV=e},this.getFreshValueHex=function(){return this.hV},void 0!==e&&("string"==typeof e?this.setString(e):void 0!==e.str?this.setString(e.str):void 0!==e.hex&&this.setStringHex(e.hex))},Be(ue.asn1.DERAbstractString,ue.asn1.ASN1Object),ue.asn1.DERAbstractTime=function(e){ue.asn1.DERAbstractTime.superclass.constructor.call(this),this.localDateToUTC=function(e){var t=e.getTime()+6e4*e.getTimezoneOffset();return new Date(t)},this.formatDate=function(e,t,r){var n=this.zeroPadding,i=this.localDateToUTC(e),o=String(i.getFullYear());"utc"==t&&(o=o.substr(2,2));var s=o+n(String(i.getMonth()+1),2)+n(String(i.getDate()),2)+n(String(i.getHours()),2)+n(String(i.getMinutes()),2)+n(String(i.getSeconds()),2);if(!0===r){var a=i.getMilliseconds();if(0!=a){var u=n(String(a),3);s=s+"."+(u=u.replace(/[0]+$/,""))}}return s+"Z"},this.zeroPadding=function(e,t){return e.length>=t?e:new Array(t-e.length+1).join("0")+e},this.getString=function(){return this.s},this.setString=function(e){this.hTLV=null,this.isModified=!0,this.s=e,this.hV=ge(e)},this.setByDateValue=function(e,t,r,n,i,o){var s=new Date(Date.UTC(e,t-1,r,n,i,o,0));this.setByDate(s)},this.getFreshValueHex=function(){return this.hV}},Be(ue.asn1.DERAbstractTime,ue.asn1.ASN1Object),ue.asn1.DERAbstractStructured=function(e){ue.asn1.DERAbstractString.superclass.constructor.call(this),this.setByASN1ObjectArray=function(e){this.hTLV=null,this.isModified=!0,this.asn1Array=e},this.appendASN1Object=function(e){this.hTLV=null,this.isModified=!0,this.asn1Array.push(e)},this.asn1Array=new Array,void 0!==e&&void 0!==e.array&&(this.asn1Array=e.array)},Be(ue.asn1.DERAbstractStructured,ue.asn1.ASN1Object),ue.asn1.DERBoolean=function(e){ue.asn1.DERBoolean.superclass.constructor.call(this),this.hT="01",this.hTLV=0==e?"010100":"0101ff"},Be(ue.asn1.DERBoolean,ue.asn1.ASN1Object),ue.asn1.DERInteger=function(e){ue.asn1.DERInteger.superclass.constructor.call(this),this.hT="02",this.setByBigInteger=function(e){this.hTLV=null,this.isModified=!0,this.hV=ue.asn1.ASN1Util.bigIntToMinTwosComplementsHex(e)},this.setByInteger=function(e){var t=new b(String(e),10);this.setByBigInteger(t)},this.setValueHex=function(e){this.hV=e},this.getFreshValueHex=function(){return this.hV},void 0!==e&&(void 0!==e.bigint?this.setByBigInteger(e.bigint):void 0!==e.int?this.setByInteger(e.int):"number"==typeof e?this.setByInteger(e):void 0!==e.hex&&this.setValueHex(e.hex))},Be(ue.asn1.DERInteger,ue.asn1.ASN1Object),ue.asn1.DERBitString=function(e){if(void 0!==e&&void 0!==e.obj){var t=ue.asn1.ASN1Util.newObject(e.obj);e.hex="00"+t.getEncodedHex()}ue.asn1.DERBitString.superclass.constructor.call(this),this.hT="03",this.setHexValueIncludingUnusedBits=function(e){this.hTLV=null,this.isModified=!0,this.hV=e},this.setUnusedBitsAndHexValue=function(e,t){if(e<0||7i.length&&(i=n[r]);return(e=e.replace(i,"::")).slice(1,-1)}function De(e){var t="malformed hex value";if(!e.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/))throw t;if(8!=e.length)return 32==e.length?Le(e):e;try{return parseInt(e.substr(0,2),16)+"."+parseInt(e.substr(2,2),16)+"."+parseInt(e.substr(4,2),16)+"."+parseInt(e.substr(6,2),16)}catch(e){throw t}}function Ne(e){return e.match(/.{4}/g).map(function(e){var t=parseInt(e.substr(0,2),16),r=parseInt(e.substr(2),16);if(0==t&r<128)return String.fromCharCode(r);if(t<8){var n=128|63&r;return Se((192|(7&t)<<3|(192&r)>>6).toString(16)+n.toString(16))}n=128|(15&t)<<2|(192&r)>>6;var i=128|63&r;return Se((224|(240&t)>>4).toString(16)+n.toString(16)+i.toString(16))}).join("")}function Oe(e){for(var t=encodeURIComponent(e),r="",n=0;n"7"?"00"+e:e}le.getLblen=function(e,t){if("8"!=e.substr(t+2,1))return 1;var r=parseInt(e.substr(t+3,1));return 0==r?-1:0=n)break}return s},le.getNthChildIdx=function(e,t,r){return le.getChildIdx(e,t)[r]},le.getIdxbyList=function(e,t,r,n){var i,o,s=le;return 0==r.length?void 0!==n&&e.substr(t,2)!==n?-1:t:(i=r.shift())>=(o=s.getChildIdx(e,t)).length?-1:s.getIdxbyList(e,o[i],r,n)},le.getIdxbyListEx=function(e,t,r,n){var i,o,s=le;if(0==r.length)return void 0!==n&&e.substr(t,2)!==n?-1:t;i=r.shift(),o=s.getChildIdx(e,t);for(var a=0,u=0;u=e.length?null:i.getTLV(e,o)},le.getTLVbyListEx=function(e,t,r,n){var i=le,o=i.getIdxbyListEx(e,t,r,n);return-1==o?null:i.getTLV(e,o)},le.getVbyList=function(e,t,r,n,i){var o,s,a=le;return-1==(o=a.getIdxbyList(e,t,r,n))||o>=e.length?null:(s=a.getV(e,o),!0===i&&(s=s.substr(2)),s)},le.getVbyListEx=function(e,t,r,n,i){var o,s,a=le;return-1==(o=a.getIdxbyListEx(e,t,r,n))?null:(s=a.getV(e,o),"03"==e.substr(o,2)&&!1!==i&&(s=s.substr(2)),s)},le.getInt=function(e,t,r){null==r&&(r=-1);try{var n=e.substr(t,2);if("02"!=n&&"03"!=n)return r;var i=le.getV(e,t);return"02"==n?parseInt(i,16):function(e){try{var t=e.substr(0,2);if("00"==t)return parseInt(e.substr(2),16);var r=parseInt(t,16),n=e.substr(2),i=parseInt(n,16).toString(2);return"0"==i&&(i="00000000"),i=i.slice(0,0-r),parseInt(i,2)}catch(e){return-1}}(i)}catch(e){return r}},le.getOID=function(e,t,r){null==r&&(r=null);try{return"06"!=e.substr(t,2)?r:function(e){if(!He(e))return null;try{var t=[],r=e.substr(0,2),n=parseInt(r,16);t[0]=new String(Math.floor(n/40)),t[1]=new String(n%40);for(var i=e.substr(2),o=[],s=0;s0&&(c=c+"."+a.join(".")),c}catch(e){return null}}(le.getV(e,t))}catch(e){return r}},le.getOIDName=function(e,t,r){null==r&&(r=null);try{var n=le.getOID(e,t,r);if(n==r)return r;var i=ue.asn1.x509.OID.oid2name(n);return""==i?n:i}catch(e){return r}},le.getString=function(e,t,r){null==r&&(r=null);try{return be(le.getV(e,t))}catch(e){return r}},le.hextooidstr=function(e){var t=function(e,t){return e.length>=t?e:new Array(t-e.length+1).join("0")+e},r=[],n=e.substr(0,2),i=parseInt(n,16);r[0]=new String(Math.floor(i/40)),r[1]=new String(i%40);for(var o=e.substr(2),s=[],a=0;a0&&(h=h+"."+u.join(".")),h},le.dump=function(e,t,r,n){var i=le,o=i.getV,s=i.dump,a=i.getChildIdx,u=e;e instanceof ue.asn1.ASN1Object&&(u=e.getEncodedHex());var c=function(e,t){return e.length<=2*t?e:e.substr(0,t)+"..(total "+e.length/2+"bytes).."+e.substr(e.length-t,t)};void 0===t&&(t={ommit_long_octet:32}),void 0===r&&(r=0),void 0===n&&(n="");var h,l=t.ommit_long_octet;if("01"==(h=u.substr(r,2)))return"00"==(d=o(u,r))?n+"BOOLEAN FALSE\n":n+"BOOLEAN TRUE\n";if("02"==h)return n+"INTEGER "+c(d=o(u,r),l)+"\n";if("03"==h){var d=o(u,r);return i.isASN1HEX(d.substr(2))?(S=n+"BITSTRING, encapsulates\n")+s(d.substr(2),t,0,n+" "):n+"BITSTRING "+c(d,l)+"\n"}if("04"==h)return d=o(u,r),i.isASN1HEX(d)?(S=n+"OCTETSTRING, encapsulates\n")+s(d,t,0,n+" "):n+"OCTETSTRING "+c(d,l)+"\n";if("05"==h)return n+"NULL\n";if("06"==h){var f=o(u,r),p=ue.asn1.ASN1Util.oidHexToInt(f),g=ue.asn1.x509.OID.oid2name(p),y=p.replace(/\./g," ");return""!=g?n+"ObjectIdentifier "+g+" ("+y+")\n":n+"ObjectIdentifier ("+y+")\n"}if("0a"==h)return n+"ENUMERATED "+parseInt(o(u,r))+"\n";if("0c"==h)return n+"UTF8String '"+Se(o(u,r))+"'\n";if("13"==h)return n+"PrintableString '"+Se(o(u,r))+"'\n";if("14"==h)return n+"TeletexString '"+Se(o(u,r))+"'\n";if("16"==h)return n+"IA5String '"+Se(o(u,r))+"'\n";if("17"==h)return n+"UTCTime "+Se(o(u,r))+"\n";if("18"==h)return n+"GeneralizedTime "+Se(o(u,r))+"\n";if("1a"==h)return n+"VisualString '"+Se(o(u,r))+"'\n";if("1e"==h)return n+"BMPString '"+Ne(o(u,r))+"'\n";if("30"==h){if("3000"==u.substr(r,4))return n+"SEQUENCE {}\n";S=n+"SEQUENCE\n";var v=t;if((2==(_=a(u,r)).length||3==_.length)&&"06"==u.substr(_[0],2)&&"04"==u.substr(_[_.length-1],2)){g=i.oidname(o(u,_[0]));var m=JSON.parse(JSON.stringify(t));m.x509ExtName=g,v=m}for(var w=0;w<_.length;w++)S+=s(u,v,_[w],n+" ");return S}if("31"==h){S=n+"SET\n";var _=a(u,r);for(w=0;w<_.length;w++)S+=s(u,t,_[w],n+" ");return S}if(128&(h=parseInt(h,16))){var S,b=31&h;if(32&h){for(S=n+"["+b+"]\n",_=a(u,r),w=0;w<_.length;w++)S+=s(u,t,_[w],n+" ");return S}return d=o(u,r),le.isASN1HEX(d)?(S=n+"["+b+"]\n")+s(d,t,0,n+" "):(("68747470"==d.substr(0,8)||"subjectAltName"===t.x509ExtName&&2==b)&&(d=Se(d)),n+"["+b+"] "+d+"\n")}return n+"UNKNOWN("+h+") "+o(u,r)+"\n"},le.isContextTag=function(e,t){var r,n;e=e.toLowerCase();try{r=parseInt(e,16)}catch(e){return-1}if(void 0===t)return 128==(192&r);try{return null!=t.match(/^\[[0-9]+\]$/)&&!((n=parseInt(t.substr(1,t.length-1),10))>31)&&128==(192&r)&&(31&r)==n}catch(e){return!1}},le.isASN1HEX=function(e){var t=le;if(e.length%2==1)return!1;var r=t.getVblen(e,0),n=e.substr(0,2),i=t.getL(e,0);return e.length-n.length-i.length==2*r},le.checkStrictDER=function(e,t,r,n,i){var o=le;if(void 0===r){if("string"!=typeof e)throw new Error("not hex string");if(e=e.toLowerCase(),!ue.lang.String.isHex(e))throw new Error("not hex string");r=e.length,i=(n=e.length/2)<128?1:Math.ceil(n.toString(16))+1}if(o.getL(e,t).length>2*i)throw new Error("L of TLV too long: idx="+t);var s=o.getVblen(e,t);if(s>n)throw new Error("value of L too long than hex: idx="+t);var a=o.getTLV(e,t),u=a.length-2-o.getL(e,t).length;if(u!==2*s)throw new Error("V string length and L's value not the same:"+u+"/"+2*s);if(0===t&&e.length!=a.length)throw new Error("total length and TLV length unmatch:"+e.length+"!="+a.length);var c=e.substr(t,2);if("02"===c){var h=o.getVidx(e,t);if("00"==e.substr(h,2)&&e.charCodeAt(h+2)<56)throw new Error("not least zeros for DER INTEGER")}if(32&parseInt(c,16)){for(var l=o.getVblen(e,t),d=0,f=o.getChildIdx(e,t),p=0;p=t?e:new Array(t-e.length+1).join(r)+e};function Be(e,t){var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e,e.superclass=t.prototype,t.prototype.constructor==Object.prototype.constructor&&(t.prototype.constructor=t)}void 0!==ue&&ue||(t.KJUR=ue={}),void 0!==ue.crypto&&ue.crypto||(ue.crypto={}),ue.crypto.Util=new function(){this.DIGESTINFOHEAD={sha1:"3021300906052b0e03021a05000414",sha224:"302d300d06096086480165030402040500041c",sha256:"3031300d060960864801650304020105000420",sha384:"3041300d060960864801650304020205000430",sha512:"3051300d060960864801650304020305000440",md2:"3020300c06082a864886f70d020205000410",md5:"3020300c06082a864886f70d020505000410",ripemd160:"3021300906052b2403020105000414"},this.DEFAULTPROVIDER={md5:"cryptojs",sha1:"cryptojs",sha224:"cryptojs",sha256:"cryptojs",sha384:"cryptojs",sha512:"cryptojs",ripemd160:"cryptojs",hmacmd5:"cryptojs",hmacsha1:"cryptojs",hmacsha224:"cryptojs",hmacsha256:"cryptojs",hmacsha384:"cryptojs",hmacsha512:"cryptojs",hmacripemd160:"cryptojs",MD5withRSA:"cryptojs/jsrsa",SHA1withRSA:"cryptojs/jsrsa",SHA224withRSA:"cryptojs/jsrsa",SHA256withRSA:"cryptojs/jsrsa",SHA384withRSA:"cryptojs/jsrsa",SHA512withRSA:"cryptojs/jsrsa",RIPEMD160withRSA:"cryptojs/jsrsa",MD5withECDSA:"cryptojs/jsrsa",SHA1withECDSA:"cryptojs/jsrsa",SHA224withECDSA:"cryptojs/jsrsa",SHA256withECDSA:"cryptojs/jsrsa",SHA384withECDSA:"cryptojs/jsrsa",SHA512withECDSA:"cryptojs/jsrsa",RIPEMD160withECDSA:"cryptojs/jsrsa",SHA1withDSA:"cryptojs/jsrsa",SHA224withDSA:"cryptojs/jsrsa",SHA256withDSA:"cryptojs/jsrsa",MD5withRSAandMGF1:"cryptojs/jsrsa",SHAwithRSAandMGF1:"cryptojs/jsrsa",SHA1withRSAandMGF1:"cryptojs/jsrsa",SHA224withRSAandMGF1:"cryptojs/jsrsa",SHA256withRSAandMGF1:"cryptojs/jsrsa",SHA384withRSAandMGF1:"cryptojs/jsrsa",SHA512withRSAandMGF1:"cryptojs/jsrsa",RIPEMD160withRSAandMGF1:"cryptojs/jsrsa"},this.CRYPTOJSMESSAGEDIGESTNAME={md5:y.algo.MD5,sha1:y.algo.SHA1,sha224:y.algo.SHA224,sha256:y.algo.SHA256,sha384:y.algo.SHA384,sha512:y.algo.SHA512,ripemd160:y.algo.RIPEMD160},this.getDigestInfoHex=function(e,t){if(void 0===this.DIGESTINFOHEAD[t])throw"alg not supported in Util.DIGESTINFOHEAD: "+t;return this.DIGESTINFOHEAD[t]+e},this.getPaddedDigestInfoHex=function(e,t,r){var n=this.getDigestInfoHex(e,t),i=r/4;if(n.length+22>i)throw"key is too short for SigAlg: keylen="+r+","+t;for(var o="0001",s="00"+n,a="",u=i-4-s.length,c=0;c=0)return!1;if(n.compareTo(r.ONE)<0||n.compareTo(o)>=0)return!1;var a=n.modInverse(o),u=e.multiply(a).mod(o),c=t.multiply(a).mod(o);return s.multiply(u).add(i.multiply(c)).getX().toBigInteger().mod(o).equals(t)},this.serializeSig=function(e,t){var r=e.toByteArraySigned(),n=t.toByteArraySigned(),i=[];return i.push(2),i.push(r.length),(i=i.concat(r)).push(2),i.push(n.length),(i=i.concat(n)).unshift(i.length),i.unshift(48),i},this.parseSig=function(e){var t;if(48!=e[0])throw new Error("Signature not a valid DERSequence");if(2!=e[t=2])throw new Error("First element in signature must be a DERInteger");var n=e.slice(t+2,t+2+e[t+1]);if(2!=e[t+=2+e[t+1]])throw new Error("Second element in signature must be a DERInteger");var i=e.slice(t+2,t+2+e[t+1]);return t+=2+e[t+1],{r:r.fromByteArrayUnsigned(n),s:r.fromByteArrayUnsigned(i)}},this.parseSigCompact=function(e){if(65!==e.length)throw"Signature has the wrong length";var t=e[0]-27;if(t<0||t>7)throw"Invalid signature type";var n=this.ecparams.n;return{r:r.fromByteArrayUnsigned(e.slice(1,33)).mod(n),s:r.fromByteArrayUnsigned(e.slice(33,65)).mod(n),i:t}},this.readPKCS5PrvKeyHex=function(e){if(!1===c(e))throw new Error("not ASN.1 hex string");var t,r,n;try{t=u(e,0,["[0]",0],"06"),r=u(e,0,[1],"04");try{n=u(e,0,["[1]",0],"03")}catch(e){}}catch(e){throw new Error("malformed PKCS#1/5 plain ECC private key")}if(this.curveName=s(t),void 0===this.curveName)throw"unsupported curve name";this.setNamedCurve(this.curveName),this.setPublicKeyHex(n),this.setPrivateKeyHex(r),this.isPublic=!1},this.readPKCS8PrvKeyHex=function(e){if(!1===c(e))throw new t("not ASN.1 hex string");var r,n,i;try{u(e,0,[1,0],"06"),r=u(e,0,[1,1],"06"),n=u(e,0,[2,0,1],"04");try{i=u(e,0,[2,0,"[1]",0],"03")}catch(e){}}catch(e){throw new t("malformed PKCS#8 plain ECC private key")}if(this.curveName=s(r),void 0===this.curveName)throw new t("unsupported curve name");this.setNamedCurve(this.curveName),this.setPublicKeyHex(i),this.setPrivateKeyHex(n),this.isPublic=!1},this.readPKCS8PubKeyHex=function(e){if(!1===c(e))throw new t("not ASN.1 hex string");var r,n;try{u(e,0,[0,0],"06"),r=u(e,0,[0,1],"06"),n=u(e,0,[1],"03")}catch(e){throw new t("malformed PKCS#8 ECC public key")}if(this.curveName=s(r),null===this.curveName)throw new t("unsupported curve name");this.setNamedCurve(this.curveName),this.setPublicKeyHex(n)},this.readCertPubKeyHex=function(e,r){if(!1===c(e))throw new t("not ASN.1 hex string");var n,i;try{n=u(e,0,[0,5,0,1],"06"),i=u(e,0,[0,5,1],"03")}catch(e){throw new t("malformed X.509 certificate ECC public key")}if(this.curveName=s(n),null===this.curveName)throw new t("unsupported curve name");this.setNamedCurve(this.curveName),this.setPublicKeyHex(i)},void 0!==e&&void 0!==e.curve&&(this.curveName=e.curve),void 0===this.curveName&&(this.curveName="secp256r1"),this.setNamedCurve(this.curveName),void 0!==e&&(void 0!==e.prv&&this.setPrivateKeyHex(e.prv),void 0!==e.pub&&this.setPublicKeyHex(e.pub))},ue.crypto.ECDSA.parseSigHex=function(e){var t=ue.crypto.ECDSA.parseSigHexInHexRS(e);return{r:new b(t.r,16),s:new b(t.s,16)}},ue.crypto.ECDSA.parseSigHexInHexRS=function(e){var t=le,r=t.getChildIdx,n=t.getV;if(t.checkStrictDER(e,0),"30"!=e.substr(0,2))throw new Error("signature is not a ASN.1 sequence");var i=r(e,0);if(2!=i.length)throw new Error("signature shall have two elements");var o=i[0],s=i[1];if("02"!=e.substr(o,2))throw new Error("1st item not ASN.1 integer");if("02"!=e.substr(s,2))throw new Error("2nd item not ASN.1 integer");return{r:n(e,o),s:n(e,s)}},ue.crypto.ECDSA.asn1SigToConcatSig=function(e){var t=ue.crypto.ECDSA.parseSigHexInHexRS(e),r=t.r,n=t.s;if("00"==r.substr(0,2)&&r.length%32==2&&(r=r.substr(2)),"00"==n.substr(0,2)&&n.length%32==2&&(n=n.substr(2)),r.length%32==30&&(r="00"+r),n.length%32==30&&(n="00"+n),r.length%32!=0)throw"unknown ECDSA sig r length error";if(n.length%32!=0)throw"unknown ECDSA sig s length error";return r+n},ue.crypto.ECDSA.concatSigToASN1Sig=function(e){if(e.length/2*8%128!=0)throw"unknown ECDSA concatinated r-s sig length error";var t=e.substr(0,e.length/2),r=e.substr(e.length/2);return ue.crypto.ECDSA.hexRSSigToASN1Sig(t,r)},ue.crypto.ECDSA.hexRSSigToASN1Sig=function(e,t){var r=new b(e,16),n=new b(t,16);return ue.crypto.ECDSA.biRSSigToASN1Sig(r,n)},ue.crypto.ECDSA.biRSSigToASN1Sig=function(e,t){var r=ue.asn1,n=new r.DERInteger({bigint:e}),i=new r.DERInteger({bigint:t});return new r.DERSequence({array:[n,i]}).getEncodedHex()},ue.crypto.ECDSA.getName=function(e){return"2b8104001f"===e?"secp192k1":"2a8648ce3d030107"===e?"secp256r1":"2b8104000a"===e?"secp256k1":"2b81040021"===e?"secp224r1":"2b81040022"===e?"secp384r1":-1!=="|secp256r1|NIST P-256|P-256|prime256v1|".indexOf(e)?"secp256r1":-1!=="|secp256k1|".indexOf(e)?"secp256k1":-1!=="|secp224r1|NIST P-224|P-224|".indexOf(e)?"secp224r1":-1!=="|secp384r1|NIST P-384|P-384|".indexOf(e)?"secp384r1":null},void 0!==ue&&ue||(t.KJUR=ue={}),void 0!==ue.crypto&&ue.crypto||(ue.crypto={}),ue.crypto.ECParameterDB=new function(){var e={},t={};function r(e){return new b(e,16)}this.getByName=function(r){var n=r;if(void 0!==t[n]&&(n=t[r]),void 0!==e[n])return e[n];throw"unregistered EC curve name: "+n},this.regist=function(n,i,o,s,a,u,c,h,l,d,f,p){e[n]={};var g=r(o),y=r(s),v=r(a),m=r(u),w=r(c),_=new se(g,y,v),S=_.decodePointHex("04"+h+l);e[n].name=n,e[n].keylen=i,e[n].curve=_,e[n].G=S,e[n].n=m,e[n].h=w,e[n].oid=f,e[n].info=p;for(var b=0;b=2*a)break}var l={};return l.keyhex=u.substr(0,2*i[e].keylen),l.ivhex=u.substr(2*i[e].keylen,2*i[e].ivlen),l},a=function(e,t,r,n){var o=y.enc.Base64.parse(e),s=y.enc.Hex.stringify(o);return(0,i[t].proc)(s,r,n)};return{version:"1.0.0",parsePKCS5PEM:function(e){return o(e)},getKeyAndUnusedIvByPasscodeAndIvsalt:function(e,t,r){return s(e,t,r)},decryptKeyB64:function(e,t,r,n){return a(e,t,r,n)},getDecryptedKeyHex:function(e,t){var r=o(e),n=(r.type,r.cipher),i=r.ivsalt,u=r.data,c=s(n,t,i).keyhex;return a(u,n,c,i)},getEncryptedPKCS5PEMFromPrvKeyHex:function(e,t,r,n,o){var a="";if(void 0!==n&&null!=n||(n="AES-256-CBC"),void 0===i[n])throw new Error("KEYUTIL unsupported algorithm: "+n);void 0!==o&&null!=o||(o=function(e){var t=y.lib.WordArray.random(e);return y.enc.Hex.stringify(t)}(i[n].ivlen).toUpperCase());var u=function(e,t,r,n){return(0,i[t].eproc)(e,r,n)}(t,n,s(n,r,o).keyhex,o);return a="-----BEGIN "+e+" PRIVATE KEY-----\r\n",a+="Proc-Type: 4,ENCRYPTED\r\n",a+="DEK-Info: "+n+","+o+"\r\n",a+="\r\n",(a+=u.replace(/(.{64})/g,"$1\r\n"))+"\r\n-----END "+e+" PRIVATE KEY-----\r\n"},parseHexOfEncryptedPKCS8:function(e){var t=le,r=t.getChildIdx,n=t.getV,i={},o=r(e,0);if(2!=o.length)throw new Error("malformed format: SEQUENCE(0).items != 2: "+o.length);i.ciphertext=n(e,o[1]);var s=r(e,o[0]);if(2!=s.length)throw new Error("malformed format: SEQUENCE(0.0).items != 2: "+s.length);if("2a864886f70d01050d"!=n(e,s[0]))throw new Error("this only supports pkcs5PBES2");var a=r(e,s[1]);if(2!=s.length)throw new Error("malformed format: SEQUENCE(0.0.1).items != 2: "+a.length);var u=r(e,a[1]);if(2!=u.length)throw new Error("malformed format: SEQUENCE(0.0.1.1).items != 2: "+u.length);if("2a864886f70d0307"!=n(e,u[0]))throw"this only supports TripleDES";i.encryptionSchemeAlg="TripleDES",i.encryptionSchemeIV=n(e,u[1]);var c=r(e,a[0]);if(2!=c.length)throw new Error("malformed format: SEQUENCE(0.0.1.0).items != 2: "+c.length);if("2a864886f70d01050c"!=n(e,c[0]))throw new Error("this only supports pkcs5PBKDF2");var h=r(e,c[1]);if(h.length<2)throw new Error("malformed format: SEQUENCE(0.0.1.0.1).items < 2: "+h.length);i.pbkdf2Salt=n(e,h[0]);var l=n(e,h[1]);try{i.pbkdf2Iter=parseInt(l,16)}catch(e){throw new Error("malformed format pbkdf2Iter: "+l)}return i},getPBKDF2KeyHexFromParam:function(e,t){var r=y.enc.Hex.parse(e.pbkdf2Salt),n=e.pbkdf2Iter,i=y.PBKDF2(t,r,{keySize:6,iterations:n});return y.enc.Hex.stringify(i)},_getPlainPKCS8HexFromEncryptedPKCS8PEM:function(e,t){var r=Pe(e,"ENCRYPTED PRIVATE KEY"),n=this.parseHexOfEncryptedPKCS8(r),i=Ke.getPBKDF2KeyHexFromParam(n,t),o={};o.ciphertext=y.enc.Hex.parse(n.ciphertext);var s=y.enc.Hex.parse(i),a=y.enc.Hex.parse(n.encryptionSchemeIV),u=y.TripleDES.decrypt(o,s,{iv:a});return y.enc.Hex.stringify(u)},getKeyFromEncryptedPKCS8PEM:function(e,t){var r=this._getPlainPKCS8HexFromEncryptedPKCS8PEM(e,t);return this.getKeyFromPlainPrivatePKCS8Hex(r)},parsePlainPrivatePKCS8Hex:function(e){var t=le,r=t.getChildIdx,n=t.getV,i={algparam:null};if("30"!=e.substr(0,2))throw new Error("malformed plain PKCS8 private key(code:001)");var o=r(e,0);if(o.length<3)throw new Error("malformed plain PKCS8 private key(code:002)");if("30"!=e.substr(o[1],2))throw new Error("malformed PKCS8 private key(code:003)");var s=r(e,o[1]);if(2!=s.length)throw new Error("malformed PKCS8 private key(code:004)");if("06"!=e.substr(s[0],2))throw new Error("malformed PKCS8 private key(code:005)");if(i.algoid=n(e,s[0]),"06"==e.substr(s[1],2)&&(i.algparam=n(e,s[1])),"04"!=e.substr(o[2],2))throw new Error("malformed PKCS8 private key(code:006)");return i.keyidx=t.getVidx(e,o[2]),i},getKeyFromPlainPrivatePKCS8PEM:function(e){var t=Pe(e,"PRIVATE KEY");return this.getKeyFromPlainPrivatePKCS8Hex(t)},getKeyFromPlainPrivatePKCS8Hex:function(e){var t,r=this.parsePlainPrivatePKCS8Hex(e);if("2a864886f70d010101"==r.algoid)t=new ne;else if("2a8648ce380401"==r.algoid)t=new ue.crypto.DSA;else{if("2a8648ce3d0201"!=r.algoid)throw new Error("unsupported private key algorithm");t=new ue.crypto.ECDSA}return t.readPKCS8PrvKeyHex(e),t},_getKeyFromPublicPKCS8Hex:function(e){var t,r=le.getVbyList(e,0,[0,0],"06");if("2a864886f70d010101"===r)t=new ne;else if("2a8648ce380401"===r)t=new ue.crypto.DSA;else{if("2a8648ce3d0201"!==r)throw new Error("unsupported PKCS#8 public key hex");t=new ue.crypto.ECDSA}return t.readPKCS8PubKeyHex(e),t},parsePublicRawRSAKeyHex:function(e){var t=le,r=t.getChildIdx,n=t.getV,i={};if("30"!=e.substr(0,2))throw new Error("malformed RSA key(code:001)");var o=r(e,0);if(2!=o.length)throw new Error("malformed RSA key(code:002)");if("02"!=e.substr(o[0],2))throw new Error("malformed RSA key(code:003)");if(i.n=n(e,o[0]),"02"!=e.substr(o[1],2))throw new Error("malformed RSA key(code:004)");return i.e=n(e,o[1]),i},parsePublicPKCS8Hex:function(e){var t=le,r=t.getChildIdx,n=t.getV,i={algparam:null},o=r(e,0);if(2!=o.length)throw new Error("outer DERSequence shall have 2 elements: "+o.length);var s=o[0];if("30"!=e.substr(s,2))throw new Error("malformed PKCS8 public key(code:001)");var a=r(e,s);if(2!=a.length)throw new Error("malformed PKCS8 public key(code:002)");if("06"!=e.substr(a[0],2))throw new Error("malformed PKCS8 public key(code:003)");if(i.algoid=n(e,a[0]),"06"==e.substr(a[1],2)?i.algparam=n(e,a[1]):"30"==e.substr(a[1],2)&&(i.algparam={},i.algparam.p=t.getVbyList(e,a[1],[0],"02"),i.algparam.q=t.getVbyList(e,a[1],[1],"02"),i.algparam.g=t.getVbyList(e,a[1],[2],"02")),"03"!=e.substr(o[1],2))throw new Error("malformed PKCS8 public key(code:004)");return i.key=n(e,o[1]).substr(2),i}}}();function Ve(e,t){for(var r="",n=t/4-e.length,i=0;i>24,(16711680&i)>>16,(65280&i)>>8,255&i])))),i+=1;return n}function Je(e){for(var t in ue.crypto.Util.DIGESTINFOHEAD){var r=ue.crypto.Util.DIGESTINFOHEAD[t],n=r.length;if(e.substring(0,n)==r)return[t,e.substring(n)]}return[]}function We(e){var t,r=le,n=r.getChildIdx,i=r.getV,o=r.getTLV,s=r.getVbyList,a=r.getVbyListEx,u=r.getTLVbyList,c=r.getTLVbyListEx,h=r.getIdxbyList,l=r.getIdxbyListEx,d=r.getVidx,f=r.getInt,p=r.oidname,g=r.hextooidstr,y=Pe;try{t=ue.asn1.x509.AlgorithmIdentifier.PSSNAME2ASN1TLV}catch(e){}this.HEX2STAG={"0c":"utf8",13:"prn",16:"ia5","1a":"vis","1e":"bmp"},this.hex=null,this.version=0,this.foffset=0,this.aExtInfo=null,this.getVersion=function(){if(null===this.hex||0!==this.version)return this.version;var e=u(this.hex,0,[0,0]);if("a0"==e.substr(0,2)){var t=u(e,0,[0]),r=f(t,0);if(r<0||21){var a=o(e,s[1]),u=this.getGeneralName(a);null!=u.uri&&(i.uri=u.uri)}if(s.length>2){var c=o(e,s[2]);"0101ff"==c&&(i.reqauth=!0),"010100"==c&&(i.reqauth=!1)}return i},this.getX500NameRule=function(e){for(var t=null,r=[],n=0;n0&&(e.ext=this.getExtParamArray()),e.sighex=this.getSignatureValueHex(),e},this.getExtParamArray=function(e){null==e&&-1!=l(this.hex,0,[0,"[3]"])&&(e=c(this.hex,0,[0,"[3]",0],"30"));for(var t=[],r=n(e,0),i=0;i2&&"04"===y.substr(g[1],2)))throw new Error("unsupported PKCS#1/5 hexadecimal key");(T=new a).readPKCS5PrvKeyHex(y)}return T}if("pkcs8prv"===r)return l.getKeyFromPlainPrivatePKCS8Hex(e);if("pkcs8pub"===r)return l._getKeyFromPublicPKCS8Hex(e);if("x509pub"===r)return We.getPublicKeyFromCertHex(e);if(-1!=e.indexOf("-END CERTIFICATE-",0)||-1!=e.indexOf("-END X509 CERTIFICATE-",0)||-1!=e.indexOf("-END TRUSTED CERTIFICATE-",0))return We.getPublicKeyFromCertPEM(e);if(-1!=e.indexOf("-END PUBLIC KEY-")){var m=Pe(e,"PUBLIC KEY");return l._getKeyFromPublicPKCS8Hex(m)}if(-1!=e.indexOf("-END RSA PRIVATE KEY-")&&-1==e.indexOf("4,ENCRYPTED")){var w=h(e,"RSA PRIVATE KEY");return l.getKey(w,null,"pkcs5prv")}if(-1!=e.indexOf("-END DSA PRIVATE KEY-")&&-1==e.indexOf("4,ENCRYPTED")){var _=o(n=h(e,"DSA PRIVATE KEY"),0,[1],"02"),S=o(n,0,[2],"02"),E=o(n,0,[3],"02"),F=o(n,0,[4],"02"),x=o(n,0,[5],"02");return(T=new u).setPrivate(new b(_,16),new b(S,16),new b(E,16),new b(F,16),new b(x,16)),T}if(-1!=e.indexOf("-END EC PRIVATE KEY-")&&-1==e.indexOf("4,ENCRYPTED"))return w=h(e,"EC PRIVATE KEY"),l.getKey(w,null,"pkcs5prv");if(-1!=e.indexOf("-END PRIVATE KEY-"))return l.getKeyFromPlainPrivatePKCS8PEM(e);if(-1!=e.indexOf("-END RSA PRIVATE KEY-")&&-1!=e.indexOf("4,ENCRYPTED")){var A=l.getDecryptedKeyHex(e,t),k=new ne;return k.readPKCS5PrvKeyHex(A),k}if(-1!=e.indexOf("-END EC PRIVATE KEY-")&&-1!=e.indexOf("4,ENCRYPTED")){var P,T=o(n=l.getDecryptedKeyHex(e,t),0,[1],"04"),I=o(n,0,[2,0],"06"),C=o(n,0,[3,0],"03").substr(2);if(void 0===ue.crypto.OID.oidhex2name[I])throw new Error("undefined OID(hex) in KJUR.crypto.OID: "+I);return(P=new a({curve:ue.crypto.OID.oidhex2name[I]})).setPublicKeyHex(C),P.setPrivateKeyHex(T),P.isPublic=!1,P}if(-1!=e.indexOf("-END DSA PRIVATE KEY-")&&-1!=e.indexOf("4,ENCRYPTED"))return _=o(n=l.getDecryptedKeyHex(e,t),0,[1],"02"),S=o(n,0,[2],"02"),E=o(n,0,[3],"02"),F=o(n,0,[4],"02"),x=o(n,0,[5],"02"),(T=new u).setPrivate(new b(_,16),new b(S,16),new b(E,16),new b(F,16),new b(x,16)),T;if(-1!=e.indexOf("-END ENCRYPTED PRIVATE KEY-"))return l.getKeyFromEncryptedPKCS8PEM(e,t);throw new Error("not supported argument")},Ke.generateKeypair=function(e,t){if("RSA"==e){var r=t;(s=new ne).generate(r,"10001"),s.isPrivate=!0,s.isPublic=!0;var n=new ne,i=s.n.toString(16),o=s.e.toString(16);return n.setPublic(i,o),n.isPrivate=!1,n.isPublic=!0,(a={}).prvKeyObj=s,a.pubKeyObj=n,a}if("EC"==e){var s,a,u=t,c=new ue.crypto.ECDSA({curve:u}).generateKeyPairHex();return(s=new ue.crypto.ECDSA({curve:u})).setPublicKeyHex(c.ecpubhex),s.setPrivateKeyHex(c.ecprvhex),s.isPrivate=!0,s.isPublic=!1,(n=new ue.crypto.ECDSA({curve:u})).setPublicKeyHex(c.ecpubhex),n.isPrivate=!1,n.isPublic=!0,(a={}).prvKeyObj=s,a.pubKeyObj=n,a}throw new Error("unknown algorithm: "+e)},Ke.getPEM=function(e,t,r,n,i,o){var s=ue,a=s.asn1,u=a.DERObjectIdentifier,c=a.DERInteger,h=a.ASN1Util.newObject,l=a.x509.SubjectPublicKeyInfo,d=s.crypto,f=d.DSA,p=d.ECDSA,g=ne;function v(e){return h({seq:[{int:0},{int:{bigint:e.n}},{int:e.e},{int:{bigint:e.d}},{int:{bigint:e.p}},{int:{bigint:e.q}},{int:{bigint:e.dmp1}},{int:{bigint:e.dmq1}},{int:{bigint:e.coeff}}]})}function m(e){return h({seq:[{int:1},{octstr:{hex:e.prvKeyHex}},{tag:["a0",!0,{oid:{name:e.curveName}}]},{tag:["a1",!0,{bitstr:{hex:"00"+e.pubKeyHex}}]}]})}function w(e){return h({seq:[{int:0},{int:{bigint:e.p}},{int:{bigint:e.q}},{int:{bigint:e.g}},{int:{bigint:e.y}},{int:{bigint:e.x}}]})}if((void 0!==g&&e instanceof g||void 0!==f&&e instanceof f||void 0!==p&&e instanceof p)&&1==e.isPublic&&(void 0===t||"PKCS8PUB"==t))return ke(E=new l(e).getEncodedHex(),"PUBLIC KEY");if("PKCS1PRV"==t&&void 0!==g&&e instanceof g&&(void 0===r||null==r)&&1==e.isPrivate)return ke(E=v(e).getEncodedHex(),"RSA PRIVATE KEY");if("PKCS1PRV"==t&&void 0!==p&&e instanceof p&&(void 0===r||null==r)&&1==e.isPrivate){var _=new u({name:e.curveName}).getEncodedHex(),S=m(e).getEncodedHex(),b="";return(b+=ke(_,"EC PARAMETERS"))+ke(S,"EC PRIVATE KEY")}if("PKCS1PRV"==t&&void 0!==f&&e instanceof f&&(void 0===r||null==r)&&1==e.isPrivate)return ke(E=w(e).getEncodedHex(),"DSA PRIVATE KEY");if("PKCS5PRV"==t&&void 0!==g&&e instanceof g&&void 0!==r&&null!=r&&1==e.isPrivate){var E=v(e).getEncodedHex();return void 0===n&&(n="DES-EDE3-CBC"),this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA",E,r,n,o)}if("PKCS5PRV"==t&&void 0!==p&&e instanceof p&&void 0!==r&&null!=r&&1==e.isPrivate)return E=m(e).getEncodedHex(),void 0===n&&(n="DES-EDE3-CBC"),this.getEncryptedPKCS5PEMFromPrvKeyHex("EC",E,r,n,o);if("PKCS5PRV"==t&&void 0!==f&&e instanceof f&&void 0!==r&&null!=r&&1==e.isPrivate)return E=w(e).getEncodedHex(),void 0===n&&(n="DES-EDE3-CBC"),this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA",E,r,n,o);var F=function(e,t){var r=x(e,t);return new h({seq:[{seq:[{oid:{name:"pkcs5PBES2"}},{seq:[{seq:[{oid:{name:"pkcs5PBKDF2"}},{seq:[{octstr:{hex:r.pbkdf2Salt}},{int:r.pbkdf2Iter}]}]},{seq:[{oid:{name:"des-EDE3-CBC"}},{octstr:{hex:r.encryptionSchemeIV}}]}]}]},{octstr:{hex:r.ciphertext}}]}).getEncodedHex()},x=function(e,t){var r=y.lib.WordArray.random(8),n=y.lib.WordArray.random(8),i=y.PBKDF2(t,r,{keySize:6,iterations:100}),o=y.enc.Hex.parse(e),s=y.TripleDES.encrypt(o,i,{iv:n})+"",a={};return a.ciphertext=s,a.pbkdf2Salt=y.enc.Hex.stringify(r),a.pbkdf2Iter=100,a.encryptionSchemeAlg="DES-EDE3-CBC",a.encryptionSchemeIV=y.enc.Hex.stringify(n),a};if("PKCS8PRV"==t&&null!=g&&e instanceof g&&1==e.isPrivate){var A=v(e).getEncodedHex();return E=h({seq:[{int:0},{seq:[{oid:{name:"rsaEncryption"}},{null:!0}]},{octstr:{hex:A}}]}).getEncodedHex(),void 0===r||null==r?ke(E,"PRIVATE KEY"):ke(S=F(E,r),"ENCRYPTED PRIVATE KEY")}if("PKCS8PRV"==t&&void 0!==p&&e instanceof p&&1==e.isPrivate)return A=new h({seq:[{int:1},{octstr:{hex:e.prvKeyHex}},{tag:["a1",!0,{bitstr:{hex:"00"+e.pubKeyHex}}]}]}).getEncodedHex(),E=h({seq:[{int:0},{seq:[{oid:{name:"ecPublicKey"}},{oid:{name:e.curveName}}]},{octstr:{hex:A}}]}).getEncodedHex(),void 0===r||null==r?ke(E,"PRIVATE KEY"):ke(S=F(E,r),"ENCRYPTED PRIVATE KEY");if("PKCS8PRV"==t&&void 0!==f&&e instanceof f&&1==e.isPrivate)return A=new c({bigint:e.x}).getEncodedHex(),E=h({seq:[{int:0},{seq:[{oid:{name:"dsa"}},{seq:[{int:{bigint:e.p}},{int:{bigint:e.q}},{int:{bigint:e.g}}]}]},{octstr:{hex:A}}]}).getEncodedHex(),void 0===r||null==r?ke(E,"PRIVATE KEY"):ke(S=F(E,r),"ENCRYPTED PRIVATE KEY");throw new Error("unsupported object nor format")},Ke.getKeyFromCSRPEM=function(e){var t=Pe(e,"CERTIFICATE REQUEST");return Ke.getKeyFromCSRHex(t)},Ke.getKeyFromCSRHex=function(e){var t=Ke.parseCSRHex(e);return Ke.getKey(t.p8pubkeyhex,null,"pkcs8pub")},Ke.parseCSRHex=function(e){var t=le,r=t.getChildIdx,n=t.getTLV,i={},o=e;if("30"!=o.substr(0,2))throw new Error("malformed CSR(code:001)");var s=r(o,0);if(s.length<1)throw new Error("malformed CSR(code:002)");if("30"!=o.substr(s[0],2))throw new Error("malformed CSR(code:003)");var a=r(o,s[0]);if(a.length<3)throw new Error("malformed CSR(code:004)");return i.p8pubkeyhex=n(o,a[2]),i},Ke.getKeyID=function(e){var t=Ke,r=le;"string"==typeof e&&-1!=e.indexOf("BEGIN ")&&(e=t.getKey(e));var n=Pe(t.getPEM(e)),i=r.getIdxbyList(n,0,[1]),o=r.getV(n,i).substring(2);return ue.crypto.Util.hashHex(o,"sha1")},Ke.getJWKFromKey=function(e){var t={};if(e instanceof ne&&e.isPrivate)return t.kty="RSA",t.n=me(e.n.toString(16)),t.e=me(e.e.toString(16)),t.d=me(e.d.toString(16)),t.p=me(e.p.toString(16)),t.q=me(e.q.toString(16)),t.dp=me(e.dmp1.toString(16)),t.dq=me(e.dmq1.toString(16)),t.qi=me(e.coeff.toString(16)),t;if(e instanceof ne&&e.isPublic)return t.kty="RSA",t.n=me(e.n.toString(16)),t.e=me(e.e.toString(16)),t;if(e instanceof ue.crypto.ECDSA&&e.isPrivate){if("P-256"!==(n=e.getShortNISTPCurveName())&&"P-384"!==n)throw new Error("unsupported curve name for JWT: "+n);var r=e.getPublicKeyXYHex();return t.kty="EC",t.crv=n,t.x=me(r.x),t.y=me(r.y),t.d=me(e.prvKeyHex),t}if(e instanceof ue.crypto.ECDSA&&e.isPublic){var n;if("P-256"!==(n=e.getShortNISTPCurveName())&&"P-384"!==n)throw new Error("unsupported curve name for JWT: "+n);return r=e.getPublicKeyXYHex(),t.kty="EC",t.crv=n,t.x=me(r.x),t.y=me(r.y),t}throw new Error("not supported key object")},ne.getPosArrayOfChildrenFromHex=function(e){return le.getChildIdx(e,0)},ne.getHexValueArrayOfChildrenFromHex=function(e){var t,r=le.getV,n=r(e,(t=ne.getPosArrayOfChildrenFromHex(e))[0]),i=r(e,t[1]),o=r(e,t[2]),s=r(e,t[3]),a=r(e,t[4]),u=r(e,t[5]),c=r(e,t[6]),h=r(e,t[7]),l=r(e,t[8]);return(t=new Array).push(n,i,o,s,a,u,c,h,l),t},ne.prototype.readPrivateKeyFromPEMString=function(e){var t=Pe(e),r=ne.getHexValueArrayOfChildrenFromHex(t);this.setPrivateEx(r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8])},ne.prototype.readPKCS5PrvKeyHex=function(e){var t=ne.getHexValueArrayOfChildrenFromHex(e);this.setPrivateEx(t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},ne.prototype.readPKCS8PrvKeyHex=function(e){var t,r,n,i,o,s,a,u,c=le,h=c.getVbyListEx;if(!1===c.isASN1HEX(e))throw new Error("not ASN.1 hex string");try{t=h(e,0,[2,0,1],"02"),r=h(e,0,[2,0,2],"02"),n=h(e,0,[2,0,3],"02"),i=h(e,0,[2,0,4],"02"),o=h(e,0,[2,0,5],"02"),s=h(e,0,[2,0,6],"02"),a=h(e,0,[2,0,7],"02"),u=h(e,0,[2,0,8],"02")}catch(e){throw new Error("malformed PKCS#8 plain RSA private key")}this.setPrivateEx(t,r,n,i,o,s,a,u)},ne.prototype.readPKCS5PubKeyHex=function(e){var t=le,r=t.getV;if(!1===t.isASN1HEX(e))throw new Error("keyHex is not ASN.1 hex string");var n=t.getChildIdx(e,0);if(2!==n.length||"02"!==e.substr(n[0],2)||"02"!==e.substr(n[1],2))throw new Error("wrong hex for PKCS#5 public key");var i=r(e,n[0]),o=r(e,n[1]);this.setPublic(i,o)},ne.prototype.readPKCS8PubKeyHex=function(e){var t=le;if(!1===t.isASN1HEX(e))throw new Error("not ASN.1 hex string");if("06092a864886f70d010101"!==t.getTLVbyListEx(e,0,[0,0]))throw new Error("not PKCS8 RSA public key");var r=t.getTLVbyListEx(e,0,[1,0]);this.readPKCS5PubKeyHex(r)},ne.prototype.readCertPubKeyHex=function(e,t){var r,n;(r=new We).readCertHex(e),n=r.getPublicKeyHex(),this.readPKCS8PubKeyHex(n)},new RegExp("[^0-9a-f]","gi"),ne.prototype.sign=function(e,t){var r=function(e){return ue.crypto.Util.hashString(e,t)}(e);return this.signWithMessageHash(r,t)},ne.prototype.signWithMessageHash=function(e,t){var r=te(ue.crypto.Util.getPaddedDigestInfoHex(e,t,this.n.bitLength()),16);return Ve(this.doPrivate(r).toString(16),this.n.bitLength())},ne.prototype.signPSS=function(e,t,r){var n=function(e){return ue.crypto.Util.hashHex(e,t)}(Ee(e));return void 0===r&&(r=-1),this.signWithMessageHashPSS(n,t,r)},ne.prototype.signWithMessageHashPSS=function(e,t,r){var n,i=be(e),o=i.length,s=this.n.bitLength()-1,a=Math.ceil(s/8),u=function(e){return ue.crypto.Util.hashHex(e,t)};if(-1===r||void 0===r)r=o;else if(-2===r)r=a-o-2;else if(r<-2)throw new Error("invalid salt length");if(a0&&(c=new Array(r),(new ee).nextBytes(c),c=String.fromCharCode.apply(String,c));var h=be(u(Ee("\0\0\0\0\0\0\0\0"+i+c))),l=[];for(n=0;n>8*a-s&255;for(p[0]&=~g,n=0;nn)return!1;var i=this.doPublic(r).toString(16);if(i.length+3!=n/4)return!1;var o=Je(i.replace(/^1f+00/,""));if(0==o.length)return!1;var s=o[0];return o[1]==function(e){return ue.crypto.Util.hashString(e,s)}(e)},ne.prototype.verifyWithMessageHash=function(e,t){if(t.length!=Math.ceil(this.n.bitLength()/4))return!1;var r=te(t,16);if(r.bitLength()>this.n.bitLength())return 0;var n=Je(this.doPublic(r).toString(16).replace(/^1f+00/,""));return 0!=n.length&&(n[0],n[1]==e)},ne.prototype.verifyPSS=function(e,t,r,n){var i=function(e){return ue.crypto.Util.hashHex(e,r)}(Ee(e));return void 0===n&&(n=-1),this.verifyWithMessageHashPSS(i,t,r,n)},ne.prototype.verifyWithMessageHashPSS=function(e,t,r,n){if(t.length!=Math.ceil(this.n.bitLength()/4))return!1;var i,o=new b(t,16),s=function(e){return ue.crypto.Util.hashHex(e,r)},a=be(e),u=a.length,c=this.n.bitLength()-1,h=Math.ceil(c/8);if(-1===n||void 0===n)n=u;else if(-2===n)n=h-u-2;else if(n<-2)throw new Error("invalid salt length");if(h>8*h-c&255;if(0!=(d.charCodeAt(0)&p))throw new Error("bits beyond keysize not zero");var g=qe(f,d.length,s),y=[];for(i=0;i0&&-1==(":"+r.join(":")+":").indexOf(":"+v+":"))throw"algorithm '"+v+"' not accepted in the list";if("none"!=v&&null===t)throw"key shall be specified to verify.";if("string"==typeof t&&-1!=t.indexOf("-----BEGIN ")&&(t=Ke.getKey(t)),!("RS"!=d&&"PS"!=d||t instanceof n))throw"key shall be a RSAKey obj for RS* and PS* algs";if("ES"==d&&!(t instanceof u))throw"key shall be a ECDSA obj for ES* algs";var m=null;if(void 0===o.jwsalg2sigalg[y.alg])throw"unsupported alg name: "+v;if("none"==(m=o.jwsalg2sigalg[v]))throw"not supported";if("Hmac"==m.substr(0,4)){if(void 0===t)throw"hexadecimal key shall be specified for HMAC";var w=new c({alg:m,pass:t});return w.updateString(p),g==w.doFinal()}if(-1!=m.indexOf("withECDSA")){var _,S=null;try{S=u.concatSigToASN1Sig(g)}catch(e){return!1}return(_=new h({alg:m})).init(t),_.updateString(p),_.verify(S)}return(_=new h({alg:m})).init(t),_.updateString(p),_.verify(g)},ue.jws.JWS.parse=function(e){var t,r,n,i=e.split("."),o={};if(2!=i.length&&3!=i.length)throw"malformed sJWS: wrong number of '.' splitted elements";return t=i[0],r=i[1],3==i.length&&(n=i[2]),o.headerObj=ue.jws.JWS.readSafeJSONString(he(t)),o.payloadObj=ue.jws.JWS.readSafeJSONString(he(r)),o.headerPP=JSON.stringify(o.headerObj,null," "),null==o.payloadObj?o.payloadPP=he(r):o.payloadPP=JSON.stringify(o.payloadObj,null," "),void 0!==n&&(o.sigHex=we(n)),o},ue.jws.JWS.verifyJWT=function(e,t,r){var n=ue.jws,i=n.JWS,o=i.readSafeJSONString,s=i.inArray,a=i.includedArray,u=e.split("."),c=u[0],h=u[1],l=(we(u[2]),o(he(c))),d=o(he(h));if(void 0===l.alg)return!1;if(void 0===r.alg)throw"acceptField.alg shall be specified";if(!s(l.alg,r.alg))return!1;if(void 0!==d.iss&&"object"===f(r.iss)&&!s(d.iss,r.iss))return!1;if(void 0!==d.sub&&"object"===f(r.sub)&&!s(d.sub,r.sub))return!1;if(void 0!==d.aud&&"object"===f(r.aud))if("string"==typeof d.aud){if(!s(d.aud,r.aud))return!1}else if("object"==f(d.aud)&&!a(d.aud,r.aud))return!1;var p=n.IntDate.getNow();return void 0!==r.verifyAt&&"number"==typeof r.verifyAt&&(p=r.verifyAt),void 0!==r.gracePeriod&&"number"==typeof r.gracePeriod||(r.gracePeriod=0),!(void 0!==d.exp&&"number"==typeof d.exp&&d.exp+r.gracePeriodt.length&&(r=t.length);for(var n=0;n + * @license MIT + */ +var n=r(30),i=r(31),o=r(32);function s(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(e,t){if(s()=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|e}function p(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return B(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return K(e).length;default:if(n)return B(e).length;t=(""+t).toLowerCase(),n=!0}}function g(e,t,r){var n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,r);case"utf8":case"utf-8":return A(this,t,r);case"ascii":return P(this,t,r);case"latin1":case"binary":return T(this,t,r);case"base64":return x(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function y(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function v(e,t,r,n,i){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof t&&(t=u.from(t,n)),u.isBuffer(t))return 0===t.length?-1:m(e,t,r,n,i);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):m(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function m(e,t,r,n,i){var o,s=1,a=e.length,u=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;s=2,a/=2,u/=2,r/=2}function c(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var h=-1;for(o=r;oa&&(r=a-u),o=r;o>=0;o--){for(var l=!0,d=0;di&&(n=i):n=i;var o=t.length;if(o%2!=0)throw new TypeError("Invalid hex string");n>o/2&&(n=o/2);for(var s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function x(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function A(e,t,r){r=Math.min(e.length,r);for(var n=[],i=t;i239?4:c>223?3:c>191?2:1;if(i+l<=r)switch(l){case 1:c<128&&(h=c);break;case 2:128==(192&(o=e[i+1]))&&(u=(31&c)<<6|63&o)>127&&(h=u);break;case 3:o=e[i+1],s=e[i+2],128==(192&o)&&128==(192&s)&&(u=(15&c)<<12|(63&o)<<6|63&s)>2047&&(u<55296||u>57343)&&(h=u);break;case 4:o=e[i+1],s=e[i+2],a=e[i+3],128==(192&o)&&128==(192&s)&&128==(192&a)&&(u=(15&c)<<18|(63&o)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(h=u)}null===h?(h=65533,l=1):h>65535&&(h-=65536,n.push(h>>>10&1023|55296),h=56320|1023&h),n.push(h),i+=l}return function(e){var t=e.length;if(t<=k)return String.fromCharCode.apply(String,e);for(var r="",n=0;n0&&(e=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(e+=" ... ")),""},u.prototype.compare=function(e,t,r,n,i){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&t>=r)return 0;if(n>=i)return-1;if(t>=r)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0),a=Math.min(o,s),c=this.slice(n,i),h=e.slice(t,r),l=0;li)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o=!1;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return _(this,e,t,r);case"ascii":return S(this,e,t,r);case"latin1":case"binary":return b(this,e,t,r);case"base64":return E(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return F(this,e,t,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var k=4096;function P(e,t,r){var n="";r=Math.min(e.length,r);for(var i=t;in)&&(r=n);for(var i="",o=t;or)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,r,n,i,o){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function L(e,t,r,n){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-r,2);i>>8*(n?i:1-i)}function D(e,t,r,n){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-r,4);i>>8*(n?i:3-i)&255}function N(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function O(e,t,r,n,o){return o||N(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function H(e,t,r,n,o){return o||N(e,0,r,8),i.write(e,t,r,n,52,8),r+8}u.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t0&&(i*=256);)n+=this[e+--t]*i;return n},u.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,r){e|=0,t|=0,r||R(e,t,this.length);for(var n=this[e],i=1,o=0;++o=(i*=128)&&(n-=Math.pow(2,8*t)),n},u.prototype.readIntBE=function(e,t,r){e|=0,t|=0,r||R(e,t,this.length);for(var n=t,i=1,o=this[e+--n];n>0&&(i*=256);)o+=this[e+--n]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*t)),o},u.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},u.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},u.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),i.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),i.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),i.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||R(e,8,this.length),i.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,r,n){e=+e,t|=0,r|=0,n||U(this,e,t,r,Math.pow(2,8*r)-1,0);var i=1,o=0;for(this[t]=255&e;++o=0&&(o*=256);)this[t+i]=e/o&255;return t+r},u.prototype.writeUInt8=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):D(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);U(this,e,t,r,i-1,-i)}var o=0,s=1,a=0;for(this[t]=255&e;++o=0&&(s*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/s|0)-a&255;return t+r},u.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):D(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||U(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,r){return O(this,e,t,!0,r)},u.prototype.writeFloatBE=function(e,t,r){return O(this,e,t,!1,r)},u.prototype.writeDoubleLE=function(e,t,r){return H(this,e,t,!0,r)},u.prototype.writeDoubleBE=function(e,t,r){return H(this,e,t,!1,r)},u.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t=0;--i)e[i+t]=this[i+r];else if(o<1e3||!u.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320)}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r)}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function K(e){return n.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(j,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function V(e,t,r,n){for(var i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}}).call(this,r(29))},function(e,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"==typeof window&&(r=window)}e.exports=r},function(e,t,r){"use strict";t.byteLength=function(e){var t=u(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,n=u(e),s=n[0],a=n[1],c=new o(function(e,t,r){return 3*(t+r)/4-r}(0,s,a)),h=0,l=a>0?s-4:s;for(r=0;r>16&255,c[h++]=t>>8&255,c[h++]=255&t;return 2===a&&(t=i[e.charCodeAt(r)]<<2|i[e.charCodeAt(r+1)]>>4,c[h++]=255&t),1===a&&(t=i[e.charCodeAt(r)]<<10|i[e.charCodeAt(r+1)]<<4|i[e.charCodeAt(r+2)]>>2,c[h++]=t>>8&255,c[h++]=255&t),c},t.fromByteArray=function(e){for(var t,r=e.length,i=r%3,o=[],s=16383,a=0,u=r-i;au?u:a+s));return 1===i?(t=e[r-1],o.push(n[t>>2]+n[t<<4&63]+"==")):2===i&&(t=(e[r-2]<<8)+e[r-1],o.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"=")),o.join("")};for(var n=[],i=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0;a<64;++a)n[a]=s[a],i[s.charCodeAt(a)]=a;function u(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function c(e,t,r){for(var i,o,s=[],a=t;a>18&63]+n[o>>12&63]+n[o>>6&63]+n[63&o]);return s.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(e,t){ +/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ +t.read=function(e,t,r,n,i){var o,s,a=8*i-n-1,u=(1<>1,h=-7,l=r?i-1:0,d=r?-1:1,f=e[t+l];for(l+=d,o=f&(1<<-h)-1,f>>=-h,h+=a;h>0;o=256*o+e[t+l],l+=d,h-=8);for(s=o&(1<<-h)-1,o>>=-h,h+=n;h>0;s=256*s+e[t+l],l+=d,h-=8);if(0===o)o=1-c;else{if(o===u)return s?NaN:1/0*(f?-1:1);s+=Math.pow(2,n),o-=c}return(f?-1:1)*s*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var s,a,u,c=8*o-i-1,h=(1<>1,d=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:o-1,p=n?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=h):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),(t+=s+l>=1?d/u:d*Math.pow(2,1-l))*u>=2&&(s++,u/=2),s+l>=h?(a=0,s=h):s+l>=1?(a=(t*u-1)*Math.pow(2,i),s+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,i),s=0));i>=8;e[r+f]=255&a,f+=p,a/=256,i-=8);for(s=s<0;e[r+f]=255&s,f+=p,s/=256,c-=8);e[r+f-p]|=128*g}},function(e,t){var r={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.jws,r=e.KeyUtil,i=e.X509,o=e.crypto,s=e.hextob64u,a=e.b64tohex,u=e.AllowedSigningAlgs;return function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)}return e.parseJwt=function e(r){n.Log.debug("JoseUtil.parseJwt");try{var i=t.JWS.parse(r);return{header:i.headerObj,payload:i.payloadObj}}catch(e){n.Log.error(e)}},e.validateJwt=function(t,o,s,u,c,h,l){n.Log.debug("JoseUtil.validateJwt");try{if("RSA"===o.kty)if(o.e&&o.n)o=r.getKey(o);else{if(!o.x5c||!o.x5c.length)return n.Log.error("JoseUtil.validateJwt: RSA key missing key material",o),Promise.reject(new Error("RSA key missing key material"));var d=a(o.x5c[0]);o=i.getPublicKeyFromCertHex(d)}else{if("EC"!==o.kty)return n.Log.error("JoseUtil.validateJwt: Unsupported key type",o&&o.kty),Promise.reject(new Error(o.kty));if(!(o.crv&&o.x&&o.y))return n.Log.error("JoseUtil.validateJwt: EC key missing key material",o),Promise.reject(new Error("EC key missing key material"));o=r.getKey(o)}return e._validateJwt(t,o,s,u,c,h,l)}catch(e){return n.Log.error(e&&e.message||e),Promise.reject("JWT validation failed")}},e.validateJwtAttributes=function(t,r,i,o,s,a){o||(o=0),s||(s=parseInt(Date.now()/1e3));var u=e.parseJwt(t).payload;if(!u.iss)return n.Log.error("JoseUtil._validateJwt: issuer was not provided"),Promise.reject(new Error("issuer was not provided"));if(u.iss!==r)return n.Log.error("JoseUtil._validateJwt: Invalid issuer in token",u.iss),Promise.reject(new Error("Invalid issuer in token: "+u.iss));if(!u.aud)return n.Log.error("JoseUtil._validateJwt: aud was not provided"),Promise.reject(new Error("aud was not provided"));if(!(u.aud===i||Array.isArray(u.aud)&&u.aud.indexOf(i)>=0))return n.Log.error("JoseUtil._validateJwt: Invalid audience in token",u.aud),Promise.reject(new Error("Invalid audience in token: "+u.aud));if(u.azp&&u.azp!==i)return n.Log.error("JoseUtil._validateJwt: Invalid azp in token",u.azp),Promise.reject(new Error("Invalid azp in token: "+u.azp));if(!a){var c=s+o,h=s-o;if(!u.iat)return n.Log.error("JoseUtil._validateJwt: iat was not provided"),Promise.reject(new Error("iat was not provided"));if(c1&&void 0!==arguments[1]?arguments[1]:"#";!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e);var n=i.UrlUtility.parseUrlFragment(t,r);this.error=n.error,this.error_description=n.error_description,this.error_uri=n.error_uri,this.code=n.code,this.state=n.state,this.id_token=n.id_token,this.session_state=n.session_state,this.access_token=n.access_token,this.token_type=n.token_type,this.scope=n.scope,this.profile=void 0,this.expires_in=n.expires_in}return n(e,[{key:"expires_in",get:function(){if(this.expires_at){var e=parseInt(Date.now()/1e3);return this.expires_at-e}},set:function(e){var t=parseInt(e);if("number"==typeof t&&t>0){var r=parseInt(Date.now()/1e3);this.expires_at=r+t}}},{key:"expired",get:function(){var e=this.expires_in;if(void 0!==e)return e<=0}},{key:"scopes",get:function(){return(this.scope||"").split(" ")}},{key:"isOpenIdConnect",get:function(){return this.scopes.indexOf("openid")>=0||!!this.id_token}}]),e}()},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SignoutRequest=void 0;var n=r(0),i=r(3),o=r(9);t.SignoutRequest=function e(t){var r=t.url,s=t.id_token_hint,a=t.post_logout_redirect_uri,u=t.data,c=t.extraQueryParams,h=t.request_type;if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),!r)throw n.Log.error("SignoutRequest.ctor: No url passed"),new Error("url");for(var l in s&&(r=i.UrlUtility.addQueryParam(r,"id_token_hint",s)),a&&(r=i.UrlUtility.addQueryParam(r,"post_logout_redirect_uri",a),u&&(this.state=new o.State({data:u,request_type:h}),r=i.UrlUtility.addQueryParam(r,"state",this.state.id))),c)r=i.UrlUtility.addQueryParam(r,l,c[l]);this.url=r}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SignoutResponse=void 0;var n=r(3);t.SignoutResponse=function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e);var r=n.UrlUtility.parseUrlFragment(t,"?");this.error=r.error,this.error_description=r.error_description,this.error_uri=r.error_uri,this.state=r.state}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.InMemoryWebStorage=void 0;var n=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c.SilentRenewService,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:h.SessionMonitor,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:d.TokenRevocationClient,l=arguments.length>4&&void 0!==arguments[4]?arguments[4]:f.TokenClient,g=arguments.length>5&&void 0!==arguments[5]?arguments[5]:p.JoseUtil;(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,t),r instanceof s.UserManagerSettings||(r=new s.UserManagerSettings(r));var y=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this,r));return y._events=new u.UserManagerEvents(r),y._silentRenewService=new n(y),y.settings.automaticSilentRenew&&(i.Log.debug("UserManager.ctor: automaticSilentRenew is configured, setting up silent renew"),y.startSilentRenew()),y.settings.monitorSession&&(i.Log.debug("UserManager.ctor: monitorSession is configured, setting up session monitor"),y._sessionMonitor=new o(y)),y._tokenRevocationClient=new a(y._settings),y._tokenClient=new l(y._settings),y._joseUtil=g,y}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.getUser=function(){var e=this;return this._loadUser().then(function(t){return t?(i.Log.info("UserManager.getUser: user loaded"),e._events.load(t,!1),t):(i.Log.info("UserManager.getUser: user not found in storage"),null)})},t.prototype.removeUser=function(){var e=this;return this.storeUser(null).then(function(){i.Log.info("UserManager.removeUser: user removed from storage"),e._events.unload()})},t.prototype.signinRedirect=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(e=Object.assign({},e)).request_type="si:r";var t={useReplaceToNavigate:e.useReplaceToNavigate};return this._signinStart(e,this._redirectNavigator,t).then(function(){i.Log.info("UserManager.signinRedirect: successful")})},t.prototype.signinRedirectCallback=function(e){return this._signinEnd(e||this._redirectNavigator.url).then(function(e){return e.profile&&e.profile.sub?i.Log.info("UserManager.signinRedirectCallback: successful, signed in sub: ",e.profile.sub):i.Log.info("UserManager.signinRedirectCallback: no sub"),e})},t.prototype.signinPopup=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(e=Object.assign({},e)).request_type="si:p";var t=e.redirect_uri||this.settings.popup_redirect_uri||this.settings.redirect_uri;return t?(e.redirect_uri=t,e.display="popup",this._signin(e,this._popupNavigator,{startUrl:t,popupWindowFeatures:e.popupWindowFeatures||this.settings.popupWindowFeatures,popupWindowTarget:e.popupWindowTarget||this.settings.popupWindowTarget}).then(function(e){return e&&(e.profile&&e.profile.sub?i.Log.info("UserManager.signinPopup: signinPopup successful, signed in sub: ",e.profile.sub):i.Log.info("UserManager.signinPopup: no sub")),e})):(i.Log.error("UserManager.signinPopup: No popup_redirect_uri or redirect_uri configured"),Promise.reject(new Error("No popup_redirect_uri or redirect_uri configured")))},t.prototype.signinPopupCallback=function(e){return this._signinCallback(e,this._popupNavigator).then(function(e){return e&&(e.profile&&e.profile.sub?i.Log.info("UserManager.signinPopupCallback: successful, signed in sub: ",e.profile.sub):i.Log.info("UserManager.signinPopupCallback: no sub")),e}).catch(function(e){i.Log.error(e.message)})},t.prototype.signinSilent=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t=Object.assign({},t),this._loadUser().then(function(r){return r&&r.refresh_token?(t.refresh_token=r.refresh_token,e._useRefreshToken(t)):(t.request_type="si:s",t.id_token_hint=t.id_token_hint||e.settings.includeIdTokenInSilentRenew&&r&&r.id_token,r&&e._settings.validateSubOnSilentRenew&&(i.Log.debug("UserManager.signinSilent, subject prior to silent renew: ",r.profile.sub),t.current_sub=r.profile.sub),e._signinSilentIframe(t))})},t.prototype._useRefreshToken=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this._tokenClient.exchangeRefreshToken(t).then(function(t){return t?t.access_token?e._loadUser().then(function(r){if(r){var n=Promise.resolve();return t.id_token&&(n=e._validateIdTokenFromTokenRefreshToken(r.profile,t.id_token)),n.then(function(){return i.Log.debug("UserManager._useRefreshToken: refresh token response success"),r.id_token=t.id_token||r.id_token,r.access_token=t.access_token,r.refresh_token=t.refresh_token||r.refresh_token,r.expires_in=t.expires_in,e.storeUser(r).then(function(){return e._events.load(r),r})})}return null}):(i.Log.error("UserManager._useRefreshToken: No access token returned from token endpoint"),Promise.reject("No access token returned from token endpoint")):(i.Log.error("UserManager._useRefreshToken: No response returned from token endpoint"),Promise.reject("No response returned from token endpoint"))})},t.prototype._validateIdTokenFromTokenRefreshToken=function(e,t){var r=this;return this._metadataService.getIssuer().then(function(n){return r.settings.getEpochTime().then(function(o){return r._joseUtil.validateJwtAttributes(t,n,r._settings.client_id,r._settings.clockSkew,o).then(function(t){return t?t.sub!==e.sub?(i.Log.error("UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub"),Promise.reject(new Error("sub in id_token does not match current sub"))):t.auth_time&&t.auth_time!==e.auth_time?(i.Log.error("UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time"),Promise.reject(new Error("auth_time in id_token does not match original auth_time"))):t.azp&&t.azp!==e.azp?(i.Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp"),Promise.reject(new Error("azp in id_token does not match original azp"))):!t.azp&&e.azp?(i.Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token"),Promise.reject(new Error("azp not in id_token, but present in original id_token"))):void 0:(i.Log.error("UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token"),Promise.reject(new Error("Failed to validate id_token")))})})})},t.prototype._signinSilentIframe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.redirect_uri||this.settings.silent_redirect_uri||this.settings.redirect_uri;return t?(e.redirect_uri=t,e.prompt=e.prompt||"none",this._signin(e,this._iframeNavigator,{startUrl:t,silentRequestTimeout:e.silentRequestTimeout||this.settings.silentRequestTimeout}).then(function(e){return e&&(e.profile&&e.profile.sub?i.Log.info("UserManager.signinSilent: successful, signed in sub: ",e.profile.sub):i.Log.info("UserManager.signinSilent: no sub")),e})):(i.Log.error("UserManager.signinSilent: No silent_redirect_uri configured"),Promise.reject(new Error("No silent_redirect_uri configured")))},t.prototype.signinSilentCallback=function(e){return this._signinCallback(e,this._iframeNavigator).then(function(e){return e&&(e.profile&&e.profile.sub?i.Log.info("UserManager.signinSilentCallback: successful, signed in sub: ",e.profile.sub):i.Log.info("UserManager.signinSilentCallback: no sub")),e})},t.prototype.signinCallback=function(e){var t=this;return this.readSigninResponseState(e).then(function(r){var n=r.state;return r.response,"si:r"===n.request_type?t.signinRedirectCallback(e):"si:p"===n.request_type?t.signinPopupCallback(e):"si:s"===n.request_type?t.signinSilentCallback(e):Promise.reject(new Error("invalid response_type in state"))})},t.prototype.signoutCallback=function(e,t){var r=this;return this.readSignoutResponseState(e).then(function(n){var i=n.state,o=n.response;return i?"so:r"===i.request_type?r.signoutRedirectCallback(e):"so:p"===i.request_type?r.signoutPopupCallback(e,t):Promise.reject(new Error("invalid response_type in state")):o})},t.prototype.querySessionStatus=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(t=Object.assign({},t)).request_type="si:s";var r=t.redirect_uri||this.settings.silent_redirect_uri||this.settings.redirect_uri;return r?(t.redirect_uri=r,t.prompt="none",t.response_type=t.response_type||this.settings.query_status_response_type,t.scope=t.scope||"openid",t.skipUserInfo=!0,this._signinStart(t,this._iframeNavigator,{startUrl:r,silentRequestTimeout:t.silentRequestTimeout||this.settings.silentRequestTimeout}).then(function(t){return e.processSigninResponse(t.url).then(function(e){if(i.Log.debug("UserManager.querySessionStatus: got signin response"),e.session_state&&e.profile.sub)return i.Log.info("UserManager.querySessionStatus: querySessionStatus success for sub: ",e.profile.sub),{session_state:e.session_state,sub:e.profile.sub,sid:e.profile.sid};i.Log.info("querySessionStatus successful, user not authenticated")}).catch(function(t){if(t.session_state&&e.settings.monitorAnonymousSession&&("login_required"==t.message||"consent_required"==t.message||"interaction_required"==t.message||"account_selection_required"==t.message))return i.Log.info("UserManager.querySessionStatus: querySessionStatus success for anonymous user"),{session_state:t.session_state};throw t})})):(i.Log.error("UserManager.querySessionStatus: No silent_redirect_uri configured"),Promise.reject(new Error("No silent_redirect_uri configured")))},t.prototype._signin=function(e,t){var r=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this._signinStart(e,t,n).then(function(t){return r._signinEnd(t.url,e)})},t.prototype._signinStart=function(e,t){var r=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return t.prepare(n).then(function(t){return i.Log.debug("UserManager._signinStart: got navigator window handle"),r.createSigninRequest(e).then(function(e){return i.Log.debug("UserManager._signinStart: got signin request"),n.url=e.url,n.id=e.state.id,t.navigate(n)}).catch(function(e){throw t.close&&(i.Log.debug("UserManager._signinStart: Error after preparing navigator, closing navigator window"),t.close()),e})})},t.prototype._signinEnd=function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.processSigninResponse(e).then(function(e){i.Log.debug("UserManager._signinEnd: got signin response");var n=new a.User(e);if(r.current_sub){if(r.current_sub!==n.profile.sub)return i.Log.debug("UserManager._signinEnd: current user does not match user returned from signin. sub from signin: ",n.profile.sub),Promise.reject(new Error("login_required"));i.Log.debug("UserManager._signinEnd: current user matches user returned from signin")}return t.storeUser(n).then(function(){return i.Log.debug("UserManager._signinEnd: user stored"),t._events.load(n),n})})},t.prototype._signinCallback=function(e,t){i.Log.debug("UserManager._signinCallback");var r="query"===this._settings.response_mode||!this._settings.response_mode&&l.SigninRequest.isCode(this._settings.response_type)?"?":"#";return t.callback(e,void 0,r)},t.prototype.signoutRedirect=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(e=Object.assign({},e)).request_type="so:r";var t=e.post_logout_redirect_uri||this.settings.post_logout_redirect_uri;t&&(e.post_logout_redirect_uri=t);var r={useReplaceToNavigate:e.useReplaceToNavigate};return this._signoutStart(e,this._redirectNavigator,r).then(function(){i.Log.info("UserManager.signoutRedirect: successful")})},t.prototype.signoutRedirectCallback=function(e){return this._signoutEnd(e||this._redirectNavigator.url).then(function(e){return i.Log.info("UserManager.signoutRedirectCallback: successful"),e})},t.prototype.signoutPopup=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(e=Object.assign({},e)).request_type="so:p";var t=e.post_logout_redirect_uri||this.settings.popup_post_logout_redirect_uri||this.settings.post_logout_redirect_uri;return e.post_logout_redirect_uri=t,e.display="popup",e.post_logout_redirect_uri&&(e.state=e.state||{}),this._signout(e,this._popupNavigator,{startUrl:t,popupWindowFeatures:e.popupWindowFeatures||this.settings.popupWindowFeatures,popupWindowTarget:e.popupWindowTarget||this.settings.popupWindowTarget}).then(function(){i.Log.info("UserManager.signoutPopup: successful")})},t.prototype.signoutPopupCallback=function(e,t){return void 0===t&&"boolean"==typeof e&&(t=e,e=null),this._popupNavigator.callback(e,t,"?").then(function(){i.Log.info("UserManager.signoutPopupCallback: successful")})},t.prototype._signout=function(e,t){var r=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this._signoutStart(e,t,n).then(function(e){return r._signoutEnd(e.url)})},t.prototype._signoutStart=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=this,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return arguments[1].prepare(r).then(function(n){return i.Log.debug("UserManager._signoutStart: got navigator window handle"),t._loadUser().then(function(o){return i.Log.debug("UserManager._signoutStart: loaded current user from storage"),(t._settings.revokeAccessTokenOnSignout?t._revokeInternal(o):Promise.resolve()).then(function(){var s=e.id_token_hint||o&&o.id_token;return s&&(i.Log.debug("UserManager._signoutStart: Setting id_token into signout request"),e.id_token_hint=s),t.removeUser().then(function(){return i.Log.debug("UserManager._signoutStart: user removed, creating signout request"),t.createSignoutRequest(e).then(function(e){return i.Log.debug("UserManager._signoutStart: got signout request"),r.url=e.url,e.state&&(r.id=e.state.id),n.navigate(r)})})})}).catch(function(e){throw n.close&&(i.Log.debug("UserManager._signoutStart: Error after preparing navigator, closing navigator window"),n.close()),e})})},t.prototype._signoutEnd=function(e){return this.processSignoutResponse(e).then(function(e){return i.Log.debug("UserManager._signoutEnd: got signout response"),e})},t.prototype.revokeAccessToken=function(){var e=this;return this._loadUser().then(function(t){return e._revokeInternal(t,!0).then(function(r){if(r)return i.Log.debug("UserManager.revokeAccessToken: removing token properties from user and re-storing"),t.access_token=null,t.refresh_token=null,t.expires_at=null,t.token_type=null,e.storeUser(t).then(function(){i.Log.debug("UserManager.revokeAccessToken: user stored"),e._events.load(t)})})}).then(function(){i.Log.info("UserManager.revokeAccessToken: access token revoked successfully")})},t.prototype._revokeInternal=function(e,t){var r=this;if(e){var n=e.access_token,o=e.refresh_token;return this._revokeAccessTokenInternal(n,t).then(function(e){return r._revokeRefreshTokenInternal(o,t).then(function(t){return e||t||i.Log.debug("UserManager.revokeAccessToken: no need to revoke due to no token(s), or JWT format"),e||t})})}return Promise.resolve(!1)},t.prototype._revokeAccessTokenInternal=function(e,t){return!e||e.indexOf(".")>=0?Promise.resolve(!1):this._tokenRevocationClient.revoke(e,t).then(function(){return!0})},t.prototype._revokeRefreshTokenInternal=function(e,t){return e?this._tokenRevocationClient.revoke(e,t,"refresh_token").then(function(){return!0}):Promise.resolve(!1)},t.prototype.startSilentRenew=function(){this._silentRenewService.start()},t.prototype.stopSilentRenew=function(){this._silentRenewService.stop()},t.prototype._loadUser=function(){return this._userStore.get(this._userStoreKey).then(function(e){return e?(i.Log.debug("UserManager._loadUser: user storageString loaded"),a.User.fromStorageString(e)):(i.Log.debug("UserManager._loadUser: no user storageString"),null)})},t.prototype.storeUser=function(e){if(e){i.Log.debug("UserManager.storeUser: storing user");var t=e.toStorageString();return this._userStore.set(this._userStoreKey,t)}return i.Log.debug("storeUser.storeUser: removing user"),this._userStore.remove(this._userStoreKey)},n(t,[{key:"_redirectNavigator",get:function(){return this.settings.redirectNavigator}},{key:"_popupNavigator",get:function(){return this.settings.popupNavigator}},{key:"_iframeNavigator",get:function(){return this.settings.iframeNavigator}},{key:"_userStore",get:function(){return this.settings.userStore}},{key:"events",get:function(){return this._events}},{key:"_userStoreKey",get:function(){return"user:"+this.settings.authority+":"+this.settings.client_id}}]),t}(o.OidcClient)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.UserManagerSettings=void 0;var n=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},n=r.popup_redirect_uri,i=r.popup_post_logout_redirect_uri,l=r.popupWindowFeatures,d=r.popupWindowTarget,f=r.silent_redirect_uri,p=r.silentRequestTimeout,g=r.automaticSilentRenew,y=void 0!==g&&g,v=r.validateSubOnSilentRenew,m=void 0!==v&&v,w=r.includeIdTokenInSilentRenew,_=void 0===w||w,S=r.monitorSession,b=void 0===S||S,E=r.monitorAnonymousSession,F=void 0!==E&&E,x=r.checkSessionInterval,A=void 0===x?2e3:x,k=r.stopCheckSessionOnError,P=void 0===k||k,T=r.query_status_response_type,I=r.revokeAccessTokenOnSignout,C=void 0!==I&&I,R=r.accessTokenExpiringNotificationTime,U=void 0===R?60:R,L=r.redirectNavigator,D=void 0===L?new o.RedirectNavigator:L,N=r.popupNavigator,O=void 0===N?new s.PopupNavigator:N,H=r.iframeNavigator,j=void 0===H?new a.IFrameNavigator:H,M=r.userStore,B=void 0===M?new u.WebStorageStateStore({store:c.Global.sessionStorage}):M;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var K=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this,arguments[0]));return K._popup_redirect_uri=n,K._popup_post_logout_redirect_uri=i,K._popupWindowFeatures=l,K._popupWindowTarget=d,K._silent_redirect_uri=f,K._silentRequestTimeout=p,K._automaticSilentRenew=y,K._validateSubOnSilentRenew=m,K._includeIdTokenInSilentRenew=_,K._accessTokenExpiringNotificationTime=U,K._monitorSession=b,K._monitorAnonymousSession=F,K._checkSessionInterval=A,K._stopCheckSessionOnError=P,T?K._query_status_response_type=T:arguments[0]&&arguments[0].response_type?K._query_status_response_type=h.SigninRequest.isOidc(arguments[0].response_type)?"id_token":"code":K._query_status_response_type="id_token",K._revokeAccessTokenOnSignout=C,K._redirectNavigator=D,K._popupNavigator=O,K._iframeNavigator=j,K._userStore=B,K}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),n(t,[{key:"popup_redirect_uri",get:function(){return this._popup_redirect_uri}},{key:"popup_post_logout_redirect_uri",get:function(){return this._popup_post_logout_redirect_uri}},{key:"popupWindowFeatures",get:function(){return this._popupWindowFeatures}},{key:"popupWindowTarget",get:function(){return this._popupWindowTarget}},{key:"silent_redirect_uri",get:function(){return this._silent_redirect_uri}},{key:"silentRequestTimeout",get:function(){return this._silentRequestTimeout}},{key:"automaticSilentRenew",get:function(){return this._automaticSilentRenew}},{key:"validateSubOnSilentRenew",get:function(){return this._validateSubOnSilentRenew}},{key:"includeIdTokenInSilentRenew",get:function(){return this._includeIdTokenInSilentRenew}},{key:"accessTokenExpiringNotificationTime",get:function(){return this._accessTokenExpiringNotificationTime}},{key:"monitorSession",get:function(){return this._monitorSession}},{key:"monitorAnonymousSession",get:function(){return this._monitorAnonymousSession}},{key:"checkSessionInterval",get:function(){return this._checkSessionInterval}},{key:"stopCheckSessionOnError",get:function(){return this._stopCheckSessionOnError}},{key:"query_status_response_type",get:function(){return this._query_status_response_type}},{key:"revokeAccessTokenOnSignout",get:function(){return this._revokeAccessTokenOnSignout}},{key:"redirectNavigator",get:function(){return this._redirectNavigator}},{key:"popupNavigator",get:function(){return this._popupNavigator}},{key:"iframeNavigator",get:function(){return this._iframeNavigator}},{key:"userStore",get:function(){return this._userStore}}]),t}(i.OidcClientSettings)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RedirectNavigator=void 0;var n=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1])||arguments[1];n.Log.debug("UserManagerEvents.load"),e.prototype.load.call(this,t),r&&this._userLoaded.raise(t)},t.prototype.unload=function(){n.Log.debug("UserManagerEvents.unload"),e.prototype.unload.call(this),this._userUnloaded.raise()},t.prototype.addUserLoaded=function(e){this._userLoaded.addHandler(e)},t.prototype.removeUserLoaded=function(e){this._userLoaded.removeHandler(e)},t.prototype.addUserUnloaded=function(e){this._userUnloaded.addHandler(e)},t.prototype.removeUserUnloaded=function(e){this._userUnloaded.removeHandler(e)},t.prototype.addSilentRenewError=function(e){this._silentRenewError.addHandler(e)},t.prototype.removeSilentRenewError=function(e){this._silentRenewError.removeHandler(e)},t.prototype._raiseSilentRenewError=function(e){n.Log.debug("UserManagerEvents._raiseSilentRenewError",e.message),this._silentRenewError.raise(e)},t.prototype.addUserSignedIn=function(e){this._userSignedIn.addHandler(e)},t.prototype.removeUserSignedIn=function(e){this._userSignedIn.removeHandler(e)},t.prototype._raiseUserSignedIn=function(){n.Log.debug("UserManagerEvents._raiseUserSignedIn"),this._userSignedIn.raise()},t.prototype.addUserSignedOut=function(e){this._userSignedOut.addHandler(e)},t.prototype.removeUserSignedOut=function(e){this._userSignedOut.removeHandler(e)},t.prototype._raiseUserSignedOut=function(){n.Log.debug("UserManagerEvents._raiseUserSignedOut"),this._userSignedOut.raise()},t.prototype.addUserSessionChanged=function(e){this._userSessionChanged.addHandler(e)},t.prototype.removeUserSessionChanged=function(e){this._userSessionChanged.removeHandler(e)},t.prototype._raiseUserSessionChanged=function(){n.Log.debug("UserManagerEvents._raiseUserSessionChanged"),this._userSessionChanged.raise()},t}(i.AccessTokenEvents)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Timer=void 0;var n=function(){function e(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:o.Global.timer,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var s=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this,r));return s._timer=n,s._nowFunc=i||function(){return Date.now()/1e3},s}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.init=function(e){e<=0&&(e=1),e=parseInt(e);var t=this.now+e;if(this.expiration===t&&this._timerHandle)i.Log.debug("Timer.init timer "+this._name+" skipping initialization since already initialized for expiration:",this.expiration);else{this.cancel(),i.Log.debug("Timer.init timer "+this._name+" for duration:",e),this._expiration=t;var r=5;e{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};return(()=>{"use strict";function e(...e){console.log(...e)}function t(...e){console.warn(...e)}n.r(i),n.d(i,{ACL_LINK:()=>Zt,CrossOriginForbiddenError:()=>lr,FetchError:()=>yr,NotEditableError:()=>pr,NotFoundError:()=>fr,SameOriginForbiddenError:()=>dr,UnauthorizedError:()=>hr,WebOperationError:()=>gr,appContext:()=>tr,authSession:()=>kr,authn:()=>Ar,createTypeIndexLogic:()=>mr,getSuggestedIssuers:()=>xr,offlineTestID:()=>rr,solidLogicSingleton:()=>Er,store:()=>Pr});const r=new TextEncoder,o=new TextDecoder;function s(...e){const t=e.reduce((e,{length:t})=>e+t,0),r=new Uint8Array(t);let n=0;for(const t of e)r.set(t,n),n+=t.length;return r}const a=e=>(e=>{let t=e;"string"==typeof t&&(t=r.encode(t));const n=[];for(let e=0;e{let t=e;t instanceof Uint8Array&&(t=o.decode(t)),t=t.replace(/-/g,"+").replace(/_/g,"/").replace(/\s/g,"");try{return(e=>{const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e>3};case"RS256":case"RS384":case"RS512":return{hash:r,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:r,name:"ECDSA",namedCurve:t.namedCurve};case"Ed25519":return{name:"Ed25519"};case"EdDSA":return{name:t.name};default:throw new f(`alg ${e} is not supported either by JOSE or your javascript runtime`)}}_.code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";const b=crypto,E=e=>e instanceof CryptoKey,F=(e,t)=>{if(e.startsWith("RS")||e.startsWith("PS")){const{modulusLength:r}=t.algorithm;if("number"!=typeof r||r<2048)throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`)}};function x(e,t="algorithm.name"){return new TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`)}function A(e,t){return e.name===t}function k(e){return parseInt(e.name.slice(4),10)}function P(e,t){if(t.length&&!t.some(t=>e.usages.includes(t))){let e="CryptoKey does not support this operation, its usages must include ";if(t.length>2){const r=t.pop();e+=`one of ${t.join(", ")}, or ${r}.`}else 2===t.length?e+=`one of ${t[0]} or ${t[1]}.`:e+=`${t[0]}.`;throw new TypeError(e)}}function T(e,t,...r){switch(t){case"HS256":case"HS384":case"HS512":{if(!A(e.algorithm,"HMAC"))throw x("HMAC");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw x(`SHA-${r}`,"algorithm.hash");break}case"RS256":case"RS384":case"RS512":{if(!A(e.algorithm,"RSASSA-PKCS1-v1_5"))throw x("RSASSA-PKCS1-v1_5");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw x(`SHA-${r}`,"algorithm.hash");break}case"PS256":case"PS384":case"PS512":{if(!A(e.algorithm,"RSA-PSS"))throw x("RSA-PSS");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw x(`SHA-${r}`,"algorithm.hash");break}case"EdDSA":if("Ed25519"!==e.algorithm.name&&"Ed448"!==e.algorithm.name)throw x("Ed25519 or Ed448");break;case"Ed25519":if(!A(e.algorithm,"Ed25519"))throw x("Ed25519");break;case"ES256":case"ES384":case"ES512":{if(!A(e.algorithm,"ECDSA"))throw x("ECDSA");const r=function(e){switch(e){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}(t);if(e.algorithm.namedCurve!==r)throw x(r,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}P(e,r)}function I(e,t,...r){if((r=r.filter(Boolean)).length>2){const t=r.pop();e+=`one of type ${r.join(", ")}, or ${t}.`}else 2===r.length?e+=`one of type ${r[0]} or ${r[1]}.`:e+=`of type ${r[0]}.`;return null==t?e+=` Received ${t}`:"function"==typeof t&&t.name?e+=` Received function ${t.name}`:"object"==typeof t&&null!=t&&t.constructor?.name&&(e+=` Received an instance of ${t.constructor.name}`),e}const C=(e,...t)=>I("Key must be ",e,...t);function R(e,t,...r){return I(`Key for the ${e} algorithm must be `,t,...r)}const U=e=>!!E(e)||"KeyObject"===e?.[Symbol.toStringTag],L=["CryptoKey"];function D(e){if("object"!=typeof(t=e)||null===t||"[object Object]"!==Object.prototype.toString.call(e))return!1;var t;if(null===Object.getPrototypeOf(e))return!0;let r=e;for(;null!==Object.getPrototypeOf(r);)r=Object.getPrototypeOf(r);return Object.getPrototypeOf(e)===r}function N(e){return D(e)&&"string"==typeof e.kty}const O=async e=>{if(!e.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');const{algorithm:t,keyUsages:r}=function(e){let t,r;switch(e.kty){case"RSA":switch(e.alg){case"PS256":case"PS384":case"PS512":t={name:"RSA-PSS",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":t={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":t={name:"RSA-OAEP",hash:`SHA-${parseInt(e.alg.slice(-3),10)||1}`},r=e.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new f('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"EC":switch(e.alg){case"ES256":t={name:"ECDSA",namedCurve:"P-256"},r=e.d?["sign"]:["verify"];break;case"ES384":t={name:"ECDSA",namedCurve:"P-384"},r=e.d?["sign"]:["verify"];break;case"ES512":t={name:"ECDSA",namedCurve:"P-521"},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:"ECDH",namedCurve:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new f('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"OKP":switch(e.alg){case"Ed25519":t={name:"Ed25519"},r=e.d?["sign"]:["verify"];break;case"EdDSA":t={name:e.crv},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new f('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;default:throw new f('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:t,keyUsages:r}}(e),n=[t,e.ext??!1,e.key_ops??r],i={...e};return delete i.alg,delete i.use,b.subtle.importKey("jwk",i,...n)},H=e=>u(e);let j,M;const B=e=>"KeyObject"===e?.[Symbol.toStringTag],K=async(e,t,r,n,i=!1)=>{let o=e.get(t);if(o?.[n])return o[n];const s=await O({...r,alg:n});return i&&Object.freeze(t),o?o[n]=s:e.set(t,{[n]:s}),s},V=(e,t)=>{if(B(e)){let r=e.export({format:"jwk"});return delete r.d,delete r.dp,delete r.dq,delete r.p,delete r.q,delete r.qi,r.k?H(r.k):(M||(M=new WeakMap),K(M,e,r,t))}if(N(e)){if(e.k)return u(e.k);M||(M=new WeakMap);return K(M,e,e,t,!0)}return e},q=(e,t)=>{if(B(e)){let r=e.export({format:"jwk"});return r.k?H(r.k):(j||(j=new WeakMap),K(j,e,r,t))}if(N(e)){if(e.k)return u(e.k);j||(j=new WeakMap);return K(j,e,e,t,!0)}return e};async function J(e,t,r){if("sign"===r&&(t=await q(t,e)),"verify"===r&&(t=await V(t,e)),E(t))return T(t,e,r),t;if(t instanceof Uint8Array){if(!e.startsWith("HS"))throw new TypeError(C(t,...L));return b.subtle.importKey("raw",t,{hash:`SHA-${e.slice(-3)}`,name:"HMAC"},!1,[r])}throw new TypeError(C(t,...L,"Uint8Array","JSON Web Key"))}const W=async(e,t,r,n)=>{const i=await J(e,t,"verify");F(e,i);const o=S(e,i.algorithm);try{return await b.subtle.verify(o,i,r,n)}catch{return!1}},$=(...e)=>{const t=e.filter(Boolean);if(0===t.length||1===t.length)return!0;let r;for(const e of t){const t=Object.keys(e);if(r&&0!==r.size)for(const e of t){if(r.has(e))return!1;r.add(e)}else r=new Set(t)}return!0},z=e=>e?.[Symbol.toStringTag],Y=(e,t,r)=>{if(void 0!==t.use&&"sig"!==t.use)throw new TypeError("Invalid key for this operation, when present its use must be sig");if(void 0!==t.key_ops&&!0!==t.key_ops.includes?.(r))throw new TypeError(`Invalid key for this operation, when present its key_ops must include ${r}`);if(void 0!==t.alg&&t.alg!==e)throw new TypeError(`Invalid key for this operation, when present its alg must be ${e}`);return!0},G=(e,t,r,n)=>{if(!(t instanceof Uint8Array)){if(n&&N(t)){if(function(e){return N(e)&&"oct"===e.kty&&"string"==typeof e.k}(t)&&Y(e,t,r))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!U(t))throw new TypeError(R(e,t,...L,"Uint8Array",n?"JSON Web Key":null));if("secret"!==t.type)throw new TypeError(`${z(t)} instances for symmetric algorithms must be of type "secret"`)}};function X(e,t,r,n){t.startsWith("HS")||"dir"===t||t.startsWith("PBES2")||/^A\d{3}(?:GCM)?KW$/.test(t)?G(t,r,n,e):((e,t,r,n)=>{if(n&&N(t))switch(r){case"sign":if(function(e){return"oct"!==e.kty&&"string"==typeof e.d}(t)&&Y(e,t,r))return;throw new TypeError("JSON Web Key for this operation be a private JWK");case"verify":if(function(e){return"oct"!==e.kty&&void 0===e.d}(t)&&Y(e,t,r))return;throw new TypeError("JSON Web Key for this operation be a public JWK")}if(!U(t))throw new TypeError(R(e,t,...L,n?"JSON Web Key":null));if("secret"===t.type)throw new TypeError(`${z(t)} instances for asymmetric algorithms must not be of type "secret"`);if("sign"===r&&"public"===t.type)throw new TypeError(`${z(t)} instances for asymmetric algorithm signing must be of type "private"`);if("decrypt"===r&&"public"===t.type)throw new TypeError(`${z(t)} instances for asymmetric algorithm decryption must be of type "private"`);if(t.algorithm&&"verify"===r&&"private"===t.type)throw new TypeError(`${z(t)} instances for asymmetric algorithm verifying must be of type "public"`);if(t.algorithm&&"encrypt"===r&&"private"===t.type)throw new TypeError(`${z(t)} instances for asymmetric algorithm encryption must be of type "public"`)})(t,r,n,e)}X.bind(void 0,!1);const Q=X.bind(void 0,!0);const Z=function(e,t,r,n,i){if(void 0!==i.crit&&void 0===n?.crit)throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');if(!n||void 0===n.crit)return new Set;if(!Array.isArray(n.crit)||0===n.crit.length||n.crit.some(e=>"string"!=typeof e||0===e.length))throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let o;o=void 0!==r?new Map([...Object.entries(r),...t.entries()]):t;for(const t of n.crit){if(!o.has(t))throw new f(`Extension Header Parameter "${t}" is not recognized`);if(void 0===i[t])throw new e(`Extension Header Parameter "${t}" is missing`);if(o.get(t)&&void 0===n[t])throw new e(`Extension Header Parameter "${t}" MUST be integrity protected`)}return new Set(n.crit)},ee=(e,t)=>{if(void 0!==t&&(!Array.isArray(t)||t.some(e=>"string"!=typeof e)))throw new TypeError(`"${e}" option must be an array of strings`);if(t)return new Set(t)};async function te(e,t){if(!D(e))throw new TypeError("JWK must be an object");switch(t||(t=e.alg),e.kty){case"oct":if("string"!=typeof e.k||!e.k)throw new TypeError('missing "k" (Key Value) Parameter value');return u(e.k);case"RSA":if("oth"in e&&void 0!==e.oth)throw new f('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');case"EC":case"OKP":return O({...e,alg:t});default:throw new f('Unsupported "kty" (Key Type) Parameter value')}}async function re(e,t,n){if(e instanceof Uint8Array&&(e=o.decode(e)),"string"!=typeof e)throw new p("Compact JWS must be a string or Uint8Array");const{0:i,1:a,2:c,length:h}=e.split(".");if(3!==h)throw new p("Invalid Compact JWS");const l=await async function(e,t,n){if(!D(e))throw new p("Flattened JWS must be an object");if(void 0===e.protected&&void 0===e.header)throw new p('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==e.protected&&"string"!=typeof e.protected)throw new p("JWS Protected Header incorrect type");if(void 0===e.payload)throw new p("JWS Payload missing");if("string"!=typeof e.signature)throw new p("JWS Signature missing or incorrect type");if(void 0!==e.header&&!D(e.header))throw new p("JWS Unprotected Header incorrect type");let i={};if(e.protected)try{const t=u(e.protected);i=JSON.parse(o.decode(t))}catch{throw new p("JWS Protected Header is invalid")}if(!$(i,e.header))throw new p("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const a={...i,...e.header};let c=!0;if(Z(p,new Map([["b64",!0]]),n?.crit,i,a).has("b64")&&(c=i.b64,"boolean"!=typeof c))throw new p('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:h}=a;if("string"!=typeof h||!h)throw new p('JWS "alg" (Algorithm) Header Parameter missing or invalid');const l=n&&ee("algorithms",n.algorithms);if(l&&!l.has(h))throw new d('"alg" (Algorithm) Header Parameter value not allowed');if(c){if("string"!=typeof e.payload)throw new p("JWS Payload must be a string")}else if("string"!=typeof e.payload&&!(e.payload instanceof Uint8Array))throw new p("JWS Payload must be a string or an Uint8Array instance");let f=!1;"function"==typeof t?(t=await t(i,e),f=!0,Q(h,t,"verify"),N(t)&&(t=await te(t,h))):Q(h,t,"verify");const g=s(r.encode(e.protected??""),r.encode("."),"string"==typeof e.payload?r.encode(e.payload):e.payload);let y,v;try{y=u(e.signature)}catch{throw new p("Failed to base64url decode the signature")}if(!await W(h,t,y,g))throw new _;if(c)try{v=u(e.payload)}catch{throw new p("Failed to base64url decode the payload")}else v="string"==typeof e.payload?r.encode(e.payload):e.payload;const m={payload:v};return void 0!==e.protected&&(m.protectedHeader=i),void 0!==e.header&&(m.unprotectedHeader=e.header),f?{...m,key:t}:m}({payload:a,protected:i,signature:c},t,n),f={payload:l.payload,protectedHeader:l.protectedHeader};return"function"==typeof t?{...f,key:l.key}:f}const ne=e=>Math.floor(e.getTime()/1e3),ie=86400,oe=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i,se=e=>{const t=oe.exec(e);if(!t||t[4]&&t[1])throw new TypeError("Invalid time period format");const r=parseFloat(t[2]);let n;switch(t[3].toLowerCase()){case"sec":case"secs":case"second":case"seconds":case"s":n=Math.round(r);break;case"minute":case"minutes":case"min":case"mins":case"m":n=Math.round(60*r);break;case"hour":case"hours":case"hr":case"hrs":case"h":n=Math.round(3600*r);break;case"day":case"days":case"d":n=Math.round(r*ie);break;case"week":case"weeks":case"w":n=Math.round(604800*r);break;default:n=Math.round(31557600*r)}return"-"===t[1]||"ago"===t[4]?-n:n},ae=e=>e.toLowerCase().replace(/^application\//,""),ue=(e,t,r={})=>{let n;try{n=JSON.parse(o.decode(t))}catch{}if(!D(n))throw new g("JWT Claims Set must be a top-level JSON object");const{typ:i}=r;if(i&&("string"!=typeof e.typ||ae(e.typ)!==ae(i)))throw new h('unexpected "typ" JWT header value',n,"typ","check_failed");const{requiredClaims:s=[],issuer:a,subject:u,audience:c,maxTokenAge:d}=r,f=[...s];void 0!==d&&f.push("iat"),void 0!==c&&f.push("aud"),void 0!==u&&f.push("sub"),void 0!==a&&f.push("iss");for(const e of new Set(f.reverse()))if(!(e in n))throw new h(`missing required "${e}" claim`,n,e,"missing");if(a&&!(Array.isArray(a)?a:[a]).includes(n.iss))throw new h('unexpected "iss" claim value',n,"iss","check_failed");if(u&&n.sub!==u)throw new h('unexpected "sub" claim value',n,"sub","check_failed");if(c&&(p=n.aud,y="string"==typeof c?[c]:c,!("string"==typeof p?y.includes(p):Array.isArray(p)&&y.some(Set.prototype.has.bind(new Set(p))))))throw new h('unexpected "aud" claim value',n,"aud","check_failed");var p,y;let v;switch(typeof r.clockTolerance){case"string":v=se(r.clockTolerance);break;case"number":v=r.clockTolerance;break;case"undefined":v=0;break;default:throw new TypeError("Invalid clockTolerance option type")}const{currentDate:m}=r,w=ne(m||new Date);if((void 0!==n.iat||d)&&"number"!=typeof n.iat)throw new h('"iat" claim must be a number',n,"iat","invalid");if(void 0!==n.nbf){if("number"!=typeof n.nbf)throw new h('"nbf" claim must be a number',n,"nbf","invalid");if(n.nbf>w+v)throw new h('"nbf" claim timestamp check failed',n,"nbf","check_failed")}if(void 0!==n.exp){if("number"!=typeof n.exp)throw new h('"exp" claim must be a number',n,"exp","invalid");if(n.exp<=w-v)throw new l('"exp" claim timestamp check failed',n,"exp","check_failed")}if(d){const e=w-n.iat;if(e-v>("number"==typeof d?d:se(d)))throw new l('"iat" claim timestamp check failed (too far in the past)',n,"iat","check_failed");if(e<0-v)throw new h('"iat" claim timestamp check failed (it should be in the past)',n,"iat","check_failed")}return n};const ce=async(e,t,r)=>{let n,i,o=!1;"function"==typeof AbortController&&(n=new AbortController,i=setTimeout(()=>{o=!0,n.abort()},t));const s=await fetch(e.href,{signal:n?n.signal:void 0,redirect:"manual",headers:r.headers}).catch(e=>{if(o)throw new w;throw e});if(void 0!==i&&clearTimeout(i),200!==s.status)throw new c("Expected 200 OK from the JSON Web Key Set HTTP response");try{return await s.json()}catch{throw new c("Failed to parse the JSON Web Key Set HTTP response as JSON")}};function he(e){return D(e)}function le(e){return"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}class de{constructor(e){if(this._cached=new WeakMap,!function(e){return e&&"object"==typeof e&&Array.isArray(e.keys)&&e.keys.every(he)}(e))throw new y("JSON Web Key Set malformed");this._jwks=le(e)}async getKey(e,t){const{alg:r,kid:n}={...e,...t?.header},i=function(e){switch("string"==typeof e&&e.slice(0,2)){case"RS":case"PS":return"RSA";case"ES":return"EC";case"Ed":return"OKP";default:throw new f('Unsupported "alg" value for a JSON Web Key Set')}}(r),o=this._jwks.keys.filter(e=>{let t=i===e.kty;if(t&&"string"==typeof n&&(t=n===e.kid),t&&"string"==typeof e.alg&&(t=r===e.alg),t&&"string"==typeof e.use&&(t="sig"===e.use),t&&Array.isArray(e.key_ops)&&(t=e.key_ops.includes("verify")),t)switch(r){case"ES256":t="P-256"===e.crv;break;case"ES256K":t="secp256k1"===e.crv;break;case"ES384":t="P-384"===e.crv;break;case"ES512":t="P-521"===e.crv;break;case"Ed25519":t="Ed25519"===e.crv;break;case"EdDSA":t="Ed25519"===e.crv||"Ed448"===e.crv}return t}),{0:s,length:a}=o;if(0===a)throw new v;if(1!==a){const e=new m,{_cached:t}=this;throw e[Symbol.asyncIterator]=async function*(){for(const e of o)try{yield await fe(t,e,r)}catch{}},e}return fe(this._cached,s,r)}}async function fe(e,t,r){const n=e.get(t)||e.set(t,{}).get(t);if(void 0===n[r]){const e=await te({...t,ext:!0},r);if(e instanceof Uint8Array||"public"!==e.type)throw new y("JSON Web Key Set members must be public keys");n[r]=e}return n[r]}function pe(e){const t=new de(e),r=async(e,r)=>t.getKey(e,r);return Object.defineProperties(r,{jwks:{value:()=>le(t._jwks),enumerable:!0,configurable:!1,writable:!1}}),r}let ge;if("undefined"==typeof navigator||!navigator.userAgent?.startsWith?.("Mozilla/5.0 ")){ge=`${"jose"}/${"v5.10.0"}`}const ye=Symbol();class ve{constructor(e,t){if(!(e instanceof URL))throw new TypeError("url must be an instance of URL");var r,n;this._url=new URL(e.href),this._options={agent:t?.agent,headers:t?.headers},this._timeoutDuration="number"==typeof t?.timeoutDuration?t?.timeoutDuration:5e3,this._cooldownDuration="number"==typeof t?.cooldownDuration?t?.cooldownDuration:3e4,this._cacheMaxAge="number"==typeof t?.cacheMaxAge?t?.cacheMaxAge:6e5,void 0!==t?.[ye]&&(this._cache=t?.[ye],r=t?.[ye],n=this._cacheMaxAge,"object"==typeof r&&null!==r&&"uat"in r&&"number"==typeof r.uat&&!(Date.now()-r.uat>=n)&&"jwks"in r&&D(r.jwks)&&Array.isArray(r.jwks.keys)&&Array.prototype.every.call(r.jwks.keys,D)&&(this._jwksTimestamp=this._cache.uat,this._local=pe(this._cache.jwks)))}coolingDown(){return"number"==typeof this._jwksTimestamp&&Date.now(){this._local=pe(e),this._cache&&(this._cache.uat=Date.now(),this._cache.jwks=e),this._jwksTimestamp=Date.now(),this._pendingFetch=void 0}).catch(e=>{throw this._pendingFetch=void 0,e})),await this._pendingFetch}}const me=async e=>{if(e instanceof Uint8Array)return{kty:"oct",k:a(e)};if(!E(e))throw new TypeError(C(e,...L,"Uint8Array"));if(!e.extractable)throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");const{ext:t,key_ops:r,alg:n,use:i,...o}=await b.subtle.exportKey("jwk",e);return o};async function we(e){return me(e)}const _e=async(e,t,r)=>{const n=await J(e,t,"sign");F(e,n);const i=await b.subtle.sign(S(e,n.algorithm),n,r);return new Uint8Array(i)};class Se{constructor(e){if(!(e instanceof Uint8Array))throw new TypeError("payload must be an instance of Uint8Array");this._payload=e}setProtectedHeader(e){if(this._protectedHeader)throw new TypeError("setProtectedHeader can only be called once");return this._protectedHeader=e,this}setUnprotectedHeader(e){if(this._unprotectedHeader)throw new TypeError("setUnprotectedHeader can only be called once");return this._unprotectedHeader=e,this}async sign(e,t){if(!this._protectedHeader&&!this._unprotectedHeader)throw new p("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");if(!$(this._protectedHeader,this._unprotectedHeader))throw new p("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const n={...this._protectedHeader,...this._unprotectedHeader};let i=!0;if(Z(p,new Map([["b64",!0]]),t?.crit,this._protectedHeader,n).has("b64")&&(i=this._protectedHeader.b64,"boolean"!=typeof i))throw new p('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:u}=n;if("string"!=typeof u||!u)throw new p('JWS "alg" (Algorithm) Header Parameter missing or invalid');Q(u,e,"sign");let c,h=this._payload;i&&(h=r.encode(a(h))),c=this._protectedHeader?r.encode(a(JSON.stringify(this._protectedHeader))):r.encode("");const l=s(c,r.encode("."),h),d=await _e(u,e,l),f={signature:a(d),payload:""};return i&&(f.payload=o.decode(h)),this._unprotectedHeader&&(f.header=this._unprotectedHeader),this._protectedHeader&&(f.protected=o.decode(c)),f}}class be{constructor(e){this._flattened=new Se(e)}setProtectedHeader(e){return this._flattened.setProtectedHeader(e),this}async sign(e,t){const r=await this._flattened.sign(e,t);if(void 0===r.payload)throw new TypeError("use the flattened module for creating JWS with b64: false");return`${r.protected}.${r.payload}.${r.signature}`}}function Ee(e,t){if(!Number.isFinite(t))throw new TypeError(`Invalid ${e} input`);return t}class Fe{constructor(e={}){if(!D(e))throw new TypeError("JWT Claims Set MUST be an object");this._payload=e}setIssuer(e){return this._payload={...this._payload,iss:e},this}setSubject(e){return this._payload={...this._payload,sub:e},this}setAudience(e){return this._payload={...this._payload,aud:e},this}setJti(e){return this._payload={...this._payload,jti:e},this}setNotBefore(e){return"number"==typeof e?this._payload={...this._payload,nbf:Ee("setNotBefore",e)}:e instanceof Date?this._payload={...this._payload,nbf:Ee("setNotBefore",ne(e))}:this._payload={...this._payload,nbf:ne(new Date)+se(e)},this}setExpirationTime(e){return"number"==typeof e?this._payload={...this._payload,exp:Ee("setExpirationTime",e)}:e instanceof Date?this._payload={...this._payload,exp:Ee("setExpirationTime",ne(e))}:this._payload={...this._payload,exp:ne(new Date)+se(e)},this}setIssuedAt(e){return void 0===e?this._payload={...this._payload,iat:ne(new Date)}:e instanceof Date?this._payload={...this._payload,iat:Ee("setIssuedAt",ne(e))}:this._payload="string"==typeof e?{...this._payload,iat:Ee("setIssuedAt",ne(new Date)+se(e))}:{...this._payload,iat:Ee("setIssuedAt",e)},this}}class xe extends Fe{setProtectedHeader(e){return this._protectedHeader=e,this}async sign(e,t){const n=new be(r.encode(JSON.stringify(this._payload)));if(n.setProtectedHeader(this._protectedHeader),Array.isArray(this._protectedHeader?.crit)&&this._protectedHeader.crit.includes("b64")&&!1===this._protectedHeader.b64)throw new g("JWTs MUST NOT use unencoded payload");return n.sign(e,t)}}function Ae(e){const t=e?.modulusLength??2048;if("number"!=typeof t||t<2048)throw new f("Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used");return t}async function ke(e,t){return async function(e,t){let r,n;switch(e){case"PS256":case"PS384":case"PS512":r={name:"RSA-PSS",hash:`SHA-${e.slice(-3)}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Ae(t)},n=["sign","verify"];break;case"RS256":case"RS384":case"RS512":r={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.slice(-3)}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Ae(t)},n=["sign","verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":r={name:"RSA-OAEP",hash:`SHA-${parseInt(e.slice(-3),10)||1}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Ae(t)},n=["decrypt","unwrapKey","encrypt","wrapKey"];break;case"ES256":r={name:"ECDSA",namedCurve:"P-256"},n=["sign","verify"];break;case"ES384":r={name:"ECDSA",namedCurve:"P-384"},n=["sign","verify"];break;case"ES512":r={name:"ECDSA",namedCurve:"P-521"},n=["sign","verify"];break;case"Ed25519":r={name:"Ed25519"},n=["sign","verify"];break;case"EdDSA":{n=["sign","verify"];const e=t?.crv??"Ed25519";switch(e){case"Ed25519":case"Ed448":r={name:e};break;default:throw new f("Invalid or unsupported crv option provided")}break}case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":{n=["deriveKey","deriveBits"];const e=t?.crv??"P-256";switch(e){case"P-256":case"P-384":case"P-521":r={name:"ECDH",namedCurve:e};break;case"X25519":case"X448":r={name:e};break;default:throw new f("Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, X25519, and X448")}break}default:throw new f('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}return b.subtle.generateKey(r,t?.extractable??!1,n)}(e,t)}const Pe={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let Te;const Ie=new Uint8Array(16);const Ce=[];for(let e=0;e<256;++e)Ce.push((e+256).toString(16).slice(1));function Re(e,t=0){return(Ce[e[t+0]]+Ce[e[t+1]]+Ce[e[t+2]]+Ce[e[t+3]]+"-"+Ce[e[t+4]]+Ce[e[t+5]]+"-"+Ce[e[t+6]]+Ce[e[t+7]]+"-"+Ce[e[t+8]]+Ce[e[t+9]]+"-"+Ce[e[t+10]]+Ce[e[t+11]]+Ce[e[t+12]]+Ce[e[t+13]]+Ce[e[t+14]]+Ce[e[t+15]]).toLowerCase()}const Ue=function(e,t,r){if(Pe.randomUUID&&!t&&!e)return Pe.randomUUID();const n=(e=e||{}).random??e.rng?.()??function(){if(!Te){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");Te=crypto.getRandomValues.bind(crypto)}return Te(Ie)}();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=15&n[6]|64,n[8]=63&n[8]|128,t){if((r=r||0)<0||r+16>t.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[r+e]=n[e];return t}return Re(n)},Le="solidClientAuthn:",De=["ES256","RS256"],Ne="error",Oe="login",He="logout",je="newRefreshToken",Me="sessionExpired",Be="sessionExtended",Ke="sessionRestore",Ve="timeoutSet",qe=["openid","offline_access","webid"];class Je{handleables;constructor(e){this.handleables=e,this.handleables=e}async getProperHandler(e){const t=await Promise.all(this.handleables.map(t=>t.canHandle(...e)));for(let e=0;e{try{return JSON.stringify(e)}catch(t){return e.toString()}}).join(", ")}`)}}async function We(e,t,r,n){let i,o;try{const{payload:o}=await async function(e,t,r){const n=await re(e,t,r);if(n.protectedHeader.crit?.includes("b64")&&!1===n.protectedHeader.b64)throw new g("JWTs MUST NOT use unencoded payload");const i={payload:ue(n.protectedHeader,n.payload,r),protectedHeader:n.protectedHeader};return"function"==typeof t?{...i,key:n.key}:i}(e,function(e,t){const r=new ve(e,t),n=async(e,t)=>r.getKey(e,t);return Object.defineProperties(n,{coolingDown:{get:()=>r.coolingDown(),enumerable:!0,configurable:!1},fresh:{get:()=>r.fresh(),enumerable:!0,configurable:!1},reload:{value:()=>r.reload(),enumerable:!0,configurable:!1,writable:!1},reloading:{get:()=>!!r._pendingFetch,enumerable:!0,configurable:!1},jwks:{value:()=>r._local?.jwks(),enumerable:!0,configurable:!1,writable:!1}}),n}(new URL(t)),{issuer:r,audience:n});i=o}catch(e){throw new Error(`Token verification failed: ${e.stack}`)}if("string"==typeof i.azp&&(o=i.azp),"string"==typeof i.webid)return{webId:i.webid,clientId:o};if("string"!=typeof i.sub)throw new Error(`The token ${JSON.stringify(i)} is invalid: it has no 'webid' claim and no 'sub' claim.`);try{return new URL(i.sub),{webId:i.sub,clientId:o}}catch(e){throw new Error(`The token has no 'webid' claim, and its 'sub' claim of [${i.sub}] is invalid as a URL - error [${e}].`)}}function $e(e){try{const t=new URL(e),r=!t.searchParams.has("code")&&!t.searchParams.has("state"),n=""===t.hash;return r&&n}catch(e){return!1}}function ze(e){const t=new URL(e);return t.searchParams.delete("state"),t.searchParams.delete("code"),t.searchParams.delete("error"),t.searchParams.delete("error_description"),t.searchParams.delete("iss"),t}class Ye{storageUtility;redirector;constructor(e,t){this.storageUtility=e,this.redirector=t,this.storageUtility=e,this.redirector=t}parametersGuard=e=>void 0!==e.issuerConfiguration.grantTypesSupported&&e.issuerConfiguration.grantTypesSupported.indexOf("authorization_code")>-1&&void 0!==e.redirectUrl;async canHandle(e){return this.parametersGuard(e)}async setupRedirectHandler({oidcLoginOptions:e,state:t,codeVerifier:r,targetUrl:n}){if(!this.parametersGuard(e))throw new Error("The authorization code grant requires a redirectUrl.");var i,o;await Promise.all([this.storageUtility.setForUser(t,{sessionId:e.sessionId}),this.storageUtility.setForUser(e.sessionId,{codeVerifier:r,issuer:e.issuer.toString(),redirectUrl:e.redirectUrl,dpop:Boolean(e.dpop).toString(),keepAlive:(i=e.keepAlive,o=!0,"boolean"==typeof i?Boolean(i):Boolean(o)).toString()})]),this.redirector.redirect(n,{handleRedirect:e.handleRedirect})}}class Ge{sessionInfoManager;constructor(e){this.sessionInfoManager=e,this.sessionInfoManager=e}async canHandle(){return!0}async handle(e){await this.sessionInfoManager.clear(e)}}class Xe{redirector;constructor(e){this.redirector=e,this.redirector=e}async canHandle(e,t){return"idp"===t?.logoutType}async handle(e,t){if("idp"!==t?.logoutType)throw new Error("Attempting to call idp logout handler to perform app logout");if(void 0===t.toLogoutUrl)throw new Error("Cannot perform IDP logout. Did you log in using the OIDC authentication flow?");this.redirector.redirect(t.toLogoutUrl(t),{handleRedirect:t.handleRedirect})}}class Qe{handlers;constructor(e,t){this.handlers=[new Ge(e),new Xe(t)]}async canHandle(){return!0}async handle(e,t){for(const r of this.handlers)await r.canHandle(e,t)&&await r.handle(e,t)}}function Ze(){return{isLoggedIn:!1,sessionId:Ue(),fetch:(...e)=>fetch(...e)}}async function et(e,t){await Promise.all([t.deleteAllUserData(e,{secure:!1}),t.deleteAllUserData(e,{secure:!0})])}class tt{storageUtility;constructor(e){this.storageUtility=e,this.storageUtility=e}update(e,t){throw new Error("Not Implemented")}set(e,t){throw new Error("Not Implemented")}get(e){throw new Error("Not implemented")}async getAll(){throw new Error("Not implemented")}async clear(e){return et(e,this.storageUtility)}async register(e){throw new Error("Not implemented")}async getRegisteredSessionIdAll(){throw new Error("Not implemented")}async clearAll(){throw new Error("Not implemented")}async setOidcContext(e,t){throw new Error("Not implemented")}}function rt({endSessionEndpoint:e,idTokenHint:t}){if(void 0!==e)return function({state:r,postLogoutUrl:n}){return function({endSessionEndpoint:e,idTokenHint:t,postLogoutRedirectUri:r,state:n}){const i=new URL(e);return void 0!==t&&i.searchParams.append("id_token_hint",t),void 0!==r&&(i.searchParams.append("post_logout_redirect_uri",r),void 0!==n&&i.searchParams.append("state",n)),i.toString()}({endSessionEndpoint:e,idTokenHint:t,state:r,postLogoutRedirectUri:n})}}function nt(e){try{return new URL(e),!0}catch{return!1}}async function it(e,t,r,n){let i;if(function(e,t){return t.scopesSupported.includes("webid")&&void 0!==e.clientId&&nt(e.clientId)}(e,t))i={clientId:e.clientId,clientName:e.clientName,clientType:"solid-oidc"};else{if(!function(e){return void 0!==e.clientId&&!nt(e.clientId)}(e))return n.getClient({sessionId:e.sessionId,clientName:e.clientName,redirectUrl:e.redirectUrl},t);i={clientId:e.clientId,clientSecret:e.clientSecret,clientName:e.clientName,clientType:"static"}}const o={clientId:i.clientId,clientType:i.clientType};return"static"===i.clientType&&(o.clientSecret=i.clientSecret),i.clientName&&(o.clientName=i.clientName),await r.setForUser(e.sessionId,o),i}const ot=(e,t)=>fetch(e,t);class st{loginHandler;redirectHandler;logoutHandler;sessionInfoManager;issuerConfigFetcher;boundLogout;constructor(e,t,r,n,i){this.loginHandler=e,this.redirectHandler=t,this.logoutHandler=r,this.sessionInfoManager=n,this.issuerConfigFetcher=i,this.loginHandler=e,this.redirectHandler=t,this.logoutHandler=r,this.sessionInfoManager=n,this.issuerConfigFetcher=i}fetch=ot;logout=async(e,t)=>{await this.logoutHandler.handle(e,"idp"===t?.logoutType?{...t,toLogoutUrl:this.boundLogout}:t),this.fetch=ot,delete this.boundLogout};getSessionInfo=async e=>this.sessionInfoManager.get(e);getAllSessionInfo=async()=>this.sessionInfoManager.getAll()}async function at(e,t,r){try{const[n,i,o,s,a]=await Promise.all([t.getForUser(e,"issuer",{errorIfNull:!0}),t.getForUser(e,"codeVerifier"),t.getForUser(e,"redirectUrl"),t.getForUser(e,"dpop",{errorIfNull:!0}),t.getForUser(e,"keepAlive")]);await t.deleteForUser(e,"codeVerifier");return{codeVerifier:i,redirectUrl:o,issuerConfig:await r.fetchConfig(n),dpop:"true"===s,keepAlive:"string"!=typeof a||"true"===a}}catch(t){throw new Error(`Failed to retrieve OIDC context from storage associated with session [${e}]: ${t}`)}}class ut{secureStorage;insecureStorage;constructor(e,t){this.secureStorage=e,this.insecureStorage=t,this.secureStorage=e,this.insecureStorage=t}getKey(e){return`solidClientAuthenticationUser:${e}`}async getUserData(e,t){const r=await(t?this.secureStorage:this.insecureStorage).get(this.getKey(e));if(void 0===r)return{};try{return JSON.parse(r)}catch(n){throw new Error(`Data for user [${e}] in [${t?"secure":"unsecure"}] storage is corrupted - expected valid JSON, but got: ${r}`)}}async setUserData(e,t,r){await(r?this.secureStorage:this.insecureStorage).set(this.getKey(e),JSON.stringify(t))}async get(e,t){const r=await(t?.secure?this.secureStorage:this.insecureStorage).get(e);if(void 0===r&&t?.errorIfNull)throw new Error(`[${e}] is not stored`);return r}async set(e,t,r){return(r?.secure?this.secureStorage:this.insecureStorage).set(e,t)}async delete(e,t){return(t?.secure?this.secureStorage:this.insecureStorage).delete(e)}async getForUser(e,t,r){const n=await this.getUserData(e,r?.secure);let i;if(n&&n[t]||(i=void 0),i=n[t],void 0===i&&r?.errorIfNull)throw new Error(`Field [${t}] for user [${e}] is not stored`);return i||void 0}async setForUser(e,t,r){let n;try{n=await this.getUserData(e,r?.secure)}catch{n={}}await this.setUserData(e,{...n,...t},r?.secure)}async deleteForUser(e,t,r){const n=await this.getUserData(e,r?.secure);delete n[t],await this.setUserData(e,n,r?.secure)}async deleteAllUserData(e,t){await(t?.secure?this.secureStorage:this.insecureStorage).delete(this.getKey(e))}}class ct{map={};async get(e){return this.map[e]||void 0}async set(e,t){this.map[e]=t}async delete(e){delete this.map[e]}}class ht extends Error{constructor(e){super(e)}}Error;class lt extends Error{missingFields;constructor(e){super(`Invalid response from OIDC provider: missing fields ${e}`),this.missingFields=e}}class dt extends Error{error;errorDescription;constructor(e,t,r){super(e),this.error=t,this.errorDescription=r}}function ft(e){const t=new URL(e);return new URL(t.pathname,t.origin).toString()}async function pt(e,t,r){return new xe({htu:ft(e),htm:t.toUpperCase(),jti:Ue()}).setProtectedHeader({alg:De[0],jwk:r.publicKey,typ:"dpop+jwt"}).setIssuedAt().sign(r.privateKey,{})}async function gt(e,t,r,n){if(void 0!==r)return async function(e,t,r,n){const i=new Headers(n?.headers);return i.set("Authorization",`DPoP ${t}`),i.set("DPoP",await pt(e,n?.method??"get",r)),{...n,headers:i}}(e,t,r,n);const i=new Headers(n?.headers);return i.set("Authorization",`Bearer ${t}`),{...n,headers:i}}async function yt(e,t,r,n,i=fetch){return i(t,await gt(t.toString(),e,n,r))}const vt=e=>void 0!==e?e-5>0?e-5:e:600;function mt(e,t){let r,n=e;const i=t?.refreshOptions;if(void 0!==i){const e=async()=>{try{const{accessToken:o,refreshToken:s,expiresIn:a}=await async function(e,t,r){const n=await e.tokenRefresher.refresh(e.sessionId,e.refreshToken,t);return r?.emit(Be,n.expiresIn??600),{accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn}}(i,t.dpopKey,t.eventEmitter);n=o,void 0!==s&&(i.refreshToken=s),clearTimeout(r),r=setTimeout(e,1e3*vt(a)),t.eventEmitter?.emit(Ve,r)}catch(e){e instanceof dt&&(t?.eventEmitter?.emit(Ne,e.error,e.errorDescription),t?.eventEmitter?.emit(Me)),e instanceof lt&&e.missingFields.includes("access_token")&&t?.eventEmitter?.emit(Me)}};r=setTimeout(e,1e3*vt(t.expiresIn)),t.eventEmitter?.emit(Ve,r)}else if(void 0!==t&&void 0!==t.eventEmitter){const e=setTimeout(()=>{t.eventEmitter.emit(Me)},1e3*vt(t.expiresIn));t.eventEmitter.emit(Ve,e)}return async(e,r)=>{let i=await yt(n,e,r,t?.dpopKey,t?.fetch);const o=!i.ok&&(s=i.status,![401,403].includes(s));var s;if(i.ok||o)return i;return i.url!==e&&void 0!==t?.dpopKey&&(i=await yt(n,i.url,r,t.dpopKey,t.fetch)),i}}var wt=n(7),_t=n(516);function St(e,t){if("string"!=typeof e.client_id)throw new Error(`Dynamic client registration failed: no client_id has been found on ${JSON.stringify(e)}`);if(t.redirectUrl&&function(e){return Array.isArray(e.redirect_uris)&&e.redirect_uris.every(e=>"string"==typeof e)}(e)&&e.redirect_uris[0]!==t.redirectUrl.toString())throw new Error(`Dynamic client registration failed: the returned redirect URIs ${JSON.stringify(e.redirect_uris)} don't match the provided ${JSON.stringify([t.redirectUrl.toString()])}`);return!0}async function bt(e,t){if(!t.registrationEndpoint)throw new Error("Dynamic Registration could not be completed because the issuer has no registration endpoint.");if(!Array.isArray(t.idTokenSigningAlgValuesSupported))throw new Error("The OIDC issuer discovery profile is missing the 'id_token_signing_alg_values_supported' value, which is mandatory.");const r=(n=t.idTokenSigningAlgValuesSupported,De.find(e=>n.includes(e))??null);var n;const i={client_name:e.clientName,application_type:"web",redirect_uris:[e.redirectUrl?.toString()],subject_type:"public",token_endpoint_auth_method:"client_secret_basic",id_token_signed_response_alg:r,grant_types:["authorization_code","refresh_token"]},o=await fetch(t.registrationEndpoint.toString(),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(o.ok){const t=await o.json();return St(t,e),{clientId:t.client_id,clientSecret:t.client_secret,expiresAt:t.client_secret_expires_at,idTokenSignedResponseAlg:t.id_token_signed_response_alg,clientType:"dynamic"}}throw 400===o.status&&function(e,t){if("invalid_redirect_uri"===e.error)throw new Error(`Dynamic client registration failed: the provided redirect uri [${t.redirectUrl?.toString()}] is invalid - ${e.error_description??""}`);if("invalid_client_metadata"===e.error)throw new Error(`Dynamic client registration failed: the provided client metadata ${JSON.stringify(t)} is invalid - ${e.error_description??""}`);throw new Error(`Dynamic client registration failed: ${e.error} - ${e.error_description??""}`)}(await o.json(),e),new Error(`Dynamic client registration failed: the server returned ${o.status} ${o.statusText} - ${await o.text()}`)}function Et(e){return void 0!==e.error_description&&"string"==typeof e.error_description}function Ft(e,t){if(void 0!==(r=e).error&&"string"==typeof r.error)throw new dt(`Token endpoint returned error [${e.error}]${Et(e)?`: ${e.error_description}`:""}${function(e){return void 0!==e.error_uri&&"string"==typeof e.error_uri}(e)?` (see ${e.error_uri})`:""}`,e.error,Et(e)?e.error_description:void 0);var r;if(!function(e){return void 0!==e.access_token&&"string"==typeof e.access_token}(e))throw new lt(["access_token"]);if(!function(e){return void 0!==e.id_token&&"string"==typeof e.id_token}(e))throw new lt(["id_token"]);if(!function(e){return void 0!==e.token_type&&"string"==typeof e.token_type}(e))throw new lt(["token_type"]);if(!function(e){return void 0===e.expires_in||"number"==typeof e.expires_in}(e))throw new lt(["expires_in"]);if(!t&&"bearer"!==e.token_type.toLowerCase())throw new Error(`Invalid token endpoint response: requested a [Bearer] token, but got a 'token_type' value of [${e.token_type}].`);return e}async function xt(e,t,r,n){!function(e,t){if(t.grantType&&(!e.grantTypesSupported||!e.grantTypesSupported.includes(t.grantType)))throw new Error(`The issuer [${e.issuer}] does not support the [${t.grantType}] grant`);if(!e.tokenEndpoint)throw new Error(`This issuer [${e.issuer}] does not have a token endpoint`)}(e,r);const i={"content-type":"application/x-www-form-urlencoded"};let o;n&&(o=await async function(){const{privateKey:e,publicKey:t}=await ke(De[0]),r={privateKey:e,publicKey:await we(t)};return[r.publicKey.alg]=De,r}(),i.DPoP=await pt(e.tokenEndpoint,"POST",o)),t.clientSecret&&(i.Authorization=`Basic ${btoa(`${t.clientId}:${t.clientSecret}`)}`);const s={grant_type:r.grantType,redirect_uri:r.redirectUrl,code:r.code,code_verifier:r.codeVerifier,client_id:t.clientId},a={method:"POST",headers:i,body:new URLSearchParams(s).toString()},u=await fetch(e.tokenEndpoint,a),c=Ft(await u.json(),n),{webId:h,clientId:l}=await We(c.id_token,e.jwksUri,e.issuer,t.clientId);return{accessToken:c.access_token,idToken:c.id_token,refreshToken:(d=c,void 0!==d.refresh_token&&"string"==typeof d.refresh_token?c.refresh_token:void 0),webId:h,clientId:l,dpopKey:o,expiresIn:c.expires_in};var d}async function At(e,t,r,n){if(void 0===r.clientId)throw new Error("No client ID available when trying to refresh the access token.");const i={grant_type:"refresh_token",refresh_token:e};let o={};void 0!==n&&(o={DPoP:await pt(t.tokenEndpoint,"POST",n)});let s={};void 0!==r.clientSecret?s={Authorization:`Basic ${btoa(`${r.clientId}:${r.clientSecret}`)}`}:(e=>{try{return new URL(e),!0}catch{return!1}})(r.clientId)&&(i.client_id=r.clientId);const a=await fetch(t.tokenEndpoint,{method:"POST",body:new URLSearchParams(i).toString(),headers:{...o,...s,"Content-Type":"application/x-www-form-urlencoded"}});let u;try{u=await a.json()}catch(e){throw new Error(`The token endpoint of issuer ${t.issuer} returned a malformed response.`)}const c=Ft(u,void 0!==n),{webId:h}=await We(c.id_token,t.jwksUri,t.issuer,r.clientId);return{accessToken:c.access_token,idToken:c.id_token,refreshToken:"string"==typeof c.refresh_token?c.refresh_token:void 0,webId:h,dpopKey:n,expiresIn:c.expires_in}}class kt extends ut{constructor(e,t){super(e,t)}}class Pt extends st{login=async(e,t)=>{"none"!==e.prompt&&await this.sessionInfoManager.clear(e.sessionId);const r=e.redirectUrl??function(e){const t=ze(e);return t.hash="",e.includes(`${t.origin}/`)?t.href:`${t.origin}${t.href.substring(t.origin.length+1)}`}(window.location.href);if(!$e(r))throw new Error(`${r} is not a valid redirect URL, it is either a malformed IRI, includes a hash fragment, or reserved query parameters ('code' or 'state').`);await this.loginHandler.handle({...e,redirectUrl:r,clientName:e.clientName??e.clientId,eventEmitter:t})};validateCurrentSession=async e=>{const t=await this.sessionInfoManager.get(e);return void 0===t||void 0===t.clientAppId||void 0===t.issuer?null:t};handleIncomingRedirect=async(e,t)=>{try{const r=await this.redirectHandler.handle(e,t,void 0);return this.fetch=r.fetch.bind(window),this.boundLogout=r.getLogoutUrl,await this.cleanUrlAfterRedirect(e),{isLoggedIn:r.isLoggedIn,webId:r.webId,sessionId:r.sessionId,expirationDate:r.expirationDate,clientAppId:r.clientAppId}}catch(r){return await this.cleanUrlAfterRedirect(e),void t.emit(Ne,"redirect",r)}};async cleanUrlAfterRedirect(e){const t=ze(e).href;for(window.history.replaceState(null,"",t);window.location.href!==t;)await new Promise(e=>{setTimeout(()=>e(),1)})}}function Tt(e){return"string"==typeof e.oidcIssuer}function It(e){return"string"==typeof e.redirectUrl}class Ct{storageUtility;oidcHandler;issuerConfigFetcher;clientRegistrar;constructor(e,t,r,n){this.storageUtility=e,this.oidcHandler=t,this.issuerConfigFetcher=r,this.clientRegistrar=n,this.storageUtility=e,this.oidcHandler=t,this.issuerConfigFetcher=r,this.clientRegistrar=n}async canHandle(e){return Tt(e)&&It(e)}async handle(e){if(!Tt(e))throw new ht(`OidcLoginHandler requires an OIDC issuer: missing property 'oidcIssuer' in ${JSON.stringify(e)}`);if(!It(e))throw new ht(`OidcLoginHandler requires a redirect URL: missing property 'redirectUrl' in ${JSON.stringify(e)}`);const t=await this.issuerConfigFetcher.fetchConfig(e.oidcIssuer),r=await it(e,t,this.storageUtility,this.clientRegistrar),n={issuer:t.issuer,dpop:"dpop"===e.tokenType.toLowerCase(),...e,issuerConfiguration:t,client:r,scopes:(i=e.customScopes,Array.isArray(i)?Array.from(new Set([...qe,...i.filter(e=>"string"==typeof e&&!e.includes(" "))])):qe)};var i;return this.oidcHandler.handle(n)}}class Rt extends Ye{async handle(e){const t={authority:e.issuer.toString(),client_id:e.client.clientId,client_secret:e.client.clientSecret,redirect_uri:e.redirectUrl,response_type:"code",scope:e.scopes.join(" "),filterProtocolClaims:!0,loadUserInfo:!1,code_verifier:!0,prompt:e.prompt??"consent"},r=new _t.OidcClient(t);try{const t=await r.createSigninRequest();return await this.setupRedirectHandler({oidcLoginOptions:e,state:t.state._id,codeVerifier:t.state._code_verifier,targetUrl:t.url.toString()})}catch(e){console.error(e)}}}const Ut={issuer:{toKey:"issuer",convertToUrl:!0},authorization_endpoint:{toKey:"authorizationEndpoint",convertToUrl:!0},token_endpoint:{toKey:"tokenEndpoint",convertToUrl:!0},userinfo_endpoint:{toKey:"userinfoEndpoint",convertToUrl:!0},jwks_uri:{toKey:"jwksUri",convertToUrl:!0},registration_endpoint:{toKey:"registrationEndpoint",convertToUrl:!0},end_session_endpoint:{toKey:"endSessionEndpoint",convertToUrl:!0},scopes_supported:{toKey:"scopesSupported"},response_types_supported:{toKey:"responseTypesSupported"},response_modes_supported:{toKey:"responseModesSupported"},grant_types_supported:{toKey:"grantTypesSupported"},acr_values_supported:{toKey:"acrValuesSupported"},subject_types_supported:{toKey:"subjectTypesSupported"},id_token_signing_alg_values_supported:{toKey:"idTokenSigningAlgValuesSupported"},id_token_encryption_alg_values_supported:{toKey:"idTokenEncryptionAlgValuesSupported"},id_token_encryption_enc_values_supported:{toKey:"idTokenEncryptionEncValuesSupported"},userinfo_signing_alg_values_supported:{toKey:"userinfoSigningAlgValuesSupported"},userinfo_encryption_alg_values_supported:{toKey:"userinfoEncryptionAlgValuesSupported"},userinfo_encryption_enc_values_supported:{toKey:"userinfoEncryptionEncValuesSupported"},request_object_signing_alg_values_supported:{toKey:"requestObjectSigningAlgValuesSupported"},request_object_encryption_alg_values_supported:{toKey:"requestObjectEncryptionAlgValuesSupported"},request_object_encryption_enc_values_supported:{toKey:"requestObjectEncryptionEncValuesSupported"},token_endpoint_auth_methods_supported:{toKey:"tokenEndpointAuthMethodsSupported"},token_endpoint_auth_signing_alg_values_supported:{toKey:"tokenEndpointAuthSigningAlgValuesSupported"},display_values_supported:{toKey:"displayValuesSupported"},claim_types_supported:{toKey:"claimTypesSupported"},claims_supported:{toKey:"claimsSupported"},service_documentation:{toKey:"serviceDocumentation"},claims_locales_supported:{toKey:"claimsLocalesSupported"},ui_locales_supported:{toKey:"uiLocalesSupported"},claims_parameter_supported:{toKey:"claimsParameterSupported"},request_parameter_supported:{toKey:"requestParameterSupported"},request_uri_parameter_supported:{toKey:"requestUriParameterSupported"},require_request_uri_registration:{toKey:"requireRequestUriRegistration"},op_policy_uri:{toKey:"opPolicyUri",convertToUrl:!0},op_tos_uri:{toKey:"opTosUri",convertToUrl:!0}};class Lt{storageUtility;constructor(e){this.storageUtility=e,this.storageUtility=e}static getLocalStorageKey(e){return`issuerConfig:${e}`}async fetchConfig(e){let t;const r=new URL(".well-known/openid-configuration",e.endsWith("/")?e:`${e}/`).href,n=await fetch(r);try{t=function(e){const t={};return Object.keys(e).forEach(r=>{Ut[r]&&(t[Ut[r].toKey]=e[r])}),Array.isArray(t.scopesSupported)||(t.scopesSupported=["openid"]),t}(await n.json())}catch(t){throw new ht(`[${e.toString()}] has an invalid configuration: ${t.message}`)}return await this.storageUtility.set(Lt.getLocalStorageKey(e),JSON.stringify(t)),t}}async function Dt(e,t){await et(e,t),await async function(){const e=new _t.OidcClient({response_mode:"query"});await e.clearStaleState(new _t.WebStorageStateStore({}));const t=window.localStorage,r=[];for(let e=0;e<=t.length;e+=1){const n=t.key(e);n&&(n.match(/^oidc\..+$/)||n.match(/^solidClientAuthenticationUser:.+$/))&&r.push(n)}r.forEach(e=>t.removeItem(e))}()}class Nt extends tt{async get(e){const[t,r,n,i,o,s,a,u]=await Promise.all([this.storageUtility.getForUser(e,"isLoggedIn",{secure:!0}),this.storageUtility.getForUser(e,"webId",{secure:!0}),this.storageUtility.getForUser(e,"clientId",{secure:!1}),this.storageUtility.getForUser(e,"clientSecret",{secure:!1}),this.storageUtility.getForUser(e,"redirectUrl",{secure:!1}),this.storageUtility.getForUser(e,"refreshToken",{secure:!0}),this.storageUtility.getForUser(e,"issuer",{secure:!1}),this.storageUtility.getForUser(e,"tokenType",{secure:!1})]);if("string"!=typeof o||$e(o)){if(void 0!==u&&("string"!=typeof(c=u)||!["DPoP","Bearer"].includes(c)))throw new Error(`Tokens of type [${u}] are not supported.`);var c;if(void 0!==n||void 0!==t||void 0!==r||void 0!==s)return{sessionId:e,webId:r,isLoggedIn:"true"===t,redirectUrl:o,refreshToken:s,issuer:a,clientAppId:n,clientAppSecret:i,tokenType:u??"DPoP"}}else await Promise.all([this.storageUtility.deleteAllUserData(e,{secure:!1}),this.storageUtility.deleteAllUserData(e,{secure:!0})])}async clear(e){return Dt(e,this.storageUtility)}}class Ot{async canHandle(e){try{return new URL(e),!0}catch(t){throw new Error(`[${e}] is not a valid URL, and cannot be used as a redirect URL: ${t}`)}}async handle(e){return Ze()}}class Ht{storageUtility;sessionInfoManager;issuerConfigFetcher;clientRegistrar;tokerRefresher;constructor(e,t,r,n,i){this.storageUtility=e,this.sessionInfoManager=t,this.issuerConfigFetcher=r,this.clientRegistrar=n,this.tokerRefresher=i,this.storageUtility=e,this.sessionInfoManager=t,this.issuerConfigFetcher=r,this.clientRegistrar=n,this.tokerRefresher=i}async canHandle(e){try{const t=new URL(e);return null!==t.searchParams.get("code")&&null!==t.searchParams.get("state")}catch(t){throw new Error(`[${e}] is not a valid URL, and cannot be used as a redirect URL: ${t}`)}}async handle(e,t){if(!await this.canHandle(e))throw new Error(`AuthCodeRedirectHandler cannot handle [${e}]: it is missing one of [code, state].`);const r=new URL(e),n=r.searchParams.get("state"),i=await this.storageUtility.getForUser(n,"sessionId",{errorIfNull:!0}),{issuerConfig:o,codeVerifier:s,redirectUrl:a,dpop:u}=await at(i,this.storageUtility,this.issuerConfigFetcher),c=r.searchParams.get("iss");if("string"==typeof c&&c!==o.issuer)throw new Error(`The value of the iss parameter (${c}) does not match the issuer identifier of the authorization server (${o.issuer}). See [rfc9207](https://www.rfc-editor.org/rfc/rfc9207.html#section-2.3-3.1.1)`);if(void 0===s)throw new Error(`The code verifier for session ${i} is missing from storage.`);if(void 0===a)throw new Error(`The redirect URL for session ${i} is missing from storage.`);const h=await this.clientRegistrar.getClient({sessionId:i},o),l=Date.now(),d=await xt(o,h,{grantType:"authorization_code",code:r.searchParams.get("code"),codeVerifier:s,redirectUrl:a},u);let f;window.localStorage.removeItem(`oidc.${n}`),void 0!==d.refreshToken&&(f={sessionId:i,refreshToken:d.refreshToken,tokenRefresher:this.tokerRefresher});const p=mt(d.accessToken,{dpopKey:d.dpopKey,refreshOptions:f,eventEmitter:t,expiresIn:d.expiresIn});await async function(e,t,r,n,i,o,s,a){void 0!==o&&await e.setForUser(t,{refreshToken:o},{secure:s}),void 0!==r&&await e.setForUser(t,{webId:r},{secure:s}),void 0!==n&&await e.setForUser(t,{clientId:n},{secure:s}),void 0!==i&&await e.setForUser(t,{isLoggedIn:i},{secure:s}),void 0!==a&&await e.setForUser(t,{publicKey:JSON.stringify(a.publicKey),privateKey:JSON.stringify(await we(a.privateKey))},{secure:s})}(this.storageUtility,i,d.webId,d.clientId,"true",void 0,!0);const g=await this.sessionInfoManager.get(i);if(!g)throw new Error(`Could not retrieve session: [${i}].`);return Object.assign(g,{fetch:p,getLogoutUrl:rt({idTokenHint:d.idToken,endSessionEndpoint:o.endSessionEndpoint}),expirationDate:"number"==typeof d.expiresIn?l+1e3*d.expiresIn:void 0})}}class jt extends Je{constructor(e){super(e)}}class Mt{get storage(){return window.localStorage}async get(e){return this.storage.getItem(e)||void 0}async set(e,t){this.storage.setItem(e,t)}async delete(e){this.storage.removeItem(e)}}class Bt{redirect(e,t){t&&t.handleRedirect?t.handleRedirect(e):t&&t.redirectByReplacingState?window.history.replaceState({},"",e):window.location.href=e}}class Kt{storageUtility;constructor(e){this.storageUtility=e,this.storageUtility=e}async getClient(e,t){const[r,n,i,o,s]=await Promise.all([this.storageUtility.getForUser(e.sessionId,"clientId",{secure:!1}),this.storageUtility.getForUser(e.sessionId,"clientSecret",{secure:!1}),this.storageUtility.getForUser(e.sessionId,"expiresAt",{secure:!1}),this.storageUtility.getForUser(e.sessionId,"clientName",{secure:!1}),this.storageUtility.getForUser(e.sessionId,"clientType",{secure:!1})]),a=void 0!==i?Number.parseInt(i,10):-1,u=void 0!==n&&0!==a&&Math.floor(Date.now()/1e3)>a;if(r&&("string"==typeof(c=s)&&["dynamic","static","solid-oidc"].includes(c))&&!u)return void 0!==n?{clientId:r,clientSecret:n,clientName:o,clientType:"dynamic",expiresAt:a}:{clientId:r,clientName:o,clientType:s};var c;try{const r=await bt(e,t),n={clientId:r.clientId,clientType:"dynamic"};return void 0!==r.clientSecret&&(n.clientSecret=r.clientSecret,n.expiresAt=String(r.expiresAt)),r.idTokenSignedResponseAlg&&(n.idTokenSignedResponseAlg=r.idTokenSignedResponseAlg),await this.storageUtility.setForUser(e.sessionId,n,{secure:!1}),r}catch(e){throw new Error("Client registration failed.",{cause:e})}}}class Vt{async canHandle(e){try{return new URL(e).searchParams.has("error")}catch(t){throw new Error(`[${e}] is not a valid URL, and cannot be used as a redirect URL: ${t}`)}}async handle(e,t){if(void 0!==t){const r=new URL(e),n=r.searchParams.get("error"),i=r.searchParams.get("error_description");t.emit(Ne,n,i)}return Ze()}}class qt{storageUtility;issuerConfigFetcher;clientRegistrar;constructor(e,t,r){this.storageUtility=e,this.issuerConfigFetcher=t,this.clientRegistrar=r,this.storageUtility=e,this.issuerConfigFetcher=t,this.clientRegistrar=r}async refresh(e,t,r,n){const i=await at(e,this.storageUtility,this.issuerConfigFetcher),o=await this.clientRegistrar.getClient({sessionId:e},i.issuerConfig);if(void 0===t)throw new Error(`Session [${e}] has no refresh token to allow it to refresh its access token.`);if(i.dpop&&void 0===r)throw new Error(`For session [${e}], the key bound to the DPoP access token must be provided to refresh said access token.`);const s=await At(t,i.issuerConfig,o,r);return void 0!==s.refreshToken&&n?.emit(je,s.refreshToken),s}}function Jt(e){const t=new ct,r=e.secureStorage||t,n=e.insecureStorage||new Mt,i=new kt(r,n),o=new Lt(i),s=new Kt(i),a=new Nt(i),u=new qt(i,o,s),c=new Bt,h=new Ct(i,new Rt(i,c),o,s),l=new jt([new Vt,new Ht(i,a,o,s,u),new Ot]);return new Pt(h,l,new Qe(a,c),a,o)}const Wt=`${Le}currentSession`,$t=`${Le}currentUrl`;class zt{info;events;clientAuthentication;tokenRequestInProgress=!1;constructor(e={},t=void 0){this.events=new wt,e.clientAuthentication?this.clientAuthentication=e.clientAuthentication:e.secureStorage&&e.insecureStorage?this.clientAuthentication=Jt({secureStorage:e.secureStorage,insecureStorage:e.insecureStorage}):this.clientAuthentication=Jt({}),e.sessionInfo?this.info={sessionId:e.sessionInfo.sessionId,isLoggedIn:!1,webId:e.sessionInfo.webId,clientAppId:e.sessionInfo.clientAppId}:this.info={sessionId:t??Ue(),isLoggedIn:!1},this.events.on(Oe,()=>window.localStorage.setItem(Wt,this.info.sessionId)),this.events.on(Me,()=>this.internalLogout(!1)),this.events.on(Ne,()=>this.internalLogout(!1))}login=async e=>(await this.clientAuthentication.login({sessionId:this.info.sessionId,...e,tokenType:e.tokenType??"DPoP"},this.events),new Promise(()=>{}));fetch=(e,t)=>this.clientAuthentication.fetch(e,t);internalLogout=async(e,t)=>{window.localStorage.removeItem(Wt),await this.clientAuthentication.logout(this.info.sessionId,t),this.info.isLoggedIn=!1,e&&this.events.emit(He)};logout=async e=>this.internalLogout(!0,e);handleIncomingRedirect=async(e={})=>{if(this.info.isLoggedIn)return this.info;if(this.tokenRequestInProgress)return;const t="string"==typeof e?{url:e}:e,r=t.url??window.location.href;this.tokenRequestInProgress=!0;const n=await this.clientAuthentication.handleIncomingRedirect(r,this.events);if(function(e){return!!e?.isLoggedIn}(n)){this.setSessionInfo(n);const e=window.localStorage.getItem($t);null===e?this.events.emit(Oe):(window.localStorage.removeItem($t),this.events.emit(Ke,e))}else if(!0===t.restorePreviousSession){const e=window.localStorage.getItem(Wt);if(null!==e){if(await async function(e,t,r){const n=await t.validateCurrentSession(e);return null!==n&&(window.localStorage.setItem($t,window.location.href),await t.login({sessionId:e,prompt:"none",oidcIssuer:n.issuer,redirectUrl:n.redirectUrl,clientId:n.clientAppId,clientSecret:n.clientAppSecret,tokenType:n.tokenType??"DPoP"},r.events),!0)}(e,this.clientAuthentication,this))return new Promise(()=>{})}}return this.tokenRequestInProgress=!1,n};setSessionInfo(e){this.info.isLoggedIn=e.isLoggedIn,this.info.webId=e.webId,this.info.sessionId=e.sessionId,this.info.clientAppId=e.clientAppId,this.info.expirationDate=e.expirationDate,this.events.on(Be,e=>{this.info.expirationDate=Date.now()+1e3*e})}}const Yt=new zt;var Gt=n(264),Xt=n(386);const Qt=n.n(Xt)()(Gt),Zt=(0,Gt.sym)("http://www.iana.org/assignments/link-relations/acl");function er(e){const t=Qt;function r(e,r,n,i={}){const o=i.public||[],s=(0,Gt.graph)(),a=(0,Gt.Namespace)("http://www.w3.org/ns/auth/acl#");let u=s.sym(`${n}#a1`);const c=s.sym(n),h=s.sym(e);if(s.add(u,t.rdf("type"),a("Authorization"),c),s.add(u,a("accessTo"),h,c),i.defaultForNew&&s.add(u,a("default"),h,c),s.add(u,a("agent"),r,c),s.add(u,a("mode"),a("Read"),c),s.add(u,a("mode"),a("Write"),c),s.add(u,a("mode"),a("Control"),c),o.length){u=s.sym(`${n}#a2`),s.add(u,t.rdf("type"),a("Authorization"),c),s.add(u,a("accessTo"),h,c),s.add(u,a("agentClass"),t.foaf("Agent"),c);for(let e=0;eo||function(t){const r=e.fetcher;if(!r)throw new Error("Cannot fetch ACL rel, store has no fetcher");return r.load(t).then(r=>{if(!r.ok)throw new Error("fetchACLRel: While loading:"+r.error);const n=e.any(e.sym(t),Zt);if(!n)throw new Error("fetchACLRel: No Link rel=ACL header for "+t);return n})}(t).catch(e=>{throw new Error(`Error fetching rel=ACL header for ${t}: ${e}`)})).then(o=>{const s=r(t,n,o.uri,i);if(!e.fetcher)throw new Error("Cannot PUT this, store has no fetcher");return e.fetcher.webOperation("PUT",o.uri,{data:s,contentType:"text/turtle"}).then(e=>{if(!e.ok)throw new Error("Error writing ACL text: "+e.error);return o})})},genACLText:r}}const tr=()=>{let{SolidAppContext:e}=window;if(e||(e={}),e.viewingNoAuthPage=!1,e.noAuth&&window.document){if(window.document.location.href.startsWith(e.noAuth)){e.viewingNoAuthPage=!0;const t=new URLSearchParams(window.document.location.search);if(t){let r=e.viewedPage=t.get("uri")||null;if(r&&(r=decodeURI(r),!r.startsWith(e.noAuth))){const t=r.split(/\//);e.idp=t[0]+"//"+t[2],e.viewingNoAuthPage=!1}}}}return e};function rr(){const{$SolidTestEnvironment:t}=window;if(void 0!==t&&t.username)return e("Assuming the user is "+t.username),(0,Gt.sym)(t.username);if("undefined"!=typeof document&&document.location&&"http://localhost"===(""+document.location).slice(0,16)){const t=document.getElementById("appTarget");if(!t)return null;const r=t.getAttribute("testID");return r?(e("Assuming user is "+r),(0,Gt.sym)(r)):null}return null}class nr{constructor(e){this.session=e}get authSession(){return this.session}currentUser(){const e=tr();return e.viewingNoAuthPage?(0,Gt.sym)(e.webId):this&&this.session&&this.session.info&&this.session.info.webId&&this.session.info.isLoggedIn?(0,Gt.sym)(this.session.info.webId):rr()}async checkUser(t){const r=new URL(window.location.href).hash;r&&window.localStorage.setItem("preLoginRedirectHash",r),this.session.events.on(Ke,t=>{e(`Session restored to ${t}`),document.location.toString()!==t&&history.replaceState(null,"",t)});const n=new URL(window.location.href);n.hash="",await this.session.handleIncomingRedirect({restorePreviousSession:!0,url:n.href});const i=window.localStorage.getItem("preLoginRedirectHash");if(i){const e=new URL(window.location.href);e.hash!==i&&(history.pushState?history.pushState(null,document.title,i):location.hash=i,e.hash=i),window.localStorage.setItem("preLoginRedirectHash","")}let o=rr();if(o)return Promise.resolve(t?t(o):o);const s=this.webIdFromSession(this.session.info);return s&&(o=this.saveUser(s)),o&&e(`(Logged in as ${o} by authentication)`),Promise.resolve(t?t(o):o)}saveUser(e,t){let r;if(e){r="string"==typeof e?e:e.uri;const n=(0,Gt.namedNode)(r);return t&&(t.me=n),n}return null}webIdFromSession(e){return(null==e?void 0:e.webId)&&e.isLoggedIn?e.webId:null}}function ir(e){return(0,Gt.sym)(e.uri+"#id"+Date.now())}function or(e){return!e||`${window.location.origin}/`!==new URL(e.value).origin}const sr="index.ttl#this";function ar(e,t){const r=Qt;async function n(t,r,n){await e.fetcher.load(t);const i=e.any(t,new Gt.NamedNode("http://www.iana.org/assignments/link-relations/acl"));if(!i)throw new Error("Chat ACL doc not found!");const o=`\n @prefix acl: .\n <#owner>\n a acl:Authorization;\n acl:agent <${r.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Write, acl:Control.\n <#invitee>\n a acl:Authorization;\n acl:agent <${n.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Append.\n `;await e.fetcher.webOperation("PUT",i.value,{data:o,contentType:"text/turtle"})}async function i(t,n){const i=e.any(n,r.solid("privateTypeIndex"));if(!i)throw new Error("Private type index not found!");await e.fetcher.load(i);const o=ir(i),s=[(0,Gt.st)(o,r.rdf("type"),r.solid("TypeRegistration"),i.doc()),(0,Gt.st)(o,r.solid("forClass"),r.meeting("LongChat"),i.doc()),(0,Gt.st)(o,r.solid("instance"),t,i.doc())];await new Promise((t,r)=>{e.updater.update([],s,function(e,n,i){n?t(null):r(new Error(i))})})}async function o(r){const n=await t.loadMe(),i=function(e,t){const r=new URL(`IndividualChats/${new URL(e.value).host}/`,t.value).toString();return new Gt.NamedNode(r)}(r,await t.getPodRoot(n));let o=!0;try{await e.fetcher.load(new Gt.NamedNode(i.value+"index.ttl#this"))}catch(e){o=!1}return{me:n,chatContainer:i,exists:o}}async function s(e,t){return(await a({me:t,newBase:e.value})).newInstance}function a(t){const n=e,i=n.updater;if(t.me&&!t.me.uri)throw new Error("chat mintNew: Invalid userid "+t.me);const o=t.newInstance=t.newInstance||n.sym(t.newBase+sr),s=o.doc();return n.add(o,r.rdf("type"),r.meeting("LongChat"),s),n.add(o,r.dc("title"),"Chat channel",s),n.add(o,r.dc("created"),(0,Gt.term)(new Date(Date.now())),s),t.me&&n.add(o,r.dc("author"),t.me,s),new Promise(function(e,r){null==i||i.put(s,n.statementsMatching(void 0,void 0,void 0,s),"text/turtle",function(n,i,s){i?e({...t,newInstance:o}):r(new Error("FAILED to save new chat channel at: "+n+" : "+s))})})}async function u(t,n){var i;await e.fetcher.load(t.doc());const o=e.any(t,r.ldp("inbox"),void 0,t.doc());if(!o)throw new Error(`Invitee inbox not found! ${t.value}`);const s=`\n <> a ;\n ${r.rdf("seeAlso")} <${n.value}> .\n `,a=await(null===(i=e.fetcher)||void 0===i?void 0:i.webOperation("POST",o.value,{data:s,contentType:"text/turtle"}));if(!(null==a?void 0:a.headers.get("location")))throw new Error(`Invite sending returned a ${null==a?void 0:a.status}`)}return{setAcl:n,addToPrivateTypeIndex:i,findChat:o,createChatThing:s,getChat:async function(e,t=!0){const{me:r,chatContainer:a,exists:c}=await o(e);if(c)return new Gt.NamedNode(a.value+sr);if(t){const t=await s(a,r);return await u(e,t),await n(a,r,e),await i(t,r),t}return null},sendInvite:u,mintNew:a}}function ur(e,t,r,n,i){return{createInboxFor:async function(e,i){const o=await t.loadMe(),s=`${(await t.getPodRoot(o)).value}p2p-inboxes/${encodeURIComponent(i)}/`;return await n.createContainer(s),await r.setSinglePeerAccess({ownerWebId:o.value,peerWebId:e,accessToModes:"acl:Append",target:s}),s},getNewMessages:async function(e){e||(e=await t.loadMe());const r=await t.getMainInbox(e);return(await n.getContainerMembers(r)).filter(e=>!n.isContainer(e))},markAsRead:async function(t,r){const n=await e.fetcher._fetch(t);if(200!==n.status)throw new Error(`Not OK! ${t}`);const i=function(e,t){const r=t.getUTCFullYear(),n=("0"+(t.getUTCMonth()+1)).slice(-2),i=("0"+t.getUTCDate()).slice(-2),o=e.split("/"),s=o[o.length-1];return new URL(`./archive/${r}/${n}/${i}/${s}`,e).toString()}(t,r),o={method:"PUT",body:await n.text(),headers:[["Content-Type",n.headers.get("Content-Type")||"application/octet-stream"]]};"2"===(await e.fetcher._fetch(i,o)).status.toString()[0]&&await e.fetcher._fetch(t,{method:"DELETE"})}}}class cr extends Error{constructor(e){super(e),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name}}class hr extends cr{}class lr extends cr{}class dr extends cr{}class fr extends cr{}class pr extends cr{}class gr extends cr{}class yr extends cr{constructor(e,t){super(t),this.status=e}}function vr(e,r,n){const i=Qt;async function o(r){await s(r);const o=function(e){const t=e.uri.replace("/profile/","/").replace("/public/","/").split("/").slice(0,-1).join("/")+"/Settings/Preferences.ttl";return(0,Gt.sym)(t)}(r);let a;try{a=await n.followOrCreateLink(r,i.space("preferencesFile"),o,r.doc())}catch(e){if(t(`User ${r} has no pointer in profile to preferences file.`),e instanceof pr)throw e;if(e instanceof gr)throw e;if(e instanceof hr)throw e;if(e instanceof lr)throw e;if(e instanceof dr)throw e;if(e instanceof yr)throw e;throw e}try{await e.fetcher.load(a)}catch(e){const n=`Unable to load preference of user ${r}: ${e}`;if(t(n),401===e.response.status)throw new hr;if(403===e.response.status){if(or(a))throw new lr;throw new dr}throw new Error(n)}return a}async function s(t){if(!t)throw new Error("loadProfile: no user given.");try{await e.fetcher.load(t.doc())}catch(e){throw new Error(`Unable to load profile of user ${t}: ${e}`)}return t.doc()}function a(t){return e.any(t,i.space("storage"),void 0,t.doc())}return{loadMe:async function(){const t=r.currentUser();if(null===t)throw new Error("Current user not found! Not logged in?");return await e.fetcher.load(t.doc()),t},getPodRoot:function(e){const t=a(e);if(!t)throw new Error("User pod root not found!");return t},getMainInbox:async function(t){await e.fetcher.load(t);const r=e.any(t,i.ldp("inbox"),void 0,t.doc());if(!r)throw new Error("User main inbox not found!");return r},findStorage:a,loadPreferences:o,loadProfile:s,silencedLoadPreferences:async function(e){try{return await o(e)}catch(e){return}}}}function mr(e,r,n,i){const o=Qt;async function s(r){if(!r)throw new Error("loadTypeIndexesFor: No user given");const s=await n.loadProfile(r),a=h(r);let u;try{u=await i.followOrCreateLink(r,o.solid("publicTypeIndex"),a,s)}catch(e){t(`User ${r} has no pointer in profile to publicTypeIndex file.`)}const c=u?[{label:"public",index:u,agent:r}]:[];let d,f;try{d=await n.silencedLoadPreferences(r)}catch(e){d=null}if(d){const n=l(d);let a;try{a=e.any(r,o.solid("privateTypeIndex"),void 0,s)||await i.followOrCreateLink(r,o.solid("privateTypeIndex"),n,d)}catch(e){t(`User ${r} has no pointer in preference file to privateTypeIndex file.`)}f=a?[{label:"private",index:a,agent:r}]:[]}else f=[];const p=c.concat(f);if(0===p.length)return p;const g=p.map(e=>e.index);try{await e.fetcher.load(g)}catch(e){t("Problems loading type index: ",e)}return p}async function a(r){let i;try{i=await n.silencedLoadPreferences(r)}catch(e){t(`User ${r} has no pointer in profile to preferences file.`)}if(i){const t=e.each(r,o.solid("community"),void 0,i).concat(e.each(r,o.solid("community"),void 0,r.doc()));let n=[];for(const e of t)n=n.concat(await s(e));return n}return[]}async function u(e){return(await s(e)).concat((await a(e)).flat())}async function c(e,t){const r=await u(t);let n=[];for(const t of r){const r=await d(t,e);n=n.concat(r)}return n}function h(e){var t;return(0,Gt.sym)((null===(t=e.doc().dir())||void 0===t?void 0:t.uri)+"publicTypeIndex.ttl")}function l(e){var t;return(0,Gt.sym)((null===(t=e.doc().dir())||void 0===t?void 0:t.uri)+"privateTypeIndex.ttl")}async function d(t,r){const n=t.index,i=[],s=e.statementsMatching(null,o.solid("instance"),null,n).concat(e.statementsMatching(null,o.solid("instanceContainer"),null,n)).map(e=>e.subject);for(const a of s){const s=e.any(a,o.solid("forClass"),null,n);if(!r||s.sameTerm(r)){const r=e.each(a,o.solid("instance"),null,n);for(const e of r)i.push({instance:e,type:s,scope:t});const u=e.each(a,o.solid("instanceContainer"),null,n);for(const r of u)await e.fetcher.load(r),i.push({instance:(0,Gt.sym)(r.value),type:s,scope:t})}}return i}return{registerInTypeIndex:async function(t,r,n){const i=ir(r),s=[(0,Gt.st)(i,o.rdf("type"),o.solid("TypeRegistration"),r),(0,Gt.st)(i,o.solid("forClass"),n,r),(0,Gt.st)(i,o.solid("instance"),t,r)];try{await e.updater.update([],s)}catch(e){const n=`Unable to register ${t} in index ${r}: ${e}`;return console.warn(n),null}return i},getRegistrations:function(t,r){return e.each(void 0,o.solid("instance"),t).filter(t=>e.holds(t,o.solid("forClass"),r))},loadTypeIndexesFor:s,loadCommunityTypeIndexes:a,loadAllTypeIndexes:u,getScopedAppInstances:c,getAppInstances:async function(e){const t=r.currentUser();if(!t)throw new Error("getAppInstances: Must be logged in to find apps.");return(await c(e,t)).map(e=>e.instance)},suggestPublicTypeIndex:h,suggestPrivateTypeIndex:l,deleteTypeIndexRegistration:async function(t){const r=e.the(null,o.solid("instance"),t.instance,t.scope.index);if(!r)throw new Error(`deleteTypeIndexRegistration: No registration found for ${t.instance}`);const n=e.statementsMatching(r,null,null,t.scope.index);await e.updater.update(n,[])},getScopedAppsFromIndex:d}}function wr(r,n){e("SolidLogic: Unique instance created. There should only be one of these.");const i=Gt.graph();Gt.fetcher(i,{fetch:r.fetch}),i.updater=new Gt.UpdateManager(i),i.features=[];const o=new nr(n),s=er(i),a=function(e){function t(t){return e.statementsMatching(t,(0,Gt.sym)("http://www.w3.org/ns/ldp#contains"),void 0).map(e=>e.object)}function r(e){const t=e.value;return"/"===t.charAt(t.length-1)}return{isContainer:r,createContainer:async function(t){if(!r((0,Gt.sym)(t)))throw new Error(`Not a container URL ${t}`);const n=await e.fetcher._fetch(t,{method:"PUT",headers:{"Content-Type":"text/turtle","If-None-Match":"*",Link:'; rel="type"'},body:" "});if("2"!==n.status.toString()[0])throw new Error(`Not OK: got ${n.status} response while creating container at ${t}`)},getContainerElements:t,getContainerMembers:async function(r){return await e.fetcher.load(r),t(r)}}}(i),u=function(r,n,i){async function o(e){let t;try{t=await r.fetcher.load(e)}catch(t){if(404!==t.response.status){if(401===t.response.status)throw new hr;if(403===t.response.status){if(or(e))throw new lr;throw new dr}const r="createIfNotExists doc load error NOT 404: "+e+": "+t;throw new yr(t.status,t.message+r)}try{await r.fetcher.webOperation("PUT",e,{data:"",contentType:"text/turtle"})}catch(t){throw new gr("createIfNotExists: PUT FAILED: "+e+": "+t)}await r.fetcher.load(e)}return t}return{recursiveDelete:async function t(o){try{if(i.isContainer(o)){const e=await n.findAclDocUrl(o);await r.fetcher._fetch(e,{method:"DELETE"});const s=await i.getContainerMembers(o);await Promise.all(s.map(e=>t(e)))}const e=o.value;return r.fetcher._fetch(e,{method:"DELETE"})}catch(t){e(`Please manually remove ${o.value} from your system.`,t)}},setSinglePeerAccess:async function(e){let t=["@prefix acl: .","",`<#alice> a acl:Authorization;\n acl:agent <${e.ownerWebId}>;`,` acl:accessTo <${e.target}>;`,` acl:default <${e.target}>;`," acl:mode acl:Read, acl:Write, acl:Control.",""].join("\n");e.accessToModes&&(t+=["<#bobAccessTo> a acl:Authorization;",` acl:agent <${e.peerWebId}>;`,` acl:accessTo <${e.target}>;`,` acl:mode ${e.accessToModes}.`,""].join("\n")),e.defaultModes&&(t+=["<#bobDefault> a acl:Authorization;",` acl:agent <${e.peerWebId}>;`,` acl:default <${e.target}>;`,` acl:mode ${e.defaultModes}.`,""].join("\n"));const i=await n.findAclDocUrl((0,Gt.sym)(e.target));return r.fetcher._fetch(i,{method:"PUT",body:t,headers:[["Content-Type","text/turtle"]]})},createEmptyRdfDoc:async function(e,t){await r.fetcher.webOperation("PUT",e.uri,{data:`# ${new Date} ${t}\n `,contentType:"text/turtle"})},followOrCreateLink:async function(e,n,i,s){await r.fetcher.load(s);const a=r.any(e,n,null,s);if(a)return a;if(!r.updater.editable(s)){const e=`followOrCreateLink: cannot edit ${s.value}`;throw t(e),new pr(e)}try{await r.updater.update([],[(0,Gt.st)(e,n,i,s)])}catch(e){throw t(`followOrCreateLink: Error making link in ${s} to ${i}: ${e}`),new gr(e)}try{await o(i)}catch(e){throw t(`followOrCreateLink: Error loading or saving new linked document: ${i}: ${e}`),e}return i},loadOrCreateIfNotExists:o}}(i,s,a),c=vr(i,o,u),h=ar(i,c),l=ur(i,c,u,a),d=mr(i,o,c,u);return e("SolidAuthnLogic initialized"),{store:i,authn:o,acl:s,inbox:l,chat:h,profile:c,typeIndex:d,load:function(e){return i.fetcher.load(e)},updatePromise:function(e,t=[]){return new Promise((r,n)=>{i.updater.update(e,t,function(e,t,i){t?r():n(new Error(i))})})},clearStore:function(){i.statements.slice().forEach(i.remove.bind(i))}}}const _r=async(e,t)=>{const r=t&&t.credentials&&"omit"==t.credentials;return Yt.info.webId&&!r?Yt.fetch(e,t):window.fetch(e,t)},Sr=Symbol.for("solid-logic-singleton"),br="undefined"!=typeof window?window:n.g;const Er=(br[Sr]?e("SolidLogic: Using existing global singleton instance."):(e("SolidLogic: Creating new global singleton instance."),br[Sr]=wr({fetch:_r},Yt),e("Unique quadstore initialized.")),br[Sr]),Fr=[{name:"Solid Community",uri:"https://solidcommunity.net"},{name:"Solid Web",uri:"https://solidweb.org"},{name:"Solid Web ME",uri:"https://solidweb.me"},{name:"Inrupt.com",uri:"https://login.inrupt.com"}];function xr(){const e=[...Fr],{host:t,origin:r}=new URL(location.href),n=e.map(({uri:e})=>new URL(e).host);return n.includes(t)||n.some(e=>function(e,t){const r=e.length-t.length-1;return r>0&&"."===e[r]&&e.endsWith(t)}(t,e))||e.unshift({name:t,uri:r}),e}const Ar=Er.authn,kr=Er.authn.authSession,Pr=Er.store})(),i})()); +//# sourceMappingURL=solid-logic.min.js.map \ No newline at end of file diff --git a/docs/workingWithSolidUI/test.html b/docs/workingWithSolidUI/test.html new file mode 100644 index 000000000..b1bed2bb5 --- /dev/null +++ b/docs/workingWithSolidUI/test.html @@ -0,0 +1,237 @@ + + + + + + Solid-UI Test - Load and Display RDF Data + + + +
+

🎯 Solid-UI Test Page

+

This page demonstrates loading RDF data into an RDF store and displaying it using solid-ui widgets.

+ +
+ + + +
+ +
Click "Load RDF Data" to begin...
+
+ + + + + + + + + diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..3645a1651 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,102 @@ +import globals from 'globals' +import tsParser from '@typescript-eslint/parser' +import neostandard from 'neostandard' + +export default [ + ...neostandard(), + { + ignores: [ + '**/*.html', + '**/*.md', + '**/*.json', + 'docs/**', + 'Documentation/**', + 'node_modules/**', + 'coverage/**', + 'dist/**', + 'lib/**', + 'examples/**', + 'src/stories/**', + '*.js' + ], + }, + { + files: ['src/**/*.js', 'src/**/*.cjs', 'src/**/*.mjs'], + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + }, + ecmaVersion: 2022, // Support class fields and other modern syntax + sourceType: 'module' // Match TypeScript module: ESNext + }, + rules: { + // Code style - match TypeScript settings + semi: ['error', 'never'], + quotes: ['error', 'single'], + + // Strict checking - match TypeScript strictness + 'no-console': 'error', + 'no-unused-vars': 'error', // Match TypeScript noUnusedLocals: true + 'no-undef': 'error', + strict: ['error', 'global'], // Match TypeScript alwaysStrict: true + + // Additional strictness to match TypeScript behavior + 'no-implicit-globals': 'error', + 'prefer-const': 'error', // Encourage immutability + 'no-var': 'error', // Use let/const only + 'no-redeclare': 'error' + }, + }, + { + files: ['src/**/*.ts'], + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + }, + parser: tsParser, + parserOptions: { + project: ['./tsconfig.json'] + }, + }, + rules: { + semi: ['error', 'never'], + quotes: ['error', 'single'], + // Disable ESLint rules that TypeScript handles better + 'no-unused-vars': 'off', // TypeScript handles this via noUnusedLocals + 'no-undef': 'off', // TypeScript handles undefined variables + }, + }, + { + files: ['test/**/*.ts'], + languageOptions: { + parser: tsParser, + parserOptions: { + project: ['./tsconfig.test.json'], + }, + }, + rules: { + semi: ['error', 'never'], + quotes: ['error', 'single'], + // Disable ESLint rules that TypeScript handles better + 'no-unused-vars': 'off', // TypeScript handles this via noUnusedLocals + 'no-undef': 'off', // TypeScript handles undefined variables + } + }, + { + files: ['test/**/**/*.js', 'test/**/*.js'], + rules: { + semi: ['error', 'never'], + quotes: ['error', 'single'], + 'no-console': 'off', // Allow console in tests + 'no-undef': 'off', // Tests may define globals + } + } +] diff --git a/eslint.config.mjs.auth-v2 b/eslint.config.mjs.auth-v2 new file mode 100644 index 000000000..92305f796 --- /dev/null +++ b/eslint.config.mjs.auth-v2 @@ -0,0 +1,74 @@ +import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import typescriptEslintRecommended from "@typescript-eslint/eslint-plugin/configs/recommended"; // Import the recommended config +import globals from "globals"; +import tsParser from "@typescript-eslint/parser"; +import promise from 'eslint-plugin-promise'; +import promiseRecommended from 'eslint-plugin-promise/recommended'; // Import promise config +import n from 'eslint-plugin-n'; +import nRecommendedTs from 'eslint-plugin-n/configs/recommended-typescript'; +import importPlugin from 'eslint-plugin-import'; // Import import plugin +import importRecommended from 'eslint-plugin-import/config/recommended'; // Import import config + +export default [ + { + ignores: ["**/dist"], + }, + { + plugins: { + "@typescript-eslint": typescriptEslint, + promise: promise, + n: n, + import: importPlugin, // Add import plugin + }, + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + Atomics: "readonly", + SharedArrayBuffer: "readonly", + }, + parser: tsParser, + }, + files: ["src/**/*", "test/**/*"], + }, + // spread the configuration files into the final config + typescriptEslintRecommended, + promiseRecommended, + nRecommendedTs, + importRecommended, // Add import config + { + rules: { + "no-unused-vars": ["warn", { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }], + "@typescript-eslint/no-unused-vars": ["warn", { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }], + "promise/param-names": "error", + "n/no-callback-literal": "error", + // Remove rules added by the extends and not needed + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "no-var": "warn", + "n/no-unsupported-features/es-syntax": "off", + // import rules + 'import/no-unresolved': 'off', // Because of the types conflict + 'import/named': 'warn', + 'import/default': 'warn', + 'import/namespace': 'warn', + 'import/no-absolute-path': 'warn', + 'import/no-dynamic-require': 'warn', + 'import/no-webpack-loader-syntax': 'warn', + 'import/no-self-import': 'warn', + 'import/no-useless-path-segments': 'warn', + 'import/export': 'warn', + 'import/no-named-as-default': 'warn', + 'import/no-named-as-default-member': 'warn', + 'import/no-deprecated': 'warn', + 'import/no-extraneous-dependencies': 'warn', + 'import/no-mutable-exports': 'warn' + }, + } +]; diff --git a/examples/buttons/index.html b/examples/buttons/index.html new file mode 100644 index 000000000..536fe88ce --- /dev/null +++ b/examples/buttons/index.html @@ -0,0 +1,17 @@ + + + + + solid-ui UI.widgets.buttons examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/ + + diff --git a/examples/draganddrop/index.html b/examples/draganddrop/index.html new file mode 100644 index 000000000..ea10b6a98 --- /dev/null +++ b/examples/draganddrop/index.html @@ -0,0 +1,17 @@ + + + + + solid-ui UI.widgets.draganddrop examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/drag-drop--draggable + + diff --git a/examples/error/index.html b/examples/error/index.html new file mode 100644 index 000000000..11d04ea1e --- /dev/null +++ b/examples/error/index.html @@ -0,0 +1,18 @@ + + + + + solid-ui UI.widgets.error examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/display--error-message-block + + diff --git a/examples/forms/index.html b/examples/forms/index.html new file mode 100644 index 000000000..0eefe1f13 --- /dev/null +++ b/examples/forms/index.html @@ -0,0 +1,18 @@ + + + + + solid-ui UI.widgets.forms examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/forms-appendform--trivial-comment-field + + diff --git a/examples/header/index.html b/examples/header/index.html new file mode 100644 index 000000000..7c2555d59 --- /dev/null +++ b/examples/header/index.html @@ -0,0 +1,97 @@ + + + + + + solid-ui UI.widgets.header examples page + + + + + + + + +

This example demonstrates how to use the header component. The header has a different view depending + on whether or not you are logged in.

+

Unless you are already logged into your pod identity provider you + should see the logged out view. To see the logged in view click the login button above.

+

The header is customizable through the options parameter.

+

The logo can be a url of your personalized logo, otherwise it will default to Solid.

+

The menu list is an array of either links or buttons.

+

The details are below.

+

options: + + type HeaderOptions { + logo?: string, + menuList?: MenuItems[] + }

+

MenuItems can be either a MenuItemLink or a MenuItemButton: + +

type MenuItemLink = { + label: string, + url: string + } +

+

type MenuItemButton = { + label: string, + onclick: () => {} + } +

+ +
+

+ + + +

In the code below you can see that you can have a mixture of buttons and links. When you pass in an onclick + initHeader will create a + button, however if you pass in a url it will create a link. Either way, as you can see, they appear the same in the + menu. +

+ +

+  
+  
+ + + + \ No newline at end of file diff --git a/examples/log/index.html b/examples/log/index.html new file mode 100644 index 000000000..c0a50b2c0 --- /dev/null +++ b/examples/log/index.html @@ -0,0 +1,17 @@ + + + + + solid-ui UI.log examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/log--simple-message + + diff --git a/src/test/test-matrix.html b/examples/matrix/index.html similarity index 98% rename from src/test/test-matrix.html rename to examples/matrix/index.html index fc2f38038..c86fe66f2 100644 --- a/src/test/test-matrix.html +++ b/examples/matrix/index.html @@ -1,8 +1,8 @@ Test matrix.js - + - + diff --git a/examples/matrix/test-matrix.js b/examples/matrix/test-matrix.js new file mode 100644 index 000000000..dd0db09a0 --- /dev/null +++ b/examples/matrix/test-matrix.js @@ -0,0 +1,183 @@ +document.addEventListener('DOMContentLoaded', function () { + /// /////////////////////////////////////////// + + const kb = SolidLogic.store + const dom = document + + const ICAL = $rdf.Namespace('http://www.w3.org/2002/12/cal/ical#') + const SCHED = $rdf.Namespace('http://www.w3.org/ns/pim/schedule#') + const DC = $rdf.Namespace('http://purl.org/dc/elements/1.1/') + + const uri = window.location.href + const base = (window.document.title = uri.slice(0, uri.lastIndexOf('/') + 1)) + const testDocURI = base + 'test.ttl' // imaginary doc - just use its URL + const testDoc = $rdf.sym(testDocURI) + const subjectURI = testDocURI + '#event1' + const meURI = testDocURI + '#a0' + const me = kb.sym(meURI) + + // var forms_uri = window.document.title = base+ 'forms.ttl'; + + const subject = kb.sym(subjectURI) + const div = dom.getElementById('UITestArea') + + const showResults = function () { + // Now the form for responsing to the poll + // + + // div.appendChild(dom.createElement('hr')) + + const invitation = subject + + const query = new $rdf.Query('Responses') + const v = {} + ;['time', 'author', 'value', 'resp', 'cell'].map(function (x) { + query.vars.push((v[x] = $rdf.variable(x))) + }) + query.pat.add(invitation, SCHED('response'), v.resp) + query.pat.add(v.resp, DC('author'), v.author) + query.pat.add(v.resp, SCHED('cell'), v.cell) + query.pat.add(v.cell, SCHED('availabilty'), v.value) + query.pat.add(v.cell, ICAL('dtstart'), v.time) + /* + var prologue = " @prefix foaf: .\n\ + @prefix sched: .\n\ + @prefix ical: .\n\ + @prefix dc: .\n"; + */ + const prologue = dom.getElementById('Prologue').textContent + + // var config = dom.getElementById('Config').textContent; + // $rdf.parse(prologue + config, kb, testDocURI, 'text/turtle') // str, kb, base, contentType + + const tests = dom.getElementById('TestData').children + const inputText = function (tr) { + return tr.children[0].children[0].textContent + } + const output = function (tr) { + return tr.children[1] + } + let t = 0 + $rdf.parse(prologue + inputText(tests[t]), kb, testDocURI, 'text/turtle') // str, kb, base, contentType + + const options = {} + + const setAxes = function () { + options.set_x = kb.each(subject, SCHED('option')) // @@@@@ option -> dtstart in future + options.set_x = options.set_x.map(function (opt) { + return kb.any(opt, ICAL('dtstart')) + }) + + options.set_y = kb.each(subject, SCHED('response')) + options.set_y = options.set_y.map(function (resp) { + return kb.any(resp, DC('author')) + }) + } + setAxes() + + // var possibleTimes = kb.each(invitation, SCHED('option')) + // .map(function (opt) { return kb.any(opt, ICAL('dtstart')) }) + + const displayTheMatrix = function () { + const matrix = div.appendChild( + UI.matrix.matrixForQuery( + dom, + query, + v.time, + v.author, + v.value, + options, + function () {} + ) + ) + + matrix.setAttribute('class', 'matrix') + + const refreshButton = dom.createElement('button') + refreshButton.textContent = 'refresh' + refreshButton.addEventListener( + 'click', + function (_event) { + matrix.refresh() + }, + false + ) + return matrix + } + + // @@ Give other combos too-- see schedule ontology + const possibleAvailabilities = [SCHED('No'), SCHED('Maybe'), SCHED('Yes')] + + const dataPointForNT = [] + + // var doc = testDoc + options.set_y = options.set_y.filter(function (z) { + return !z.sameTerm(me) + }) + options.set_y.push(me) // Put me on the end + + options.cellFunction = function (cell, x, y, value) { + const refreshColor = function () { + const bg = kb.any(value, UI.ns.ui('backgroundColor')) + if (bg) { + cell.setAttribute( + 'style', + 'text-align: center; background-color: ' + bg + ';' + ) + } + } + if (value !== null) { + refreshColor() + } + if (y.sameTerm(me)) { + const callback = function () { + refreshColor() + } // @@ may need that + const selectOptions = {} + const predicate = SCHED('availabilty') + const cellSubject = dataPointForNT[x.toNT()] + const selector = UI.widgets.makeSelectForOptions( + dom, + kb, + cellSubject, + predicate, + possibleAvailabilities, + selectOptions, + testDoc, + callback + ) + cell.appendChild(selector) + } else if (value !== null) { + cell.textContent = UI.utils.label(value) + } + } + + const matrix = displayTheMatrix() + + const agenda = [] + + const nextTest = function nextTest () { + // First take a copy of the DOM the klast test produced + output(tests[t]).appendChild(matrix.cloneNode(true)) + + t += 1 + const test = tests[t] + if (!test) return + + kb.removeMany(undefined, undefined, undefined, testDoc) // Flush out previous test data + $rdf.parse(prologue + inputText(tests[t]), kb, testDocURI, 'text/turtle') + setAxes() + matrix.refresh() + + setTimeout(nextTest, 2000) + } + + agenda.push(nextTest) + + setTimeout(function () { + agenda.shift()() + }, 2000) + } // showResults + + showResults() +}) diff --git a/src/test/test.ttl b/examples/matrix/test.ttl similarity index 100% rename from src/test/test.ttl rename to examples/matrix/test.ttl diff --git a/examples/notepad/index.html b/examples/notepad/index.html new file mode 100644 index 000000000..6dd31bcfa --- /dev/null +++ b/examples/notepad/index.html @@ -0,0 +1,17 @@ + + + + + solid-ui UI.pad examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/notepad--notepad + + diff --git a/examples/tabs/index.html b/examples/tabs/index.html new file mode 100644 index 000000000..2b91b08cd --- /dev/null +++ b/examples/tabs/index.html @@ -0,0 +1,17 @@ + + + + + solid-ui UI.tabs examples page + + + +

These examples have moved to storybook

+ https://solidos.github.io/solid-ui/examples/storybook/?path=/docs/tabs--rdf-collection + + diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 000000000..26b8c33d5 --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,22 @@ +export default { + // verbose: true, // Uncomment for detailed test output + collectCoverage: true, + coverageDirectory: 'coverage', + testEnvironment: 'jsdom', + testEnvironmentOptions: { + customExportConditions: ['node'], + }, + testPathIgnorePatterns: ['/node_modules/', '/dist/'], + transform: { + '^.+\\.(mjs|[tj]sx?)$': ['babel-jest', { configFile: './babel.config.mjs' }], + }, + transformIgnorePatterns: [ + '/node_modules/(?!(lit|lit-html|lit-element|@lit|@lit-labs|@lit-labs/ssr-dom-shim|@lit/reactive-element|@noble/curves|@noble/hashes|@exodus/bytes|uuid|jsdom|parse5|entities|@asamuzakjp/css-color|@asamuzakjp/generational-cache|@csstools)/)', + ], + setupFilesAfterEnv: ['./test/helpers/setup.ts'], + moduleNameMapper: { + '^.+\\.css$': '/__mocks__/styleMock.js' + }, + testMatch: ['**/?(*.)+(spec|test).[tj]s?(x)'], + roots: ['/src', '/test', '/__mocks__'], +} diff --git a/package-lock.json b/package-lock.json index bd387209c..66647a36f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3843 +1,20439 @@ { - "name": "solid-ui", - "version": "0.11.5", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz", - "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==", - "requires": { - "regenerator-runtime": "^0.12.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" - } - } - }, - "@solid/jose": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solid/jose/-/jose-0.1.8.tgz", - "integrity": "sha512-JuP3z2Yuyolv7P0w7MPhjWltWbVzV0vHBFw+ZhxG2v2WOPdbGT+CvUMhCMdMG/csavceV+IpwMXMybMd8nC4sA==", - "requires": { - "@trust/json-document": "^0.1.4", - "@trust/webcrypto": "^0.9.2", - "base64url": "^3.0.0", - "text-encoding": "^0.6.4" - } - }, - "@solid/oidc-rp": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@solid/oidc-rp/-/oidc-rp-0.8.0.tgz", - "integrity": "sha512-AAHd+J1IiASDmqDQkU8ou8Gxmc7+VfpcgGFW1rCul/obCsNzSemwvEslxjstK7Yy725HtucoAbZN2BGKujeQAg==", - "requires": { - "@solid/jose": "0.1.8", - "@trust/json-document": "^0.1.4", - "@trust/webcrypto": "0.9.2", - "base64url": "^3.0.0", - "node-fetch": "^2.1.2", - "standard-http-error": "^2.0.1", - "text-encoding": "^0.6.4", - "whatwg-url": "^6.4.1" - }, - "dependencies": { - "node-fetch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", - "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" - } - } - }, - "@trust/json-document": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@trust/json-document/-/json-document-0.1.4.tgz", - "integrity": "sha1-sgI7HhRbp2hb0fNux7aRKJQAc+k=" - }, - "@trust/keyto": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@trust/keyto/-/keyto-0.3.4.tgz", - "integrity": "sha512-OAqKvuSEPIu2zCnIHzBthvGnV8nKmpv7cBlRMngLzJZzZI9CanyuSfnEI1xC4sH4TwqA0XJR7Mb0oX4bwymXIw==", - "requires": { - "asn1.js": "^4.9.1", - "base64url": "^3.0.0", - "elliptic": "^6.4.0" - } - }, - "@trust/webcrypto": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@trust/webcrypto/-/webcrypto-0.9.2.tgz", - "integrity": "sha512-5iMAVcGYKhqLJGjefB1nzuQSqUJTru0nG4CytpBT/GGp1Piz/MVnj2jORdYf4JBYzggCIa8WZUr2rchP2Ngn/w==", - "requires": { - "@trust/keyto": "^0.3.4", - "base64url": "^3.0.0", - "elliptic": "^6.4.0", - "node-rsa": "^0.4.0", - "text-encoding": "^0.6.1" - } - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "array.prototype.find": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", - "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "auth-header": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/auth-header/-/auth-header-1.0.0.tgz", - "integrity": "sha512-CPPazq09YVDUNNVWo4oSPTQmtwIzHusZhQmahCKvIsk0/xH6U3QsMAv3sM+7+Q0B1K2KJ/Q38OND317uXs4NHA==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64url": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.0.tgz", - "integrity": "sha512-LIVmqIrIWuiqTvn4RzcrwCOuHo2DD6tKmKBPXXlr4p4n4l6BZBkwFTIa3zu1XkX5MbZgro4a6BvPi+n2Mns5Gg==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true, - "optional": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true, - "optional": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", - "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", - "dev": true - }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true, - "optional": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "deglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", - "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", - "dev": true, - "requires": { - "find-root": "^1.0.0", - "glob": "^7.0.5", - "ignore": "^3.0.9", - "pkg-config": "^1.1.0", - "run-parallel": "^1.1.2", - "uniq": "^1.0.1" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-promise": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", - "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=" - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - }, - "dependencies": { - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - } - } - }, - "eslint-config-standard": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", - "dev": true - }, - "eslint-config-standard-jsx": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", - "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", - "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "object-assign": "^4.0.1", - "resolve": "^1.1.6" - } - }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", - "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", - "dev": true, - "requires": { - "builtin-modules": "^1.1.1", - "contains-path": "^0.1.0", - "debug": "^2.2.0", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.2.0", - "eslint-module-utils": "^2.0.0", - "has": "^1.0.1", - "lodash.cond": "^4.3.0", - "minimatch": "^3.0.3", - "pkg-up": "^1.0.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", - "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", - "dev": true, - "requires": { - "ignore": "^3.0.11", - "minimatch": "^3.0.2", - "object-assign": "^4.0.1", - "resolve": "^1.1.7", - "semver": "5.3.0" - } - }, - "eslint-plugin-promise": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", - "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", - "dev": true - }, - "eslint-plugin-react": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", - "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", - "dev": true, - "requires": { - "array.prototype.find": "^2.0.1", - "doctrine": "^1.2.2", - "has": "^1.0.1", - "jsx-ast-utils": "^1.3.4", - "object.assign": "^4.0.4" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-plugin-standard": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", - "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", - "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true, - "optional": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonld": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-0.4.12.tgz", - "integrity": "sha1-oC8gXVNBQU3xtthBTxuWenEgc+g=", - "requires": { - "es6-promise": "^2.0.0", - "pkginfo": "~0.4.0", - "request": "^2.61.0", - "xmldom": "0.1.19" - }, - "dependencies": { - "xmldom": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz", - "integrity": "sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw=" - } - } - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", - "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime-db": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" - }, - "mime-types": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", - "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", - "requires": { - "mime-db": "~1.35.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "minipass": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "n3": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/n3/-/n3-0.4.5.tgz", - "integrity": "sha1-W3DTq2ohyejUyb2io9TZCQm+tQg=" - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "needle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "node-rsa": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.4.2.tgz", - "integrity": "sha1-1jkXKewWqDDtWjgEKzFX0tXXJTA=", - "requires": { - "asn1": "0.2.3" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-bundled": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "optional": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-conf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "load-json-file": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } - } - }, - "pkg-config": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", - "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", - "dev": true, - "requires": { - "debug-log": "^1.0.0", - "find-root": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "pkginfo": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", - "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=" - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true - } - } - }, - "rc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "rdflib": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/rdflib/-/rdflib-0.17.0.tgz", - "integrity": "sha512-Jw3ehBx0egWrkdIZjYJezyBb83XxzNO0whMB8/2I+aV1Blsp4zoaAPjWG2QehPi12YTwybckPtAXygpK5JlY7w==", - "requires": { - "async": "^0.9.x", - "jsonld": "^0.4.5", - "n3": "^0.4.1", - "node-fetch": "^1.7.1", - "solid-auth-client": ">=0.5.1", - "xmldom": "^0.1.22" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - } - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "solid-auth-client": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/solid-auth-client/-/solid-auth-client-2.2.6.tgz", - "integrity": "sha512-LJNFtl+HriwjqqvAE7dhngFKGoFdreZJ3XxpqkVKUkLjdKCrHBmshQtm5ogVXgy/Z3jXGMeMe93YLnbjDDnK+Q==", - "requires": { - "@babel/runtime": "^7.0.0", - "@solid/oidc-rp": "^0.8.0", - "auth-header": "^1.0.0", - "commander": "^2.11.0", - "isomorphic-fetch": "^2.2.1", - "uuid": "^3.1.0" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - } - } - }, - "solid-auth-tls": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/solid-auth-tls/-/solid-auth-tls-0.1.2.tgz", - "integrity": "sha1-FoBf9pUd/PNczfTw29JhaQsjvLo=" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "standard": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", - "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", - "dev": true, - "requires": { - "eslint": "~3.19.0", - "eslint-config-standard": "10.2.1", - "eslint-config-standard-jsx": "4.0.2", - "eslint-plugin-import": "~2.2.0", - "eslint-plugin-node": "~4.2.2", - "eslint-plugin-promise": "~3.5.0", - "eslint-plugin-react": "~6.10.0", - "eslint-plugin-standard": "~3.0.1", - "standard-engine": "~7.0.0" - } - }, - "standard-engine": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", - "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", - "dev": true, - "requires": { - "deglob": "^2.1.0", - "get-stdin": "^5.0.1", - "minimist": "^1.1.0", - "pkg-conf": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "standard-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz", - "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ=" - }, - "standard-http-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz", - "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=", - "requires": { - "standard-error": ">= 1.1.0 < 2" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "tar": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "requires": { - "punycode": "^1.4.1" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "^1.1.1" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true - } - } + "name": "solid-ui", + "version": "4.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "solid-ui", + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "escape-html": "^1.0.3", + "i": "^0.3.7", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "npm": "^11.19.0", + "pane-registry": "^4.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "devDependencies": { + "@babel/cli": "^7.28.6", + "@babel/core": "^7.29.0", + "@babel/plugin-transform-runtime": "^7.29.0", + "@babel/preset-env": "^7.29.5", + "@babel/preset-typescript": "^7.28.5", + "@babel/runtime": "^7.29.2", + "@eslint/js": "^9.39.4", + "@mdx-js/react": "^3.1.1", + "@storybook/addon-actions": "8.6.18", + "@storybook/addon-docs": "8.6.18", + "@storybook/addon-essentials": "8.6.18", + "@storybook/addon-links": "8.6.18", + "@storybook/addon-mdx-gfm": "8.6.18", + "@storybook/addon-webpack5-compiler-swc": "^3.0.0", + "@storybook/html": "8.6.18", + "@storybook/html-webpack5": "8.6.18", + "@testing-library/dom": "^10.4.1", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^30.0.0", + "@types/jsdom": "^28.0.3", + "@types/node": "^25.8.0", + "@typescript-eslint/parser": "^8.59.3", + "babel-jest": "^30.4.1", + "babel-loader": "^10.1.1", + "eslint": "^9.39.4", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.15.2", + "eslint-plugin-n": "^18.0.1", + "eslint-plugin-promise": "^7.3.0", + "get-random-values": "^5.0.0", + "globals": "^17.6.0", + "isomorphic-fetch": "^3.0.0", + "jest": "^30.4.2", + "jest-environment-jsdom": "^30.4.1", + "jsdom": "^28.1.0", + "neostandard": "^0.13.0", + "nock": "^15.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-is": "^17.0.2", + "storybook": "8.6.18", + "style-loader": "^3.3.4", + "terser-webpack-plugin": "^5.6.0", + "typedoc": "^0.28.19", + "typescript": "^5.9.3", + "webpack": "^5.106.2", + "webpack-cli": "^7.0.2" + }, + "optionalDependencies": { + "fsevents": "*" + }, + "peerDependencies": { + "rdflib": "^2.4.0", + "solid-logic": "^5.0.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.10.tgz", + "integrity": "sha512-02OhhkKtgNRuicQ/nF3TRnGsxL9wp0r3Y7VlKWyOHHGmGyvXv03y+PnymU8FKFJMTjIr1Bk8U2g1HWSLrpAHww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/cli": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.28.6.tgz", + "integrity": "sha512-6EUNcuBbNkj08Oj4gAZ+BUU8yLCgKzgVX4gaTh09Ya2C8ICM4P+G30g4m3akRxSYAp3A/gnWchrNst7px4/nUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.28", + "commander": "^6.2.0", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.6.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.29.7.tgz", + "integrity": "sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.29.7.tgz", + "integrity": "sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.29.7.tgz", + "integrity": "sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.7.tgz", + "integrity": "sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.29.7.tgz", + "integrity": "sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.29.7.tgz", + "integrity": "sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.29.7.tgz", + "integrity": "sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz", + "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.29.7.tgz", + "integrity": "sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz", + "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", + "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.29.7.tgz", + "integrity": "sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.29.7.tgz", + "integrity": "sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.29.7.tgz", + "integrity": "sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz", + "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.29.7.tgz", + "integrity": "sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.29.7.tgz", + "integrity": "sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.29.7.tgz", + "integrity": "sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.29.7.tgz", + "integrity": "sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.7.tgz", + "integrity": "sha512-TM2ZcQLoG2/y4HODiStCo10DibYhWhGWAwVv+EQKmG/7GFl0N+AAmUiXOMKM+aiJ9XBJ9AHVZBvTzMnJ2sM3cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.29.7.tgz", + "integrity": "sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.29.7.tgz", + "integrity": "sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz", + "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.29.7.tgz", + "integrity": "sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz", + "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.29.7.tgz", + "integrity": "sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.29.7.tgz", + "integrity": "sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.29.7.tgz", + "integrity": "sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz", + "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz", + "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.29.7.tgz", + "integrity": "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.29.7.tgz", + "integrity": "sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz", + "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-syntax-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.29.7.tgz", + "integrity": "sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.29.7.tgz", + "integrity": "sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz", + "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.29.7.tgz", + "integrity": "sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.7.tgz", + "integrity": "sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.29.7", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.29.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.29.7", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.29.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.29.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.29.7", + "@babel/plugin-syntax-import-attributes": "^7.29.7", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.29.7", + "@babel/plugin-transform-async-generator-functions": "^7.29.7", + "@babel/plugin-transform-async-to-generator": "^7.29.7", + "@babel/plugin-transform-block-scoped-functions": "^7.29.7", + "@babel/plugin-transform-block-scoping": "^7.29.7", + "@babel/plugin-transform-class-properties": "^7.29.7", + "@babel/plugin-transform-class-static-block": "^7.29.7", + "@babel/plugin-transform-classes": "^7.29.7", + "@babel/plugin-transform-computed-properties": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-dotall-regex": "^7.29.7", + "@babel/plugin-transform-duplicate-keys": "^7.29.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-dynamic-import": "^7.29.7", + "@babel/plugin-transform-explicit-resource-management": "^7.29.7", + "@babel/plugin-transform-exponentiation-operator": "^7.29.7", + "@babel/plugin-transform-export-namespace-from": "^7.29.7", + "@babel/plugin-transform-for-of": "^7.29.7", + "@babel/plugin-transform-function-name": "^7.29.7", + "@babel/plugin-transform-json-strings": "^7.29.7", + "@babel/plugin-transform-literals": "^7.29.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.29.7", + "@babel/plugin-transform-member-expression-literals": "^7.29.7", + "@babel/plugin-transform-modules-amd": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-modules-systemjs": "^7.29.7", + "@babel/plugin-transform-modules-umd": "^7.29.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-new-target": "^7.29.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.29.7", + "@babel/plugin-transform-numeric-separator": "^7.29.7", + "@babel/plugin-transform-object-rest-spread": "^7.29.7", + "@babel/plugin-transform-object-super": "^7.29.7", + "@babel/plugin-transform-optional-catch-binding": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/plugin-transform-private-methods": "^7.29.7", + "@babel/plugin-transform-private-property-in-object": "^7.29.7", + "@babel/plugin-transform-property-literals": "^7.29.7", + "@babel/plugin-transform-regenerator": "^7.29.7", + "@babel/plugin-transform-regexp-modifiers": "^7.29.7", + "@babel/plugin-transform-reserved-words": "^7.29.7", + "@babel/plugin-transform-shorthand-properties": "^7.29.7", + "@babel/plugin-transform-spread": "^7.29.7", + "@babel/plugin-transform-sticky-regex": "^7.29.7", + "@babel/plugin-transform-template-literals": "^7.29.7", + "@babel/plugin-transform-typeof-symbol": "^7.29.7", + "@babel/plugin-transform-unicode-escapes": "^7.29.7", + "@babel/plugin-transform-unicode-property-regex": "^7.29.7", + "@babel/plugin-transform-unicode-regex": "^7.29.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.29.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz", + "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz", + "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.2.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz", + "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@digitalbazaar/http-client": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-4.3.0.tgz", + "integrity": "sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==", + "license": "BSD-3-Clause", + "dependencies": { + "ky": "^1.14.2", + "undici": "^6.23.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@digitalbazaar/http-client/node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.0.0.tgz", + "integrity": "sha512-dDlz3W405VMFO4w5kIP9DOmELBcvFQGmLoKSdIRstBDubKFYwaNHV1NnlzMCQpXQFGWVALmeMORAuiLx18AvZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@frogcat/ttl2jsonld": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/@frogcat/ttl2jsonld/-/ttl2jsonld-0.0.10.tgz", + "integrity": "sha512-0NLM96V3ziZkkOlhixSZiXe8CzewECVNtSj04s2hW2e65SgzQPzM12VWSovuRIy+2UJA2Bjkf9405yrty9tgcg==", + "license": "MIT", + "bin": { + "ttl2jsonld": "bin/cli.js" + } + }, + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "license": "Apache-2.0", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "jest-mock": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment-jsdom-abstract": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.4.1.tgz", + "integrity": "sha512-dSlKrqug3siYNHVnjwIldShY12wAH3spwRltO/+8VOjg0X+xEq7vOs3DbBs4LRKsu7OH+NUb9kuZUNBF9Ho3TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", + "@types/jsdom": "^21.1.7", + "@types/node": "*", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/@jest/environment-jsdom-abstract/node_modules/@types/jsdom": { + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.4.1", + "jest-snapshot": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", + "@types/node": "*", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/reporters/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.4.1", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz", + "integrity": "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.2.tgz", + "integrity": "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.8.tgz", + "integrity": "sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@noble/curves": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.2.0.tgz", + "integrity": "sha512-T/BoHgFXirb0ENSPBquzX0rcjXeM6Lo892a2jlYJkqk83LqZx0l1Of7DzlKJ6jkpvMrkHSnAcgb5JegL8SeIkQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "2.2.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@rdfjs/types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-2.0.1.tgz", + "integrity": "sha512-uyAzpugX7KekAXAHq26m3JlUIZJOC0uSBhpnefGV5i15bevDyyejoB7I+9MKeUrzXD8OOUI3+4FeV1wwQr5ihA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@storybook/addon-actions": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.18.tgz", + "integrity": "sha512-GcYhtE91GjIQTuZlwpTJ8jfMp6NC79nkpe1DGe0eetTpyQqLq1WUt+ACkk0Z5lqq2u8HBc09zCCGw+D8iCLpYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-actions/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@storybook/addon-backgrounds": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.18.tgz", + "integrity": "sha512-froND3WwvSCYzjEBO8QODStaWNL+aGXqxBEbrMnGYejDFST4qEFkvM2IYWMnLBkRgrgJ0yIqTeDQoyH9b9/8uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "memoizerific": "^1.11.3", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-controls": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.18.tgz", + "integrity": "sha512-K09dHDCfGW3cudsfuyfu0Yi49aZ2h7VYK4IXDGo1sfmtzVh4xd3HrZQQMVUeKLcfDP/NnJowT+fLVwg04CLrxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "dequal": "^2.0.2", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-docs": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.18.tgz", + "integrity": "sha512-55ADer0yNmmeR928Y3UAv3r4i7bJSd9LwywsQ+lRol/FNe0ZcwLEz31xL+jVsqQFNnDh/imsDIp8aYapGMtfEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/blocks": "8.6.18", + "@storybook/csf-plugin": "8.6.18", + "@storybook/react-dom-shim": "8.6.18", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-essentials": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.18.tgz", + "integrity": "sha512-MmH7gFb8pyfRoAth0w2RW8j7mBaEJbEWGP3juIoH03ZqTGmbMUbJXElCuRgxQhve7pyz39zLsgtE78D7G+76ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/addon-actions": "8.6.18", + "@storybook/addon-backgrounds": "8.6.18", + "@storybook/addon-controls": "8.6.18", + "@storybook/addon-docs": "8.6.18", + "@storybook/addon-highlight": "8.6.18", + "@storybook/addon-measure": "8.6.18", + "@storybook/addon-outline": "8.6.18", + "@storybook/addon-toolbars": "8.6.18", + "@storybook/addon-viewport": "8.6.18", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-highlight": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.18.tgz", + "integrity": "sha512-wTFJ1DPM0C8gK6nGTJxH75byayQj7BPAz02fME4AOmT6clrBpVl1zSTFTkXaSr+k4xOfeMR/xNUfVskaXz6T9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-links": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.6.18.tgz", + "integrity": "sha512-FFlQcPRTgXoFZr2uawtf7lNc/ceIVRhU13BkJbJZKlil3+C8ORFDO1vnREzHje9JzeOWm/rzI0ay0RVetCcXzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.18" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-mdx-gfm": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-mdx-gfm/-/addon-mdx-gfm-8.6.18.tgz", + "integrity": "sha512-u4+6N7wAjtEfXKQrve9vUyhVsRwSTBJPQdsEScfwoVjg+amCQQDhjbwB78gsCjrxXcbHtpqNM6DXHy8yvhocOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-gfm": "^4.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-measure": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.18.tgz", + "integrity": "sha512-fMEOJXgPrTm6qHlWoRM+WTLE7Mr1QBIf2ei+pujBQFcWkD6Gjc2pV8zKzvh93d+EA13wD8AmwOq1DEw9J+XH+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-outline": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.18.tgz", + "integrity": "sha512-TErFqfCtlV2xt9B6/kskROt69TPjr6AXdHpMselaRrN1X4WEjcMk9GT9PcNP7FXqL88/VYqUb3uNMiAmpDmS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-toolbars": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.18.tgz", + "integrity": "sha512-x037KXCEcNfPISGX485DtiP+8Bw/cOT45plcQa8eiAQVrVcUwYaDoLubE9YV5b5CsSAjX8sDviGTme6ALfq7+w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-viewport": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.18.tgz", + "integrity": "sha512-z9sDJSkuWQb4BP+Z1+H+y/Q0rFbPSDcw+OBBEhMfRcJPPXavdC2pNQ0GdQNVw+tDwhAXj+U7jehKnMDKaP7TyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "memoizerific": "^1.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/addon-webpack5-compiler-swc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-webpack5-compiler-swc/-/addon-webpack5-compiler-swc-3.0.0.tgz", + "integrity": "sha512-qkQwQEvHlxwPCHz/xakGfXJusEa1gKMw7enELh6QGopblfN3rMiV084boqiIqBReqWTasSwHOqvuElAu0NQ+8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@swc/core": "^1.10.8", + "swc-loader": "^0.2.6" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@storybook/blocks": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.18.tgz", + "integrity": "sha512-esZv4msPQ9LxgTb8YUIZhhxVMuI6BPi5bkXtk8c7w7sWuAsqsCe/RnVInn7ooUry2gjnD4hd9+8Eqj0b8oTVoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/icons": "^1.2.12", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^8.6.18" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-webpack5": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.18.tgz", + "integrity": "sha512-rg73TpqIUzXc66c/AaQ4kuc8yiZ+tStvy5fb1OnFYZ9rAeYQejDD0OIIaI2rqtX5XYuxC+yQEGitMntlIMV0og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core-webpack": "8.6.18", + "@types/semver": "^7.3.4", + "browser-assert": "^1.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "cjs-module-lexer": "^1.2.3", + "constants-browserify": "^1.0.0", + "css-loader": "^6.7.1", + "es-module-lexer": "^1.5.0", + "fork-ts-checker-webpack-plugin": "^8.0.0", + "html-webpack-plugin": "^5.5.0", + "magic-string": "^0.30.5", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "semver": "^7.3.7", + "style-loader": "^3.3.1", + "terser-webpack-plugin": "^5.3.1", + "ts-dedent": "^2.0.0", + "url": "^0.11.0", + "util": "^0.12.4", + "util-deprecate": "^1.0.2", + "webpack": "5", + "webpack-dev-middleware": "^6.1.2", + "webpack-hot-middleware": "^2.25.1", + "webpack-virtual-modules": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-webpack5/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/components": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.18.tgz", + "integrity": "sha512-55yViiZzPS/cPBuOeW4QGxGqrusjXVyxuknmbYCIwDtFyyvI/CgbjXRHdxNBaIjz+IlftxvBmmSaOqFG5+/dkA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/core": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.18.tgz", + "integrity": "sha512-dRBP2TnX6fGdS0T2mXBHjkS/3Nlu1ra1huovZVFuM67CYMzrhM/3hX/zru1vWSC5rqY93ZaAhjMciPW4pK5mMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/theming": "8.6.18", + "better-opn": "^3.0.2", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "esbuild-register": "^3.5.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "process": "^0.11.10", + "recast": "^0.23.5", + "semver": "^7.6.2", + "util": "^0.12.5", + "ws": "^8.2.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/@storybook/core-webpack": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.18.tgz", + "integrity": "sha512-M+y/DFbiT3CJYQ90wJdXT4WxYImphof1f11StZSxJGo0u5PnCCdCze1qchXubApXRDO2T8HGxurXfhTEMqaGsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/core/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.18.tgz", + "integrity": "sha512-x1ioz/L0CwaelCkHci3P31YtvwayN3FBftvwQOPbvRh9qeb4Cpz5IdVDmyvSxxYwXN66uAORNoqgjTi7B4/y5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/html": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/html/-/html-8.6.18.tgz", + "integrity": "sha512-7yjb09rf7wP4hlVlirVPe+Jjo6kRsr4zEhuHlLM97Jf5Ojf7LH+vtvV9M3F7zs50lm9jTNBd45oWfTX8T7d2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/components": "8.6.18", + "@storybook/global": "^5.0.0", + "@storybook/manager-api": "8.6.18", + "@storybook/preview-api": "8.6.18", + "@storybook/theming": "8.6.18", + "ts-dedent": "^2.0.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/html-webpack5": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/html-webpack5/-/html-webpack5-8.6.18.tgz", + "integrity": "sha512-WQo2P3F5aD11PSQUg/OAbR/5qNmHM/5WTI2PcWaXOUBPXQ7uzgsrr7s+lRx2zW3+370X1ooCVoB262M70xYOHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/builder-webpack5": "8.6.18", + "@storybook/global": "^5.0.0", + "@storybook/html": "8.6.18", + "@storybook/preset-html-webpack": "8.6.18" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/icons": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.6.0.tgz", + "integrity": "sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta" + } + }, + "node_modules/@storybook/manager-api": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.18.tgz", + "integrity": "sha512-BjIp12gEMgzFkEsgKpDIbZdnSWTZpm2dlws8WiPJCpgJtG+HWSxZ0/Ms30Au9yfwzQEKRSbV/5zpsKMGc2SIJw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/preset-html-webpack": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/preset-html-webpack/-/preset-html-webpack-8.6.18.tgz", + "integrity": "sha512-qGvbhcYXXjnvufaISWybn0gySjSYqhpeS5aGXrNzbHOdvMnjwP3R4oFTI/sKQTZgyZZ4goqMxyR6+5SozSm8SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core-webpack": "8.6.18", + "html-loader": "^3.1.0", + "webpack": "5" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/preview-api": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.18.tgz", + "integrity": "sha512-joXRXh3GdVvzhbfIgmix1xs90p8Q/nja7AhEAC2egn5Pl7SKsIYZUCYI6UdrQANb2myg9P552LKXfPect8llKg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.18.tgz", + "integrity": "sha512-N4xULcAWZQTUv4jy1/d346Tyb4gufuC3UaLCuU/iVSZ1brYF4OW3ANr+096btbMxY8pR/65lmtoqr5CTGwnBvA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.18" + } + }, + "node_modules/@storybook/theming": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.18.tgz", + "integrity": "sha512-n6OEjEtHupa2PdTwWzRepr7cO8NkDd4rgF6BKLitRbujOspLxzMBEqdphs+QLcuiCIgf33SqmEA64QWnbSMhPw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", + "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@swc/core": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.24.tgz", + "integrity": "sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.26" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.24", + "@swc/core-darwin-x64": "1.15.24", + "@swc/core-linux-arm-gnueabihf": "1.15.24", + "@swc/core-linux-arm64-gnu": "1.15.24", + "@swc/core-linux-arm64-musl": "1.15.24", + "@swc/core-linux-ppc64-gnu": "1.15.24", + "@swc/core-linux-s390x-gnu": "1.15.24", + "@swc/core-linux-x64-gnu": "1.15.24", + "@swc/core-linux-x64-musl": "1.15.24", + "@swc/core-win32-arm64-msvc": "1.15.24", + "@swc/core-win32-ia32-msvc": "1.15.24", + "@swc/core-win32-x64-msvc": "1.15.24" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.24.tgz", + "integrity": "sha512-uM5ZGfFXjtvtJ+fe448PVBEbn/CSxS3UAyLj3O9xOqKIWy3S6hPTXSPbszxkSsGDYKi+YFhzAsR4r/eXLxEQ0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.24.tgz", + "integrity": "sha512-fMIb/Zfn929pw25VMBhV7Ji2Dl+lCWtUPNdYJQYOke+00E5fcQ9ynxtP8+qhUo/HZc+mYQb1gJxwHM9vty+lXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.24.tgz", + "integrity": "sha512-vOkjsyjjxnoYx3hMEWcGxQrMgnNrRm6WAegBXrN8foHtDAR+zpdhpGF5a4lj1bNPgXAvmysjui8cM1ov/Clkaw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.24.tgz", + "integrity": "sha512-h/oNu+upkXJ6Cicnq7YGVj9PkdfarLCdQa8l/FlHYvfv8CEiMaeeTnpLU7gSBH/rGxosM6Qkfa/J9mThGF9CLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.24.tgz", + "integrity": "sha512-ZpF/pRe1guk6sKzQI9D1jAORtjTdNlyeXn9GDz8ophof/w2WhojRblvSDJaGe7rJjcPN8AaOkhwdRUh7q8oYIg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.24.tgz", + "integrity": "sha512-QZEsZfisHTSJlmyChgDFNmKPb3W6Lhbfo/O76HhIngfEdnQNmukS38/VSe1feho+xkV5A5hETyCbx3sALBZKAQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.24.tgz", + "integrity": "sha512-DLdJKVsJgglqQrJBuoUYNmzm3leI7kUZhLbZGHv42onfKsGf6JDS3+bzCUQfte/XOqDjh/tmmn1DR/CF/tCJFw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.24.tgz", + "integrity": "sha512-IpLYfposPA/XLxYOKpRfeccl1p5dDa3+okZDHHTchBkXEaVCnq5MADPmIWwIYj1tudt7hORsEHccG5no6IUQRw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.24.tgz", + "integrity": "sha512-JHy3fMSc0t/EPWgo74+OK5TGr51aElnzqfUPaiRf2qJ/BfX5CUCfMiWVBuhI7qmVMBnk1jTRnL/xZnOSHDPLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.24.tgz", + "integrity": "sha512-Txj+qUH1z2bUd1P3JvwByfjKFti3cptlAxhWgmunBUUxy/IW3CXLZ6l6Gk4liANadKkU71nIU1X30Z5vpMT3BA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.24.tgz", + "integrity": "sha512-15D/nl3XwrhFpMv+MADFOiVwv3FvH9j8c6Rf8EXBT3Q5LoMh8YnDnSgPYqw1JzPnksvsBX6QPXLiPqmcR/Z4qQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.24.tgz", + "integrity": "sha512-PR0PlTlPra2JbaDphrOAzm6s0v9rA0F17YzB+XbWD95B4g2cWcZY9LAeTa4xll70VLw9Jr7xBrlohqlQmelMFQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsdom": { + "version": "28.0.3", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-28.0.3.tgz", + "integrity": "sha512-/HQ2uFoetFTXuye8vzIcHw2z6Fwi7Hi/qcgC+RoS9NCyewiqxhVGqlG+ViGB6lkax481R6dmhf1I7lIGlzJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^8.0.0", + "undici-types": "^7.21.0" + } + }, + "node_modules/@types/jsdom/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@types/jsdom/node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.2.tgz", + "integrity": "sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/type-utils": "8.58.2", + "@typescript-eslint/utils": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.58.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.4.tgz", + "integrity": "sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.4", + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/typescript-estree": "8.59.4", + "@typescript-eslint/visitor-keys": "8.59.4", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.4.tgz", + "integrity": "sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.4", + "@typescript-eslint/types": "^8.59.4", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.4.tgz", + "integrity": "sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/visitor-keys": "8.59.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.4.tgz", + "integrity": "sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.4.tgz", + "integrity": "sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.4.tgz", + "integrity": "sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.4", + "@typescript-eslint/tsconfig-utils": "8.59.4", + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/visitor-keys": "8.59.4", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.4.tgz", + "integrity": "sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.4", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.2.tgz", + "integrity": "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.58.2", + "@typescript-eslint/types": "^8.58.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.2.tgz", + "integrity": "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.2.tgz", + "integrity": "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.2.tgz", + "integrity": "sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/utils": "8.58.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz", + "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.2.tgz", + "integrity": "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.58.2", + "@typescript-eslint/tsconfig-utils": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.2.tgz", + "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.2.tgz", + "integrity": "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@uvdsl/solid-oidc-client-browser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@uvdsl/solid-oidc-client-browser/-/solid-oidc-client-browser-0.2.3.tgz", + "integrity": "sha512-WzVlxv46EUSoqm7ovsWJRZq8KEI/CdpA9O1fXoiP8bihs2cNxPnet3YcqvIYWYMsTrf0zsR031l5s/BzQ9MEgA==", + "license": "MIT", + "dependencies": { + "jose": "^5.9.6" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abs": { + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.15.tgz", + "integrity": "sha512-bpFChpVyZ2F2ppgx7qjZ5TTEO6VVwBauUZDZibpclRGhfcXTHyj11nlqwrg5dN1knxCchssROehm76uCcCayRA==", + "license": "MIT", + "dependencies": { + "ul": "^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-jest": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "30.4.1", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.4.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" + } + }, + "node_modules/babel-jest/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-loader": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.1.1.tgz", + "integrity": "sha512-JwKSzk2kjIe7mgPK+/lyZ2QAaJcpahNAdM+hgR2HI8D0OJVkdj8Rl6J3kaLYki9pwF7P2iWnD8qVv80Lq1ABtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0 || ^8.0.0-beta.1", + "@rspack/core": "^1.0.0 || ^2.0.0-0", + "webpack": ">=5.61.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.4.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.18.tgz", + "integrity": "sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/better-opn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", + "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "open": "^8.0.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-assert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", + "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001788", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canonicalize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.1.0.tgz", + "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", + "license": "Apache-2.0", + "bin": { + "canonicalize": "bin/canonicalize.js" + } + }, + "node_modules/capture-stack-trace": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", + "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", + "license": "MIT", + "dependencies": { + "capture-stack-trace": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deffy": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.5.tgz", + "integrity": "sha512-6TX2cfIo97eKqWmqgMDAUulCwnveAe3K+4VGsTGPJsL3NtSEnSBFZ3sUXdS4EBhZ8GbdaZBzXQ04ton18dJrug==", + "license": "MIT", + "dependencies": { + "typpy": "^2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.336", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.336.tgz", + "integrity": "sha512-AbH9q9J455r/nLmdNZes0G0ZKcRX73FicwowalLs6ijwOmCJSRRrLX63lcAlzy9ux3dWK1w1+1nsBJEWN11hcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz", + "integrity": "sha512-N97Ybd2jJHVQ+Ft3Q5+C2gM3kgygkdeQmEqbN2z15UTVyyEsIwLA1VK39O1DHEJhXbwIFcJLqm6iARNhFANcQA==", + "license": "MIT", + "dependencies": { + "typpy": "^2.2.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", + "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", + "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "29.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", + "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.0.0" + }, + "engines": { + "node": "^20.12.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "jest": "*", + "typescript": ">=4.8.4 <7.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-n": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.0.1.tgz", + "integrity": "sha512-q3ARhk+eZRc7myR0KHx+R3/GJeOHF+Ir6PK95Pu2tEX8Sl/4BIpmmVLva2kPrjC2gCmn6WHlHm+3yeo6Rxhycw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.57.1", + "ts-declaration-location": "^1.0.6", + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "ts-declaration-location": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.3.0.tgz", + "integrity": "sha512-6uGiOR0INuujr6PEQmeSSP7GbIMJ/ebEXXiEzb/nOj68LknH5Pxzb/AbZivmr6VE6TkTE8rTjRK9zhKpK6HsRA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exec-limiter": { + "version": "3.2.14", + "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.14.tgz", + "integrity": "sha512-ZQjJmAnXD+1kQ6ejMZAS5Vxdt7LLMz0Eq7mEu6+7NhlauykuyLihhUkpp4S784QKsmJQIpuuERhQ8Tav8bF3zQ==", + "license": "MIT", + "dependencies": { + "limit-it": "^3.0.0", + "typpy": "^2.1.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.name": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.14.tgz", + "integrity": "sha512-s99L814NRuLxwF2sJMIcLhkQhueGXb3oKyvorzrUKKwlVB0SBbWrgZt4+EwKAo3ujCXnT7vshmCvXgZA09kCMw==", + "license": "MIT", + "dependencies": { + "noop6": "^1.0.1" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-random-values": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-5.0.0.tgz", + "integrity": "sha512-K4SoyabzMZ+stdDY4atTAml/UztnBFBu1Hk3vC4paSKHl/Cecxfe07SQhevII4/mnwGBa/q9pfaZo2lS9G4Pvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "window-or-global": "^1.0.1" + }, + "engines": { + "node": "22 || >=24" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/git-package-json": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.11.tgz", + "integrity": "sha512-A/P5K2qqQ52+BwBf+qyrjtdauMlb7n1WVa++/VPDxTcgKZ2X5/Eh/EQwbxNvRKBsKAkMAeyV/UIdnb/saVFnnQ==", + "license": "MIT", + "dependencies": { + "deffy": "^2.2.1", + "err": "^1.1.1", + "gry": "^5.0.0", + "normalize-package-data": "^2.3.5", + "oargv": "^3.4.1", + "one-by-one": "^3.1.0", + "r-json": "^1.2.1", + "r-package-json": "^1.0.0", + "tmp": "0.0.28" + } + }, + "node_modules/git-source": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.11.tgz", + "integrity": "sha512-oubUf/uply9xvR5olZxxPpip19wMEpESN3bFfPcFMvl/0fwrVrcAppwOJ7Dghcguze68WAIjs/A1YrdMDIW8XA==", + "license": "MIT", + "dependencies": { + "git-url-parse": "^5.0.1" + } + }, + "node_modules/git-up": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz", + "integrity": "sha512-SRVN3rOLACva8imc7BFrB6ts5iISWKH1/h/1Z+JZYoUI7UVQM7gQqk4M2yxUENbq2jUUT09NEND5xwP1i7Ktlw==", + "license": "MIT", + "dependencies": { + "is-ssh": "^1.0.0", + "parse-url": "^1.0.0" + } + }, + "node_modules/git-url-parse": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz", + "integrity": "sha512-4uSiOgrryNEMBX+gTWogenYRUh2j1D+95STTSEF2RCTgLkfJikl8c7BGr0Bn274hwuxTsbS2/FQ5pVS9FoXegQ==", + "license": "MIT", + "dependencies": { + "git-up": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz", + "integrity": "sha512-MnypzkaW8dldA8AbJFjMs7y14+ykd2V8JCLKSvX1Gmzx1alH3Y+3LArywHDoAF2wS3pnZp4gacoYtvqBeF6drQ==", + "license": "MIT", + "dependencies": { + "create-error-class": "^3.0.1", + "duplexer2": "^0.1.4", + "is-plain-obj": "^1.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "node-status-codes": "^1.0.0", + "object-assign": "^4.0.1", + "parse-json": "^2.1.0", + "pinkie-promise": "^2.0.0", + "read-all-stream": "^3.0.0", + "readable-stream": "^2.0.5", + "timed-out": "^2.0.0", + "unzip-response": "^1.0.0", + "url-parse-lax": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/got/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/got/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/got/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/gry": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz", + "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==", + "license": "MIT", + "dependencies": { + "abs": "^1.2.1", + "exec-limiter": "^3.0.0", + "one-by-one": "^3.0.0", + "ul": "^5.0.0" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "license": "ISC" + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-loader": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-3.1.2.tgz", + "integrity": "sha512-9WQlLiAV5N9fCna4MUmBW/ifaUbuFZ2r7IZmtXzhyfyi4zgPEjXsmsYCKs+yT873MzRj+f1WMjuAiPNA7C6Tcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "html-minifier-terser": "^6.0.2", + "parse5": "^6.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/html-loader/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.7", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", + "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/i": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz", + "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterate-object": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.5.tgz", + "integrity": "sha512-eL23u8oFooYTq6TtJKjp2RYjZnCkUYQvC0T/6fJfWykXJ3quvdDdzKZ3CEjy8b3JGOvLTjDYMEMIp5243R906A==", + "license": "MIT" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", + "import-local": "^3.2.0", + "jest-cli": "30.4.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.4.1", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "p-limit": "^3.1.0", + "pretty-format": "30.4.1", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-circus": "30.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "parse-json": "^5.2.0", + "pretty-format": "30.4.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-config/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-config/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.4.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "jest-util": "30.4.1", + "pretty-format": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.4.1.tgz", + "integrity": "sha512-o3nfaN4zej7qgk2X0j8Jhq/S9nAVKs2xK3QeQxeHVvpkEPxaA1yxDGydR+iVI7zPy7Cp62Aq2h3Ja46QvfWHGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/environment-jsdom-abstract": "30.4.1", + "jsdom": "^26.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jest-environment-jsdom/node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jest-environment-node": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", + "picomatch": "^4.0.3", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-leak-detector": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.4.1", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", + "picomatch": "^4.0.3", + "pretty-format": "30.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "@types/node": "*", + "jest-util": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/jest-runtime/node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-watcher": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.4.1", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.4.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.8.0.tgz", + "integrity": "sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdom": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^6.0.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.21.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonld": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-9.0.0.tgz", + "integrity": "sha512-pjMIdkXfC1T2wrX9B9i2uXhGdyCmgec3qgMht+TDj+S0qX3bjWMQUfL7NeqEhuRTi8G5ESzmL9uGlST7nzSEWg==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/http-client": "^4.2.0", + "canonicalize": "^2.1.0", + "lru-cache": "^6.0.0", + "rdf-canonize": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsonld/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonld/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ky": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz", + "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/limit-it": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.11.tgz", + "integrity": "sha512-VdLa1lZYZnzT98oLMeCDl6Lwd9cEYIMQlPg34qL6CYuA+yQKoG7K12tfgI5K6bRC51kRM8v1UX67IhpNsnvo3A==", + "license": "MIT", + "dependencies": { + "typpy": "^2.0.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lit": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.3.tgz", + "integrity": "sha512-fycuvZg/hkpozL00lm1pEJH5nN/lr9ZXd6mJI2HSN4+Bzc+LDNdEApJ6HFbPkdFNHLvOplIIuJvxkS4XUxqirw==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-element": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.2.tgz", + "integrity": "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-html": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.2.tgz", + "integrity": "sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-or-similar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-or-similar": "^1.5.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/n3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", + "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neostandard": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/neostandard/-/neostandard-0.13.0.tgz", + "integrity": "sha512-R3iglFr+Dla/8qFBqsMxBvcYBOgP6rAGw7uRHKMpM3bUP0wLDRzUstxtEI9RfEwn7xszE/UUnh8H090Ru4Z52A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@stylistic/eslint-plugin": "2.11.0", + "eslint-plugin-n": "^17.23.2", + "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-react": "^7.37.5", + "find-up": "^8.0.0", + "globals": "^17.3.0", + "peowly": "^1.3.3", + "typescript-eslint": "^8.56.0" + }, + "bin": { + "neostandard": "cli.mjs" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": "^9.0.0" + } + }, + "node_modules/neostandard/node_modules/eslint-plugin-n": { + "version": "17.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.24.0.tgz", + "integrity": "sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" + } + }, + "node_modules/neostandard/node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/neostandard/node_modules/find-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-8.0.0.tgz", + "integrity": "sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^8.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/neostandard/node_modules/locate-path": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-8.0.0.tgz", + "integrity": "sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/neostandard/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/neostandard/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/neostandard/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/neostandard/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/nock": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-15.0.0.tgz", + "integrity": "sha512-EoAVk4Y8Yv4JUQz62sv8zmv+DoBblD/pht/q7aW/td1WietaFWrivzhMGGCLmx2qjpLcOrbyammedW8IRUU5TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mswjs/interceptors": "^0.39.5", + "json-stringify-safe": "^5.0.1" + }, + "engines": { + "node": ">=18.20.0 <20 || >=20.12.1" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-status-codes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/noop6": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.10.tgz", + "integrity": "sha512-WZvuCILZFZHK+WuqCQwxLBGllkBK1ct8s8Mu9FMDbEsBE6/bqNxyFGbX7Xky+6bYFL8X2Ou4Cis4CJyrwXLvQA==", + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm": { + "version": "11.19.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.19.0.tgz", + "integrity": "sha512-SDd/hHg3KqHE5Ht2NHWxNYNtqCQ2pXAPLl6OtQhPyED5PHsRfrOtO199MZTIG2cQoQ1ZRI9t28shrD+2cr3AAw==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which" + ], + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^9.9.1", + "@npmcli/config": "^10.12.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/map-workspaces": "^5.0.3", + "@npmcli/metavuln-calculator": "^9.0.3", + "@npmcli/package-json": "^7.0.5", + "@npmcli/promise-spawn": "^9.0.1", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.4", + "@sigstore/tuf": "^4.0.2", + "abbrev": "^4.0.0", + "archy": "~1.0.0", + "cacache": "^20.0.4", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^13.0.6", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^9.0.3", + "ini": "^6.0.0", + "init-package-json": "^8.2.5", + "is-cidr": "^6.0.4", + "json-parse-even-better-errors": "^5.0.0", + "libnpmaccess": "^10.0.3", + "libnpmdiff": "^8.1.12", + "libnpmexec": "^10.3.2", + "libnpmfund": "^7.0.26", + "libnpmorg": "^8.0.1", + "libnpmpack": "^9.1.12", + "libnpmpublish": "^11.2.0", + "libnpmsearch": "^9.0.1", + "libnpmteam": "^8.0.2", + "libnpmversion": "^8.0.4", + "make-fetch-happen": "^15.0.6", + "minimatch": "^10.2.5", + "minipass": "^7.1.3", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^12.4.0", + "nopt": "^9.0.0", + "npm-audit-report": "^7.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.2", + "npm-pick-manifest": "^11.0.3", + "npm-profile": "^12.0.2", + "npm-registry-fetch": "^19.1.1", + "npm-user-validate": "^4.0.0", + "p-map": "^7.0.4", + "pacote": "^21.5.1", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.1.0", + "qrcode-terminal": "^0.12.0", + "read": "^5.0.1", + "semver": "^7.8.5", + "spdx-expression-parse": "^4.0.0", + "ssri": "^13.0.1", + "supports-color": "^10.2.2", + "tar": "^7.5.19", + "text-table": "~0.2.0", + "tiny-relative-date": "^2.0.2", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^7.0.2", + "which": "^6.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/@gar/promise-retry": { + "version": "1.0.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "9.9.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^6.0.0", + "cacache": "^20.0.1", + "common-ancestor-path": "^2.0.0", + "hosted-git-info": "^9.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.0.0", + "proggy": "^4.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "semver": "^7.3.7", + "ssri": "^13.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "10.12.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "ini": "^6.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "5.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "7.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "10.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "4.0.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "3.2.1", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.5.1", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "4.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "4.0.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "3.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "4.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/npm/node_modules/bin-links": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "5.0.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "20.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.6.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "3.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.4.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "5.0.5", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "8.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "2.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.4.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/diff": { + "version": "8.0.4", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.3", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "13.0.6", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "9.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.2.0", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.7.2", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "8.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "8.2.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^3.0.1", + "read": "^5.0.1", + "semver": "^7.7.2", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "10.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "6.0.4", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^5.0.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm/node_modules/isexe": { + "version": "4.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "10.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "8.1.12", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.9.1", + "@npmcli/installed-package-contents": "^4.0.0", + "binary-extensions": "^3.0.0", + "diff": "^8.0.2", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tar": "^7.5.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "10.3.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/arborist": "^9.9.1", + "@npmcli/package-json": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "proc-log": "^6.0.0", + "read": "^5.0.1", + "semver": "^7.3.7", + "signal-exit": "^4.1.0", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "7.0.26", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.9.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "9.1.12", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.9.1", + "@npmcli/run-script": "^10.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "11.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.7", + "sigstore": "^4.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "9.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "8.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "11.5.1", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "15.0.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "10.2.5", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.3", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "5.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "iconv-lite": "^0.7.2" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.6", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^7.1.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "12.4.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "8.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "13.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "10.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "11.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "12.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "19.1.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "4.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "7.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "21.5.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "5.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^5.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "2.0.2", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "6.1.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "5.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^3.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.8.5", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "4.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.1", + "@sigstore/tuf": "^4.0.2", + "@sigstore/verify": "^3.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.9", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.23", + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "13.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "10.2.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "7.5.19", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "2.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.17", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "4.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/undici": { + "version": "6.27.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/which": { + "version": "6.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "7.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "5.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/oargv": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.11.tgz", + "integrity": "sha512-FGTon9C71936EnOjx/NTsMxlLeWmw8zQQld4KDmgRxRtZ8fH1XpbLLRHmOioeZs/WoURz2OGR4KmDoTaL4ErJQ==", + "license": "MIT", + "dependencies": { + "iterate-object": "^1.1.0", + "ul": "^5.0.0" + } + }, + "node_modules/obj-def": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.10.tgz", + "integrity": "sha512-RJpNUkO+1r/rXTBs82iU4scoC9Q1yp9HZbSk0ldpFe8362S6eTjUjSgTmECa1TtOBIe5pn4pwSzxIiWc8+jmWg==", + "license": "MIT", + "dependencies": { + "deffy": "^2.2.2" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/one-by-one": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.9.tgz", + "integrity": "sha512-H10TAq02LKrkSRTQz1mgvcKb64rRajZ+B5HWHBvkGigYNCPqL0Q/tLIN3vfha/DqZxXeKNfyCmgfEYo2hgFQgA==", + "license": "MIT", + "dependencies": { + "obj-def": "^1.0.0", + "sliced": "^1.0.1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT" + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", + "integrity": "sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==", + "license": "MIT", + "dependencies": { + "got": "^5.0.0", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/package-json-path": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.10.tgz", + "integrity": "sha512-DOlmVIfx+qDHHWaaxg573brZ8mH0Nxo4ecYA4SKkrpCOhCP64NXk7VxJtWVKZQ9urfU2Ivl74HeYUO42PLCpLw==", + "license": "MIT", + "dependencies": { + "abs": "^1.2.1" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/package-lock.json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-lock.json/-/package-lock.json-1.0.0.tgz", + "integrity": "sha512-+yEXtNdlCs5N0Zy/9uvkifgf/RqnGu0WqP4j9Wu1Us4YReFe1YNBh2Krmf8B1xGxjpYnta63K55QP8bkafnOzA==" + }, + "node_modules/package.json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz", + "integrity": "sha512-pSxZ6XR5yEawRN2ekxx9IKgPN5uNAYco7MCPxtBEWMKO3UKWa1X2CtQMzMgloeGj2g2o6cue3Sb5iPkByIJqlw==", + "deprecated": "Use pkg.json instead.", + "license": "MIT", + "dependencies": { + "git-package-json": "^1.4.0", + "git-source": "^1.1.0", + "package-json": "^2.3.1" + } + }, + "node_modules/pane-registry": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-4.0.0.tgz", + "integrity": "sha512-B30YMN3TBsPxROyjYiIdP89V++wWoPluG+peBNgOOnw6nqGSyZZ8BE1csOEOr17HrKLxyof41wFLUdKFmz/ycg==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.0", + "solid-logic": "5.0.0" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-url": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz", + "integrity": "sha512-1wj9nkgH/5EboDxLwaTMGJh3oH3f+Gue+aGdh631oCqoSBpokzmMmOldvOeBPtB8GJBYJbaF93KPzlkU+Y1ksg==", + "license": "MIT", + "dependencies": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "node_modules/parse-url/node_modules/protocols": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", + "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/peowly": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/peowly/-/peowly-1.3.3.tgz", + "integrity": "sha512-5UmUtvuCv3KzBX2NuQw2uF28o0t8Eq4KkPRZfUCzJs+DiNVKw7OaYn29vNDgrt/Pggs23CPlSTqgzlhHJfpT0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.6.0", + "typescript": ">=5.8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/polished": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/r-json": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.3.1.tgz", + "integrity": "sha512-5nhRFfjVMQdrwKUfUlRpDUCocdKtjSnYZ1R/86mpZDV3MfsZ3dYYNjSGuMX+mPBvFvQBhdzxSqxkuLPLv4uFGg==", + "license": "MIT", + "dependencies": { + "w-json": "1.3.10" + } + }, + "node_modules/r-package-json": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.10.tgz", + "integrity": "sha512-g+KLu+aq3tkhW6gzjsfdWAyd+ZkueLTzkX2zpB2GIW7M/lOXal3nB8U36XOrIBGogJsz2H//xWA4mj9uGlcigw==", + "license": "MIT", + "dependencies": { + "package-json-path": "^1.0.0", + "r-json": "^1.2.1" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rdf-canonize": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-5.0.0.tgz", + "integrity": "sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/rdflib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/rdflib/-/rdflib-2.4.0.tgz", + "integrity": "sha512-DPBFlnkA7lWgskbgyPsRxHE5S/9Ni5KHNgwzrq8CucG+TBxEHTGRSeMKjWhZlZhBhmQFu0YQGjOYyrzmkX/gwg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@frogcat/ttl2jsonld": "^0.0.10", + "@rdfjs/types": "^2.0.1", + "@xmldom/xmldom": "^0.9.10", + "cross-fetch": "^4.1.0", + "jsonld": "^9.0.0", + "n3": "^2.0.3", + "package-lock.json": "^1.0.0", + "package.json": "^2.0.1", + "solid-namespace": "^0.5.4" + } + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-is-18": { + "name": "react-is", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-is-19": { + "name": "react-is", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", + "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-all-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==", + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-all-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/read-all-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/read-all-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/read-all-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==", + "deprecated": "Unsupported", + "license": "MIT" + }, + "node_modules/solid-logic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-5.0.0.tgz", + "integrity": "sha512-3DEIL/sfXA8X3AxDewLNeemkeKIPzpprfMrxQAz/mgbgIpBSkvTygoxc0nAsRKoKKZat022XlfXM8nx1B934LA==", + "license": "MIT", + "dependencies": { + "@uvdsl/solid-oidc-client-browser": "^0.2.3", + "solid-namespace": "^0.5.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rdflib": "^2.4.0" + } + }, + "node_modules/solid-namespace": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/solid-namespace/-/solid-namespace-0.5.4.tgz", + "integrity": "sha512-oPAv8xIg2MOLz069JRdvsSbYCpQN+umPJJ9LBFPzCrYuSw+dW4TMUOTDxTWS5xy+B3XN4+Fx3iIS5Jm8abm4Mg==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/storybook": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.18.tgz", + "integrity": "sha512-p8seiSI6FiVY6P3V0pG+5v7c8pDMehMAFRWEhG5XqIBSQszzOjDnW2rNvm3odoLKfo3V3P6Cs6Hv9ILzymULyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core": "8.6.18" + }, + "bin": { + "getstorybook": "bin/index.cjs", + "sb": "bin/index.cjs", + "storybook": "bin/index.cjs" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swc-loader": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz", + "integrity": "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@swc/counter": "^0.1.3" + }, + "peerDependencies": { + "@swc/core": "^1.2.147", + "webpack": ">=2" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tapable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/timed-out": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", + "integrity": "sha512-pqqJOi1rF5zNs/ps4vmbE4SFCrM4iR7LW+GHAsHqO/EumqbIWceioevYLM5xZRgQSH6gFgL9J/uB7EcJhQ9niQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tldts": { + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.28.tgz", + "integrity": "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.28" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.28.tgz", + "integrity": "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", + "integrity": "sha512-c2mmfiBmND6SOVxzogm1oda0OJ1HZVIk/5n26N59dDTh80MUeavpiCls4PGAdkX1PFkKokLpcf7prSjCeXLsJg==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/ts-declaration-location/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedoc": { + "version": "0.28.19", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.19.tgz", + "integrity": "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^3.23.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.1", + "minimatch": "^10.2.5", + "yaml": "^2.8.3" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18", + "pnpm": ">= 10" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" + } + }, + "node_modules/typedoc/node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.2.tgz", + "integrity": "sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.58.2", + "@typescript-eslint/parser": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/utils": "8.58.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.2.tgz", + "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typpy": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.4.0.tgz", + "integrity": "sha512-a16Uv5doNtvHzaG4wZCHmXN+l9xxmTMpyODtPz7B3DSTsDVNXilTSJGuNw68sUh0Un4bf+ghRMbEcJCI6r06mQ==", + "license": "MIT", + "dependencies": { + "function.name": "^1.0.3" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ul": { + "version": "5.2.16", + "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.16.tgz", + "integrity": "sha512-v1YrSEsJZpJsywzF/MKgsQwMdOwBlwwmNiUOJh/yX6FHrq7dYjeua1YOhLV0q0KioqEFZC4P7MsKmpEsGdZz3w==", + "license": "MIT", + "dependencies": { + "deffy": "^2.2.2", + "typpy": "^2.3.4" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.25.0.tgz", + "integrity": "sha512-AXNgS1Byr27fTI+2bsPEkV9CxkT8H6xNyRI68b3TatlZo3RkzlqQBLL+w7SmGPVpokjHbcuNVQUWE7FRTg+LRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", + "license": "MIT", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/w-json": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/w-json/-/w-json-1.3.10.tgz", + "integrity": "sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw==", + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/webpack": { + "version": "5.106.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.2.tgz", + "integrity": "sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.20.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "loader-runner": "^4.3.1", + "mime-db": "^1.54.0", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.0.2.tgz", + "integrity": "sha512-dB0R4T+C/8YuvM+fabdvil6QE44/ChDXikV5lOOkrUeCkW5hTJv2pGLE3keh+D5hjYw8icBaJkZzpFoaHV4T+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^1.0.0", + "commander": "^14.0.3", + "cross-spawn": "^7.0.6", + "envinfo": "^7.14.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^6.0.1" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.101.0", + "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0", + "webpack-dev-server": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", + "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-hot-middleware": { + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz", + "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-html-community": "0.0.8", + "html-entities": "^2.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/window-or-global": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz", + "integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } } diff --git a/package.json b/package.json index 2100cc265..b2b048174 100644 --- a/package.json +++ b/package.json @@ -1,64 +1,227 @@ { - "name": "solid-ui", - "version": "0.11.5", - "description": "UI library for writing Solid read-write-web applications", - "main": "./lib/index.js", - "files": [ - "lib", - "dist" - ], - "scripts": { - "build-lib": "babel src -d lib", - "build": "npm run build-lib", - "postversion": "git push origin master --follow-tags", - "prepublishOnly": "npm run build", - "standard": "standard", - "test": "npm run standard" - }, - "repository": { - "type": "git", - "url": "https://github.com/solid/solid-ui" - }, - "keywords": [ - "solid", - "decentralized", - "widgets", - "ui", - "web", - "rdf", - "ldp", - "linked", - "data" - ], - "author": "Tim Berners-Lee ", - "contributors": [ - "Daniel Friedman " - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/solid/solid-ui/issues" - }, - "homepage": "https://github.com/solid/solid-ui", - "dependencies": { - "escape-html": "^1.0.3", - "node-uuid": "^1.4.7", - "rdflib": ">=0.17.0", - "regenerate": "^1.3.2", - "solid-auth-client": "^2.2.6", - "solid-auth-tls": "^0.1.2" - }, - "devDependencies": { - "babel-cli": "^6.18.0", - "babel-preset-es2015": "^6.18.0", - "standard": "^10.0.2" - }, - "standard": { - "globals": [ - "$rdf", - "tabulator", - "QUnit", - "$SolidTestEnvironment", - "AudioContext" - ] - } + "name": "solid-ui", + "version": "4.0.0", + "description": "UI library for Solid applications", + "main": "dist/solid-ui.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/solid-ui.esm.js", + "require": "./dist/solid-ui.js" + }, + "./components/header": { + "types": "./dist/components/header/index.d.ts", + "import": "./dist/components/header/index.esm.js", + "require": "./dist/components/header/index.js" + }, + "./components/layout/header": { + "types": "./dist/components/header/index.d.ts", + "import": "./dist/components/header/index.esm.js", + "require": "./dist/components/header/index.js" + }, + "./components/loginButton": { + "types": "./dist/components/loginButton/index.d.ts", + "import": "./dist/components/loginButton/index.esm.js", + "require": "./dist/components/loginButton/index.js" + }, + "./components/login-button": { + "types": "./dist/components/loginButton/index.d.ts", + "import": "./dist/components/loginButton/index.esm.js", + "require": "./dist/components/loginButton/index.js" + }, + "./components/auth/login-button": { + "types": "./dist/components/loginButton/index.d.ts", + "import": "./dist/components/loginButton/index.esm.js", + "require": "./dist/components/loginButton/index.js" + }, + "./components/auth/signup-button": { + "types": "./dist/components/signupButton/index.d.ts", + "import": "./dist/components/signupButton/index.esm.js", + "require": "./dist/components/signupButton/index.js" + }, + "./components/signup-button": { + "types": "./dist/components/signupButton/index.d.ts", + "import": "./dist/components/signupButton/index.esm.js", + "require": "./dist/components/signupButton/index.js" + }, + "./components/media/photo-capture": { + "types": "./dist/components/photoCapture/index.d.ts", + "import": "./dist/components/photoCapture/index.esm.js", + "require": "./dist/components/photoCapture/index.js" + }, + "./components/photo-capture": { + "types": "./dist/components/photoCapture/index.d.ts", + "import": "./dist/components/photoCapture/index.esm.js", + "require": "./dist/components/photoCapture/index.js" + }, + "./components/actions/button": { + "types": "./dist/components/button/index.d.ts", + "import": "./dist/components/button/index.esm.js", + "require": "./dist/components/button/index.js" + }, + "./components/button": { + "types": "./dist/components/button/index.d.ts", + "import": "./dist/components/button/index.esm.js", + "require": "./dist/components/button/index.js" + }, + "./components/footer": { + "types": "./dist/components/footer/index.d.ts", + "import": "./dist/components/footer/index.esm.js", + "require": "./dist/components/footer/index.js" + }, + "./components/layout/footer": { + "types": "./dist/components/footer/index.d.ts", + "import": "./dist/components/footer/index.esm.js", + "require": "./dist/components/footer/index.js" + }, + "./components/forms/select": { + "types": "./dist/components/select/index.d.ts", + "import": "./dist/components/select/index.esm.js", + "require": "./dist/components/select/index.js" + }, + "./components/select": { + "types": "./dist/components/select/index.d.ts", + "import": "./dist/components/select/index.esm.js", + "require": "./dist/components/select/index.js" + }, + "./components/forms/combobox": { + "types": "./dist/components/combobox/index.d.ts", + "import": "./dist/components/combobox/index.esm.js", + "require": "./dist/components/combobox/index.js" + }, + "./components/combobox": { + "types": "./dist/components/combobox/index.d.ts", + "import": "./dist/components/combobox/index.esm.js", + "require": "./dist/components/combobox/index.js" + } + }, + "files": [ + "dist/", + "README.md", + "LICENSE" + ], + "scripts": { + "clean": "rm -rf ./dist ./src/versionInfo.ts ./docs/api .tsbuildinfo", + "build": "npm run clean && npm run sync-component-exports && npm run typecheck && npm run build-version && npm run build-dist && npm run build-js && npm run postbuild-js && npm run build-storybook", + "build-version": "sh ./timestamp.sh > src/versionInfo.ts && eslint 'src/versionInfo.ts' --fix", + "prebuild-js": "rm -f .tsbuildinfo", + "build-js": "tsc", + "sync-component-exports": "node scripts/sync-component-exports.mjs", + "postbuild-js": "rm -f dist/versionInfo.d.ts dist/versionInfo.d.ts.map && node scripts/build-component-dts.mjs", + "build-dist": "webpack --progress", + "build-form-examples": "npm run build-js && npm run build-version && npm run build-dist && cp ./dist/solid-ui.js ./docs/form-examples/", + "lint": "eslint", + "lint-fix": "eslint --fix", + "typecheck": "tsc --noEmit", + "typecheck-test": "tsc --noEmit -p tsconfig.test.json", + "test": "jest --no-coverage", + "test-coverage": "jest --coverage --collectCoverageFrom=src/**/*.[jt]s", + "test-debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch", + "watch:js": "tsc --watch --preserveWatchOutput", + "watch:component-dts": "node scripts/watch-component-dts.mjs", + "watch:component-exports": "node scripts/watch-component-exports.mjs", + "watch:dist": "webpack --watch --mode development", + "watch": "npm run sync-component-exports && npm run build-version && npm run build-js && npm run postbuild-js && sh -c 'npm run watch:js & npm run watch:component-dts & npm run watch:component-exports & npm run watch:dist & wait'", + "dev": "npm run sync-component-exports && npm run build-version && sh -c 'npm run watch:js & npm run watch:component-dts & npm run watch:component-exports & npm run watch:dist & wait'", + "doc": "typedoc --out ./docs/api/ ./src/ --excludeInternal", + "prepublishOnly": "npm run build && npm run lint && npm test && npm run doc", + "preversion": "npm run sync-component-exports && npm run lint && npm run typecheck && npm test", + "postpublish": "git push origin main --follow-tags", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build --output-dir ./examples/storybook" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/SolidOS/solid-ui.git" + }, + "keywords": [ + "solid", + "decentralized", + "widgets", + "ui", + "web", + "rdf", + "ldp", + "linked", + "data" + ], + "author": "Tim Berners-Lee ", + "contributors": [ + "Daniel Friedman " + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/SolidOS/solid-ui/issues" + }, + "homepage": "https://github.com/SolidOS/solid-ui", + "dependencies": { + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "escape-html": "^1.0.3", + "i": "^0.3.7", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "npm": "^11.19.0", + "pane-registry": "^4.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "peerDependencies": { + "rdflib": "^2.4.0", + "solid-logic": "^5.0.0" + }, + "devDependencies": { + "@babel/cli": "^7.28.6", + "@babel/core": "^7.29.0", + "@babel/plugin-transform-runtime": "^7.29.0", + "@babel/preset-env": "^7.29.5", + "@babel/preset-typescript": "^7.28.5", + "@babel/runtime": "^7.29.2", + "@eslint/js": "^9.39.4", + "@mdx-js/react": "^3.1.1", + "@storybook/addon-actions": "8.6.18", + "@storybook/addon-docs": "8.6.18", + "@storybook/addon-essentials": "8.6.18", + "@storybook/addon-links": "8.6.18", + "@storybook/addon-mdx-gfm": "8.6.18", + "@storybook/addon-webpack5-compiler-swc": "^3.0.0", + "@storybook/html": "8.6.18", + "@storybook/html-webpack5": "8.6.18", + "@testing-library/dom": "^10.4.1", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^30.0.0", + "@types/jsdom": "^28.0.3", + "@types/node": "^25.8.0", + "@typescript-eslint/parser": "^8.59.3", + "babel-jest": "^30.4.1", + "babel-loader": "^10.1.1", + "eslint": "^9.39.4", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.15.2", + "eslint-plugin-n": "^18.0.1", + "eslint-plugin-promise": "^7.3.0", + "get-random-values": "^5.0.0", + "globals": "^17.6.0", + "isomorphic-fetch": "^3.0.0", + "jest": "^30.4.2", + "jest-environment-jsdom": "^30.4.1", + "jsdom": "^28.1.0", + "neostandard": "^0.13.0", + "nock": "^15.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-is": "^17.0.2", + "storybook": "8.6.18", + "style-loader": "^3.3.4", + "terser-webpack-plugin": "^5.6.0", + "typedoc": "^0.28.19", + "typescript": "^5.9.3", + "webpack": "^5.106.2", + "webpack-cli": "^7.0.2" + }, + "optionalDependencies": { + "fsevents": "*" + } } diff --git a/scripts/build-component-dts.mjs b/scripts/build-component-dts.mjs new file mode 100644 index 000000000..333a299eb --- /dev/null +++ b/scripts/build-component-dts.mjs @@ -0,0 +1,45 @@ +import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from 'fs' +import path from 'path' +import { v2Components } from './component-manifest.mjs' + +const distDir = path.resolve(process.cwd(), 'dist') +const v2ComponentsDir = path.join(distDir, 'v2', 'components') +const publicComponentsDir = path.join(distDir, 'components') + +if (!existsSync(v2ComponentsDir)) { + throw new Error(`Missing expected directory: ${v2ComponentsDir}`) +} + +const manifestComponents = v2Components.map(({ sourceDir, sourcePath = sourceDir }) => ({ + publicDir: sourceDir, + sourcePath +})) + +const fallbackComponentDirs = readdirSync(v2ComponentsDir).filter(name => { + const fullPath = path.join(v2ComponentsDir, name) + return statSync(fullPath).isDirectory() +}).map(name => ({ + publicDir: name, + sourcePath: name +})) + +const componentDirs = manifestComponents.length > 0 ? manifestComponents : fallbackComponentDirs + +for (const { publicDir, sourcePath } of componentDirs) { + const sourceIndex = path.join(v2ComponentsDir, sourcePath, 'index.d.ts') + if (!existsSync(sourceIndex)) { + continue + } + + const outputDir = path.join(publicComponentsDir, publicDir) + mkdirSync(outputDir, { recursive: true }) + + const relativePath = path.relative(outputDir, sourceIndex) + .replace(/\\/g, '/') + .replace(/\.d\.ts$/, '') + + writeFileSync( + path.join(outputDir, 'index.d.ts'), + `export * from '${relativePath}';\n` + ) +} diff --git a/scripts/component-manifest.mjs b/scripts/component-manifest.mjs new file mode 100644 index 000000000..7cee7d316 --- /dev/null +++ b/scripts/component-manifest.mjs @@ -0,0 +1,64 @@ +export const v2Components = [ + { + sourceDir: 'header', + sourcePath: 'layout/header', + exportNames: ['header', 'layout/header'] + }, + { + sourceDir: 'loginButton', + sourcePath: 'auth/loginButton', + exportNames: ['loginButton', 'login-button', 'auth/login-button'] + }, + { + sourceDir: 'signupButton', + sourcePath: 'auth/signupButton', + exportNames: ['auth/signup-button', 'signup-button'] + }, + { + sourceDir: 'photoCapture', + sourcePath: 'media/photoCapture', + exportNames: ['media/photo-capture', 'photo-capture'] + }, + { + sourceDir: 'button', + sourcePath: 'actions/button', + exportNames: ['actions/button', 'button'] + }, + { + sourceDir: 'footer', + sourcePath: 'layout/footer', + exportNames: ['footer', 'layout/footer'] + }, + { + sourceDir: 'select', + sourcePath: 'forms/select', + exportNames: ['forms/select', 'select'] + }, + { + sourceDir: 'combobox', + sourcePath: 'forms/combobox', + exportNames: ['forms/combobox', 'combobox'] + } +] + +export const componentEntries = Object.fromEntries( + v2Components.map(({ sourceDir, sourcePath = sourceDir }) => [ + sourceDir, + { + import: `./src/v2/components/${sourcePath}/index.ts` + } + ]) +) + +export const componentExports = Object.fromEntries( + v2Components.flatMap(({ sourceDir, exportNames }) => + exportNames.map(exportName => [ + `./components/${exportName}`, + { + types: `./dist/components/${sourceDir}/index.d.ts`, + import: `./dist/components/${sourceDir}/index.esm.js`, + require: `./dist/components/${sourceDir}/index.js` + } + ]) + ) +) diff --git a/scripts/sync-component-exports.mjs b/scripts/sync-component-exports.mjs new file mode 100644 index 000000000..09c73dbd3 --- /dev/null +++ b/scripts/sync-component-exports.mjs @@ -0,0 +1,24 @@ +import { readFileSync, writeFileSync } from 'fs' +import path from 'path' +import { componentExports } from './component-manifest.mjs' + +const packageJsonPath = path.resolve(process.cwd(), 'package.json') +const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) + +const preservedExports = Object.fromEntries( + Object.entries(packageJson.exports || {}).filter(([subpath]) => !subpath.startsWith('./components/')) +) + +const nextExports = { + ...preservedExports, + ...componentExports +} + +if (JSON.stringify(packageJson.exports || {}) === JSON.stringify(nextExports)) { + console.log('package.json exports are already in sync') + process.exit(0) +} + +packageJson.exports = nextExports + +writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`) diff --git a/scripts/watch-component-dts.mjs b/scripts/watch-component-dts.mjs new file mode 100644 index 000000000..d25a4cf7c --- /dev/null +++ b/scripts/watch-component-dts.mjs @@ -0,0 +1,60 @@ +import { spawn } from 'child_process' +import { existsSync, watch } from 'fs' +import path from 'path' + +const componentDir = path.resolve(process.cwd(), 'dist/v2/components') +const scriptPath = path.resolve(process.cwd(), 'scripts/build-component-dts.mjs') +let buildTimer = null +let running = false +let waiting = false + +const runBuild = () => { + if (running) return + running = true + const child = spawn(process.execPath, [scriptPath], { + stdio: 'inherit' + }) + + child.on('exit', code => { + running = false + if (code !== 0) { + console.error(`build-component-dts exited with code ${code}`) + } + }) +} + +const scheduleBuild = () => { + clearTimeout(buildTimer) + buildTimer = setTimeout(() => { + if (existsSync(componentDir)) { + runBuild() + } + }, 150) +} + +const startWatcher = () => { + if (!existsSync(componentDir)) { + if (!waiting) { + console.log(`Waiting for ${componentDir} to exist before watching component declarations...`) + waiting = true + } + setTimeout(startWatcher, 250) + return + } + + if (waiting) { + console.log(`${componentDir} exists; starting watch...`) + } else { + console.log(`Watching ${componentDir} for component declaration changes...`) + } + + watch(componentDir, { recursive: true }, (eventType, filename) => { + if (!filename) return + if (filename.endsWith('.d.ts') || filename.endsWith('.js') || filename.endsWith('.map')) { + scheduleBuild() + } + }) +} + +runBuild() +startWatcher() diff --git a/scripts/watch-component-exports.mjs b/scripts/watch-component-exports.mjs new file mode 100644 index 000000000..516cf681f --- /dev/null +++ b/scripts/watch-component-exports.mjs @@ -0,0 +1,58 @@ +import { spawn } from 'child_process' +import { existsSync, watch } from 'fs' +import path from 'path' + +const scriptsDir = path.resolve(process.cwd(), 'scripts') +const manifestFile = 'component-manifest.mjs' +const syncScript = path.resolve(scriptsDir, 'sync-component-exports.mjs') +let syncTimer = null +let running = false +let rerunRequested = false + +const runSync = () => { + if (running) { + rerunRequested = true + return + } + + running = true + rerunRequested = false + + const child = spawn(process.execPath, [syncScript], { + stdio: 'inherit' + }) + + child.on('exit', code => { + running = false + + if (code !== 0) { + console.error(`sync-component-exports exited with code ${code}`) + } + + if (rerunRequested) { + runSync() + } + }) +} + +const scheduleSync = () => { + clearTimeout(syncTimer) + syncTimer = setTimeout(() => { + runSync() + }, 150) +} + +if (!existsSync(scriptsDir)) { + throw new Error(`Missing expected directory: ${scriptsDir}`) +} + +console.log(`Watching ${path.join(scriptsDir, manifestFile)} for export manifest changes...`) + +runSync() + +watch(scriptsDir, (eventType, filename) => { + if (!filename) return + if (filename === manifestFile) { + scheduleSync() + } +}) diff --git a/src/acl-control.js b/src/acl-control.js deleted file mode 100644 index e47ec3746..000000000 --- a/src/acl-control.js +++ /dev/null @@ -1,556 +0,0 @@ -/* global confirm */ -// ///////////////////////////// ACL User Interface - -// See https://www.coshx.com/blog/2014/04/11/preventing-drag-and-drop-disasters-with-a-chrome-userscript/ -// Without this dropping anything onto a browser page will cause chrome etc to jump to diff page -// throwing away all the user's work. - -/* global alert */ -var UI = {} - -UI.acl = require('./acl') -UI.icons = require('./iconBase') -UI.ns = require('./ns') -UI.widgets = require('./widgets') -UI.style = require('./style') -UI.utils = require('./utils') - -UI.aclControl = module.exports = {} - -// In apps which may use drag and drop, this utility takes care of the fact -// by default in a browser, an uncuaght user drop into a browser window -// causes the bowser to lose all its work in tat window and navigate to another page -UI.aclControl.preventBrowserDropEvents = function (document) { - console.log('preventBrowserDropEvents called.') - if (typeof window !== 'undefined') { - if (window.preventBrowserDropEventsDone) return - window.preventBrowserDropEventsDone = true - } - - function preventDrag (e) { - e.stopPropagation() - e.preventDefault() - } - - function handleDrop (e) { - if (e.dataTransfer.files.length > 0) { - if (!confirm('Are you sure you want to drop this file here? ' + - '(Cancel opens it in a new tab)')) { - e.stopPropagation() - e.preventDefault() - console.log('@@@@ document-level DROP suppressed: ' + e.dataTransfer.dropEffect) - } - } - } - document.addEventListener('drop', handleDrop, false) - document.addEventListener('dragenter', preventDrag, false) - document.addEventListener('dragover', preventDrag, false) -} - -UI.aclControl.shortNameForFolder = function (x) { - var str = x.uri - if (str.slice(-1) === '/') { - str = str.slice(0, -1) - } - var slash = str.lastIndexOf('/') - if (slash >= 0) { - str = str.slice(slash + 1) - } - return str || '/' -} - -UI.aclControl.ACLControlBox5 = function (subject, dom, noun, kb, callback) { - var updater = kb.updater || new $rdf.UpdateManager(kb) - var ACL = UI.ns.acl - var doc = subject.doc() // The ACL is actually to the doc describing the thing - - var table = dom.createElement('table') - table.setAttribute('style', 'margin: 1em; border: 0.1em #ccc ;') - var headerRow = table.appendChild(dom.createElement('tr')) - headerRow.textContent = 'Sharing for ' + noun + ' ' + UI.utils.label(subject) - headerRow.setAttribute('style', 'min-width: 20em; padding: 1em; font-size: 120%; border-bottom: 0.1em solid red; margin-bottom: 2em;') - - var statusRow = table.appendChild(dom.createElement('tr')) - - var statusCell = statusRow.appendChild(dom.createElement('td')) - var statusBlock = statusCell.appendChild(dom.createElement('div')) - statusBlock.setAttribute('style', 'padding: 2em;') - var MainRow = table.appendChild(dom.createElement('tr')) - var box = MainRow.appendChild(dom.createElement('table')) - var bottomRow = table.appendChild(dom.createElement('tr')) - - // A world button can be dragged to gve public access. - // later, allow it to be pressed to make pubicly viewable? - var publicAccessCell = bottomRow.appendChild(dom.createElement('td')) - var publicAccessButton = publicAccessCell.appendChild(UI.widgets.button(dom, UI.icons.iconBase + 'noun_98053.svg', 'Public')) - UI.widgets.makeDraggable(publicAccessButton, UI.ns.foaf('Agent')) // Represent everyone - - var bigButtonStyle = 'border-radius: 0.3em; background-color: white; border: 0.1em solid #888;' - - // This is the main function which produces an editable access control. - // There are two of these in all iff the defaults are separate - // - function ACLControlEditable (box, doc, aclDoc, kb, options) { - var defaultOrMain = options.doingDefault ? 'default' : 'main' - options = options || {} - var ac = UI.acl.readACL(doc, aclDoc, kb, options.doingDefaults) // Note kb might not be normal one - var byCombo - box[defaultOrMain] = byCombo = UI.acl.ACLbyCombination(ac) - var kToCombo = function (k) { - var y = ['Read', 'Append', 'Write', 'Control'] - var combo = [] - for (var i = 0; i < 4; i++) { - if (k & (1 << i)) { - combo.push('http://www.w3.org/ns/auth/acl#' + y[i]) - } - } - combo.sort() - combo = combo.join('\n') - return combo - } - var colloquial = {13: 'Owners', 9: 'Owners (write locked)', 5: 'Editors', 3: 'Posters', 2: 'Submitters', 1: 'Viewers'} - var recommended = {13: true, 5: true, 3: true, 2: true, 1: true} - var explanation = { - 13: 'can read, write, and control sharing.', - 9: 'can read and control sharing, currently write-locked.', - 5: 'can read and change information', - 3: 'can add new information, and read but not change existing information', - 2: 'can add new information but not read any', - 1: 'can read but not change information' - } - - var kToColor = {13: 'purple', 9: 'blue', 5: 'red', 3: 'orange', 2: '#cc0', 1: 'green'} - - var ktToList = function (k) { - var list = '' - var y = ['Read', 'Append', 'Write', 'Control'] - for (var i = 0; i < 4; i++) { - if (k & (1 << i)) { - list += y[i] - } - } - return list - } - - var removeAgentFromCombos = function (uri) { - for (var k = 0; k < 16; k++) { - var a = byCombo[kToCombo(k)] - if (a) { - for (var i = 0; i < a.length; i++) { - while (i < a.length && a[i][1] === uri) { - a.splice(i, 1) - } - } - } - } - } - - // - var agentTriage = function (uri) { - var ns = UI.ns - var obj = $rdf.sym(uri) - var types = kb.findTypeURIs(obj) - for (var ty in types) { - console.log(' drop object type includes: ' + ty) - } - // An Origin URI is one like https://fred.github.io eith no trailing slash - if (uri.startsWith('http') && uri.split('/').length === 3) { // there is no third slash - return {pred: 'origin', obj: obj} // The only way to know an origin alas - } - - if (ns.vcard('WebID').uri in types) return {pred: 'agent', obj: obj} - - if (ns.vcard('Group').uri in types) { - return {pred: 'agentGroup', obj: obj} // @@ note vcard membership not RDFs - } - if (obj.sameTerm(ns.foaf('Agent')) || - obj.sameTerm(ns.rdf('Resource')) || obj.sameTerm(ns.owl('Thing'))) { - return {pred: 'agentClass', obj: obj} - } - if (ns.vcard('Individual').uri in types || ns.foaf('Person').uri in types || ns.foaf('Agent').uri in types) { - var pref = kb.any(obj, ns.foaf('preferredURI')) - if (pref) return {pred: 'agent', obj: $rdf.sym(pref)} - return {pred: 'agent', obj: obj} - } - if (ns.solid('AppProvider').uri in types) { - return {pred: 'origin', obj: obj} - } - if (ns.solid('AppProviderClass').uri in types) { - return {pred: 'originClass', obj: obj} - } - console.log(' Triage fails for ' + uri) - } - - box.saveBack = function (callback) { - var kb2 = $rdf.graph() - if (!box.isContainer) { - UI.acl.makeACLGraphbyCombo(kb2, doc, box.mainByCombo, aclDoc, true) - } else if (box.defaultsDiffer) { // Pair of controls - UI.acl.makeACLGraphbyCombo(kb2, doc, box.mainByCombo, aclDoc, true) - UI.acl.makeACLGraphbyCombo(kb2, doc, box.defByCombo, aclDoc, false, true) - } else { // Linked controls - UI.acl.makeACLGraphbyCombo(kb2, doc, box.mainByCombo, aclDoc, true, true) - } - var updater = kb2.updater || new $rdf.UpdateManager(kb2) - updater.put(aclDoc, kb2.statementsMatching(undefined, undefined, undefined, aclDoc), - 'text/turtle', function (uri, ok, message) { - var error = null - if (!ok) { - error = 'ACL file save failed: ' + message - console.log(error) - } else { - kb.fetcher.unload(aclDoc) - kb.add(kb2.statements) - kb.fetcher.requested[aclDoc.uri] = 'done' // missing: save headers - console.log('ACL modification: success!') - } - callback(ok, error) - }) - } - - var renderCombo = function (byCombo, combo) { - var row = box.appendChild(dom.createElement('tr')) - row.combo = combo - row.setAttribute('style', 'color: ' + - (options.modify ? (kToColor[k] || 'black') : '#888') + ';') - - var left = row.appendChild(dom.createElement('td')) - - left.textContent = colloquial[k] || ktToList[k] - left.setAttribute('style', 'padding-bottom: 2em;') - - var middle = row.appendChild(dom.createElement('td')) - var middleTable = middle.appendChild(dom.createElement('table')) - middleTable.style.width = '100%' - - var right = row.appendChild(dom.createElement('td')) - right.textContent = explanation[k] || 'Unusual combination' - right.setAttribute('style', 'max-width: 30%;') - - var addAgent = function (pred, obj) { - if (middleTable.NoneTR) { - middleTable.removeChild(middleTable.NoneTR) - delete middleTable.NoneTR - } - var opt = {} - if (options.modify) { - opt.deleteFunction = function deletePerson () { - var arr = byCombo[combo] - for (var b = 0; b < arr.length; b++) { - if (arr[b][0] === pred && arr[b][1] === obj) { - arr.splice(b, 1) // remove from ACL - break - } - } - box.saveBack(function (ok, error) { - if (ok) { - middleTable.removeChild(tr) - } else { - alert(error) - } - }) - } - } - var tr = middleTable.appendChild( - UI.widgets.personTR(dom, ACL(pred), $rdf.sym(obj), opt)) - tr.predObj = [pred.uri, obj.uri] - } - - var syncCombo = function (combo) { - var i - var arr = byCombo[combo] - if (arr && arr.length) { - var already = middleTable.children - arr.sort() - for (var j = 0; j < already.length; j++) { - already[j].trashme = true - } - for (var a = 0; a < arr.length; a++) { - var found = false - for (i = 0; i < already.length; i++) { - if (already[i].predObj && // skip NoneTR - already[i].predObj[0] === arr[a][0] && - already[i].predObj[1] === arr[a][1]) { - found = true - delete already[i].trashme - break - } - } - if (!found) { - addAgent(arr[a][0], arr[a][1]) - } - } - for (i = already.length - 1; i >= 0; i--) { - if (already[i].trashme) { - middleTable.removeChild(already[i]) - } - } - } else { - UI.widgets.clearElement(middleTable) - var tr = middleTable.appendChild(dom.createElement('tr')) - tr.textContent = 'None' - tr.setAttribute('style', 'padding: 1em;') - middleTable.NoneTR = tr - } - } - - syncCombo(combo) - row.refresh = function () { - syncCombo(combo) - } - - if (options.modify) { - // see http://html5demos.com/drag-anything - row.addEventListener('dragover', function (e) { - e.preventDefault() // Neeed else drop does not work [sic] - e.dataTransfer.dropEffect = 'copy' - // console.log('dragover event') // millions of them - }) - - row.addEventListener('dragenter', function (e) { - console.log('dragenter event dropEffect: ' + e.dataTransfer.dropEffect) - this.style.backgroundColor = '#ccc' - e.dataTransfer.dropEffect = 'link' - console.log('dragenter event dropEffect 2: ' + e.dataTransfer.dropEffect) - }) - row.addEventListener('dragleave', function (e) { - console.log('dragleave event dropEffect: ' + e.dataTransfer.dropEffect) - this.style.backgroundColor = 'white' - }) - - row.addEventListener('drop', function (e) { - if (e.preventDefault) e.preventDefault() // stops the browser from redirecting off to the text. - console.log('Drop event. dropEffect: ' + e.dataTransfer.dropEffect) - console.log('Drop event. types: ' + (e.dataTransfer.types ? e.dataTransfer.types.join(', ') : 'NOPE')) - - var uris = null - var text - var thisEle = this - if (e.dataTransfer.types) { - for (var t = 0; t < e.dataTransfer.types.length; t++) { - var type = e.dataTransfer.types[t] - if (type === 'text/uri-list') { - uris = e.dataTransfer.getData(type).split('\n') // @ ignore those starting with # - console.log('Dropped text/uri-list: ' + uris) - } else if (type === 'text/plain') { - text = e.dataTransfer.getData(type) - } - } - if (uris === null && text && text.slice(0, 4) === 'http') { - uris = text - console.log("Waring: Poor man's drop: using text for URI") // chrome disables text/uri-list?? - } - } else { - // ... however, if we're IE, we don't have the .types property, so we'll just get the Text value - uris = [ e.dataTransfer.getData('Text') ] - console.log('@@ WARNING non-standrad drop event: ' + uris[0]) - } - console.log('Dropped URI list (2): ' + uris) - if (uris) { - uris.map(function (u) { - var saveAndRestoreUI = function () { - if (!(combo in byCombo)) { - byCombo[combo] = [] - } - removeAgentFromCombos(u) // Combos are mutually distinct - byCombo[combo].push([res.pred, res.obj.uri]) - console.log('ACL: setting access to ' + subject + ' by ' + res.pred + ': ' + res.obj) - box.saveBack(function (ok, error) { - if (ok) { - thisEle.style.backgroundColor = 'white' // restore look to before drag - syncPanel() - } else { - alert(error) - } - }) - } - - var res = agentTriage(u) // eg 'agent', 'origin', agentClass' - if (!res) { - console.log(' looking up dropped thing ' + u) - kb.fetcher.nowOrWhenFetched(u, function (ok, mess) { - if (!ok) { - console.log('Error looking up dropped thing ' + u + ': ' + mess) - } else { - res = agentTriage(u) - if (!res) { - console.log('Error: Drop fails to drop appropriate thing! ' + u) - } else { - saveAndRestoreUI() - } - } - }) - } else { - saveAndRestoreUI() - } - }) - } - return false - }) - } // if modify - } - var syncPanel = function () { - var kids = box.children - for (var i = 0; i < kids.length; i++) { - if (kids[i].refresh) { - kids[i].refresh() - } - } // @@ later -- need to addd combos not in the box? - } - - var k, combo - for (k = 15; k > 0; k--) { - combo = kToCombo(k) - if ((options.modify && recommended[k]) || byCombo[combo]) { - renderCombo(byCombo, combo) - } // if - } // for - return byCombo - } // ACLControlEditable - - var renderBox = function () { - box.innerHTML = '' - UI.acl.getACLorDefault(doc, function (ok, p2, targetDoc, targetACLDoc, defaultHolder, defaultACLDoc) { - var defa = !p2 - // @@ Could also set from classes ldp:Container etc etc - if (!ok) { - statusBlock.textContent += 'Error reading ' + (defa ? ' default ' : '') + 'ACL.' + - ' status ' + targetDoc + ': ' + targetACLDoc - } else { - box.isContainer = targetDoc.uri.slice(-1) === '/' // Give default for all directories - if (defa) { - var defaults = kb.each(undefined, ACL('defaultForNew'), defaultHolder, defaultACLDoc) - if (!defaults.length) { - statusBlock.textContent += ' (No defaults given.)' - } else { - statusBlock.innerHTML = '' - statusBlock.textContent = 'The sharing for this ' + noun + ' is the default for folder ' - var a = statusBlock.appendChild(dom.createElement('a')) - a.setAttribute('href', defaultHolder.uri) - a.textContent = UI.aclControl.shortNameForFolder(defaultHolder) - var kb2 = UI.acl.adoptACLDefault(doc, targetACLDoc, defaultHolder, defaultACLDoc) - ACLControlEditable(box, doc, targetACLDoc, kb2, {modify: false}) // Add btton to save them as actual - box.style.cssText = 'color: #777;' - - var editPlease = bottomRow.appendChild(dom.createElement('button')) - editPlease.textContent = 'Set specific sharing\nfor this ' + noun - editPlease.style.cssText = bigButtonStyle - editPlease.addEventListener('click', function (event) { - updater.put(targetACLDoc, kb2.statements, - 'text/turtle', function (uri, ok, message) { - if (!ok) { - statusBlock.textContent += ' (Error writing back access control file: ' + message + ')' - } else { - kb.add(kb2.statements) - statusBlock.textContent = ' (Now editing specific access for this ' + noun + ')' - // box.style.cssText = 'color: black;' - bottomRow.removeChild(editPlease) - renderBox() - } - }) - }) - } // defaults.length - } else { // Not using defaults - var useDefault - var addDefaultButton = function (prospectiveDefaultHolder) { - useDefault = bottomRow.appendChild(dom.createElement('button')) - useDefault.textContent = 'Stop specific sharing for this ' + noun + - ' -- just use default' // + UI.utils.label(thisDefaultHolder) - if (prospectiveDefaultHolder) { - useDefault.textContent += ' for ' + UI.utils.label(prospectiveDefaultHolder) - } - useDefault.style.cssText = bigButtonStyle - useDefault.addEventListener('click', function (event) { - kb.fetcher.delete(targetACLDoc.uri) - .then(function () { - statusBlock.textContent = ' The sharing for this ' + noun + ' is now the default.' - bottomRow.removeChild(useDefault) - box.style.cssText = 'color: #777;' - renderBox() - }) - .catch(function (e) { - statusBlock.textContent += ' (Error deleting access control file: ' + targetACLDoc + ': ' + e + ')' - }) - }) - } - var prospectiveDefaultHolder - - var str = targetDoc.uri.split('#')[0] - var p = str.slice(0, -1).lastIndexOf('/') - var q = str.indexOf('//') - var targetDocDir = ((q >= 0 && p < q + 2) || p < 0) ? null : str.slice(0, p + 1) - - if (targetDocDir) { - UI.acl.getACLorDefault($rdf.sym(targetDocDir), function (ok2, p22, targetDoc2, targetACLDoc2, defaultHolder2, defaultACLDoc2) { - if (ok2) { - prospectiveDefaultHolder = p22 ? targetDoc2 : defaultHolder2 - } - addDefaultButton(prospectiveDefaultHolder) - }) - } else { - addDefaultButton() - } - - box.addControlForDefaults = function () { - box.notice.textContent = 'Access to things within this folder:' - box.notice.style.cssText = 'font-size: 120%; color: black;' - var mergeButton = UI.widgets.clearElement(box.offer).appendChild(dom.createElement('button')) - mergeButton.innerHTML = '

Set default for folder contents to
just track the sharing for the folder

' - mergeButton.style.cssText = bigButtonStyle - mergeButton.addEventListener('click', function (e) { - delete box.defaultsDiffer - delete box.defByCombo - box.saveBack(function (ok, error) { - if (ok) { - box.removeControlForDefaults() - } else { - alert(error) - } - }) - }, false) - box.defaultsDiffer = true - box.defByCombo = ACLControlEditable(box, targetDoc, targetACLDoc, kb, {modify: true, doingDefaults: true}) - } - box.removeControlForDefaults = function () { - statusBlock.textContent = 'This is also the default for things in this folder.' - box.notice.textContent = 'Sharing for things within the folder currently tracks sharing for the folder.' - box.notice.style.cssText = 'font-size: 80%; color: #888;' - var splitButton = UI.widgets.clearElement(box.offer).appendChild(dom.createElement('button')) - splitButton.innerHTML = '

Set the sharing of folder contets
separately from the sharing for the folder

' - splitButton.style.cssText = bigButtonStyle - splitButton.addEventListener('click', function (e) { - box.addControlForDefaults() - statusBlock.textContent = '' - }) - while (box.divider.nextSibling) { - box.removeChild(box.divider.nextSibling) - } - statusBlock.textContent = 'This is now also the default for things in this folder.' - } - - box.mainByCombo = ACLControlEditable(box, targetDoc, targetACLDoc, kb, {modify: true}) // yes can edit - box.divider = box.appendChild(dom.createElement('tr')) - box.notice = box.divider.appendChild(dom.createElement('td')) - box.notice.style.cssText = 'font-size: 80%; color: #888;' - box.offer = box.divider.appendChild(dom.createElement('td')) - box.notice.setAttribute('colspan', '2') - - if (box.isContainer) { - var ac = UI.acl.readACL(targetDoc, targetACLDoc, kb) - var acd = UI.acl.readACL(targetDoc, targetACLDoc, kb, true) - box.defaultsDiffer = !UI.acl.sameACL(ac, acd) - console.log('Defaults differ ACL: ' + box.defaultsDiffer) - if (box.defaultsDiffer) { - box.addControlForDefaults() - } else { - box.removeControlForDefaults() - } - } - } // Not using defaults - } - }) - } - renderBox() - return table -} // ACLControlBox -// ends diff --git a/src/acl.js b/src/acl.js deleted file mode 100644 index 8d7b39105..000000000 --- a/src/acl.js +++ /dev/null @@ -1,411 +0,0 @@ -// Access control logic - -var acl = module.exports = {} - -var UI = { - acl: acl, - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - store: require('./store'), - widgets: require('./widgets') -} - -const utils = require('./utils') -const kb = UI.store - -// //////////////////////////////////// Solid ACL non-UI functions -// - -// Take the "defaltForNew" ACL and convert it into the equivlent ACL -// which the resource would have had. Return it as a new separate store. - -UI.acl.adoptACLDefault = function (doc, aclDoc, defaultResource, defaultACLdoc) { - var kb = UI.store - var ACL = UI.ns.acl - var isContainer = doc.uri.slice(-1) === '/' // Give default for all directories - var defaults = kb.each(undefined, ACL('defaultForNew'), defaultResource, defaultACLdoc) - var proposed = [] - defaults.map(function (da) { - proposed = proposed.concat(kb.statementsMatching(da, ACL('agent'), undefined, defaultACLdoc)) - .concat(kb.statementsMatching(da, ACL('agentClass'), undefined, defaultACLdoc)) - .concat(kb.statementsMatching(da, ACL('agentGroup'), undefined, defaultACLdoc)) - .concat(kb.statementsMatching(da, ACL('origin'), undefined, defaultACLdoc)) - .concat(kb.statementsMatching(da, ACL('originClass'), undefined, defaultACLdoc)) - .concat(kb.statementsMatching(da, ACL('mode'), undefined, defaultACLdoc)) - proposed.push($rdf.st(da, ACL('accessTo'), doc, defaultACLdoc)) // Suppose - if (isContainer) { // By default, make this apply to folder contents too - proposed.push($rdf.st(da, ACL('defaultForNew'), doc, defaultACLdoc)) - } - }) - var kb2 = $rdf.graph() // Potential - derived is kept apart - proposed.map(function (st) { - var move = function (sym) { - var y = defaultACLdoc.uri.length // The default ACL file - return $rdf.sym((sym.uri.slice(0, y) === defaultACLdoc.uri) - ? aclDoc.uri + sym.uri.slice(y) : sym.uri) - } - kb2.add(move(st.subject), move(st.predicate), move(st.object), $rdf.sym(aclDoc.uri)) - }) - - return kb2 -} - -// Read and canonicalize the ACL for x in aclDoc -// -// Accumulate the access rights which each agent or class has -// -UI.acl.readACL = function (x, aclDoc, kb, getDefaults) { - kb = kb || UI.store - var ns = UI.ns - var predicate = getDefaults ? ns.acl('defaultForNew') : ns.acl('accessTo') - var ACL = UI.ns.acl - var ac = {'agent': [], 'agentClass': [], 'agentGroup': [], 'origin': [], 'originClass': []} - var auths = kb.each(undefined, predicate, x) - for (var pred in {'agent': true, 'agentClass': true, 'agentGroup': true, 'origin': true, 'originClass': true}) { - auths.map(function (a) { - kb.each(a, ACL('mode')).map(function (mode) { - kb.each(a, ACL(pred)).map(function (agent) { - if (!ac[pred][agent.uri]) ac[pred][agent.uri] = [] - ac[pred][agent.uri][mode.uri] = a // could be "true" but leave pointer just in case - }) - }) - }) - } - return ac -} - -// Compare two ACLs -UI.acl.sameACL = function (a, b) { - var contains = function (a, b) { - for (var pred in {'agent': true, 'agentClass': true, 'agentGroup': true, 'origin': true, 'originClass': true}) { - if (a[pred]) { - for (var agent in a[pred]) { - for (var mode in a[pred][agent]) { - if (!b[pred][agent] || !b[pred][agent][mode]) { - return false - } - } - } - } - } - return true - } - return contains(a, b) && contains(b, a) -} - -// Union N ACLs -UI.acl.ACLunion = function (list) { - var b = list[0] - var a, ag - for (var k = 1; k < list.length; k++) { - ['agent', 'agentClass', 'agentGroup', 'origin', 'originClass'].map(function (pred) { - a = list[k] - if (a[pred]) { - for (ag in a[pred]) { - for (var mode in a[pred][ag]) { - if (!b[pred][ag]) b[pred][ag] = [] - b[pred][ag][mode] = true - } - } - } - }) - } - return b -} - -// Merge ACLs lists from things to form union - -UI.acl.loadUnionACL = function (subjectList, callbackFunction) { - var aclList = [] - var doList = function (list) { - if (list.length) { - var doc = list.shift().doc() - UI.acl.getACLorDefault(doc, function (ok, p2, targetDoc, targetACLDoc, defaultHolder, defaultACLDoc) { - var defa = !p2 - if (!ok) return callbackFunction(ok, targetACLDoc) - aclList.push((defa) ? UI.widgets.readACL(defaultHolder, defaultACLDoc) - : UI.widgets.readACL(targetDoc, targetACLDoc)) - doList(list.slice(1)) - }) - } else { // all gone - callbackFunction(true, UI.widgets.ACLunion(aclList)) - } - } - doList(subjectList) -} - -// Represents these as a RDF graph by combination of modes -// -// Each agent can only be in one place in this model, one combination of modes. -// Combos are like full control, read append, read only etc. -// -UI.acl.ACLbyCombination = function (ac) { - var byCombo = []; - ['agent', 'agentClass', 'agentGroup', 'origin', 'originClass'].map(function (pred) { - for (var agent in ac[pred]) { - var combo = [] - for (var mode in ac[pred][agent]) { - combo.push(mode) - } - combo.sort() - combo = combo.join('\n') - if (!byCombo[combo]) byCombo[combo] = [] - byCombo[combo].push([pred, agent]) - } - }) - return byCombo -} - -// Write ACL graph to store from AC -// -UI.acl.makeACLGraph = function (kb, x, ac, aclDoc) { - var byCombo = UI.acl.ACLbyCombination(ac) - return UI.acl.makeACLGraphbyCombo(kb, x, byCombo, aclDoc) -} - -// Write ACL graph to store from combo -// -UI.acl.makeACLGraphbyCombo = function (kb, x, byCombo, aclDoc, main, defa) { - var ACL = UI.ns.acl - for (var combo in byCombo) { - var modeURIs = combo.split('\n') - var short = modeURIs.map(function (u) { return u.split('#')[1] }).join('') - if (defa && !main) short += 'Default' // don't muddle authorizations - var a = kb.sym(aclDoc.uri + '#' + short) - kb.add(a, UI.ns.rdf('type'), ACL('Authorization'), aclDoc) - if (main) { - kb.add(a, ACL('accessTo'), x, aclDoc) - } - if (defa) { - kb.add(a, ACL('defaultForNew'), x, aclDoc) - } - for (var i = 0; i < modeURIs.length; i++) { - kb.add(a, ACL('mode'), kb.sym(modeURIs[i]), aclDoc) - } - var pairs = byCombo[combo] - for (i = 0; i < pairs.length; i++) { - var pred = pairs[i][0] - var ag = pairs[i][1] - kb.add(a, ACL(pred), kb.sym(ag), aclDoc) - } - } -} - -// Debugguing short strings for dumping ACL -// and who knows maybe in the UI -// -UI.acl.ACLToString = function (ac) { - return UI.widgets.comboToString( - UI.widgets.ACLbyCombination(ac)) -} -UI.acl.comboToString = function (byCombo) { - var str = '' - for (var combo in byCombo) { - var modeURIs = combo.split('\n') - var initials = modeURIs.map(function (u) { return u.split('#')[1][0] }).join('') - str += initials + ':' - var pairs = byCombo[combo] - for (var i = 0; i < pairs.length; i++) { - var pred = pairs[i][0] - var ag = $rdf.sym(pairs[i][1]) - str += (pred === 'agent') ? '@' : '' - str += (ag.sameTerm(UI.ns.foaf('Agent')) ? '*' - : utils.label(ag)) - if (i < pairs.length - 1) str += ',' - } - str += ';' - } - return '{' + str.slice(0, -1) + '}' // drop extra semicolon -} - -// Write ACL graph to string -// -UI.acl.makeACLString = function (x, ac, aclDoc) { - var kb = $rdf.graph() - UI.widgets.makeACLGraph(kb, x, ac, aclDoc) - return $rdf.serialize(aclDoc, kb, aclDoc.uri, 'text/turtle') -} - -// Write ACL graph to web -// -UI.acl.putACLObject = function (kb, x, ac, aclDoc, callbackFunction) { - var byCombo = UI.widgets.ACLbyCombination(ac) - return UI.widgets.putACLbyCombo(kb, x, byCombo, aclDoc, callbackFunction) -} - -// Write ACL graph to web from combo -// -UI.acl.putACLbyCombo = function (kb, x, byCombo, aclDoc, callbackFunction) { - var kb2 = $rdf.graph() - UI.widgets.makeACLGraphbyCombo(kb2, x, byCombo, aclDoc, true) - - // var str = UI.widgets.makeACLString = function(x, ac, aclDoc) - kb.updater.put(aclDoc, kb2.statementsMatching(undefined, undefined, undefined, aclDoc), - 'text/turtle', function (uri, ok, message) { - if (!ok) { - callbackFunction(ok, message) - } else { - kb.fetcher.unload(aclDoc) - UI.widgets.makeACLGraphbyCombo(kb, x, byCombo, aclDoc, true) - kb.fetcher.requested[aclDoc.uri] = 'done' // missing: save headers - callbackFunction(ok) - } - }) -} - -// Fix the ACl for an individual card as a function of the groups it is in -// -// All group files must be loaded first -// - -UI.acl.fixIndividualCardACL = function (person, log, callbackFunction) { - var groups = UI.store.each(undefined, UI.ns.vcard('hasMember'), person) - // var doc = person.doc() - if (groups) { - UI.widgets.fixIndividualACL(person, groups, log, callbackFunction) - } else { - log('This card is in no groups') - callbackFunction(true) // fine, no requirements to access. default should be ok - } -// @@ if no groups, then use default for People container or the book top container.? -} - -UI.acl.fixIndividualACL = function (item, subjects, log, callbackFunction) { - log = log || console.log - var doc = item.doc() - UI.acl.getACLorDefault(doc, function (ok, exists, targetDoc, targetACLDoc, defaultHolder, defaultACLDoc) { - if (!ok) return callbackFunction(false, targetACLDoc) // ie message - var ac = (exists) ? UI.widgets.readACL(targetDoc, targetACLDoc) : UI.widgets.readACL(defaultHolder, defaultACLDoc) - UI.widgets.loadUnionACL(subjects, function (ok, union) { - if (!ok) return callbackFunction(false, union) - if (UI.widgets.sameACL(union, ac)) { - log('Nice - same ACL. no change ' + utils.label(item) + ' ' + doc) - } else { - log('Group ACLs differ for ' + utils.label(item) + ' ' + doc) - - // log("Group ACLs: " + UI.widgets.makeACLString(targetDoc, union, targetACLDoc)) - // log((exists ? "Previous set" : "Default") + " ACLs: " + - // UI.widgets.makeACLString(targetDoc, ac, targetACLDoc)) - - UI.widgets.putACLObject(UI.store, targetDoc, union, targetACLDoc, callbackFunction) - } - }) - }) -} - -UI.acl.setACL = function (docURI, aclText, callbackFunction) { - var aclDoc = kb.any(kb.sym(docURI), - kb.sym('http://www.iana.org/assignments/link-relations/acl')) // @@ check that this get set by web.js - if (aclDoc) { // Great we already know where it is - kb.fetcher.webOperation('PUT', aclDoc.uri, {data: aclText, contentType: 'text/turtle'}).then(callbackFunction) // @@@ check params - } else { - kb.fetcher.nowOrWhenFetched(docURI, undefined, function (ok, body) { - if (!ok) return callbackFunction(ok, 'Gettting headers for ACL: ' + body) - var aclDoc = kb.any(kb.sym(docURI), - kb.sym('http://www.iana.org/assignments/link-relations/acl')) // @@ check that this get set by web.js - if (!aclDoc) { - // complainIfBad(false, "No Link rel=ACL header for " + docURI) - callbackFunction(false, 'No Link rel=ACL header for ' + docURI) - } else { - kb.fetcher.webOperation('PUT', aclDoc.uri, {data: aclText, contentType: 'text/turtle'}).then(callbackFunction) - } - }) - } -} - -// Get ACL file or default if necessary -// -// callbackFunction(true, true, doc, aclDoc) The ACL did exist -// callbackFunction(true, false, doc, aclDoc, defaultHolder, defaultACLDoc) ACL file did not exist but a default did -// callbackFunction(false, false, status, message) error getting original -// callbackFunction(false, true, status, message) error getting defualt - -UI.acl.getACLorDefault = function (doc, callbackFunction) { - UI.acl.getACL(doc, function (ok, status, aclDoc, message) { - var kb = UI.store - var ACL = UI.ns.acl - if (!ok) return callbackFunction(false, false, status, message) - - // Recursively search for the ACL file which gives default access - var tryParent = function (uri) { - if (uri.slice(-1) === '/') { - uri = uri.slice(0, -1) - } - var right = uri.lastIndexOf('/') - var left = uri.indexOf('/', uri.indexOf('//') + 2) - uri = uri.slice(0, right + 1) - var doc2 = $rdf.sym(uri) - UI.acl.getACL(doc2, function (ok, status, defaultACLDoc) { - if (!ok) { - return callbackFunction(false, true, status, '( No ACL pointer ' + uri + ' ' + status + ')' + defaultACLDoc) - } else if (status === 403) { - return callbackFunction(false, true, status, '( default ACL file FORBIDDEN. Stop.' + uri + ')') - } else if (status === 404) { - if (left >= right) { - return callbackFunction(false, true, 499, 'Nothing to hold a default') - } else { - tryParent(uri) - } - } else if (status !== 200) { - return callbackFunction(false, true, status, "Error status '" + status + "' searching for default for " + doc2) - } else { // 200 - // statusBlock.textContent += (" ACCESS set at " + uri + ". End search.") - var defaults = kb.each(undefined, ACL('defaultForNew'), kb.sym(uri), defaultACLDoc) - if (!defaults.length) { - tryParent(uri) // Keep searching - } else { - var defaultHolder = kb.sym(uri) - callbackFunction(true, false, doc, aclDoc, defaultHolder, defaultACLDoc) - } - } - }) - } // tryParent - - if (!ok) { - return callbackFunction(false, false, status, - 'Error accessing Access Control information for ' + doc + ') ' + message) - } else if (status === 404) { - tryParent(doc.uri) // @@ construct default one - the server should do that - } else if (status === 403) { - return callbackFunction(false, false, status, '(Sharing not available to you)' + message) - } else if (status !== 200) { - return callbackFunction(false, false, status, 'Error ' + status + - ' accessing Access Control information for ' + doc + ': ' + message) - } else { // 200 - return callbackFunction(true, true, doc, aclDoc) - } - }) // Call to getACL -} // getACLorDefault - -// Calls back (ok, status, acldoc, message) -// -// (false, 900, errormessage) no link header -// (true, 403, documentSymbol, fileaccesserror) not authorized -// (true, 404, documentSymbol, fileaccesserror) if does not exist -// (true, 200, documentSymbol) if file exitss and read OK -// -UI.acl.getACL = function (doc, callbackFunction) { - UI.store.fetcher.nowOrWhenFetched(doc, undefined, function (ok, body) { - if (!ok) return callbackFunction(ok, "Can't get headers to find ACL for " + doc + ': ' + body) - var kb = UI.store - var aclDoc = kb.any(doc, - kb.sym('http://www.iana.org/assignments/link-relations/acl')) // @@ check that this get set by web.js - if (!aclDoc) { - callbackFunction(false, 900, 'No Link rel=ACL header for ' + doc) - } else { - if (UI.store.fetcher.nonexistent[aclDoc.uri]) { - return callbackFunction(true, 404, aclDoc, 'ACL file ' + aclDoc + ' does not exist.') - } - UI.store.fetcher.nowOrWhenFetched(aclDoc, undefined, function (ok, message, response) { - if (!ok) { - callbackFunction(true, response.status, aclDoc, "Can't read Access Control File " + aclDoc + ': ' + message) - } else { - callbackFunction(true, 200, aclDoc) - } - }) - } - }) -} - -// ///////////////////////////////////////// End of ACL stuff diff --git a/src/acl/access-controller.ts b/src/acl/access-controller.ts new file mode 100644 index 000000000..146567667 --- /dev/null +++ b/src/acl/access-controller.ts @@ -0,0 +1,261 @@ +/** + * Contains the [[AccessController]] class + * @packageDocumentation + */ + +import { adoptACLDefault, getProspectiveHolder, makeACLGraphbyCombo, sameACL } from './acl' +import { fetcher, graph, NamedNode, UpdateManager } from 'rdflib' +import { AccessGroups } from './access-groups' +import { DataBrowserContext } from 'pane-registry' +import { shortNameForFolder } from './acl-control' +import * as utils from '../utils' +import * as debug from '../debug' +import { style } from '../style' + +/** + * Rendered HTML component used in the databrowser's Sharing pane. + */ +export class AccessController { + public mainCombo: AccessGroups + public defaultsCombo: AccessGroups | null + private readonly isContainer: boolean + private defaultsDiffer: boolean + private readonly rootElement: HTMLDivElement + private isUsingDefaults: boolean + + constructor ( + public subject: NamedNode, + public noun: string, + public context: DataBrowserContext, + private statusElement: HTMLElement, + public targetIsProtected: boolean, + private targetDoc: NamedNode, + private targetACLDoc: NamedNode, + private defaultHolder: NamedNode | null, + private defaultACLDoc: NamedNode | null, + private prospectiveDefaultHolder: NamedNode | undefined, + public store, + public dom: HTMLDocument + ) { + this.rootElement = dom.createElement('div') + this.rootElement.setAttribute('style', style.aclGroupContent) + this.isContainer = targetDoc.uri.slice(-1) === '/' // Give default for all directories + if (defaultHolder && defaultACLDoc) { + this.isUsingDefaults = true + const aclDefaultStore = adoptACLDefault(this.targetDoc, targetACLDoc, defaultHolder, defaultACLDoc) + this.mainCombo = new AccessGroups(targetDoc, targetACLDoc, this, aclDefaultStore, { defaults: this.isContainer }) + this.defaultsCombo = null + this.defaultsDiffer = false + } else { + this.isUsingDefaults = false + this.mainCombo = new AccessGroups(targetDoc, targetACLDoc, this, store) + this.defaultsCombo = new AccessGroups(targetDoc, targetACLDoc, this, store, { defaults: this.isContainer }) + this.defaultsDiffer = !sameACL(this.mainCombo.aclMap, this.defaultsCombo.aclMap) + } + } + + public get isEditable (): boolean { + return !this.isUsingDefaults + } + + public render (): HTMLElement { + this.rootElement.innerHTML = '' + if (this.isUsingDefaults) { + this.renderStatus(`The sharing for this ${this.noun} is the default for folder `) + if (this.defaultHolder) { + const defaultHolderLink = this.statusElement.appendChild(this.dom.createElement('a')) + defaultHolderLink.href = this.defaultHolder.uri + defaultHolderLink.innerText = shortNameForFolder(this.defaultHolder) + } + } else if (!this.defaultsDiffer && this.isContainer) { + this.renderStatus('This is also the default for things in this folder.') + } else { + this.renderStatus('') + } + this.rootElement.appendChild(this.mainCombo.render()) + if (this.defaultsCombo && this.defaultsDiffer) { + this.rootElement.appendChild(this.renderRemoveDefaultsController()) + this.rootElement.appendChild(this.defaultsCombo.render()) + } else if (this.isEditable && this.isContainer) { + this.rootElement.appendChild(this.renderAddDefaultsController()) + } + if (!this.targetIsProtected && this.isUsingDefaults) { + this.rootElement.appendChild(this.renderAddAclsController()) + } else if (!this.targetIsProtected) { + this.rootElement.appendChild(this.renderRemoveAclsController()) + } + return this.rootElement + } + + private renderRemoveAclsController (): HTMLElement { + const useDefaultButton = this.dom.createElement('button') + useDefaultButton.innerText = `Remove custom sharing settings for this ${this.noun} -- just use default${this.prospectiveDefaultHolder ? ` for ${utils.label(this.prospectiveDefaultHolder)}` : ''}` + useDefaultButton.setAttribute('style', style.bigButton) + useDefaultButton.addEventListener('click', () => this.removeAcls() + .then(() => this.render()) + .catch(error => this.renderStatus(error))) + return useDefaultButton + } + + private renderAddAclsController (): HTMLElement { + const addAclButton = this.dom.createElement('button') + addAclButton.innerText = `Set specific sharing for this ${this.noun}` + addAclButton.setAttribute('style', style.bigButton) + addAclButton.addEventListener('click', () => this.addAcls() + .then(() => this.render()) + .catch(error => this.renderStatus(error))) + return addAclButton + } + + private renderAddDefaultsController (): HTMLElement { + const containerElement = this.dom.createElement('div') + containerElement.setAttribute('style', style.defaultsController) + + const noticeElement = containerElement.appendChild(this.dom.createElement('div')) + noticeElement.innerText = 'Sharing for things within the folder currently tracks sharing for the folder.' + noticeElement.setAttribute('style', style.defaultsControllerNotice) + + const button = containerElement.appendChild(this.dom.createElement('button')) + button.innerText = 'Set the sharing of folder contents separately from the sharing for the folder' + button.setAttribute('style', style.bigButton) + button.addEventListener('click', () => this.addDefaults() + .then(() => this.render())) + return containerElement + } + + private renderRemoveDefaultsController (): HTMLElement { + const containerElement = this.dom.createElement('div') + containerElement.setAttribute('style', style.defaultsController) + + const noticeElement = containerElement.appendChild(this.dom.createElement('div')) + noticeElement.innerText = 'Access to things within this folder:' + noticeElement.setAttribute('style', style.defaultsControllerNotice) + + const button = containerElement.appendChild(this.dom.createElement('button')) + button.innerText = 'Set default for folder contents to just track the sharing for the folder' + button.setAttribute('style', style.bigButton) + button.addEventListener('click', () => this.removeDefaults() + .then(() => this.render()) + .catch(error => this.renderStatus(error))) + return containerElement + } + + public renderTemporaryStatus (message: string): void { + // @@ TODO Introduce better system for error notification to user https://github.com/solidos/mashlib/issues/87 + this.statusElement.setAttribute('style', style.aclControlBoxStatusRevealed) + this.statusElement.innerText = message + this.statusElement.setAttribute('style', style.temporaryStatusInit) + setTimeout(() => { + this.statusElement.setAttribute('style', style.temporaryStatusEnd) + }) + setTimeout(() => { + this.statusElement.innerText = '' + }, 5000) + } + + public renderStatus (message: string): void { + // @@ TODO Introduce better system for error notification to user https://github.com/solidos/mashlib/issues/87 + if (!message) { + this.statusElement.setAttribute('style', style.aclControlBoxStatusRevealed) + } + this.statusElement.innerText = message + } + + private async addAcls (): Promise { + if (!this.defaultHolder || !this.defaultACLDoc) { + const message = 'Unable to find defaults to copy' + debug.error(message) + return Promise.reject(message) + } + const aclGraph = adoptACLDefault(this.targetDoc, this.targetACLDoc, this.defaultHolder, this.defaultACLDoc) + aclGraph.statements.forEach(st => this.store.add(st.subject, st.predicate, st.object, this.targetACLDoc)) + try { + await this.store.fetcher.putBack(this.targetACLDoc) + this.isUsingDefaults = false + return Promise.resolve() + } catch (error) { + const message = ` Error writing back access control file! ${error}` + debug.error(message) + return Promise.reject(message) + } + } + + private async addDefaults (): Promise { + this.defaultsCombo = new AccessGroups(this.targetDoc, this.targetACLDoc, this, this.store, { defaults: true }) + this.defaultsDiffer = true + } + + private async removeAcls (): Promise { + try { + await this.store.fetcher.delete(this.targetACLDoc.uri, {}) + this.isUsingDefaults = true + try { + this.prospectiveDefaultHolder = await getProspectiveHolder(this.targetDoc.uri) + } catch (error) { + // No need to show this error in status, but good to warn about it in console + debug.warn(error) + } + } catch (error) { + const message = `Error deleting access control file: ${this.targetACLDoc}: ${error}` + debug.error(message) + return Promise.reject(message) + } + } + + private async removeDefaults (): Promise { + const fallbackCombo = this.defaultsCombo + try { + this.defaultsCombo = null + this.defaultsDiffer = false + await this.save() + } catch (error) { + this.defaultsCombo = fallbackCombo + this.defaultsDiffer = true + debug.error(error) + return Promise.reject(error) + } + } + + public save (): Promise { + // build graph + const newAClGraph = graph() + if (!this.isContainer) { + makeACLGraphbyCombo(newAClGraph, this.targetDoc, this.mainCombo.byCombo, this.targetACLDoc, true) + } else if (this.defaultsCombo && this.defaultsDiffer) { + // Pair of controls + makeACLGraphbyCombo(newAClGraph, this.targetDoc, this.mainCombo.byCombo, this.targetACLDoc, true) + makeACLGraphbyCombo(newAClGraph, this.targetDoc, this.defaultsCombo.byCombo, this.targetACLDoc, false, true) + } else { + // Linked controls + makeACLGraphbyCombo(newAClGraph, this.targetDoc, this.mainCombo.byCombo, this.targetACLDoc, true, true) + } + + // add authenticated fetcher + newAClGraph.fetcher = fetcher(newAClGraph, { fetch: this.store.fetcher._fetch }) + const updater = newAClGraph.updater || new UpdateManager(newAClGraph) + + // save ACL resource + return new Promise((resolve, reject) => { + updater.put( + this.targetACLDoc, + newAClGraph.statementsMatching(undefined, undefined, undefined, this.targetACLDoc), + 'text/turtle', + (uri, ok, message) => { + if (!ok) { + return reject(new Error(`ACL file save failed: ${message}`)) + } + this.store.fetcher.unload(this.targetACLDoc) + this.store.add(newAClGraph.statements) + this.store.fetcher.requested[this.targetACLDoc.uri] = 'done' // missing: save headers + this.mainCombo.store = this.store + if (this.defaultsCombo) { + this.defaultsCombo.store = this.store + } + this.defaultsDiffer = !!this.defaultsCombo && !sameACL(this.mainCombo.aclMap, this.defaultsCombo.aclMap) + debug.log('ACL modification: success!') + resolve() + } + ) + }) + } +} diff --git a/src/acl/access-groups.ts b/src/acl/access-groups.ts new file mode 100644 index 000000000..695473750 --- /dev/null +++ b/src/acl/access-groups.ts @@ -0,0 +1,374 @@ +/** + * Contains the [[AccessGroups]] + * and [[AccessGroupsOptions]] classes + * @packageDocumentation + */ + +import { NamedNode, sym, Store } from 'rdflib' +import { ACLbyCombination, readACL } from './acl' +import * as widgets from '../widgets' +import ns from '../ns' +import { AccessController } from './access-controller' +import { AgentMapMap, ComboList, PartialAgentTriple } from './types' +import { AddAgentButtons } from './add-agent-buttons' +import * as debug from '../debug' +import { style } from '../style' + +const ACL = ns.acl + +const COLLOQUIAL = { + 13: 'Owners', + 9: 'Owners (write locked)', + 5: 'Editors', + 3: 'Posters', + 2: 'Submitters', + 1: 'Viewers' +} + +const RECOMMENDED = { + 13: true, + 5: true, + 3: true, + 2: true, + 1: true +} + +const EXPLANATION = { + 13: 'can read, write, and control sharing.', + 9: 'can read and control sharing, currently write-locked.', + 5: 'can read and change information', + 3: 'can add new information, and read but not change existing information', + 2: 'can add new information but not read any', + 1: 'can read but not change information' +} + +/** + * Type for the options parameter of [[AccessGroups]] + */ +export interface AccessGroupsOptions { + defaults?: boolean +} + +/** + * Renders the table of Owners, Editors, Posters, Submitters, Viewers + * for https://github.com/solidos/userguide/blob/main/views/sharing/userguide.md + */ +export class AccessGroups { + private readonly defaults: boolean + public byCombo: ComboList + public aclMap: AgentMapMap + private readonly addAgentButton: AddAgentButtons + private readonly rootElement: HTMLElement + private _store: Store // @@ was LiveStore but does not need to be connected to web + + constructor ( + private doc: NamedNode, + private aclDoc: NamedNode, + public controller: AccessController, + store: Store, // @@ was LiveStore + private _options: AccessGroupsOptions = {} + ) { + this.defaults = this._options.defaults || false + this._store = store + this.aclMap = readACL(doc, aclDoc, store, this.defaults) + this.byCombo = ACLbyCombination(this.aclMap) + this.addAgentButton = new AddAgentButtons(this) + this.rootElement = this.controller.dom.createElement('div') + this.rootElement.setAttribute('style', style.accessGroupList) + } + + public get store () { + return this._store + } + + public set store (store) { + this._store = store + this.aclMap = readACL(this.doc, this.aclDoc, store, this.defaults) + this.byCombo = ACLbyCombination(this.aclMap) + } + + public render (): HTMLElement { + this.rootElement.innerHTML = '' + this.renderGroups().forEach(group => this.rootElement.appendChild(group)) + if (this.controller.isEditable) { + this.rootElement.appendChild(this.addAgentButton.render()) + } + return this.rootElement + } + + private renderGroups (): HTMLElement[] { + const groupElements: HTMLElement[] = [] + for (let comboIndex = 15; comboIndex > 0; comboIndex--) { + const combo = kToCombo(comboIndex) + if ((this.controller.isEditable && RECOMMENDED[comboIndex]) || this.byCombo[combo]) { + groupElements.push(this.renderGroup(comboIndex, combo)) + } + } + return groupElements + } + + private renderGroup (comboIndex: number, combo: string): HTMLElement { + const groupRow = this.controller.dom.createElement('div') + groupRow.setAttribute('style', style.accessGroupListItem) + widgets.makeDropTarget(groupRow, (uris) => this.handleDroppedUris(uris, combo) + .then(() => this.controller.render()) + .catch(error => this.controller.renderStatus(error))) + const groupColumns = this.renderGroupElements(comboIndex, combo) + groupColumns.forEach(column => groupRow.appendChild(column)) + return groupRow + } + + private renderGroupElements (comboIndex, combo): HTMLElement[] { + const groupNameColumn = this.controller.dom.createElement('div') + groupNameColumn.setAttribute('style', style.group) + if (this.controller.isEditable) { + switch (comboIndex) { + case 1: + groupNameColumn.setAttribute('style', style.group1) + break + case 2: + groupNameColumn.setAttribute('style', style.group2) + break + case 3: + groupNameColumn.setAttribute('style', style.group3) + break + case 5: + groupNameColumn.setAttribute('style', style.group5) + break + case 9: + groupNameColumn.setAttribute('style', style.group9) + break + case 13: + groupNameColumn.setAttribute('style', style.group13) + break + default: + groupNameColumn.setAttribute('style', style.group) + } + } + groupNameColumn.innerText = COLLOQUIAL[comboIndex] || ktToList(comboIndex) + + const groupAgentsColumn = this.controller.dom.createElement('div') + groupAgentsColumn.setAttribute('style', style.group) + if (this.controller.isEditable) { + switch (comboIndex) { + case 1: + groupAgentsColumn.setAttribute('style', style.group1) + break + case 2: + groupAgentsColumn.setAttribute('style', style.group2) + break + case 3: + groupAgentsColumn.setAttribute('style', style.group3) + break + case 5: + groupAgentsColumn.setAttribute('style', style.group5) + break + case 9: + groupAgentsColumn.setAttribute('style', style.group9) + break + case 13: + groupAgentsColumn.setAttribute('style', style.group13) + break + default: + groupAgentsColumn.setAttribute('style', style.group) + } + } + const groupAgentsTable = groupAgentsColumn.appendChild(this.controller.dom.createElement('table')) + const combos = this.byCombo[combo] || [] + combos + .map(([pred, obj]) => this.renderAgent(groupAgentsTable, combo, pred, obj)) + .forEach(agentElement => groupAgentsTable.appendChild(agentElement)) + + const groupDescriptionElement = this.controller.dom.createElement('div') + groupDescriptionElement.setAttribute('style', style.group) + if (this.controller.isEditable) { + switch (comboIndex) { + case 1: + groupDescriptionElement.setAttribute('style', style.group1) + break + case 2: + groupDescriptionElement.setAttribute('style', style.group2) + break + case 3: + groupDescriptionElement.setAttribute('style', style.group3) + break + case 5: + groupDescriptionElement.setAttribute('style', style.group5) + break + case 9: + groupDescriptionElement.setAttribute('style', style.group9) + break + case 13: + groupDescriptionElement.setAttribute('style', style.group13) + break + default: + groupDescriptionElement.setAttribute('style', style.group) + } + } + groupDescriptionElement.innerText = EXPLANATION[comboIndex] || 'Unusual combination' + + return [groupNameColumn, groupAgentsColumn, groupDescriptionElement] + } + + private renderAgent (groupAgentsTable, combo, pred, obj): HTMLElement { + const personRow = widgets.personTR(this.controller.dom, ACL(pred), sym(obj), this.controller.isEditable + ? { + deleteFunction: () => this.deleteAgent(combo, pred, obj) + .then(() => groupAgentsTable.removeChild(personRow)) + .catch(error => this.controller.renderStatus(error)) + } + : {}) + return personRow + } + + private async deleteAgent (combo, pred, obj): Promise { + const combos = this.byCombo[combo] || [] + const comboToRemove = combos.find(([comboPred, comboObj]) => comboPred === pred && comboObj === obj) + if (comboToRemove) { + combos.splice(combos.indexOf(comboToRemove), 1) + } + await this.controller.save() + } + + public async addNewURI (uri: string): Promise { + await this.handleDroppedUri(uri, kToCombo(1)) + await this.controller.save() + } + + private async handleDroppedUris (uris: string[], combo: string): Promise { + try { + await Promise.all(uris.map(uri => this.handleDroppedUri(uri, combo))) + await this.controller.save() + } catch (error) { + return Promise.reject(error) + } + } + + private async handleDroppedUri (uri: string, combo: string, secondAttempt: boolean = false): Promise { + const agent = findAgent(uri, this.store) // eg 'agent', 'origin', agentClass' + const thing = sym(uri) + if (!agent && !secondAttempt) { + debug.log(` Not obvious: looking up dropped thing ${thing}`) + try { + await this._store?.fetcher?.load(thing.doc()) + } catch (error) { + const message = `Ignore error looking up dropped thing: ${error}` + debug.error(message) + return Promise.reject(new Error(message)) + } + return this.handleDroppedUri(uri, combo, true) + } else if (!agent) { + const detectedTypes = Object.keys(this.store.findTypeURIs(thing)) + const typeDetails = detectedTypes.length > 0 + ? `Detected RDF types: ${detectedTypes.join(', ')}` + : 'No RDF type was detected for this URI.' + const error = + `Error: Failed to add access target: ${uri} is not a recognized ACL target type.` + + ' Expected one of: vcard:WebID, vcard:Group, foaf:Person, foaf:Agent, solid:AppProvider, solid:AppProviderClass, or recognized ACL classes.' + + ' Hint: try dropping a WebID profile URI, a vcard:Group URI, or a web app origin.' + + typeDetails + debug.error(error) + return Promise.reject(new Error(error)) + } + this.setACLCombo(combo, uri, agent, this.controller.subject) + } + + private setACLCombo (combo: string, uri: string, res: PartialAgentTriple, subject: NamedNode): void { + if (!(combo in this.byCombo)) { + this.byCombo[combo] = [] + } + this.removeAgentFromCombos(uri) // Combos are mutually distinct + this.byCombo[combo].push([res.pred, res.obj.uri]) + debug.log(`ACL: setting access to ${subject} by ${res.pred}: ${res.obj}`) + } + + private removeAgentFromCombos (uri: string): void { + for (let k = 0; k < 16; k++) { + const combos = this.byCombo[kToCombo(k)] + if (combos) { + for (let i = 0; i < combos.length; i++) { + while (i < combos.length && combos[i][1] === uri) { + combos.splice(i, 1) + } + } + } + } + } +} + +function kToCombo (k: number): string { + const y = ['Read', 'Append', 'Write', 'Control'] + const combo: string[] = [] + for (let i = 0; i < 4; i++) { + if (k & (1 << i)) { + combo.push('http://www.w3.org/ns/auth/acl#' + y[i]) + } + } + combo.sort() + return combo.join('\n') +} + +function ktToList (k: number): string { + let list = '' + const y = ['Read', 'Append', 'Write', 'Control'] + for (let i = 0; i < 4; i++) { + if (k & (1 << i)) { + list += y[i] + } + } + return list +} + +function findAgent (uri, kb): PartialAgentTriple | null { + const obj = sym(uri) + const types = kb.findTypeURIs(obj) + for (const ty in types) { + debug.log(' drop object type includes: ' + ty) + } + // An Origin URI is one like https://fred.github.io eith no trailing slash + if (uri.startsWith('http') && uri.split('/').length === 3) { + // there is no third slash + return { pred: 'origin', obj } // The only way to know an origin alas + } + // @@ This is an almighty kludge needed because drag and drop adds extra slashes to origins + if ( + uri.startsWith('http') && + uri.split('/').length === 4 && + uri.endsWith('/') + ) { + // there IS third slash + debug.log('Assuming final slash on dragged origin URI was unintended!') + return { pred: 'origin', obj: sym(uri.slice(0, -1)) } // Fix a URI where the drag and drop system has added a spurious slash + } + + if (ns.vcard('WebID').uri in types) return { pred: 'agent', obj } + + if (ns.vcard('Group').uri in types) { + return { pred: 'agentGroup', obj } // @@ note vcard membership not RDFs + } + if ( + obj.sameTerm(ns.foaf('Agent')) || + obj.sameTerm(ns.acl('AuthenticatedAgent')) || // AuthenticatedAgent + obj.sameTerm(ns.rdf('Resource')) || + obj.sameTerm(ns.owl('Thing')) + ) { + return { pred: 'agentClass', obj } + } + if ( + ns.vcard('Individual').uri in types || + ns.foaf('Person').uri in types || + ns.foaf('Agent').uri in types + ) { + const pref = kb.any(obj, ns.foaf('preferredURI')) + if (pref) return { pred: 'agent', obj: sym(pref) } + return { pred: 'agent', obj } + } + if (ns.solid('AppProvider').uri in types) { + return { pred: 'origin', obj } + } + if (ns.solid('AppProviderClass').uri in types) { + return { pred: 'originClass', obj } + } + debug.log(' Triage fails for ' + uri) + return null +} diff --git a/src/acl/acl-control.ts b/src/acl/acl-control.ts new file mode 100644 index 000000000..8bc646144 --- /dev/null +++ b/src/acl/acl-control.ts @@ -0,0 +1,216 @@ +/** + * Functions for rendering the ACL User Interface. + * See https://github.com/solidos/userguide/blob/main/views/sharing/userguide.md#view + * for a screenshot. + * @packageDocumentation + */ + +import ns from '../ns' +import * as utils from '../utils' +import { getACLorDefault, getProspectiveHolder } from './acl' +import { Store, NamedNode } from 'rdflib' +import { DataBrowserContext } from 'pane-registry' +import { AccessController } from './access-controller' +import { style } from '../style' +import { log, warn } from '../debug' + +let global: Window = window +const preventBrowserDropEventsDone = Symbol('prevent double triggering of drop event') + +/** + * See https://coshx.com/preventing-drag-and-drop-disasters-with-a-chrome-userscript + * Without this dropping anything onto a browser page will cause chrome etc to jump to diff page + * throwing away all the user's work. + * + * In apps which may use drag and drop, this utility takes care of the fact + * by default in a browser, an uncaught user drop into a browser window + * causes the browser to lose all its work in that window and navigate to another page + * + * @param document The DOM + * @returns void + */ +export function preventBrowserDropEvents (document: HTMLDocument): void { + log('preventBrowserDropEvents called.') + if (typeof global !== 'undefined') { + if (global[preventBrowserDropEventsDone]) return + global[preventBrowserDropEventsDone] = true + } + + document.addEventListener('drop', handleDrop, false) + document.addEventListener('dragenter', preventDrag, false) + document.addEventListener('dragover', preventDrag, false) +} + +/** @internal */ +export function preventDrag (e) { + e.stopPropagation() + e.preventDefault() +} + +/** @internal */ +export function handleDrop (e) { + if (e.dataTransfer.files.length > 0) { + if ( + !global.confirm('Are you sure you want to drop this file here? (Cancel opens it in a new tab)') + ) { + e.stopPropagation() + e.preventDefault() + log('@@@@ document-level DROP suppressed: ' + e.dataTransfer.dropEffect + ) + } + } +} + +/** + * Get a folder's own filename in the directory tree. Also works for + * domain names; the URL protocol ('https://') acts as the tree root + * with short name '/' (see also test/unit/acl/acl-control.test.ts). + * + * ```typescript + * shortNameForFolder($rdf.namedNode('http://example.com/some/folder/')) + * // 'folder' + * + * shortNameForFolder($rdf.namedNode('http://example.com/some/folder')) + * // 'folder' + * + * shortNameForFolder($rdf.namedNode('http://example.com/')) + * // 'example.com' + * + * shortNameForFolder($rdf.namedNode('http://example.com')) + * // 'example.com' + * + * shortNameForFolder($rdf.namedNode('http://')) + * // '/' + * ``` + * + * It also works with relative URLs: + * ```typescript + * shortNameForFolder($rdf.namedNode('../folder/')) + * // 'folder' + * ``` + * + * @param x RDF Node for the folder URL + * @returns Short name for the folder + */ +export function shortNameForFolder (x: NamedNode): string { + let str = x.uri + + // Strip the trailing slash + if (str.slice(-1) === '/') { + str = str.slice(0, -1) + } + + // Remove the path if present, keeping only the part + // after the last slash. + const slash = str.lastIndexOf('/') + if (slash >= 0) { + str = str.slice(slash + 1) + } + // Return the folder's filename, or '/' if nothing found + // (but see https://github.com/solidos/solid-ui/issues/196 + // regarding whether this happens at the domain root or + // not) + return str || '/' +} + +/** + * A wrapper that retrieves ACL data and uses it + * to render an [[AccessController]] component. + * Presumably the '5' is a version number of some sort, + * but all we know is it was already called ACLControlBox5 + * when it was introduced into solid-ui in + * https://github.com/solidos/solid-ui/commit/948b874bd93e7bf5160e6e224821b888f07d15f3#diff-4192a29f38a0ababd563b36b47eba5bbR54 + */ +export function ACLControlBox5 ( + subject: NamedNode, + context: DataBrowserContext, + noun: string, + kb: Store +): HTMLElement { + const dom = context.dom + const doc = subject.doc() // The ACL is actually to the doc describing the thing + + const container = dom.createElement('div') + container.setAttribute('style', style.aclControlBoxContainer) + + const header = container.appendChild(dom.createElement('h1')) + header.textContent = `Sharing for ${noun} ${utils.label(subject)}` + header.setAttribute('style', style.aclControlBoxHeader) + + const status = container.appendChild(dom.createElement('div')) + status.setAttribute('style', style.aclControlBoxStatus) + + try { + loadController(doc, kb, subject, noun, context, dom, status) + .then(controller => container.appendChild(controller.render())) + } catch (error) { + status.innerText = error + } + + return container +} + +async function loadController ( + doc: NamedNode, + kb: Store, + subject: NamedNode, + noun: string, + context: DataBrowserContext, + dom: HTMLDocument, + status: HTMLElement +): Promise { + return new Promise((resolve, reject) => getACLorDefault(doc, async ( + ok, + isDirectACL, + targetDoc, + targetACLDoc, + defaultHolder, + defaultACLDoc + ) => { + if (!ok) { + return reject(new Error(`Error reading ${isDirectACL ? '' : ' default '}ACL. status ${targetDoc}: ${targetACLDoc}`)) + } + const targetDirectory = getDirectory(targetDoc as NamedNode) + const targetIsProtected = isStorage(targetDoc as NamedNode, targetACLDoc as NamedNode, kb) || hasProtectedAcl(targetDoc as NamedNode) + if (!targetIsProtected && targetDirectory) { + try { + const prospectiveDefaultHolder = await getProspectiveHolder(targetDirectory) + return resolve(getController(prospectiveDefaultHolder)) + } catch (error) { + // No need to show this error in status, but good to warn about it in console + warn(error) + } + } + return resolve(getController()) + + function getController (prospectiveDefaultHolder?: NamedNode) { + return new AccessController(subject, noun, context, status, targetIsProtected, targetDoc as NamedNode, targetACLDoc as NamedNode, defaultHolder as NamedNode, + defaultACLDoc as NamedNode, prospectiveDefaultHolder, kb, dom as HTMLDocument) + } + })) +} + +function getDirectory (doc: NamedNode): string | null { + const str = doc.uri.split('#')[0] + const p = str.slice(0, -1).lastIndexOf('/') + const q = str.indexOf('//') + return (q >= 0 && p < q + 2) || p < 0 ? null : str.slice(0, p + 1) +} + +function isStorage (doc: NamedNode, aclDoc: NamedNode, store: Store): boolean { + // @@ TODO: The methods used for targetIsStorage are HACKs - it should not be relied upon, and work is + // @@ underway to standardize a behavior that does not rely upon this hack + // @@ hopefully fixed as part of https://github.com/solidos/data-interoperability-panel/issues/10 + return store.holds(doc, ns.rdf('type'), ns.space('Storage'), aclDoc) +} + +function hasProtectedAcl (targetDoc: NamedNode): boolean { + // @@ TODO: This is hacky way of knowing whether or not a certain ACL file can be removed + // Hopefully we'll find a better, standardized solution to this - https://github.com/solidos/specification/issues/37 + return targetDoc.uri === targetDoc.site().uri +} + +/** @internal */ +export function setGlobalWindow (window: Window) { + global = window +} diff --git a/src/acl/acl.ts b/src/acl/acl.ts new file mode 100644 index 000000000..bfd655086 --- /dev/null +++ b/src/acl/acl.ts @@ -0,0 +1,652 @@ +/** + * Non-UI functions for access control. + * See https://github.com/solidos/web-access-control-spec + * for the spec that defines how ACL documents work. + * @packageDocumentation + */ + +import ns from '../ns' +import { solidLogicSingleton, ACL_LINK } from 'solid-logic' +import * as utils from '../utils' +import { AgentMapMap, AgentMapUnion, ComboList } from './types' +import * as debug from '../debug' +import { graph, Store, NamedNode, serialize, st, Statement, sym, LiveStore } from 'rdflib' + +const kb = solidLogicSingleton.store + +/** + * Take the "default" ACL and convert it into the equivalent ACL + * which the resource would have had. Return it as a new separate store. + * The "defaultForNew" predicate is also accepted, as a deprecated + * synonym for "default". + */ +export function adoptACLDefault ( + doc: NamedNode, + aclDoc: NamedNode, + defaultResource: NamedNode, + defaultACLDoc: NamedNode +): Store { + const ACL = ns.acl + const isContainer = doc.uri.slice(-1) === '/' // Give default for all directories + + const defaults = kb + .each(undefined, ACL('default'), defaultResource, defaultACLDoc) + .concat(kb.each(undefined, ACL('defaultForNew'), defaultResource, defaultACLDoc)) + + const proposed = defaults.reduce((accumulatedStatements, da) => accumulatedStatements + .concat(kb.statementsMatching(da as NamedNode, ns.rdf('type'), ACL('Authorization'), defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('agent'), undefined, defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('agentClass'), undefined, defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('agentGroup'), undefined, defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('origin'), undefined, defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('originClass'), undefined, defaultACLDoc)) + .concat(kb.statementsMatching(da as NamedNode, ACL('mode'), undefined, defaultACLDoc)) + .concat(st(da as NamedNode, ACL('accessTo'), doc, defaultACLDoc)) + .concat(isContainer ? st(da as NamedNode, ACL('default'), doc, defaultACLDoc) : []), [] as Statement[]) + + const kb2 = graph() // Potential - derived is kept apart + proposed.forEach(st => kb2.add(move(st.subject), move(st.predicate), move(st.object), sym(aclDoc.uri))) + return kb2 as LiveStore + + function move (symbol) { + const y = defaultACLDoc.uri.length // The default ACL file + return sym( + symbol.uri.slice(0, y) === defaultACLDoc.uri + ? aclDoc.uri + symbol.uri.slice(y) + : symbol.uri + ) + } +} + +/** + * Read and canonicalize the ACL for x in aclDoc + * + * Accumulate the access rights which each agent or class has + */ +export function readACL ( + doc: NamedNode, + aclDoc: NamedNode, + kb2: Store = kb, + getDefaults: boolean = false +): AgentMapMap { + const auths: Array = getDefaults + ? getDefaultsFallback(kb2, ns) + : kb2.each(undefined, ns.acl('accessTo'), doc) + + const ACL = ns.acl + const ac = { + agent: {}, + agentClass: {}, + agentGroup: {}, + origin: {}, + originClass: {} + } + Object.keys(ac).forEach(pred => { + auths.forEach(function (a) { + (kb2.each(a, ACL('mode')) as Array).forEach(function (mode) { + (kb2.each(a, ACL(pred)) as Array).forEach(function (agent) { + ac[pred][agent.uri] = ac[pred][agent.uri] || {} + ac[pred][agent.uri][mode.uri] = a // could be "true" but leave pointer just in case + }) + }) + }) + }) + return ac + + function getDefaultsFallback (kb, ns) { + return kb + .each(undefined, ns.acl('default'), doc) + .concat(kb.each(undefined, ns.acl('defaultForNew'), doc)) + } +} + +/** + * Compare two ACLs + */ +export function sameACL (a: AgentMapMap | AgentMapUnion, b: AgentMapMap | AgentMapUnion): boolean { + const contains = function (a, b) { + for (const pred in { + agent: true, + agentClass: true, + agentGroup: true, + origin: true, + originClass: true + }) { + if (a[pred]) { + for (const agent in a[pred]) { + for (const mode in a[pred][agent]) { + if (!b[pred][agent] || !b[pred][agent][mode]) { + return false + } + } + } + } + } + return true + } + return contains(a, b) && contains(b, a) +} + +/** + * Union N ACLs + */ +export function ACLunion (list: Array): AgentMapUnion { + const b = list[0] + let a, ag + for (let k = 1; k < list.length; k++) { + ;['agent', 'agentClass', 'agentGroup', 'origin', 'originClass'].forEach( + function (pred) { + a = list[k] + if (a[pred]) { + for (ag in a[pred]) { + for (const mode in a[pred][ag]) { + if (!b[pred][ag]) b[pred][ag] = [] + b[pred][ag][mode] = true + } + } + } + } + ) + } + return b as AgentMapUnion +} + +type loadUnionACLCallback = (ok: boolean, message?: string | NamedNode | AgentMapUnion | AgentMapMap) => void + +/** + * Merge ACLs lists from things to form union + */ +export function loadUnionACL (subjectList: Array, callbackFunction: loadUnionACLCallback): void { + const aclList: Array = [] + const doList = function (list) { + if (list.length) { + const doc = list.shift().doc() + getACLorDefault(doc, function ( + ok, + p2, + targetDoc, + targetACLDoc, + defaultHolder, + defaultACLDoc + ) { + const defa = !p2 + if (!ok || !defaultHolder || !defaultACLDoc) return callbackFunction(ok, targetACLDoc) + const acl = defa + ? readACL(defaultHolder, defaultACLDoc) + : readACL(targetDoc as NamedNode, targetACLDoc as NamedNode) + aclList.push(acl) + doList(list.slice(1)) + }) + } else { + // all gone + callbackFunction(true, ACLunion(aclList)) + } + } + doList(subjectList) +} + +/** + * Represents these as an RDF graph by combination of modes + * + * Each agent can only be in one place in this model, one combination of modes. + * Combos are like full control, read append, read only etc. + */ +export function ACLbyCombination (ac: AgentMapMap | AgentMapUnion): ComboList { + const byCombo = {} + ;['agent', 'agentClass', 'agentGroup', 'origin', 'originClass'].forEach(function (pred) { + for (const agent in ac[pred]) { + const combo: string[] = [] + for (const mode in ac[pred][agent]) { + combo.push(mode) + } + combo.sort() + const combo2 = combo.join('\n') + if (!byCombo[combo2]) byCombo[combo2] = [] + byCombo[combo2].push([pred, agent]) + } + }) + return byCombo +} + +/** + * Write ACL graph to store from AC + */ +export function makeACLGraph (kb: Store, x: NamedNode, ac: AgentMapMap, aclDoc: NamedNode): void { + const byCombo = ACLbyCombination(ac) + return makeACLGraphbyCombo(kb, x, byCombo, aclDoc) +} + +/** + * Write ACL graph to store from combo + */ +export function makeACLGraphbyCombo ( + kb: Store, + x: NamedNode, + byCombo: ComboList, + aclDoc: NamedNode, + main?: boolean, + defa?: boolean +): void { + const ACL = ns.acl + for (const combo in byCombo) { + const pairs = byCombo[combo] + if (!pairs.length) continue // do not add to store when no agent + const modeURIs = combo.split('\n') + let short = modeURIs + .map(function (u) { + return u.split('#')[1] + }) + .join('') + if (defa && !main) short += 'Default' // don't muddle authorizations + const a = kb.sym(aclDoc.uri + '#' + short) + kb.add(a, ns.rdf('type'), ACL('Authorization'), aclDoc) + if (main) { + kb.add(a, ACL('accessTo'), x, aclDoc) + } + if (defa) { + kb.add(a, ACL('default'), x, aclDoc) + } + for (let i = 0; i < modeURIs.length; i++) { + kb.add(a, ACL('mode'), kb.sym(modeURIs[i]), aclDoc) + } + for (let i = 0; i < pairs.length; i++) { + const pred = pairs[i][0] + const ag = pairs[i][1] + kb.add(a, ACL(pred), kb.sym(ag), aclDoc) + } + } +} + +/** + * Debugging short strings for dumping ACL + * and possibly in the UI + */ +export function ACLToString (ac: AgentMapMap): string { + return comboToString(ACLbyCombination(ac)) +} + +/** + * Convert a [[ComboList]] to a string + */ +export function comboToString (byCombo: ComboList): string { + let str = '' + for (const combo in byCombo) { + const modeURIs = combo.split('\n') + const initials = modeURIs + .map(function (u) { + return u.split('#')[1][0] + }) + .join('') + str += initials + ':' + const pairs = byCombo[combo] + for (let i = 0; i < pairs.length; i++) { + const pred = pairs[i][0] + const ag = sym(pairs[i][1]) + str += pred === 'agent' ? '@' : '' + str += ag.sameTerm(ns.foaf('Agent')) ? '*' : utils.label(ag) + if (i < pairs.length - 1) str += ',' + } + str += ';' + } + return '{' + str.slice(0, -1) + '}' // drop extra semicolon +} + +/** + * Write ACL graph as Turtle + */ +export function makeACLString (x: NamedNode, ac: AgentMapMap, aclDoc: NamedNode): string { + const kb2 = graph() + makeACLGraph(kb2, x, ac, aclDoc) + return serialize(aclDoc, kb2, aclDoc.uri, 'text/turtle') || '' +} + +/** + * Write ACL graph to web + */ +export function putACLObject ( + kb: LiveStore, + x: NamedNode, + ac: AgentMapMap | AgentMapUnion, + aclDoc: NamedNode, + callbackFunction: (ok: boolean, message?: string) => void +): void { + const byCombo = ACLbyCombination(ac) + return putACLbyCombo(kb, x, byCombo, aclDoc, callbackFunction) +} + +/** + * Write ACL graph to web from a [[ComboList]] + */ +export function putACLbyCombo ( + kb: LiveStore, + x: NamedNode, + byCombo: ComboList, + aclDoc: NamedNode, + callbackFunction: (ok: boolean, message?: string) => void +): void { + const kb2 = graph() + makeACLGraphbyCombo(kb2, x, byCombo, aclDoc, true) + + // const str = makeACLString = function(x, ac, aclDoc) + kb.updater?.put( + aclDoc, + kb2.statementsMatching(undefined, undefined, undefined, aclDoc), + 'text/turtle', + function (uri, ok, message) { + if (!ok) { + callbackFunction(ok, message) + } else { + kb.fetcher?.unload(aclDoc) + makeACLGraphbyCombo(kb, x, byCombo, aclDoc, true) + kb.fetcher!.requested[aclDoc.uri] = 'done' // missing: save headers + callbackFunction(ok) + } + } + ) +} + +type fixIndividualCardACLCallback = (ok: boolean, message?: string | NamedNode | AgentMapUnion | AgentMapMap) => void +type fixIndividualACLCallback = (ok: boolean, message?: string | NamedNode | AgentMapUnion | AgentMapMap) => void + +/** + * Fix the ACl for an individual card as a function of the groups it is in + * + * All group files must be loaded first + */ +export function fixIndividualCardACL (person: NamedNode, log: Function, callbackFunction: fixIndividualCardACLCallback): void { + const groups = kb.each(undefined, ns.vcard('hasMember'), person) as NamedNode[] + // const doc = person.doc() + if (groups) { + fixIndividualACL(person, groups, log, callbackFunction) + } else { + log('This card is in no groups') + callbackFunction(true) // fine, no requirements to access. default should be ok + } + // @@ if no groups, then use default for People container or the book top container.? +} + +/** + * This function is used by [[fixIndividualCardACL]] + */ +export function fixIndividualACL (item: NamedNode, subjects: Array, log: Function, callbackFunction: fixIndividualACLCallback): void { + log = log || debug.log + const doc = item.doc() + getACLorDefault(doc, function ( + ok, + exists, + targetDoc, + targetACLDoc, + defaultHolder, + defaultACLDoc + ) { + if (!ok || !defaultHolder || !defaultACLDoc) return callbackFunction(false, targetACLDoc) // ie message + const ac = exists + ? readACL(targetDoc as NamedNode, targetACLDoc as NamedNode) + : readACL(defaultHolder, defaultACLDoc) + loadUnionACL(subjects, function (ok, union) { + if (!ok) return callbackFunction(false, union) + if (sameACL(union as AgentMapMap | AgentMapUnion, ac)) { + log('Nice - same ACL. no change ' + utils.label(item) + ' ' + doc) + } else { + log('Group ACLs differ for ' + utils.label(item) + ' ' + doc) + + // log("Group ACLs: " + makeACLString(targetDoc, union, targetACLDoc)) + // log((exists ? "Previous set" : "Default") + " ACLs: " + + // makeACLString(targetDoc, ac, targetACLDoc)) + + putACLObject( + kb as unknown as LiveStore, + targetDoc as NamedNode, + union as AgentMapMap | AgentMapUnion, + targetACLDoc as NamedNode, + callbackFunction + ) + } + }) + }) +} + +/** + * Set an ACL + */ +export function setACL ( + docURI: NamedNode, + aclText: string, + callbackFunction: (ok: boolean, message: string) => void +): void { + const aclDoc = kb.any( + docURI, + ACL_LINK + ) // @@ check that this get set by web.js + if (!kb.fetcher) { + throw new Error('Store has no fetcher') + } + if (aclDoc) { + // Great we already know where it is + kb.fetcher + .webOperation('PUT', aclDoc.value, { + data: aclText, + contentType: 'text/turtle' + }) + .then((res) => { + callbackFunction(res.ok, res.error || '') + }) // @@@ check params + } else { + kb.fetcher.nowOrWhenFetched(docURI, undefined, function (ok, body) { + if (!ok) return callbackFunction(ok, 'Gettting headers for ACL: ' + body) + const aclDoc = kb.any( + docURI, + ACL_LINK + ) // @@ check that this get set by web.js + if (!aclDoc) { + // complainIfBad(false, "No Link rel=ACL header for " + docURI) + callbackFunction(false, 'No Link rel=ACL header for ' + docURI) + } else { + if (!kb.fetcher) { + throw new Error('Store has no fetcher') + } + kb.fetcher + .webOperation('PUT', aclDoc.value, { + data: aclText, + contentType: 'text/turtle' + }) + .then((res) => { + callbackFunction(res.ok, res.error || '') + }) + } + }) + } +} + +/** + * Get ACL file or default if necessary + * + * @param callbackFunction Will be called in the following ways, in the following cases: + * * `callbackFunction(true, true, doc, aclDoc)` if the ACL did exist + * * `callbackFunction(true, false, doc, aclDoc, defaultHolder, defaultACLDoc)` if the ACL file did not exist but a default did + * * `callbackFunction(false, false, status, message)` when there was an error getting the original + * * `callbackFunction(false, true, status, message)` when there was an error getting the default + */ +export function getACLorDefault ( + doc: NamedNode, + callbackFunction: ( + a: boolean, + b: boolean, + statusOrMessage: number | NamedNode, + message: string | NamedNode, + c?: NamedNode, + d?: NamedNode + ) => void +): void { + getACL(doc, function (ok, status, aclDoc, message): string | void { + const ACL = ns.acl + if (!ok) return callbackFunction(false, false, status as number, message as string) + + // Recursively search for the ACL file which gives default access + const tryParent = function (uri) { + if (uri.slice(-1) === '/') { + uri = uri.slice(0, -1) + } + const right = uri.lastIndexOf('/') + const left = uri.indexOf('/', uri.indexOf('//') + 2) + if (left > right) { + return callbackFunction(false, true, 404, 'Found no ACL resource') + } + uri = uri.slice(0, right + 1) + const doc2 = sym(uri) + getACL(doc2, function (ok, status, defaultACLDoc: any): NamedNode | void { + if (!ok) { + return callbackFunction( + false, + true, + status as number, + `( No ACL pointer ${uri} ${status})${defaultACLDoc}` + ) as void + } else if (status === 403) { + return callbackFunction( + false, + true, + status, + `( default ACL file FORBIDDEN. Stop.${uri})` + ) + } else if (status === 404) { + return tryParent(uri) + } else if (status !== 200) { + return callbackFunction( + false, + true, + status as number, + `Error status '${status}' searching for default for ${doc2}` + ) + } + // 200 + // statusBlock.textContent += (" ACCESS set at " + uri + ". End search.") + const defaults = kb + .each(undefined, ACL('default'), kb.sym(uri), defaultACLDoc) + .concat( + kb.each(undefined, ACL('defaultForNew'), kb.sym(uri), defaultACLDoc) + ) + if (!defaults.length) { + return tryParent(uri) // Keep searching + } + const defaultHolder = kb.sym(uri) + return callbackFunction( + true, + false, + doc, + aclDoc as NamedNode, + defaultHolder, + defaultACLDoc as NamedNode + ) + }) + } // tryParent + + if (!ok) { + return callbackFunction( + false, + false, + status as number, + `Error accessing Access Control information for ${doc}) ${message}` + ) + } else if (status === 404) { + tryParent(doc.uri) // @@ construct default one - the server should do that + } else if (status === 403) { + return callbackFunction( + false, + false, + status, + `(Sharing not available to you)${message}` + ) + } else if (status !== 200) { + return callbackFunction( + false, + false, + status as number, + `Error ${status} accessing Access Control information for ${doc}: ${message}` + ) + } else { + // 200 + return callbackFunction(true, true, doc, aclDoc as NamedNode) + } + }) // Call to getACL +} + +/** + * Calls back `(ok, status, acldoc, message)` as follows + * + * * `(false, 900, errormessage)` if no link header + * * `(true, 403, documentSymbol, fileaccesserror)` if not authorized + * * `(true, 404, documentSymbol, fileaccesserror)` if does not exist + * * `(true, 200, documentSymbol)` if file exists and read OK + */ +export function getACL ( + doc: NamedNode, + callbackFunction: ( + ok: boolean, + messageOrStatus: number | string, + messageOrDoc?: NamedNode | string, + message?: string + ) => void +): void { + if (!kb.fetcher) { + throw new Error('kb has no fetcher') + } + kb.fetcher.nowOrWhenFetched(doc, undefined, function (ok, body) { + if (!ok) { + return callbackFunction(ok, `Can't get headers to find ACL for ${doc}: ${body}`) + } + const aclDoc = kb.any( + doc, + ACL_LINK + ) // @@ check that this get set by web.js + if (!aclDoc) { + callbackFunction(false, 900, `No Link rel=ACL header for ${doc}`) + } else { + if (!kb.fetcher) { + throw new Error('kb has no fetcher') + } + if (kb.fetcher.nonexistent[aclDoc.value]) { + return callbackFunction( + true, + 404, + aclDoc as NamedNode, + `ACL file ${aclDoc} does not exist.` + ) + } + kb.fetcher.nowOrWhenFetched(aclDoc as NamedNode, undefined, function ( + ok, + message, + response + ) { + if (!ok) { + callbackFunction( + true, + response.status, + aclDoc as NamedNode, + `Can't read Access Control File ${aclDoc}: ${message}` + ) + } else { + callbackFunction(true, 200, aclDoc as NamedNode) + } + }) + } + }) +} + +/** + * Calls [[getACLorDefault]] and then (?) + */ +export async function getProspectiveHolder (targetDirectory: string): Promise { + return new Promise((resolve, reject) => getACLorDefault(sym(targetDirectory), ( + ok, + isDirectACL, + targetDoc, + targetACLDoc, + defaultHolder + ) => { + if (ok) { + return resolve((isDirectACL ? targetDoc : defaultHolder) as NamedNode) + } + return reject(new Error(`Error loading ${targetDirectory}`)) + })) +} diff --git a/src/acl/add-agent-buttons.ts b/src/acl/add-agent-buttons.ts new file mode 100644 index 000000000..e5c0de41a --- /dev/null +++ b/src/acl/add-agent-buttons.ts @@ -0,0 +1,286 @@ +/** + * Contains the [[AddAgentButtons]] class + * @packageDocumentation + */ + +import { NamedNode, Store } from 'rdflib' +import { AuthenticationContext } from 'solid-logic' +import * as debug from '../debug' +import { icons } from '../iconBase' +import { ensureLoadedProfile } from '../login/login' +import ns from '../ns' +import * as utils from '../utils' +import * as widgets from '../widgets' +import { style } from '../style' +import { AccessGroups } from './access-groups' + +/** + * Renders the Sharing pane's "+" button and the menus behind it, + * see https://github.com/solidos/userguide/blob/main/views/sharing/userguide.md#add + */ +export class AddAgentButtons { + private readonly rootElement: HTMLElement + private readonly barElement: HTMLElement + private isExpanded: boolean = false + + constructor (private groupList: AccessGroups) { + this.rootElement = groupList.controller.dom.createElement('div') + this.barElement = groupList.controller.dom.createElement('div') + } + + public render (): HTMLElement { + this.rootElement.innerHTML = '' + this.rootElement.appendChild(this.renderAddButton()) + this.rootElement.appendChild(this.barElement) + return this.rootElement + } + + private renderAddButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + `${icons.iconBase}noun_34653_green.svg`, + 'Add ...', + () => { + this.toggleBar() + this.renderBar() + } + ) + } + + private renderBar (): void { + this.barElement.innerHTML = '' + if (!this.isExpanded) { + return + } + this.barElement.appendChild(this.renderPersonButton()) + this.barElement.appendChild(this.renderGroupButton()) + this.barElement.appendChild(this.renderPublicButton()) + this.barElement.appendChild(this.renderAuthenticatedAgentButton()) + this.barElement.appendChild(this.renderBotButton()) + this.barElement.appendChild(this.renderAppsButton()) + } + + private renderSimplifiedBar (button: EventTarget | null) { + Array.from(this.barElement.children) + .filter(element => element !== button) + .forEach(element => this.barElement.removeChild(element)) + } + + private renderPersonButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + icons.iconBase + widgets.iconForClass['vcard:Individual'], + 'Add Person', + event => { + this.renderSimplifiedBar(event.target) + this.renderNameForm(ns.vcard('Individual'), 'person') + .then(name => this.addPerson(name)) + .then(() => this.renderCleanup()) + .catch(error => this.groupList.controller.renderStatus(error)) + } + ) + } + + private renderGroupButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + icons.iconBase + widgets.iconForClass['vcard:Group'], + 'Add Group', + event => { + this.renderSimplifiedBar(event.target) + this.renderNameForm(ns.vcard('Group'), 'group') + .then(name => this.addGroup(name)) + .then(() => this.renderCleanup()) + .catch(error => this.groupList.controller.renderStatus(error)) + } + ) + } + + private renderNameForm (type: NamedNode, noun: string): Promise { + return widgets.askName( + this.groupList.controller.dom, + this.groupList.store, + this.barElement, + ns.vcard('URI'), + type, + noun + ) + } + + private renderPublicButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + icons.iconBase + widgets.iconForClass['foaf:Agent'], + 'Add Everyone', + () => this.addAgent(ns.foaf('Agent').uri) + .then(() => this.groupList.controller.renderTemporaryStatus('Adding the general public to those who can read. Drag the globe to a different level to give them more access.')) + .then(() => this.renderCleanup())) + } + + private renderAuthenticatedAgentButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + `${icons.iconBase}noun_99101.svg`, + 'Anyone logged In', + () => this.addAgent(ns.acl('AuthenticatedAgent').uri) + .then(() => this.groupList.controller.renderTemporaryStatus('Adding anyone logged in to those who can read. Drag the ID icon to a different level to give them more access.')) + .then(() => this.renderCleanup())) + } + + private renderBotButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + icons.iconBase + 'noun_Robot_849764.svg', + 'A Software Agent (bot)', + event => { + this.renderSimplifiedBar(event.target) + this.renderNameForm(ns.schema('Application'), 'bot') + .then(name => this.addBot(name)) + .then(() => this.renderCleanup()) + }) + } + + private renderAppsButton (): HTMLElement { + return widgets.button( + this.groupList.controller.dom, + `${icons.iconBase}noun_15177.svg`, + 'A Web App (origin)', + event => { + this.renderSimplifiedBar(event.target) + const eventContext = { + div: this.barElement, + dom: this.groupList.controller.dom + } + const existingApps = this.renderAppsTable(eventContext) + .catch(error => this.groupList.controller.renderStatus(error)) + this.renderAppsView() + const newApp = this.renderNameForm(ns.schema('WebApplication'), 'webapp domain') + .then(name => this.getOriginFromName(name)) + Promise.race([ + existingApps, + newApp + ]) + .then(origin => { + if (origin) { + this.groupList.addNewURI(origin) + } + }) + .then(() => this.renderCleanup()) + } + ) + } + + private renderAppsView (): void { + const trustedApplications = this.groupList.controller.context.session.paneRegistry.byName('trustedApplications') + if (trustedApplications) { + const trustedApplicationsElement = trustedApplications.render(null, this.groupList.controller.context) + trustedApplicationsElement.setAttribute('style', style.trustedAppController) + + const cancelButton = widgets.cancelButton(this.groupList.controller.dom, () => this.renderCleanup()) + cancelButton.setAttribute('style', style.trustedAppCancelButton) + trustedApplicationsElement.insertBefore(cancelButton, trustedApplicationsElement.firstChild) + + this.barElement.appendChild(trustedApplicationsElement) + } + } + + private async renderAppsTable (eventContext: AuthenticationContext): Promise { + await ensureLoadedProfile(eventContext) + const trustedApps = (this.groupList.store as Store).each(eventContext.me, ns.acl('trustedApp')) as Array // @@ TODO fix as + const trustedOrigins = trustedApps.flatMap(app => (this.groupList.store as Store).each(app, ns.acl('origin'))) // @@ TODO fix as + + this.barElement.appendChild(this.groupList.controller.dom.createElement('p')).textContent = `You have ${trustedOrigins.length} selected web apps.` + return new Promise((resolve, reject) => { + const appsTable = this.barElement.appendChild(this.groupList.controller.dom.createElement('table')) + appsTable.setAttribute('style', style.trustedAppAddApplicationsTable) + trustedApps.forEach(app => { + const origin = (this.groupList.store as Store).any(app, ns.acl('origin')) // @@ TODO fix as + if (!origin) { + reject(new Error(`Unable to pick app: ${app.value}`)) + } + const thingTR = widgets.personTR(this.groupList.controller.dom, ns.acl('origin'), origin, {}) + const innerTable = this.groupList.controller.dom.createElement('table') + const innerRow = innerTable.appendChild(this.groupList.controller.dom.createElement('tr')) + + const innerLeftColumn = innerRow.appendChild(this.groupList.controller.dom.createElement('td')) + innerLeftColumn.appendChild(thingTR) + + const innerMiddleColumn = innerRow.appendChild(this.groupList.controller.dom.createElement('td')) + innerMiddleColumn.textContent = `Give access to ${this.groupList.controller.noun} ${utils.label(this.groupList.controller.subject)}?` + + const innerRightColumn = innerRow.appendChild(this.groupList.controller.dom.createElement('td')) + innerRightColumn.appendChild(widgets.continueButton(this.groupList.controller.dom, () => resolve(origin!.value))) + + appsTable.appendChild(innerTable) + }) + }) + } + + private renderCleanup (): void { + this.renderBar() + this.groupList.render() + } + + private async addPerson (name?: string): Promise { + if (!name) return this.toggleBar() // user cancelled + const domainNameRegexp = /^https?:/i + if (!name.match(domainNameRegexp)) { + // @@ enforce in user input live like a form element + return Promise.reject(new Error('Not a http URI')) + } + // @@ check it actually is a person and has an owner who agrees they own it + debug.log(`Adding to ACL person: ${name}`) + await this.groupList.addNewURI(name) + this.toggleBar() + } + + private async addGroup (name?: string): Promise { + if (!name) return this.toggleBar() // user cancelled + + const domainNameRegexp = /^https?:/i + if (!name.match(domainNameRegexp)) { + // @@ enforce in user input live like a form element + return Promise.reject(new Error('Not a http URI')) + } + // @@ check it actually is a group and has an owner who agrees they own it + debug.log('Adding to ACL group: ' + name) + await this.groupList.addNewURI(name) + this.toggleBar() + } + + private async addAgent (agentUri: string): Promise { + await this.groupList.addNewURI(agentUri) + this.toggleBar() + } + + private async addBot (name?: string): Promise { + if (!name) return this.toggleBar() // user cancelled + const domainNameRegexp = /^https?:/i + if (!name.match(domainNameRegexp)) { + // @@ enforce in user input live like a form element + return Promise.reject(new Error('Not a http URI')) + } + // @@ check it actually is a bot and has an owner who agrees they own it + debug.log('Adding to ACL bot: ' + name) + await this.groupList.addNewURI(name) + this.toggleBar() + } + + private async getOriginFromName (name?: string): Promise { + if (!name) return Promise.resolve() // user cancelled + const domainNameRegexp = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i + // https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html + if (!name.match(domainNameRegexp)) { + // @@ enforce in user input live like a form element + return Promise.reject(new Error('Not a domain name')) + } + const origin = 'https://' + name + debug.log('Adding to ACL origin: ' + origin) + this.toggleBar() + return origin + } + + private toggleBar (): void { + this.isExpanded = !this.isExpanded + } +} diff --git a/src/acl/index.ts b/src/acl/index.ts new file mode 100644 index 000000000..560f267eb --- /dev/null +++ b/src/acl/index.ts @@ -0,0 +1,57 @@ +/** + * Re-exports all the exports from the various files in the src/acl/ folder + * @packageDocumentation + */ + +import { + ACLbyCombination, + ACLToString, + ACLunion, + adoptACLDefault, + comboToString, + fixIndividualACL, + fixIndividualCardACL, + getACL, + getACLorDefault, + loadUnionACL, + makeACLGraph, + makeACLGraphbyCombo, + makeACLString, + putACLbyCombo, + putACLObject, + readACL, + sameACL, + setACL +} from './acl' +import { + ACLControlBox5, + preventBrowserDropEvents, + shortNameForFolder +} from './acl-control' + +export const acl = { + adoptACLDefault, + readACL, + sameACL, + ACLunion, + loadUnionACL, + ACLbyCombination, + makeACLGraph, + makeACLGraphbyCombo, + ACLToString, + comboToString, + makeACLString, + putACLObject, + putACLbyCombo, + fixIndividualCardACL, + fixIndividualACL, + setACL, + getACLorDefault, + getACL +} + +export const aclControl = { + preventBrowserDropEvents, + shortNameForFolder, + ACLControlBox5 +} diff --git a/src/acl/types.ts b/src/acl/types.ts new file mode 100644 index 000000000..bd9230499 --- /dev/null +++ b/src/acl/types.ts @@ -0,0 +1,33 @@ +/** + * Contains types for src/acl/ + * @packageDocumentation + */ + +import { NamedNode } from 'rdflib' + +export type AgentMap = { + [agentUri: string]: { + [modeUri: string]: NamedNode + } +} + +export type AgentUnion = { + [agentUri: string]: true | [] +} + +export type AgentMapMap = { + agent: T, + agentClass: T, + agentGroup: T, + origin: T, + originClass: T +} + +export type AgentMapUnion = AgentMapMap + +export type ComboList = { [key: string]: Array } + +export type PartialAgentTriple = { + pred: string, + obj: NamedNode +} diff --git a/src/chat/bookmarks.js b/src/chat/bookmarks.js new file mode 100644 index 000000000..bc88b8bad --- /dev/null +++ b/src/chat/bookmarks.js @@ -0,0 +1,180 @@ +/** + * Functions related to chat and bookmarks + * @packageDocumentation + */ + +import * as debug from '../debug' +import { icons } from '../iconBase' +import { media } from '../media/index' +import ns from '../ns' +import * as pad from '../pad' +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +import { style } from '../style' +import * as utils from '../utils' +import * as widgets from '../widgets' +import { store, createTypeIndexLogic, authn } from 'solid-logic' +import { findAppInstances } from '../login/login' + +const UI = { icons, ns, media, pad, style, utils, widgets } + +const BOOK = $rdf.Namespace('http://www.w3.org/2002/01/bookmark#') +const BOOKMARK_ICON = 'noun_45961.svg' + +const label = utils.label +const dom = window.document || null + +// @@@@ use the one in rdflib.js when it is avaiable and delete this +function updatePromise (del, ins) { + return new Promise(function (resolve, reject) { + store.updater.update(del, ins, function (uri, ok, errorBody) { + if (!ok) { + reject(new Error(errorBody)) + } else { + resolve() + } + }) // callback + }) // promise +} + +/* Bookmarking + */ +/** Find a user's bookmarks + */ +export async function findBookmarkDocument (userContext) { + const theClass = BOOK('Bookmark') + const fileTail = 'bookmarks.ttl' + const isPublic = true + + await findAppInstances(userContext, theClass, isPublic) // public -- only look for public links + + if (userContext.instances && userContext.instances.length > 0) { + userContext.bookmarkDocument = userContext.instances[0] + if (userContext.instances.length > 1) { + debug.warn('More than one bookmark file! ' + userContext.instances) // @@ todo - deal with > 1 + // Note: should pick up community bookmarks as well + } + } else { + if (userContext.publicProfile) { + // publicProfile or preferencesFile + const newBookmarkFile = $rdf.sym( + userContext.publicProfile.dir().uri + fileTail + ) + try { + debug.log('Creating new bookmark file ' + newBookmarkFile) + await store.fetcher.createIfNotExists(newBookmarkFile) + } catch (e) { + debug.warn('Can\'t make fresh bookmark file:' + e) + return userContext + } + await createTypeIndexLogic.registerInTypeIndex( + newBookmarkFile, + userContext.index, + theClass + ) + userContext.bookmarkDocument = newBookmarkFile + } else { + debug.warn('You seem to have no bookmark file, nor even a profile file!') + } + } + return userContext +} + +/** Add a bookmark + */ + +async function addBookmark (context, target) { + /* like + @prefix terms: . + @prefix bookm: . + @prefix n0: . + <> terms:references <#0.5534145389246576>. + <#0.5534145389246576> + a bookm:Bookmark; + terms:created "2019-01-26T20:26:44.374Z"^^XML:dateTime; + terms:title "Herons"; + bookm:recalls wiki:Heron; + n0:maker c:me. + */ + let title = '' + const me = authn.currentUser() // If already logged on + if (!me) throw new Error('Must be logged on to add Bookmark') + + const author = store.any(target, ns.foaf('maker')) + title = + label(author) + ': ' + store.anyValue(target, ns.sioc('content')).slice(0, 80) // @@ add chat title too? + const bookmarkDoc = context.bookmarkDocument + const bookmark = UI.widgets.newThing(bookmarkDoc, title) + const ins = [ + $rdf.st(bookmarkDoc, UI.ns.dct('references'), bookmark, bookmarkDoc), + $rdf.st(bookmark, UI.ns.rdf('type'), BOOK('Bookmark'), bookmarkDoc), + $rdf.st(bookmark, UI.ns.dct('created'), new Date(), bookmarkDoc), + $rdf.st(bookmark, BOOK('recalls'), target, bookmarkDoc), + $rdf.st(bookmark, UI.ns.foaf('maker'), me, bookmarkDoc), + $rdf.st(bookmark, UI.ns.dct('title'), title, bookmarkDoc) + ] + try { + await updatePromise([], ins) // 20190118A + } catch (e) { + const msg = 'Making bookmark: ' + e + debug.warn(msg) + return null + } + return bookmark +} + +export async function toggleBookmark (userContext, target, bookmarkButton) { + await store.fetcher.load(userContext.bookmarkDocument) + const bookmarks = store.each( + null, + BOOK('recalls'), + target, + userContext.bookmarkDocument + ) + if (bookmarks.length) { + // delete + if (!confirm('Delete bookmark on this?' + bookmarks.length)) return + for (let i = 0; i < bookmarks.length; i++) { + try { + await updatePromise(store.connectedStatements(bookmarks[i]), []) + bookmarkButton.style.backgroundColor = 'white' + debug.log('Bookmark deleted: ' + bookmarks[i]) + } catch (e) { + debug.error('Cant delete bookmark:' + e) + debug.warn('Cannot delete bookmark:' + e) + } + } + } else { + const bookmark = await addBookmark(userContext, target) + bookmarkButton.style.backgroundColor = 'yellow' + debug.log('Bookmark added: ' + bookmark) + } +} + +export async function renderBookmarksButton (userContext, target) { + async function setBookmarkButtonColor (bookmarkButton) { + await store.fetcher.load(userContext.bookmarkDocument) + const bookmarked = store.any( + null, + BOOK('recalls'), + bookmarkButton.target, + userContext.bookmarkDocument + ) + bookmarkButton.style = UI.style.buttonStyle + if (bookmarked) bookmarkButton.style.backgroundColor = 'yellow' + } + + let bookmarkButton + if (userContext.bookmarkDocument) { + bookmarkButton = UI.widgets.button( + dom, + UI.icons.iconBase + BOOKMARK_ICON, + label(BOOK('Bookmark')), + () => { + toggleBookmark(userContext, target, bookmarkButton) + } + ) + bookmarkButton.target = target + await setBookmarkButtonColor(bookmarkButton) + return bookmarkButton + } +} diff --git a/src/chat/chatLogic.js b/src/chat/chatLogic.js new file mode 100644 index 000000000..d0fea2044 --- /dev/null +++ b/src/chat/chatLogic.js @@ -0,0 +1,221 @@ +/** + * Contains the [[ChatChannel]] class and logic for Solid Chat + * @packageDocumentation + */ + +import * as debug from '../debug' +import { DateFolder } from './dateFolder' +import { store, authn } from 'solid-logic' +import ns from '../ns' +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +import * as utils from '../utils' +import { getBlankMsg, signMsg, SEC } from './signature' +import { getPrivateKey } from './keys' + +/* The Solid logic for a 'LongChat' +*/ +/** + * Common code for a chat (discussion area of messages about something) + * This version runs over a series of files for different time periods + * + * Parameters for the whole chat like its title are stored on + * index.ttl#this and the chats messages are stored in YYYY/MM/DD/chat.ttl + * + */ + +export class ChatChannel { + constructor (channel, options) { + this.channel = channel + this.channelRoot = channel.doc() + this.options = options + this.dateFolder = new DateFolder(this.channelRoot, 'chat.ttl') + this.div = null // : HTMLElement + } + + /* Store a new message in the web, + */ + async createMessage (text) { + return this.updateMessage(text) + } + + /* Store a new message in the web, + as a replacement for an existing one. + The old one iis left, and the two are linked + */ + async updateMessage (text, oldMsg = null, deleteIt, thread = null) { + const sts = [] + const now = new Date() + const timestamp = '' + now.getTime() + const dateStamp = $rdf.term(now) + const chatDocument = oldMsg ? oldMsg.doc() : this.dateFolder.leafDocumentFromDate(now) + const message = store.sym(chatDocument.uri + '#' + 'Msg' + timestamp) + // const content = store.literal(text) + + const me = authn.currentUser() // If already logged on + + const msg = getBlankMsg() + msg.id = message.uri + if (oldMsg) { // edit message replaces old one + const oldMsgMaker = store.any(oldMsg, ns.foaf('maker')) // may not be needed here, but needed on READ + if (oldMsgMaker.uri === me.uri) { + const oldMsgMostRecentVersion = await mostRecentVersion(oldMsg) + sts.push($rdf.st(oldMsgMostRecentVersion, ns.dct('isReplacedBy'), message, chatDocument)) + // if oldMsg has_reply => add has_reply to message + const oldMsgThread = store.any(oldMsgMostRecentVersion, ns.sioc('has_reply')) + if (oldMsgThread) { + sts.push($rdf.st(message, ns.sioc('has_reply'), oldMsgThread, chatDocument)) + } + if (deleteIt) { // we need to add a specific signature, else anyone can delete a msg ? + sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument)) + } + } else { + const errMsg = 'Error you cannot delete/edit a message from someone else : \n' + oldMsgMaker.uri + debug.warn(errMsg) + alert(errMsg) + throw new Error(errMsg) + } + } else { // link new message to channel + sts.push($rdf.st(this.channel, ns.wf('message'), message, chatDocument)) + } + sts.push( + $rdf.st(message, ns.sioc('content'), store.literal(text), chatDocument) + ) + msg.content = text + + sts.push( + $rdf.st(message, ns.dct('created'), dateStamp, chatDocument) + ) + msg.created = dateStamp.value + if (me) { + sts.push($rdf.st(message, ns.foaf('maker'), me, chatDocument)) + msg.maker = me.uri + // privateKey the cached private key of me, cached in store + const privateKey = await getPrivateKey(me) // me.uri) + + const sig = signMsg(msg, privateKey) + sts.push($rdf.st(message, $rdf.sym(`${SEC}proofValue`), $rdf.lit(sig), chatDocument)) + } + if (thread) { + sts.push($rdf.st(thread, ns.sioc('has_member'), message, chatDocument)) + if (!thread.doc().sameTerm(message.doc())) { + sts.push($rdf.st(thread, ns.sioc('has_member'), message, thread.doc())) + } + } + + try { + await store.updater.updateMany([], sts) + } catch (err) { + const errMsg = 'Error saving chat message: ' + err + debug.warn(errMsg) + alert(errMsg) + throw new Error(errMsg) + } + return message + } + + /* Mark a message as deleted + * Wee add a new version of the message,m witha deletion flag (deletion date) + * so that the deletion can be revoked by adding another non-deleted update + */ + async deleteMessage (message) { + return this.updateMessage('(message deleted)', message, true) + } + + // Create a new thread of replies to the thread root message + // or return one which already exists + + async createThread (threadRoot) { + const already = store.each(threadRoot, ns.sioc('has_reply'), null, threadRoot.doc()) + .filter(thread => store.holds(thread, ns.rdf('type'), ns.sioc('Thread'), thread.doc())) + if (already.length > 0) return already[0] + + const thread = $rdf.sym(threadRoot.uri + '-thread') + const insert = [ + $rdf.st(thread, ns.rdf('type'), ns.sioc('Thread'), thread.doc()), + $rdf.st(threadRoot, ns.sioc('has_reply'), thread, thread.doc()) + ] + await store.updater.update([], insert) + return thread + } +} // class ChatChannel + +// ////////// Utility functions + +// Have to not loop forever if fed loops +export async function allVersions (message) { + const versions = [message] + const done = {} + done[message.uri] = true + let m = message + while (true) { // earlier? + const prev = store.any(null, ns.dct('isReplacedBy'), m, m.doc()) + if (!prev || done[prev.uri]) break + await store.fetcher.load(prev) + versions.unshift(prev) + done[prev.uri] = true + m = prev + } + m = message + while (true) { // later? + const next = store.any(m, ns.dct('isReplacedBy'), null, m.doc()) + if (!next || done[next.uri]) break + versions.push(next) + done[next.uri] = true + m = next + } + return versions +} + +export async function originalVersion (message) { + let msg = message + const done = {} + // done[message.uri] = true + while (msg) { + if (done[msg.uri]) { + debug.error('originalVersion: verion loop' + message) + return message + } + done[msg.uri] = true + message = msg + await store.fetcher.load(message) + msg = store.any(null, ns.dct('isReplacedBy'), message, message.doc()) + } + return message +} + +export async function mostRecentVersion (message) { + let msg = message + const done = {} + while (msg) { + if (done[msg.uri]) { + debug.error('mostRecentVersion: verion loop' + message) + return message + } + done[msg.uri] = true + message = msg + await store.fetcher.load(message) + msg = store.any(message, ns.dct('isReplacedBy'), null, message.doc()) + } + return message +} + +export function isDeleted (message) { + return store.holds(message, ns.schema('dateDeleted'), null, message.doc()) +} + +export function isReplaced (message) { + return store.holds(message, ns.dct('isReplacedBy'), null, message.doc()) +} + +export function isHidden (message) { + return this.isDeleted(message) || this.isReplaced(message) +} + +// A Nickname for a person + +export function nick (person) { + const s = store.any(person, ns.foaf('nick')) + if (s) return '' + s.value + return '' + utils.label(person) +} +// ends diff --git a/src/chat/class-version-dropped-infinte.wasjs b/src/chat/class-version-dropped-infinte.wasjs new file mode 100644 index 000000000..afe3d3ee6 --- /dev/null +++ b/src/chat/class-version-dropped-infinte.wasjs @@ -0,0 +1,660 @@ +/** + * Contains the [[infiniteMessageArea]] class + * @packageDocumentation + */ +// import { authn } from '../authn/index' +import * as debug from '../debug' +import { icons } from '../iconBase' +import { store } from 'solid-logic' +// import { media } from '../media/index' +import ns from '../ns' +// import * as pad from '../pad' +// import { DateFolder } from './dateFolder' +import { mostRecentVersion, ChatChannel } from './chatLogic' +import { renderMessageEditor, renderMessageRow } from './message' +// import { findBookmarkDocument } from './bookmarks' + +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +// import { style } from '../style' +// import * as utils from '../utils' +import * as widgets from '../widgets' + +const dom = window.document + +// const UI = { authn, icons, ns, media, pad, $rdf, style, utils, widgets } + +export function desktopNotification (str) { + // Let's check if the browser supports notifications + if (!('Notification' in window)) { + debug.warn('This browser does not support desktop notification') + } else if (Notification.permission === 'granted') { + // Let's check whether notification permissions have already been granted + // eslint-disable-next-line no-new + new Notification(str) + } else if (Notification.permission !== 'denied') { + // Otherwise, we need to ask the user for permission + Notification.requestPermission().then(function (permission) { + // If the user accepts, let's create a notification + if (permission === 'granted') { + // eslint-disable-next-line no-new + new Notification(str) + } + }) + } + // At last, if the user has denied notifications, and you + // want to be respectful there is no need to bother them any more. +} + + +/** + * Common code for a chat (discussion area of messages about something) + * This version runs over a series of files for different time periods + * + * Parameters for the whole chat like its title are stored on + * index.ttl#this and the chats messages are stored in YYYY/MM/DD/chat.ttl + * + * Use to import store as param 2, now ignores it and uses the UI main store + */ + +export class InfiniteScrolChat { + constructor (chatChannel, options) { + + + function addMessage (message, messageTable) { + let content + if (store.any(mostRecentVersion(message))) { + content = store.any(mostRecentVersion(message), ns.sioc('content')) + } else { + content = store.literal('message deleted') + } + const bindings = { + '?msg': message, + '?creator': store.any(message, ns.foaf('maker')), + '?date': store.any(message, ns.dct('created')), + '?content': content // store.any(mostRecentVersion(message), ns.sioc('content')) + } + insertMessageIntoTable( + this.messageTable, + bindings, + this.messageTable.fresh, + this.options, + this.userContext + ) // fresh from elsewhere + } + + // //////// + + /* Add a new this.messageTable at the top/bottom + */ + async function insertPreviousMessages (backwards) { + const extremity = backwards ? this.earliest : this.latest + let date = extremity.this.messageTable.date // day in mssecs + + date = await this.dateFolder.loadPrevious(date, backwards) // backwards + debug.log( + `insertPreviousMessages: from ${ + backwards ? 'backwards' : 'forwards' + } loadPrevious: ${date}` + ) + if (!date && !backwards && !this.liveMessageTable) { + await appendCurrentMessages() // If necessary skip to today and add that + } + if (!date) return true // done + let live = false + if (!backwards) { + const todayDoc = this.dateFolder.leafDocumentFromDate(new Date()) + const doc = this.dateFolder.leafDocumentFromDate(date) + live = doc.sameTerm(todayDoc) // Is this todays? + } + const newMessageTable = await createMessageTable(date, live) + extremity.this.messageTable = newMessageTable // move pointer to this.earliest + if (backwards ? this.newestFirst : !this.newestFirst) { + // put on bottom or top + this.div.appendChild(newMessageTable) + } else { + // put on top as we scroll back + this.div.insertBefore(newMessageTable, this.div.firstChild) + } + return live // not done + } + + /* Remove message tables earlier than this one + */ + function removePreviousMessages (backwards, messageTable) { + if (backwards ? this.newestFirst : !this.newestFirst) { + // it was put on bottom + while (this.messageTable.nextSibling) { + this.div.removeChild(this.messageTable.nextSibling) + } + } else { + // it was put on top as we scroll back + while (this.messageTable.previousSibling) { + this.div.removeChild(this.messageTable.previousSibling) + } + } + const extr = backwards ? this.earliest : this.latest + extr.this.messageTable = this.messageTable + } + + /* Load and render message table + ** @returns DOM element generates + */ + async function createMessageTable (date, live) { + debug.log(' createMessageTable for ' + date) + const chatDocument = this.dateFolder.leafDocumentFromDate(date) + try { + await store.fetcher.load(chatDocument) + } catch (err) { + const messageTable = dom.createElement('table') + const statusTR = messageTable.appendChild(dom.createElement('tr')) // ### find status in exception + if (err.response && err.response.status && err.response.status === 404) { + debug.log('Error 404 for chat file ' + chatDocument) + return renderMessageTable(date, live) // no mssage file is fine.. will be craeted later + // statusTR.appendChild(widgets.errorMessageBlock(dom, 'no message file', 'white')) + } else { + debug.log('*** Error NON 404 for chat file ' + chatDocument) + statusTR.appendChild(widgets.errorMessageBlock(dom, err, 'pink')) + } + return statusTR + } + return renderMessageTable(date, live) + } + + + async function addNewChatDocumentIfNewDay () { + let now = new Date() + // @@ Remove listener from previous table as it is now static + const newChatDocument = this.dateFolder.leafDocumentFromDate(now) + if (!newChatDocument.sameTerm(this.latest.this.messageTable.chatDocument)) { + // It is a new day + if (this.liveMessageTable.inputRow) { + this.liveMessageTable.removeChild(this.liveMessageTable.inputRow) + delete this.liveMessageTable.inputRow + } + const oldChatDocument = this.latest.this.messageTable.chatDocument + await appendCurrentMessages() + // Adding a link in the document will ping listeners to add the new block too + if ( + !store.holds( + oldChatDocument, + ns.rdfs('seeAlso'), + newChatDocument, + oldChatDocument + ) + ) { + const sts = [ + $rdf.st( + oldChatDocument, + ns.rdfs('seeAlso'), + newChatDocument, + oldChatDocument + ) + ] + try { + store.updater.update([], sts) + } catch (err) { + alert('Unable to link old message block to new one:' + err) + } + } + } + } + + /* + function messageCount () { + var n = 0 + const tables = this.div.children + for (let i = 0; i < tables.length; i++) { + n += tables[i].children.length - 1 + // debug.log(' table length:' + tables[i].children.length) + } + return n + } + */ + + /* Add the live message block with entry field for today + */ + async function appendCurrentMessages () { + const now = new Date() + const chatDocument = this.dateFolder.leafDocumentFromDate(now) + + /// /////////////////////////////////////////////////////////// + this.messageTable = await createMessageTable(now, true) + this.div.appendChild(this.messageTable) + this.div.refresh = function () { + // only the last this.messageTable is live + addNewChatDocumentIfNewDay(new Date()).then(() => { + this.syncMessages(chatChannel, this.messageTable) + desktopNotification(chatChannel) + }) + } // The short chat version fors live update in the pane but we do it in the widget + store.updater.addDownstreamChangeListener(chatDocument, this.div.refresh) // Live update + this.liveMessageTable = this.messageTable + this.latest.this.messageTable = this.liveMessageTable + return this.messageTable + } + + async function loadMoreWhereNeeded (event, fixScroll) { + if (lock) return + lock = true + const freeze = !fixScroll + const magicZone = 150 + // const top = this.div.scrollTop + // const bottom = this.div.scrollHeight - top - this.div.clientHeight + let done + + while ( + this.div.scrollTop < magicZone && + this.earliest.this.messageTable && + !this.earliest.this.messageTable.initial && + this.earliest.this.messageTable.extendBackwards + ) { + // If this has been called before the element is actually in the + // user's DOM tree, then this scrollTop check won't work -> loop forever + // https://github.com/solidos/solid-ui/issues/366 + if (this.div.scrollHeight === 0) { + // console.log(' chat/loadMoreWhereNeeded: trying later...') + setTimeout(loadMoreWhereNeeded, 2000) // couple be less + lock = false + return // abandon now, do later + } + // console.log(' chat/loadMoreWhereNeeded: Going now') + const scrollBottom = this.div.scrollHeight - this.div.scrollTop + debug.log('infinite scroll: adding above: top ' + this.div.scrollTop) + done = await this.earliest.this.messageTable.extendBackwards() + if (freeze) { + this.div.scrollTop = this.div.scrollHeight - scrollBottom + } + if (fixScroll) fixScroll() + if (done) break + } + while ( + this.options.selectedMessage && // we started in the middle not at the bottom + this.div.scrollHeight - this.div.scrollTop - this.div.clientHeight < magicZone && // we are scrolled right to the bottom + this.latest.this.messageTable && + !this.latest.this.messageTable.final && // there is more data to come + this.latest.this.messageTable.extendForwards + ) { + const scrollTop = this.div.scrollTop + debug.log( + 'infinite scroll: adding below: bottom: ' + + (this.div.scrollHeight - this.div.scrollTop - this.div.clientHeight) + ) + done = await this.latest.this.messageTable.extendForwards() // then add more data on the bottom + if (freeze) { + this.div.scrollTop = scrollTop // while adding below keep same things in view + } + if (fixScroll) fixScroll() + if (done) break + } + lock = false + } + + async function loadInitialContent () { + function yank () { + selectedMessageTable.selectedElement.scrollIntoView({ block: 'center' }) + } + + // During initial load ONLY keep scroll to selected thing or bottom + function fixScroll () { + if (this.options.selectedElement) { + this.options.selectedElement.scrollIntoView({ block: 'center' }) // align tops or bottoms + } else { + if (this.liveMessageTable.inputRow.scrollIntoView) { + this.liveMessageTable.inputRow.scrollIntoView(this.newestFirst) // align tops or bottoms + } + } + } + + let live, selectedDocument + if (this.options.selectedMessage) { + selectedDocument = this.options.selectedMessage.doc() + const now = new Date() + const todayDocument = this.dateFolder.leafDocumentFromDate(now) + live = todayDocument.sameTerm(selectedDocument) + } + let selectedMessageTable + if (this.options.selectedMessage && !live) { + const selectedDate = this.dateFolder.dateFromLeafDocument(selectedDocument) + selectedMessageTable = await createMessageTable(selectedDate, live) + this.div.appendChild(selectedMessageTable) + this.earliest.this.messageTable = selectedMessageTable + this.latest.this.messageTable = selectedMessageTable + yank() + setTimeout(yank, 1000) // @@ kludge - restore position distubed by other cHANGES + } else { + // Live end + await appendCurrentMessages() + this.earliest.this.messageTable = this.liveMessageTable + this.latest.this.messageTable = this.liveMessageTable + } + + await loadMoreWhereNeeded(null, fixScroll) + this.div.addEventListener('scroll', loadMoreWhereNeeded) + if (this.options.solo) { + document.body.addEventListener('scroll', loadMoreWhereNeeded) + } + } + + // Body of main constructor + + this.chatChannel = chatChannel + this.options = options || {} + + this.options.authorAboveContent = true + this.newestFirst = this.options.newestFirst === '1' || this.options.newestFirst === true // hack for now + this.channelObject = new ChatChannel(chatChannel, this.options) + this.dateFolder = this.channelObject.dateFolder + + this.div = dom.createElement('this.div') + this.statusArea = this.div.appendChild(dom.createElement('this.div')) + this.userContext = { dom, statusArea, div: this.statusArea } // logged on state, pointers to user's stuff + + this.liveMessageTable = null + + this.earliest = { messageTable: null } // Stuff about each end of the loaded days + this.latest = { messageTable: null } + + this.messageTable = dom.createElement('table') + + // this.messageTable.extendBackwards = extendBackwards // Make function available to scroll stuff -- still needed? + // this.messageTable.extendForwards = extendForwards // Make function available to scroll stuff + + this.messageTable.date = date + const chatDocument = this.dateFolder.leafDocumentFromDate(date) + this.messageTable.chatDocument = chatDocument + + this.messageTable.fresh = false + this.messageTable.setAttribute('style', 'width: 100%;') // fill that this.div! + + if (live) { + this.messageTable.final = true + this.liveMessageTable = this.messageTable + this.latest.this.messageTable = this.messageTable + const tr = renderMessageEditor(this.messageTable, this.userContext, this.options) + if (this.newestFirst) { + this.messageTable.insertBefore(tr, this.messageTable.firstChild) // If newestFirst + } else { + this.messageTable.appendChild(tr) // not newestFirst + } + this.messageTable.inputRow = tr + } + + + let lock = false + + await loadInitialContent() + + }// InfiniteScrolChat constructor + + /** + * Renders a chat message inside a `this.messageTable` + */ + insertMessageIntoTable (messageTable, bindings, fresh) { + const messageRow = renderMessageRow( + bindings, + fresh, + this.options, + this.userContext + ) + const message = messageRow.AJAR_subject + if (options.selectedMessage && options.selectedMessage.sameTerm(message)) { + messageRow.style.backgroundColor = 'yellow' + this.options.selectedElement = messageRow + this.messageTable.selectedElement = messageRow + } + + let done = false + for (let ele = this.messageTable.firstChild; ; ele = ele.nextSibling) { + if (!ele) { + // empty + break + } + this.newestFirst = this.options.newestfirst === true + const dateString = messageRow.AJAR_date + if ( + (dateString > ele.AJAR_date && newestFirst) || + (dateString < ele.AJAR_date && !newestFirst) + ) { + this.messageTable.insertBefore(messageRow, ele) + done = true + break + } + } + if (!done) { + this.messageTable.appendChild(messageRow) + } + } // method interMessageIntoTable + + + + syncMessages (about, messageTable) { + const displayed = {} + let ele, ele2 + for (ele = this.messageTable.firstChild; ele; ele = ele.nextSibling) { + if (ele.AJAR_subject) { + displayed[ele.AJAR_subject.uri] = true + } + } + + const messages = store + .statementsMatching( + about, + ns.wf('message'), + null, + this.messageTable.chatDocument + ) + .map(st => { + return st.object + }) + const stored = {} + messages.forEach(function (m) { + stored[m.uri] = true + if (!displayed[m.uri]) { + addMessage(m, this.messageTable) + } + }) + + // eslint-disable-next-line space-in-parens + for (ele = this.messageTable.firstChild; ele;) { + ele2 = ele.nextSibling + if (ele.AJAR_subject && !stored[ele.AJAR_subject.uri]) { + this.messageTable.removeChild(ele) + } + ele = ele2 + } + for (ele = this.messageTable.firstChild; ele; ele = ele.nextSibling) { + if (ele.AJAR_subject) { + // Refresh thumbs up etc + widgets.refreshTree(ele) // Things inside may have changed too + } + } + } // syncMessages + + renderMessageTable (date, live) { + let scrollBackButton; + let scrollForwardButton; + + /// ///////////////// Scroll down adding more above + + extendBackwards () { + const done = await insertPreviousMessages(true) + if (done) { + if (scrollBackButton) { + scrollBackButton.firstChild.setAttribute( + 'src', + icons.iconBase + 'noun_T-Block_1114655_000000.svg' + ) // T + scrollBackButton.disabled = true + } + this.messageTable.initial = true + } else { + this.messageTable.extendedBack = true + } + setScrollBackButtonIcon() + return done + } + + setScrollBackButtonIcon () { + if (!scrollBackButton) { + return + } + const sense = this.messageTable.extendedBack ? !this.newestFirst : this.newestFirst + const scrollBackIcon = this.messageTable.initial + ? 'noun_T-Block_1114655_000000.svg' + : getScrollbackIcon(sense) + scrollBackButton.firstChild.setAttribute( + 'src', + icons.iconBase + scrollBackIcon + ) + + function getScrollbackIcon (sense) { + return sense ? 'noun_1369241.svg' : 'noun_1369237.svg' + } + } + + scrollBackButtonHandler (_event) { + if (this.messageTable.extendedBack) { + removePreviousMessages(true, this.messageTable) + this.messageTable.extendedBack = false + setScrollBackButtonIcon() + } else { + await extendBackwards() + } + } + + /// ////////////// Scroll up adding more below + + async extendForwards () { + const done = await insertPreviousMessages(false) + if (done) { + scrollForwardButton.firstChild.setAttribute( + 'src', + icons.iconBase + 'noun_T-Block_1114655_000000.svg' + ) + scrollForwardButton.disabled = true + this.messageTable.final = true + } else { + this.messageTable.extendedForwards = true + } + setScrollForwardButtonIcon() + return done + } + + function setScrollForwardButtonIcon () { + const sense = this.messageTable.extendedForwards ? !this.newestFirst : this.newestFirst // noun_T-Block_1114657_000000.svg + const scrollForwardIcon = this.messageTable.final + ? 'noun_T-Block_1114657_000000.svg' + : getScrollForwardButtonIcon(sense) + scrollForwardButton.firstChild.setAttribute( + 'src', + icons.iconBase + scrollForwardIcon + ) + + function getScrollForwardButtonIcon (sense) { + return !sense ? 'noun_1369241.svg' : 'noun_1369237.svg' + } + } + + async function scrollForwardButtonHandler (_event) { + if (this.messageTable.extendedForwards) { + removePreviousMessages(false, this.messageTable) + this.messageTable.extendedForwards = false + setScrollForwardButtonIcon() + } else { + await extendForwards() // async + this.latest.this.messageTable.scrollIntoView(this.newestFirst) + } + } + + /// Body of renderMessagtable + // + // @@ listen for swipe past end event not just button + if (this.options.infinite) { + const scrollBackButtonTR = dom.createElement('tr') + const scrollBackButtonCell = scrollBackButtonTR.appendChild( + dom.createElement('td') + ) + // up traingles: noun_1369237.svg + // down triangles: noun_1369241.svg + const scrollBackIcon = this.newestFirst + ? 'noun_1369241.svg' + : 'noun_1369237.svg' // down and up arrows respoctively + scrollBackButton = widgets.button( + dom, + icons.iconBase + scrollBackIcon, + 'Previous messages ...' + ) + scrollBackButtonCell.style = 'width:3em; height:3em;' + scrollBackButton.addEventListener('click', scrollBackButtonHandler, false) + this.messageTable.extendedBack = false + scrollBackButtonCell.appendChild(scrollBackButton) + setScrollBackButtonIcon() + + const dateCell = scrollBackButtonTR.appendChild(dom.createElement('td')) + dateCell.style = + 'text-align: center; vertical-align: middle; color: #888; font-style: italic;' + dateCell.textContent = widgets.shortDate(date.toISOString(), true) // no time, only date + + // @@@@@@@@@@@ todo move this button to other end of message cell, o + const scrollForwardButtonCell = scrollBackButtonTR.appendChild( + dom.createElement('td') + ) + const scrollForwardIcon = this.newestFirst + ? 'noun_1369241.svg' + : 'noun_1369237.svg' // down and up arrows respoctively + scrollForwardButton = widgets.button( + dom, + icons.iconBase + scrollForwardIcon, + 'Later messages ...' + ) + scrollForwardButtonCell.appendChild(scrollForwardButton) + scrollForwardButtonCell.style = 'width:3em; height:3em;' + scrollForwardButton.addEventListener( + 'click', + scrollForwardButtonHandler, + false + ) + this.messageTable.extendedForward = false + setScrollForwardButtonIcon() + + this.messageTable.extendedForwards = false + + if (!this.newestFirst) { + // opposite end from the entry field + this.messageTable.insertBefore(scrollBackButtonTR, this.messageTable.firstChild) // If not this.newestFirst + } else { + this.messageTable.appendChild(scrollBackButtonTR) // this.newestFirst + } + } + + const sts = store.statementsMatching(null, ns.wf('message'), null, chatDocument) + if (!live && sts.length === 0) { + // not todays + // no need buttomns at the moment + // this.messageTable.style.visibility = 'collapse' // Hide files with no messages + } + sts.forEach(st => { + addMessage(st.object, this.messageTable) + }) + this.messageTable.fresh = true + + // loadMessageTable(this.messageTable, chatDocument) + this.messageTable.fresh = false + return this.messageTable + } // renderMessageTable + + + +} // InfiniteScrolChat class + + export async function infiniteMessageArea2 (dom, wasStore, chatChannel, options) { + const infiniteObject = new InfiniteScrolChat(chatChannel, options) + return infiniteObject.this.div + +} + +export async function infiniteMessageArea (dom, wasStore, chatChannel, options) { + // /////////////////////////////////////////////////////////////////////// + + return this.div +} diff --git a/src/chat/dateFolder.js b/src/chat/dateFolder.js new file mode 100644 index 000000000..2cfc55dc4 --- /dev/null +++ b/src/chat/dateFolder.js @@ -0,0 +1,190 @@ +/** + * Contains the [[DateFolder]] class + * This tracks data stored in dated folders and sub-folders + * + */ +import * as debug from '../debug' +import { store } from 'solid-logic' +import ns from '../ns' +import * as $rdf from 'rdflib' // pull in first avoid cross-refs + +export async function emptyLeaf (leafDocument) { + await store.fetcher.load(leafDocument) + // files can have seealso links. skip ones with no leafObjects with a date + return !( + store.statementsMatching(null, ns.dct('created'), null, leafDocument) + .length > 0 + ) +} + +/** + * Track back through the YYYY/MM/DD tree to find the previous/next day + */ +export class DateFolder { + constructor (rootThing, leafFileName, membershipProperty) { + this.root = rootThing + this.rootFolder = rootThing.dir() + this.leafFileName = leafFileName || 'index.ttl' // typically chat.ttl + this.membershipProperty = membershipProperty || ns.wf('leafObject') + } + + /* Generate the leaf document (rdf object) from date + * @returns: - document + */ + leafDocumentFromDate (date) { + // debug.log('incoming date: ' + date) + const isoDate = date.toISOString() // Like "2018-05-07T17:42:46.576Z" + let path = isoDate.split('T')[0].replace(/-/g, '/') // Like "2018/05/07" + path = this.root.dir().uri + path + '/' + this.leafFileName + return store.sym(path) + } + + /* Generate a date object from the leaf file name + */ + dateFromLeafDocument (doc) { + const head = this.rootFolder.uri.length + const str = doc.uri.slice(head, head + 10).replace(/\//g, '-') + // let date = new Date(str + 'Z') // GMT - but fails in FF - invalid format :-( + const date = new Date(str) // not explicitly UTC but is assumed so in spec + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse + // debug.log('Date for ' + doc + ':' + date.toISOString()) + return date + } + + async loadPrevious (date, backwards) { + async function previousPeriod (file, level) { + function younger (x) { + if (backwards ? x.uri >= file.uri : x.uri <= file.uri) return false // later than we want or same -- looking for different + return true + } + function suitable (x) { + const tail = x.uri + .slice(0, -1) + .split('/') + .slice(-1)[0] + if (!'0123456789'.includes(tail[0])) return false // not numeric + return true + } + + function lastOrFirst (siblings) { + siblings = siblings.filter(suitable) + siblings.sort() // chronological order + if (!backwards) siblings.reverse() + return siblings.pop() // date folder + } + // debug.log(' previousPeriod level' + level + ' file ' + file) + const parent = file.dir() + try { + await store.fetcher.load(parent) + let siblings = store.each(parent, ns.ldp('contains')) + siblings = siblings.filter(younger) + const folder = lastOrFirst(siblings) + if (folder) return folder + // debug.log(' parent no suitable offspring ' + parent) + } catch (err) { + if (err.response && err.response.status && err.response.status === 404) { + debug.log('Error 404 for chat parent file ' + parent) + } else { + debug.log('*** Error NON 404 for chat parent file ' + parent) + // statusTR.appendChild(widgets.errorMessageBlock(dom, err, 'pink')) + throw (new Error(`*** ${err.message} for chat folder ${parent}`)) + } + } + if (level === 0) { + // debug.log('loadPrevious: returning as level is zero') + return null // 3:day, 2:month, 1: year 0: no + } + + const uncle = await previousPeriod(parent, level - 1) + if (!uncle) { + // debug.log(' previousPeriod: nothing left before. ', parent) + return null // reached first ever + } + await store.fetcher.load(uncle) + const cousins = store.each(uncle, ns.ldp('contains')) + const result = lastOrFirst(cousins) + // debug.log(' previousPeriod: returning cousins at level ' + level, cousins) + // debug.log(' previousPeriod: returning result at level ' + level, result) + + return result + } // previousPeriod + + let folder = this.leafDocumentFromDate(date).dir() + while (true) { + const found = await previousPeriod(folder, 3) + if (found) { + const leafDocument = store.sym(found.uri + this.leafFileName) + const nextDate = this.dateFromLeafDocument(leafDocument) + if (!await emptyLeaf(leafDocument)) { + return nextDate + } else { + // debug.log(' loadPrevious: skipping empty ' + leafDocument) + date = nextDate + folder = this.leafDocumentFromDate(date).dir() + // debug.log(' loadPrevious: moved back to ' + folder) + } + } else { + return null // no more left + } + } + } // loadPrevious + + async firstLeaf (backwards) { + // backwards -> last leafObject + const folderStore = $rdf.graph() + const folderFetcher = new $rdf.Fetcher(folderStore) + async function earliestSubfolder (parent) { + function suitable (x) { + const tail = x.uri + .slice(0, -1) + .split('/') + .slice(-1)[0] + if (!'0123456789'.includes(tail[0])) return false // not numeric + return true + } + // debug.log(' parent ' + parent) + delete folderFetcher.requested[parent.uri] + // try { + await folderFetcher.load(parent, { force: true }) // Force fetch as will have changed + // }catch (err) { + // } + + let kids = folderStore.each(parent, ns.ldp('contains')) + kids = kids.filter(suitable) + if (kids.length === 0) { + throw new Error(' @@@ No children to parent2 ' + parent) + } + + kids.sort() + if (backwards) kids.reverse() + return kids[0] + } + const y = await earliestSubfolder(this.root.dir()) + const month = await earliestSubfolder(y) + const d = await earliestSubfolder(month) + const leafDocument = $rdf.sym(d.uri + 'chat.ttl') + await folderFetcher.load(leafDocument) + const leafObjects = folderStore.each( + this.root, + this.membershipProperty, + null, + leafDocument + ) + if (leafObjects.length === 0) { + const msg = + ' INCONSISTENCY -- no chat leafObject in file ' + leafDocument + debug.trace(msg) + throw new Error(msg) + } + const sortMe = leafObjects.map(leafObject => [ + folderStore.any(leafObject, ns.dct('created')), + leafObject + ]) + sortMe.sort() + if (backwards) sortMe.reverse() + /* debug.log( + (backwards ? 'Latest' : 'Earliest') + ' leafObject is ' + sortMe[0][1] + ) */ + return sortMe[0][1] + } // firstleafObject +} // class diff --git a/src/chat/infinite.js b/src/chat/infinite.js new file mode 100644 index 000000000..30073d9ac --- /dev/null +++ b/src/chat/infinite.js @@ -0,0 +1,702 @@ +/** + * Contains the [[infiniteMessageArea]] class + * @packageDocumentation + */ +// import { findBookmarkDocument } from './bookmarks' +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +import { store } from 'solid-logic' +import * as debug from '../debug' +import { icons } from '../iconBase' +import ns from '../ns' +// import { style } from '../style' +// import * as utils from '../utils' +import * as widgets from '../widgets' +// import * as pad from '../pad' +// import { DateFolder } from './dateFolder' +import { ChatChannel, isDeleted } from './chatLogic' +import { renderMessageEditor, renderMessageRow } from './message' + +// const UI = { authn, icons, ns, media, pad, $rdf, store, style, utils, widgets } + +export function desktopNotification (str) { + // Let's check if the browser supports notifications + if (!('Notification' in window)) { + debug.warn('This browser does no t support desktop notification') + } else if (Notification.permission === 'granted') { + // Let's check whether notificatio n permissions have already been granted + // eslint-disable-next-line no-new + new Notification(str) + } else if (Notification.permission !== 'denied') { + // Otherwise, we need to ask the user for permission + Notification.requestPermission().then(function (permission) { + // If the user accepts, let's create a notification + if (permission === 'granted') { + // eslint-disable-next-line no-new + new Notification(str) + } + }) + } + // At last, if the user has denied notifications, and you + // want to be respectful there is no need to bother them any more. +} + +/** + * Renders a chat message inside a `messageTable` + */ +export async function insertMessageIntoTable (channelObject, messageTable, message, fresh, options, userContext) { + const messageRow = await renderMessageRow(channelObject, + message, + fresh, + options, + userContext + ) + + // const message = messageRow.AJAR_subject + if (options.selectedMessage && options.selectedMessage.sameTerm(message)) { + messageRow.style.backgroundColor = 'yellow' + options.selectedElement = messageRow + messageTable.selectedElement = messageRow + } + + let done = false + for (let ele = messageTable.firstChild; ; ele = ele.nextSibling) { + if (!ele) { + // empty + break + } + const newestFirst = options.newestfirst === true + const dateString = messageRow.AJAR_date + if ( + (dateString > ele.AJAR_date && newestFirst) || + (dateString < ele.AJAR_date && !newestFirst) + ) { + messageTable.insertBefore(messageRow, ele) + done = true + break + } + } + if (!done) { + messageTable.appendChild(messageRow) + } +} + +/** + * Common code for a chat (discussion area of messages about something) + * This version runs over a series of files for different time periods + * + * Parameters for the whole chat like its title are stored on + * index.ttl#this and the chats messages are stored in YYYY/MM/DD/chat.ttl + * + * Use to import store as param 2, now ignores it and uses the UI main store + * + * Options include: + + - shiftEnterSendsMessage: Use shift/enter to send message, Enter to add newline, instead of the reverse. + - authorDateOnLeft: Display the author's anme and date of the message in the left column instead of first above the content + - selectedMessage: Display one message highlighted with the chat around it + - solo: By itelf on a webpage, so user scroll anywhere in the web page scan scroll the chat. + - newestFirst: Arrange the chat messages chronologically newest at the top insted of at the bottom + - infinite: Use infinite scroll + - showDeletedMessages: Show messages which have been delted as "deleted message". Otherwise hide them. + - expandImagesInline: If a URI by itself in a message looks like an image URI, replace it with the image + - inlineImageHeightEms: The height (in ems) of images expaned from their URIs in the chat. + + */ +export async function infiniteMessageArea (dom, wasStore, chatChannel, options) { + // /////////////////////////////////////////////////////////////////////// + + async function syncMessages (chatChannel, messageTable) { + const displayed = {} + let ele, ele2 + for (ele = messageTable.firstChild; ele; ele = ele.nextSibling) { + if (ele.AJAR_subject) { + displayed[ele.AJAR_subject.uri] = true + } + } + const messages = store.each(chatChannel, ns.wf('message'), null, messageTable.chatDocument) + + const stored = {} + for (const m of messages) { + stored[m.uri] = true + if (!displayed[m.uri]) { + await addMessage(m, messageTable) + } + } + + for (ele = messageTable.firstChild; ele;) { + ele2 = ele.nextSibling + if (ele.AJAR_subject && !stored[ele.AJAR_subject.uri]) { + messageTable.removeChild(ele) + } + ele = ele2 + } + for (ele = messageTable.firstChild; ele; ele = ele.nextSibling) { + if (ele.AJAR_subject) { + // Refresh thumbs up etc + widgets.refreshTree(ele) // Things inside may have changed too + } + } + } // syncMessages + + // Called once per original message displayed + async function addMessage (message, messageTable) { + // const latest = await mostRecentVersion(message) + // const content = store.any(latest, ns.sioc('content')) + if (isDeleted(message) && !options.showDeletedMessages) { + return // ignore deleted messaged -- @@ could also leave a placeholder + } + /* if (isReplaced(message)) { // + return // this is old version + } */ + let thread = store.any(null, ns.sioc('has_member'), message, message.doc()) + const id = store.any(message, ns.sioc('id'), null, message.doc()) + if (id && !thread) { + thread = store.any(null, ns.sioc('has_member'), id, message.doc()) + } + + if (options.thread) { // only show things in thread + if (store.holds(message, ns.sioc('has_reply'), options.thread)) { // root of thread + // debug.log(' addMessage: displaying root of thread ' + thread) + } else if (thread && thread.sameTerm(options.thread)) { + // debug.log(' addMessage: Displaying body of thread ' + message.uri.slice(-10)) + } else { + // debug.log(' addMessage: Suppress non-thread message in thread table ' + message.uri.slice(-10)) + return // suppress message not in thread + } + } else { // Not threads + if (thread) { + // debug.log(' addMessage: Suppress thread message in non-thread table ' + message.uri.slice(-10)) + return // supress thread messages in body + } else { + // debug.log(' addMessage: Normal non-thread message in non-thread table ' + message.uri.slice(-10)) + } + } + if (!messageTable.fresh) { // if messageTable has been updated with insertMessageIntoTable() don't do it again + // debug.log('@@@ infinite insertMessageIntoTable ' + message) // alain + // debug.log('fresh ' + messageTable.fresh) + // debug.log(messageTable) + await insertMessageIntoTable(channelObject, + messageTable, + message, + messageTable.fresh, + options, + userContext + ) // fresh from elsewhere + } + } + + /* Add a new messageTable at the top/bottom + + */ + async function insertPreviousMessages (backwards) { + const extremity = backwards ? earliest : latest + let date = extremity.messageTable.date // day in mssecs + + // Are we at the top of a thread? + if (backwards && earliest.limit && date <= earliest.limit) { + if (!liveMessageTable) await appendCurrentMessages() // If necessary skip to today and add that + return true // done + } + // debug.log(' insertPreviousMessages: loadPrevious given date ' + date) + + date = await dateFolder.loadPrevious(date, backwards) // backwards + // debug.log(' insertPreviousMessages: loadPrevious returns date ' + date) + + /* debug.log( + `insertPreviousMessages: from ${ + backwards ? 'backwards' : 'forwards' + } loadPrevious: ${date}` + ) */ + if (!date && !backwards && !liveMessageTable) { + await appendCurrentMessages() // If necessary skip to today and add that + } + if (!date) return true // done + let live = false + if (!backwards) { + const todayDoc = dateFolder.leafDocumentFromDate(new Date()) + const doc = dateFolder.leafDocumentFromDate(date) + live = doc.sameTerm(todayDoc) // Is this todays? + } + const newMessageTable = await createMessageTable(date, live) + extremity.messageTable = newMessageTable // move pointer to earliest + if (backwards ? newestFirst : !newestFirst) { + // put on bottom or top + div.appendChild(newMessageTable) + } else { + // put on top as we scroll back + div.insertBefore(newMessageTable, div.firstChild) + } + return live // not done + } + + /* Remove message tables earlier than this one + */ + function removePreviousMessages (backwards, messageTable) { + if (backwards ? newestFirst : !newestFirst) { + // it was put on bottom + while (messageTable.nextSibling) { + div.removeChild(messageTable.nextSibling) + } + } else { + // it was put on top as we scroll back + while (messageTable.previousSibling) { + div.removeChild(messageTable.previousSibling) + } + } + const extr = backwards ? earliest : latest + extr.messageTable = messageTable + } + + /* Load and render message table + ** @returns DOM element generates + */ + async function createMessageTable (date, live) { + // debug.log(' createMessageTable for ' + date) + const chatDocument = dateFolder.leafDocumentFromDate(date) + try { + await store.fetcher.createIfNotExists(chatDocument) + } catch (err) { + const messageTable = dom.createElement('table') + const statusTR = messageTable.appendChild(dom.createElement('tr')) // ### find status in exception + if (err.response && err.response.status && err.response.status === 404) { + // debug.log('Error 404 for chat file ' + chatDocument) + return await renderMessageTable(date, live) // no message file is fine. will be created later + // statusTR.appendChild(widgets.errorMessageBlock(dom, 'no message file', 'white')) + } else { + debug.log('*** Error NON 404 for chat file ' + chatDocument) + statusTR.appendChild(widgets.errorMessageBlock(dom, err, 'pink')) + } + return statusTR + } + return await renderMessageTable(date, live) + } + + async function renderMessageTable (date, live) { + const scrollBackbutton = null // was let + const scrollForwardButton = null // was let + + /// ///////////////// Scroll down adding more above + + async function extendBackwards () { + const done = await insertPreviousMessages(true) + if (done) { + if (scrollBackbutton) { + scrollBackbutton.firstChild.setAttribute( + 'src', + icons.iconBase + 'noun_T-Block_1114655_000000.svg' + ) // T + scrollBackbutton.disabled = true + } + messageTable.initial = true + } else { + messageTable.extendedBack = true + } + setScrollBackbuttonIcon() + return done + } + + function setScrollBackbuttonIcon () { + if (!scrollBackbutton) { + return + } + const sense = messageTable.extendedBack ? !newestFirst : newestFirst + const scrollBackIcon = messageTable.initial + ? 'noun_T-Block_1114655_000000.svg' + : getScrollbackIcon(sense) + scrollBackbutton.firstChild.setAttribute( + 'src', + icons.iconBase + scrollBackIcon + ) + + function getScrollbackIcon (sense) { + return sense ? 'noun_1369241.svg' : 'noun_1369237.svg' + } + } + + /// ////////////// Scroll up adding more below + + async function extendForwards () { + const done = await insertPreviousMessages(false) + /* + if (done) { + scrollForwardButton.firstChild.setAttribute( + 'src', + icons.iconBase + 'noun_T-Block_1114655_000000.svg' + ) + scrollForwardButton.disabled = true + messageTable.final = true + } else { + messageTable.extendedForwards = true + } + setScrollForwardButtonIcon() + */ + return done + } + + function setScrollForwardButtonIcon () { + if (!scrollForwardButton) return + const sense = messageTable.extendedForwards ? !newestFirst : newestFirst // noun_T-Block_1114657_000000.svg + const scrollForwardIcon = messageTable.final + ? 'noun_T-Block_1114657_000000.svg' + : getScrollForwardButtonIcon(sense) + scrollForwardButton.firstChild.setAttribute( + 'src', + icons.iconBase + scrollForwardIcon + ) + + function getScrollForwardButtonIcon (sense) { + return !sense ? 'noun_1369241.svg' : 'noun_1369237.svg' + } + } + + // eslint-disable-next-line no-unused-vars + async function scrollForwardButtonHandler (_event) { + if (messageTable.extendedForwards) { + removePreviousMessages(false, messageTable) + messageTable.extendedForwards = false + setScrollForwardButtonIcon() + } else { + await extendForwards() // async + latest.messageTable.scrollIntoView(newestFirst) + } + } + + /// /////////////////////// + /* + options = options || {} + options.authorDateOnLeft = true + const newestFirst = options.newestFirst === '1' || options.newestFirst === true // hack for now + const channelObject = new ChatChannel(chatChannel, options) + const dateFolder = channelObject.dateFolder + + const div = dom.createElement('div') + const statusArea = div.appendChild(dom.createElement('div')) + const userContext = { dom, statusArea, div: statusArea } // logged on state, pointers to user's stuff + +*/ + // debug.log('Options for called message Area', options) + const messageTable = dom.createElement('table') + messageTable.style.width = '100%' // fill the pane div + messageTable.extendBackwards = extendBackwards // Make function available to scroll stuff + messageTable.extendForwards = extendForwards // Make function available to scroll stuff + + messageTable.date = date + const chatDocument = dateFolder.leafDocumentFromDate(date) + messageTable.chatDocument = chatDocument + + messageTable.fresh = false + messageTable.setAttribute('style', 'width: 100%;') // fill that div! + if (live) { + messageTable.final = true + liveMessageTable = messageTable + latest.messageTable = messageTable + const tr = renderMessageEditor(channelObject, messageTable, userContext, options) + if (newestFirst) { + messageTable.insertBefore(tr, messageTable.firstChild) // If newestFirst + } else { + messageTable.appendChild(tr) // not newestFirst + } + messageTable.inputRow = tr + } + + /// ///// Infinite scroll + // + // @@ listen for swipe past end event not just button + const test = true + if (test) { // ws options.infinite but need for non-infinite + const titleTR = dom.createElement('tr') + /* const scrollBackbuttonCell = titleTR.appendChild( + dom.createElement('td') + ) */ + // up traingles: noun_1369237.svg + // down triangles: noun_1369241.svg + /* + const scrollBackIcon = newestFirst + ? 'noun_1369241.svg' + : 'noun_1369237.svg' // down and up arrows respoctively + scrollBackbutton = widgets.button( + dom, + icons.iconBase + scrollBackIcon, + 'Previous messages ...' + ) + scrollBackbuttonCell.style = 'width:3em; height:3em;' + scrollBackbutton.addEventListener('click', scrollBackbuttonHandler, false) + messageTable.extendedBack = false + scrollBackbuttonCell.appendChild(scrollBackbutton) + setScrollBackbuttonIcon() + */ + const dateCell = titleTR.appendChild(dom.createElement('td')) + dateCell.style = + 'text-align: center; vertical-align: middle; color: #888; font-style: italic;' + dateCell.textContent = widgets.shortDate(date.toISOString(), true) // no time, only date + + // @@@@@@@@@@@ todo move this button to other end of message cell, o + const scrollForwardButtonCell = titleTR.appendChild( + dom.createElement('td') + ) + if (options.includeRemoveButton) { + scrollForwardButtonCell.appendChild(widgets.cancelButton(dom, _e => { + div.parentNode.removeChild(div) + })) + } + /* + const scrollForwardIcon = newestFirst + ? 'noun_1369241.svg' + : 'noun_1369237.svg' // down and up arrows respoctively + scrollForwardButton = widgets.button( + dom, + icons.iconBase + scrollForwardIcon, + 'Later messages ...' + ) + scrollForwardButtonCell.appendChild(scrollForwardButton) + scrollForwardButtonCell.style = 'width:3em; height:3em;' + scrollForwardButton.addEventListener( + 'click', + scrollForwardButtonHandler, + false + ) + messageTable.extendedForward = false + setScrollForwardButtonIcon() + */ + messageTable.extendedForwards = false + + if (!newestFirst) { + // opposite end from the entry field + messageTable.insertBefore(titleTR, messageTable.firstChild) // If not newestFirst + } else { + messageTable.appendChild(titleTR) // newestFirst + } + } + + const sts = store.statementsMatching(null, ns.wf('message'), null, chatDocument) + if (!live && sts.length === 0) { + // not todays + // no need buttomns at the moment + // messageTable.style.visibility = 'collapse' // Hide files with no messages + } + for (const st of sts) { + await addMessage(st.object, messageTable) + } + messageTable.fresh = true // message table updated with insertMessageIntoTable() + return messageTable + } // renderMessageTable + + async function addNewChatDocumentIfNewDay () { + // @@ Remove listener from previous table as it is now static + const newChatDocument = dateFolder.leafDocumentFromDate(new Date()) + if (!newChatDocument.sameTerm(latest.messageTable.chatDocument)) { + // It is a new day + if (liveMessageTable.inputRow) { + liveMessageTable.removeChild(liveMessageTable.inputRow) + delete liveMessageTable.inputRow + } + const oldChatDocument = latest.messageTable.chatDocument + await appendCurrentMessages() + // Adding a link in the document will ping listeners to add the new block too + if ( + !store.holds( + oldChatDocument, + ns.rdfs('seeAlso'), + newChatDocument, + oldChatDocument + ) + ) { + const sts = [ + $rdf.st( + oldChatDocument, + ns.rdfs('seeAlso'), + newChatDocument, + oldChatDocument + ) + ] + try { + store.updater.update([], sts) + } catch (err) { + alert('Unable to link old chat file to new one:' + err) + } + } + } + } + + /* + function messageCount () { + var n = 0 + const tables = div.children + for (let i = 0; i < tables.length; i++) { + n += tables[i].children.length - 1 + // debug.log(' table length:' + tables[i].children.length) + } + return n + } +*/ + + /* Add the live message block with entry field for today + */ + async function appendCurrentMessages () { + const now = new Date() + const chatDocument = dateFolder.leafDocumentFromDate(now) + + /// /////////////////////////////////////////////////////////// + const messageTable = await createMessageTable(now, true) + div.appendChild(messageTable) + div.refresh = async function () { + // only the last messageTable is live + await addNewChatDocumentIfNewDay(new Date()) + await syncMessages(chatChannel, messageTable) // @@ livemessagetable?? + desktopNotification(chatChannel) + } // The short chat version the live update listening is done in the pane but we do it in the widget @@ + store.updater.addDownstreamChangeListener(chatDocument, div.refresh) // Live update + liveMessageTable = messageTable + latest.messageTable = liveMessageTable + return messageTable + } + + async function loadMoreWhereNeeded (event, fixScroll) { + if (lock) return + lock = true + const freeze = !fixScroll + const magicZone = 150 + // const top = div.scrollTop + // const bottom = div.scrollHeight - top - div.clientHeight + let done + + while ( + div.scrollTop < magicZone && + earliest.messageTable && + !earliest.messageTable.initial && + earliest.messageTable.extendBackwards + ) { + // If this has been called before the element is actually in the + // user's DOM tree, then this scrollTop check won't work -> loop forever + // https://github.com/solidos/solid-ui/issues/366 + if (div.scrollHeight === 0) { + // debug.log(' chat/loadMoreWhereNeeded: trying later...') + setTimeout(loadMoreWhereNeeded, 2000) // couple be less + lock = false + return // abandon now, do later + } + // debug.log(' chat/loadMoreWhereNeeded: Going now') + const scrollBottom = div.scrollHeight - div.scrollTop + // debug.log('infinite scroll: adding above: top ' + div.scrollTop) + done = await earliest.messageTable.extendBackwards() + if (freeze) { + div.scrollTop = div.scrollHeight - scrollBottom + } + if (fixScroll) fixScroll() + if (done) break + } + while ( + options.selectedMessage && // we started in the middle not at the bottom + div.scrollHeight - div.scrollTop - div.clientHeight < magicZone && // we are scrolled right to the bottom + latest.messageTable && + !latest.messageTable.final && // there is more data to come + latest.messageTable.extendForwards + ) { + const scrollTop = div.scrollTop + /* debug.log( + 'infinite scroll: adding below: bottom: ' + + (div.scrollHeight - div.scrollTop - div.clientHeight) + ) */ + done = await latest.messageTable.extendForwards() // then add more data on the bottom + if (freeze) { + div.scrollTop = scrollTop // while adding below keep same things in view + } + if (fixScroll) fixScroll() + if (done) break + } + lock = false + } + + async function loadInitialContent () { + function yank () { + if (selectedMessageTable && selectedMessageTable.selectedElement) { + selectedMessageTable.selectedElement.scrollIntoView({ block: 'center' }) + } + } + + // During initial load ONLY keep scroll to selected thing or bottom + function fixScroll () { + if (options.selectedElement) { + options.selectedElement.scrollIntoView({ block: 'center' }) // align tops or bottoms + } else { + if (liveMessageTable.inputRow.scrollIntoView) { + liveMessageTable.inputRow.scrollIntoView(newestFirst) // align tops or bottoms + } + } + } + + let live, selectedDocument, threadRootDocument + if (options.selectedMessage) { + selectedDocument = options.selectedMessage.doc() + } + if (threadRootMessage) { + threadRootDocument = threadRootMessage.doc() + } + const initialDocment = selectedDocument || threadRootDocument + + if (initialDocment) { + const now = new Date() + const todayDocument = dateFolder.leafDocumentFromDate(now) + live = todayDocument.sameTerm(initialDocment) + } + + let selectedMessageTable + if (initialDocment && !live) { + const selectedDate = dateFolder.dateFromLeafDocument(initialDocment) + selectedMessageTable = await createMessageTable(selectedDate, live) + div.appendChild(selectedMessageTable) + earliest.messageTable = selectedMessageTable + latest.messageTable = selectedMessageTable + yank() + setTimeout(yank, 1000) // @@ kludge - restore position distubed by other cHANGES + } else { + // Live end + await appendCurrentMessages() + earliest.messageTable = liveMessageTable + latest.messageTable = liveMessageTable + } + + await loadMoreWhereNeeded(null, fixScroll) + div.addEventListener('scroll', loadMoreWhereNeeded) + if (options.solo) { + document.body.addEventListener('scroll', loadMoreWhereNeeded) + } + } + + // Body of main function + + options = options || {} + options.authorDateOnLeft = false // @@ make a user optiosn + const newestFirst = options.newestFirst === '1' || options.newestFirst === true // hack for now + + const channelObject = new ChatChannel(chatChannel, options) + const dateFolder = channelObject.dateFolder + + const div = dom.createElement('div') + channelObject.div = div + + const statusArea = div.appendChild(dom.createElement('div')) + const userContext = { dom, statusArea, div: statusArea } // logged on state, pointers to user's stuff + + let liveMessageTable + let threadRootMessage + const earliest = { messageTable: null } // Stuff about each end of the loaded days + const latest = { messageTable: null } + + if (options.thread) { + const thread = options.thread + threadRootMessage = store.any(null, ns.sioc('has_reply'), thread, thread.doc()) + if (threadRootMessage) { + const threadTime = store.any(threadRootMessage, ns.dct('created'), null, threadRootMessage.doc()) + if (threadTime) { + earliest.limit = new Date(threadTime.value) + // debug.log(' infinite: thread start at ' + earliest.limit) + } + } + } + + let lock = false + + await loadInitialContent() + return div +} diff --git a/src/chat/keys.ts b/src/chat/keys.ts new file mode 100644 index 000000000..283e331ef --- /dev/null +++ b/src/chat/keys.ts @@ -0,0 +1,113 @@ +import * as debug from '../debug' +import { schnorr } from '@noble/curves/secp256k1.js' +import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js' +import ns from '../ns' +import { store } from 'solid-logic' +import { NamedNode } from 'rdflib' +import * as $rdf from 'rdflib' +import { getExistingPublicKey, pubKeyUrl, privKeyUrl, getExistingPrivateKey } from '../utils/keyHelpers/accessData' +import { setAcl, keyContainerAclBody, keyAclBody } from '../utils/keyHelpers/acl' + +export function generatePrivateKey (): string { + return bytesToHex(schnorr.utils.randomSecretKey()) +} + +export function generatePublicKey (privateKey: string): string { + return bytesToHex(schnorr.getPublicKey(hexToBytes(privateKey))) +} + +/** + * getPublicKey + * used for displaying messages in chat, therefore does not + * create a new key if not found + * @param webId + * @returns string | undefined + */ +export async function getPublicKey (webId: NamedNode) { + await store.fetcher.load(webId) + const publicKeyDoc = await pubKeyUrl(webId) + try { + await store.fetcher.load(publicKeyDoc) // url.href) + const key = store.any(webId, ns.solid('publicKey')) + return key?.value // as NamedNode + } catch (_err) { + return undefined + } +} + +export async function getPrivateKey (webId: NamedNode) { + await store.fetcher.load(webId) + // find keys url's + const publicKeyDoc = await pubKeyUrl(webId) + const privateKeyDoc = await privKeyUrl(webId) + + // find key pair + const publicKey = await getExistingPublicKey(webId, publicKeyDoc) + let privateKey = await getExistingPrivateKey(webId, privateKeyDoc) + + // is publicKey valid ? + let validPublicKey = true + if (privateKey && (publicKey !== generatePublicKey(privateKey as string))) { + if (confirm('This is strange the publicKey is not valid for\n' + webId?.uri + + '\'shall we repair keeping the private key ?')) validPublicKey = false + } + + // create key pair or repair publicKey + if (!privateKey || !publicKey || !validPublicKey) { + let del: any[] = [] + let add: any[] = [] + + if (!privateKey) { + // add = [] + privateKey = generatePrivateKey() + add = [$rdf.st(webId, ns.solid('privateKey'), $rdf.literal(privateKey), store.sym(privateKeyDoc))] + await saveKey(privateKeyDoc, [], add, webId.uri) + } + if (!publicKey || !validPublicKey) { + del = [] + // delete invalid public key + if (publicKey) { + del = [$rdf.st(webId, ns.solid('publicKey'), $rdf.lit(publicKey), store.sym(publicKeyDoc))] + debug.log('delete invalid publicKey ' + del) + } + // update new valid key + const newPublicKey = generatePublicKey(privateKey) + add = [$rdf.st(webId, ns.solid('publicKey'), $rdf.literal(newPublicKey), store.sym(publicKeyDoc))] + await saveKey(publicKeyDoc, del, add) + } + const keyContainer = privateKeyDoc.substring(0, privateKeyDoc.lastIndexOf('/') + 1) + await setAcl(keyContainer, keyContainerAclBody(webId.uri)) // includes DELETE and PUT + } + return privateKey as string +} + +const deleteKeyAcl = async (keyDoc: string) => { + await store.fetcher.load(keyDoc) + + const keyAclDoc = store.any(store.sym(keyDoc), store.sym('http://www.iana.org/assignments/link-relations/acl')) + if (keyAclDoc) { + // delete READ only keyAclDoc. This is possible if the webId is an owner + try { + const response = await store.fetcher.webOperation('DELETE', keyAclDoc.value) // this may fail if webId is not an owner + debug.log('delete keyAcl' + keyAclDoc.value + ' ' + response.status) // should test 404 and 2xx + } catch (err) { + if (err.response.status !== 404) { throw new Error(err) } + debug.log('delete keyAcl' + keyAclDoc.value + ' ' + err.response.status) // should test 404 and 2xx + } + } +} + +/** + * delete acl if keydoc exists + * create/edit keyDoc + * set keyDoc acl + */ +async function saveKey (keyDoc: string, del, add, me: string = '') { + await deleteKeyAcl(keyDoc) + // save key + await store.updater.updateMany(del, add) // or a promise store.updater.update ? + + // create READ only ACL + const aclBody = keyAclBody(keyDoc, me) + await setAcl(keyDoc, aclBody) +} diff --git a/src/chat/message.js b/src/chat/message.js new file mode 100644 index 000000000..7f2298a50 --- /dev/null +++ b/src/chat/message.js @@ -0,0 +1,565 @@ +/** UI code for individual messages: display them, edit them + * + * @packageDocumentation + */ + +/* global $rdf */ +import { insertMessageIntoTable } from './infinite' +import { messageToolbar, sentimentStripLinked } from './messageTools' +import { findBookmarkDocument } from './bookmarks' +import { mostRecentVersion, originalVersion, allVersions } from './chatLogic' +import * as debug from '../debug' +import { icons } from '../iconBase' +import { store, authn } from 'solid-logic' +import { ensureLoggedIn } from '../login/login' +import { media } from '../media/index' +import ns from '../ns' +import * as pad from '../pad' +import { style } from '../style' +import * as utils from '../utils' +import * as widgets from '../widgets' +import { getBlankMsg, verifySignature, SEC } from './signature' +import { getPublicKey } from './keys' + +const dom = window.document +const messageBodyStyle = style.messageBodyStyle + +const label = utils.label + +/** + * elementForImageURI + * HTML component for an image + * @param imageUri + * @param options { inlineImageHeightEms } + * @returns HTMLAnchorElement For Image + */ +export function elementForImageURI (imageUri, options) { + const img = dom.createElement('img') + let height = '10' + if (options.inlineImageHeightEms) { + height = ('' + options.inlineImageHeightEms).trim() + } + img.setAttribute( + 'style', + 'max-height: ' + height + 'em; border-radius: 1em; margin: 0.7em;' + ) + // widgets.makeDropTarget(img, handleURIsDroppedOnMugshot, droppedFileHandler) + if (imageUri) img.setAttribute('src', imageUri) + const anchor = dom.createElement('a') + anchor.setAttribute('href', imageUri) + anchor.setAttribute('target', 'images') + anchor.appendChild(img) + widgets.makeDraggable(img, $rdf.sym(imageUri)) + return anchor +} + +const anchor = function (text, term) { + // If there is no link return an element anyway + const a = dom.createElement('a') + if (term && term.uri) { + a.setAttribute('href', term.uri) + a.addEventListener('click', widgets.openHrefInOutlineMode, true) + a.setAttribute('style', 'color: #3B5998; text-decoration: none; ') // font-weight: bold + } + a.textContent = text + return a +} + +function nickname (person) { + const s = store.any(person, ns.foaf('nick')) + if (s) return '' + s.value + return '' + label(person) +} + +/** + * creatorAndDate + * Displays creator and date for a chat message + * inside the `td1` element + * @param td1 + * @param creator + * @param date + * @param message + * @returns HTMLAnchorElement For Image + */ +export function creatorAndDate (td1, creator, date, message) { + const nickAnchor = td1.appendChild(anchor(nickname(creator), creator)) + if (creator.uri) { + store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function ( + _ok, + _body + ) { + nickAnchor.textContent = nickname(creator) + }) + } + td1.appendChild(dom.createElement('br')) + td1.appendChild(anchor(date, message)) +} + +/** + * creatorAndDateHorizontal + * Horizontally displays creator and date for a chat message + * inside the `td1` element + * @param td1 + * @param creator + * @param date + * @param message + * @returns HTMLAnchorElement For Image + */ +export function creatorAndDateHorizontal (td1, creator, date, message) { + const nickAnchor = td1.appendChild(anchor(label(creator), creator)) + if (creator.uri) { + store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function ( + _ok, + _body + ) { + nickAnchor.textContent = nickname(creator) + }) + } + const dateBit = td1.appendChild(anchor(date, message)) + dateBit.style.fontSize = '80%' + dateBit.style.marginLeft = '1em' + td1.appendChild(dom.createElement('br')) +} + +/** + * renderMessageRow + * Renders a chat message, read-only mode + * @param channelObject + * @param message + * @param fresh + * @param options + * @param userContext + * @returns Message Row HTML Table Element + */ +export async function renderMessageRow (channelObject, message, fresh, options, userContext) { + let unsignedMessage = false + const colorizeByAuthor = + options.colorizeByAuthor === '1' || options.colorizeByAuthor === true + + // const id = store.any(latestVersion, ns.sioc('id')) + // const replies = store.each(latestVersion, ns.sioc('has_reply')) + + const creator = store.any(message, ns.foaf('maker')) + const date = store.any(message, ns.dct('created')) + const latestVersion = await mostRecentVersion(message) + const latestVersionCreator = store.any(latestVersion, ns.foaf('maker')) + + // use latest content if same owner, else use original + // this is may be too strict. Should we find latest valid version if any ? + const msgId = creator.uri === latestVersionCreator?.uri ? latestVersion : message + const content = store.any(msgId, ns.sioc('content')) + + const versions = await allVersions(msgId) + if (versions.length > 1) { + debug.log('renderMessageRow versions: ', versions.join(', ')) + } + // be tolerant in accepting replies on any version of a message + const replies = versions.map(version => store.each(version, ns.sioc('has_reply'))).flat() + + let thread = null + const straightReplies = [] + for (const reply of replies) { + if (store.holds(reply, ns.rdf('type'), ns.sioc('Thread'))) { + thread = reply + debug.log('renderMessageRow: found thread: ' + thread) + } else { + straightReplies.push(reply) + } + } + if (straightReplies.length > 1) { + debug.log('renderMessageRow: found normal replies: ', straightReplies) + } + if (!thread) { + // thread = store.any(message, ns.sioc('has_reply')) + thread = store.any(null, ns.sioc('has_member'), message) + } + // debug.log('@@@@ is thread' + thread) + + // get signature + const signature = store.any(msgId, $rdf.sym(`${SEC}proofValue`)) + + // set proof message object + const msg = getBlankMsg() + msg.id = msgId.uri + msg.created = store.any(msgId, ns.dct('created')).value + msg.content = content.value + msg.maker = creator.uri + + // verify signature + if (!signature?.value) { // unsigned message + unsignedMessage = true + debug.warn(msgId.uri + ' is unsigned') // TODO replace with UI (colored message ?) + } else { // signed message, get public key and check signature + getPublicKey(creator).then(publicKey => { + // debug.log(creator.uri + '\n' + msg.created + '\n' + msg.id + '\n' + publicKey) + if (!publicKey) { + debug.warn('message is signed but ' + creator.uri + ' is missing publicKey') + } + // check that publicKey is a valid hex string + const regex = /[0-9A-Fa-f]{6}/g + if (!publicKey?.match(regex)) debug.warn('invalid publicKey hex string\n' + creator.uri + '\n' + publicKey) + // verify signature + else if (signature?.value && !verifySignature(signature?.value, msg, publicKey)) debug.warn('invalid signature\n' + msg.id) + }) + } + + const originalMessage = await originalVersion(message) + const edited = !message.sameTerm(originalMessage) + // @@ load it first @@ Or display the new data at the old date. + // @@@ kludge! + const sortDate = store.the(originalMessage, ns.dct('created'), null, originalMessage.doc()) || store.the(message, ns.dct('created'), null, message.doc()) + // In message + + const messageRow = dom.createElement('tr') + if (unsignedMessage) messageRow.setAttribute('style', 'background-color: red') + messageRow.AJAR_date = sortDate.value + messageRow.AJAR_subject = message + + const td1 = dom.createElement('td') + messageRow.appendChild(td1) + if (!options.authorDateOnLeft) { + const img = dom.createElement('img') + img.setAttribute( + 'style', + 'max-height: 2.5em; max-width: 2.5em; border-radius: 0.5em; margin: auto;' + ) + widgets.setImage(img, creator) + td1.appendChild(img) + } else { + creatorAndDate(td1, creator, widgets.shortDate(sortDate.value), message) + } + let bothDates = widgets.shortDate(sortDate.value) + if (edited) { + bothDates += ' ... ' + widgets.shortDate(date.value) + } + + // Render the content ot the message itself + const td2 = messageRow.appendChild(dom.createElement('td')) + + if (!options.authorDateOnLeft) { + creatorAndDateHorizontal( + td2, + creator, + bothDates, // widgets.shortDate(dateString) + message + ) + } + const text = content ? content.value.trim() : '??? no content?' + const isURI = /^https?:\/[^ <>]*$/i.test(text) + let para = null + if (isURI) { + const isImage = /\.(gif|jpg|jpeg|tiff|png|svg)$/i.test(text) // @@ Should use content-type not URI + if (isImage && options.expandImagesInline) { + const img = elementForImageURI(text, options) + td2.appendChild(img) + } else { + // Link but not Image + const anc = td2.appendChild(dom.createElement('a')) + para = anc.appendChild(dom.createElement('p')) + anc.href = text + para.textContent = text + td2.appendChild(anc) + } + } else { + // text + para = dom.createElement('p') + td2.appendChild(para) + para.textContent = text + } + if (para) { + const bgcolor = colorizeByAuthor + ? pad.lightColorHash(creator) + : getBgColor(fresh) + para.setAttribute( + 'style', + messageBodyStyle + 'background-color: ' + bgcolor + ';' + ) + } + + function getBgColor (fresh) { + return fresh ? '#e8ffe8' : 'white' + } + + // Sentiment strip + const strip = await sentimentStripLinked(message, message.doc()) + if (strip.children.length) { + td2.appendChild(dom.createElement('br')) + td2.appendChild(strip) + } + + // Message tool bar button + const td3 = dom.createElement('td') + messageRow.appendChild(td3) + const toolsButton = widgets.button( + dom, + icons.iconBase + 'noun_243787.svg', + '...' + ) + td3.appendChild(toolsButton) + toolsButton.addEventListener('click', async function (_event) { + if (messageRow.toolTR) { + // already got a toolbar? Toogle + messageRow.parentNode.removeChild(messageRow.toolTR) + delete messageRow.toolTR + return + } + const toolsTR = dom.createElement('tr') + const tools = await messageToolbar(message, messageRow, { ...userContext, chatOptions: options }, channelObject) + tools.style = + 'border: 0.05em solid #888; border-radius: 0 0 0.7em 0.7em; border-top: 0; height:3.5em; background-color: #fff;' // @@ fix + if (messageRow.nextSibling) { + messageRow.parentElement.insertBefore(toolsTR, messageRow.nextSibling) + } else { + messageRow.parentElement.appendChild(toolsTR) + } + messageRow.toolTR = toolsTR + toolsTR.appendChild(dom.createElement('td')) // left + const toolsTD = toolsTR.appendChild(dom.createElement('td')) + toolsTR.appendChild(dom.createElement('td')) // right + toolsTD.appendChild(tools) + }) + if (thread && options.showThread) { + // debug.log(' message has thread ' + thread) + td3.appendChild(widgets.button( + dom, + icons.iconBase + 'noun_1180164.svg', // right arrow .. @@ think of stg better + 'see thread', + _e => { + // debug.log('@@@@ Calling showThread thread ' + thread) + options.showThread(thread, options) + } + )) + } + return messageRow +} // END OF RENDERMESSAGE + +export async function switchToEditor (messageRow, message, channelObject, userContext) { + const messageTable = messageRow.parentNode + const editRow = renderMessageEditor(channelObject, messageTable, userContext, + channelObject.options, await mostRecentVersion(message)) + messageTable.insertBefore(editRow, messageRow) + editRow.originalRow = messageRow + messageRow.style.visibility = 'hidden' // Hide the original message. unhide if user cancels edit +} +/* Control for a new message -- or editing an old message *************** + * + */ +export function renderMessageEditor (channelObject, messageTable, userContext, options, originalMessage) { + function revertEditing (messageEditor) { + messageEditor.originalRow.style.visibility = 'visible' // restore read-only version + messageEditor.parentNode.removeChild(messageEditor) + } + + async function handleFieldInput (_event) { + await sendMessage(field.value, true) + } + + async function sendMessage (text, fromMainField) { + async function sendComplete (message, _text2) { + // const dateStamp = store.any(message, ns.dct('created'), null, message.doc()) + // const content = $rdf.literal(text2) + await insertMessageIntoTable(channelObject, messageTable, message, false, options, userContext) // not green + + if (originalMessage) { // editing another message + const oldRow = messageEditor.originalRow + // oldRow.style.display = '' // restore read-only version, re-attack + if (oldRow.parentNode) { + oldRow.parentNode.removeChild(oldRow) // No longer needed old version + } else { + debug.warn('No parentNode on old message ' + oldRow.textContent) + oldRow.style.backgroundColor = '#fee' + oldRow.style.visibility = 'hidden' // @@ FIX THIS AND REMOVE FROM DOM INSTEAD + } + messageEditor.parentNode.removeChild(messageEditor) // no longer need editor + } else { + if (fromMainField) { + field.value = '' // clear from out for reuse + field.setAttribute('style', messageBodyStyle) + field.disabled = false + field.scrollIntoView(options.newestFirst) // allign bottom (top) + field.focus() // Start typing next line immediately + field.select() + } + } + // await channelObject.div.refresh() // Add new day if nec @@ add back + } + + // const me = authn.currentUser() // Must be logged on or wuld have got login button + if (fromMainField) { + field.setAttribute('style', messageBodyStyle + 'color: #bbb;') // pendingedit + field.disabled = true + } + + let message + try { + message = await channelObject.updateMessage(text, originalMessage, null, options.thread) + } catch (err) { + const statusArea = userContext.statusArea || messageEditor + statusArea.appendChild( + widgets.errorMessageBlock(dom, 'Error writing message: ' + err) + ) + return + } + await sendComplete(message, text) + } // sendMessage + + // DRAG AND DROP + function droppedFileHandler (files) { + const base = messageTable.chatDocument.dir().uri + widgets.uploadFiles( + store.fetcher, + files, + base + 'Files', + base + 'Pictures', + async function (theFile, destURI) { + // @@@@@@ Wait for each if several + await sendMessage(destURI) + } + ) + } + + // When a set of URIs are dropped on the field + const droppedURIHandler = async function (uris) { + for (const uri of uris) { + await sendMessage(uri) + } + } + + // When we are actually logged on + function turnOnInput () { + function getImageDoc () { + imageDoc = $rdf.sym( + chatDocument.dir().uri + 'Image_' + Date.now() + '.png' + ) + return imageDoc + } + + async function tookPicture (imageDoc) { + if (imageDoc) { + await sendMessage(imageDoc.uri) + } + } + + // Body of turnOnInput + + let menuButton + if (options.menuHandler) { + const menuButton = widgets.button( + dom, icons.iconBase + 'noun_243787.svg', 'More') + menuButton.setAttribute('style', style.buttonStyle + 'float: right;') + // menuButton.addEventListener('click', _event => sendMessage(), false) (done in turnoninput) + rhs.appendChild(menuButton) + } + + if (options.menuHandler && menuButton) { + const me = authn.currentUser() + const menuOptions = { + me, + dom, + div: null, // @@ was: div + newBase: messageTable.chatDocument.dir().uri + } + menuButton.addEventListener( + 'click', + event => { + options.menuHandler(event, channelObject.chatChannel, menuOptions) + }, + false + ) + } + + const me = authn.currentUser() // If already logged on + creatorAndDate(lhs, me, '', null) + + field = dom.createElement('textarea') + middle.innerHTML = '' + middle.appendChild(field) + field.rows = 3 + if (originalMessage) { + field.value = store.anyValue(originalMessage, ns.sioc('content'), null, originalMessage.doc()) + } + // field.cols = 40 + field.setAttribute('style', messageBodyStyle + 'background-color: #eef;') + + // Trap the Enter BEFORE it is used ti make a newline + + field.addEventListener( + 'keydown', + async function (e) { + // User preference? + if (e.code === 'Enter') { + // if (e.keyCode === 13) { // deprocated https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode + if ((!e.shiftKey && !options.shiftEnterSendsMessage) || (e.shiftKey && options.shiftEnterSendsMessage)) { + // Shift-Enter just adds a new line + // (note alt-enter doesn't add newline anyway on my setup - so have to use shift. + await handleFieldInput(e) + } + } + }, + false + ) + + widgets.makeDropTarget(field, droppedURIHandler, droppedFileHandler) + + rhs.innerHTML = '' + + sendButton = widgets.button(dom, sendIcon, 'Send') + sendButton.style.float = 'right' + sendButton.addEventListener('click', _event => handleFieldInput(), false) + rhs.appendChild(sendButton) + + if (originalMessage) { // Are we editing another message? + const cancelButton = rhs.appendChild(widgets.cancelButton(dom)) + cancelButton.style.float = 'left' + // cancelButton.firstChild.style.opacity = '0.3' // moved to buttons + cancelButton.addEventListener('click', _event => revertEditing(messageEditor), false) + rhs.appendChild(cancelButton) + } + + const chatDocument = channelObject.dateFolder.leafDocumentFromDate(new Date()) + let imageDoc + + middle.appendChild( + media.cameraButton(dom, store, getImageDoc, tookPicture) + ) + + pad.recordParticipation(channelObject.channel, channelObject.channel.doc()) // participation = + } // turn on inpuut + + // Body of renderMessageEditor + + let sortDate, sendIcon + if (originalMessage) { + sortDate = store.anyValue(originalMessage, ns.dct('created'), null, originalMessage.doc()) + // text = store.anyValue(originalMessage, ns.sioc('content'), null, originalMessage.doc()) + sendIcon = icons.iconBase + 'noun_1180158.svg' // Green check + // cancelIcon = icons.iconBase + 'noun_1180156.svg' // Black cross + } else { + sendIcon = icons.iconBase + 'noun_383448.svg' + sortDate = '9999-01-01T00:00:00Z' // ISO format for field sort + // text = '' + } + const messageEditor = dom.createElement('tr') + const lhs = dom.createElement('td') + const middle = dom.createElement('td') + const rhs = dom.createElement('td') + messageEditor.appendChild(lhs) + messageEditor.appendChild(middle) + messageEditor.appendChild(rhs) + messageEditor.AJAR_date = sortDate + // messageEditor.appendChild(dom.createElement('br')) + + let field, sendButton + const context = { div: middle, dom } + + ensureLoggedIn(context).then(context => { + // me = context.me + turnOnInput() + Object.assign(context, userContext) + findBookmarkDocument(context).then(_context => { + // debug.log('Bookmark file: ' + context.bookmarkDocument) + }) + }) + + return messageEditor +} // renderMessageEditor diff --git a/src/chat/messageTools.js b/src/chat/messageTools.js new file mode 100644 index 000000000..9285aa18f --- /dev/null +++ b/src/chat/messageTools.js @@ -0,0 +1,315 @@ +/** + * Tools for doing things with a message + * Let us be creative here. Allow all sorts of things to + * be done to a message - linking to new or old objects in an open way + * + * Ideas: Bookmark, Like, star, pin at top of chat, reply as new thread, + * If you made it originally: edit, delete, attach + * @packageDocumentation + */ +import * as debug from '../debug' +import { icons } from '../iconBase' +// import { media } from '../media/index' +import ns from '../ns' +// import * as pad from '../pad' +import * as rdf from 'rdflib' // pull in first avoid cross-refs +// import { style } from '../style' +import * as utils from '../utils' +import * as widgets from '../widgets' +import { renderBookmarksButton } from './bookmarks' +import { authn, store } from 'solid-logic' + +import { allVersions, mostRecentVersion, isDeleted } from './chatLogic' +import { switchToEditor } from './message' + +const dom = window.document + +// THE UNUSED ICONS are here as reminders for possible future functionality +// const BOOKMARK_ICON = 'noun_45961.svg' +// const HEART_ICON = 'noun_130259.svg' -> Add this to my (private) favorites +// const MENU_ICON = 'noun_897914.svg' +// const PAPERCLIP_ICON = 'noun_25830.svg' -> add attachments to this message +// const PIN_ICON = 'noun_562340.svg' -> pin this message permanently in the chat UI +const PENCIL_ICON = 'noun_253504.svg' // edit a message +// const SPANNER_ICON = 'noun_344563.svg' -> settings +const THUMBS_UP_ICON = 'noun_1384132.svg' +const THUMBS_DOWN_ICON = 'noun_1384135.svg' +const REPLY_ICON = 'noun-reply-5506924.svg' +/** + * Emoji in Unicode + */ +const emojiMap = {} +emojiMap[ns.schema('AgreeAction')] = '👍' +emojiMap[ns.schema('DisagreeAction')] = '👎' +emojiMap[ns.schema('EndorseAction')] = '⭐️' +emojiMap[ns.schema('LikeAction')] = '❤️' + +export function emojiFromActionClass (action) { + return emojiMap[action] || null +} + +export function ActionClassFromEmoji (emoji) { + for (const a in emojiMap) { + if (emojiMap[a] === emoji) { + return rdf.sym(a.slice(1, -1)) // remove < > + } + } + return null +} + +// Allow the action to give its own emoji as content, +// or get the emoji from the class of action. +export function emojiFromAction (action) { + const content = store.any(action, ns.sioc('content'), null, action.doc()) + if (content) return content + const klass = store.any(action, ns.rdf('type'), null, action.doc()) + if (klass) { + const em = emojiFromActionClass(klass) + if (em) return em + } + return '⬜️' +} + +/** + * Create strip of sentiments expressed + */ +export async function sentimentStrip (target, doc) { // alain: seems not used + const versions = await allVersions(target) + // debug.log('sentimentStrip Versions for ' + target, versions) + const actions = versions.map(version => store.each(null, ns.schema('target'), version, doc)).flat() + // debug.log('sentimentStrip: Actions for ' + target, actions) + const strings = actions.map(action => emojiFromAction(action) || '') + return dom.createTextNode(strings.join(' ')) +} +/** + * Create strip of sentiments expressed, with hyperlinks + * + * @param target {NamedNode} - The thing about which they are expressed + * @param doc {NamedNode} - The document in which they are expressed + */ +export async function sentimentStripLinked (target, doc) { + const strip = dom.createElement('span') + async function refresh () { + strip.innerHTML = '' + if (isDeleted(target)) return strip + const versions = await allVersions(target) + // debug.log('sentimentStripLinked: Versions for ' + target, versions) + const actions = versions.map(version => store.each(null, ns.schema('target'), version, doc)).flat() + // debug.log('sentimentStripLinked: Actions for ' + target, actions) + if (actions.length === 0) return strip + const sentiments = actions.map(a => [ + store.any(a, ns.rdf('type'), null, doc), + store.any(a, ns.sioc('content'), null, doc), + store.any(a, ns.schema('agent'), null, doc) + ]) + // debug.log(' Actions sentiments ', sentiments) + sentiments.sort() + sentiments.forEach(ss => { + const [theClass, content, agent] = ss + let res + if (agent) { + res = dom.createElement('a') + res.setAttribute('href', agent.uri) + } else { + res = dom.createTextNode('') + } + res.textContent = content || emojiMap[theClass] || '⬜️' + strip.appendChild(res) + }) + // debug.log(' Actions strip ', strip) + } + refresh().then(debug.log('sentimentStripLinked: sentimentStripLinked async refreshed')) + strip.refresh = refresh + return strip +} +/** + * Creates a message toolbar component + */ +export async function messageToolbar (message, messageRow, userContext, channelObject) { + async function deleteMessage () { + const author = store.any(message, ns.foaf('maker')) + if (!me) { + alert('You can\'t delete the message, you are not logged in.') + } else if (me.sameTerm(author)) { + try { + await channelObject.deleteMessage(message) + } catch (err) { + const msg = 'Error deleting messaage ' + err + debug.warn(msg) + alert(msg) + const area = userContext.statusArea || messageRow.parentNode + area.appendChild(widgets.errorMessageBlock(dom, msg)) + } + messageRow.parentNode.removeChild(messageRow) + } else { + alert('You can\'t delete the message, you are not logged in as the author, ' + author) + } + closeToolbar() + } + + async function editMessage (messageRow) { + if (me.value === store.any(message, ns.foaf('maker')).value) { + closeToolbar() // edit is a one-off action + await switchToEditor(messageRow, message, channelObject, userContext) + } + } + + async function replyInThread () { + const thread = await channelObject.createThread(message) + const options = userContext.chatOptions + if (!options) throw new Error('replyInThread: missing options') + options.showThread(thread, options) + closeToolbar() // a one-off action + } + + // alain: TODO allow chat owner to fully delete message + sentiments and replacing messages + + const div = dom.createElement('div') + // is message deleted ? + if (await mostRecentVersion(message).value === ns.schema('dateDeleted').value) return div + function closeToolbar () { + div.parentElement.parentElement.removeChild(div.parentElement) // remive the TR + } + + async function deleteThingThen (x) { + await store.updater.update(store.connectedStatements(x), []) + } + + // Things only the original author can do + let me = authn.currentUser() // If already logged on + if (me && store.holds(message, ns.foaf('maker'), me)) { + // button to delete the message + div.appendChild(widgets.deleteButtonWithCheck(dom, div, 'message', deleteMessage)) + // button to edit the message + div.appendChild(widgets.button(dom, icons.iconBase + PENCIL_ICON, 'edit', () => editMessage(messageRow))) + } // if mine + // Things anyone can do if they have a bookmark list async + /* + var bookmarkButton = await bookmarks.renderBookmarksButton(userContext) + if (bookmarkButton) { + div.appendChild(bookmarkButton) + } + */ + // Things anyone can do if they have a bookmark list + + renderBookmarksButton(userContext).then(bookmarkButton => { + if (bookmarkButton) div.appendChild(bookmarkButton) + }) + + /** Button to allow user to express a sentiment (like, endorse, etc) about a target + * + * @param context {Object} - Provide dom and me + * @param target {NamedNode} - The thing the user expresses an opnion about + * @param icon {uristring} - The icon to be used for the button + * @param actionClass {NamedNode} - The RDF class - typically a subclass of schema:Action + * @param doc - {NamedNode} - the Solid document iunto which the data should be written + * @param mutuallyExclusive {Array} - Any RDF classes of sentimentswhich are mutiually exclusive + */ + function sentimentButton ( + context, + target, + icon, + actionClass, + doc, + mutuallyExclusive + ) { + function setColor () { + button.style.backgroundColor = action ? 'yellow' : 'white' + } + const button = widgets.button( + dom, + icon, + utils.label(actionClass), + async function (_event) { + if (action) { + await deleteThingThen(action) + action = null + setColor() + } else { + // no action + action = widgets.newThing(doc) + const insertMe = [ + rdf.st(action, ns.schema('agent'), context.me, doc), + rdf.st(action, ns.rdf('type'), actionClass, doc), + rdf.st(action, ns.schema('target'), target, doc) + ] + await store.updater.update([], insertMe) + setColor() + + if (mutuallyExclusive) { + // Delete incompative sentiments + let dirty = false + for (let i = 0; i < mutuallyExclusive.length; i++) { + const a = existingAction(mutuallyExclusive[i]) + if (a) { + await deleteThingThen(a) // but how refresh? refreshTree the parent? + dirty = true + } + } + if (dirty) { + // widgets.refreshTree(button.parentNode) // requires them all to be immediate siblings + widgets.refreshTree(messageRow) // requires them all to be immediate siblings + } + } + } + } + ) + function existingAction (actionClass) { + const actions = store + .each(null, ns.schema('agent'), context.me, doc) + .filter(x => store.holds(x, ns.rdf('type'), actionClass, doc)) + .filter(x => store.holds(x, ns.schema('target'), target, doc)) + return actions.length ? actions[0] : null + } + function refresh () { + action = existingAction(actionClass) + setColor() + } + let action + button.refresh = refresh // If the file changes, refresh live + refresh() + return button + } + + // THUMBS_UP_ICON + // https://schema.org/AgreeAction + me = authn.currentUser() // If already logged on + + if (me && (await mostRecentVersion(message).value !== ns.schema('dateDeleted').value)) { + const context1 = { me, dom, div } + div.appendChild( + sentimentButton( + context1, + message, // @@ TODO use widgets.sentimentButton + icons.iconBase + THUMBS_UP_ICON, + ns.schema('AgreeAction'), + message.doc(), + [ns.schema('DisagreeAction')] + ) + ) + // Thumbs down + div.appendChild( + sentimentButton( + context1, + message, + icons.iconBase + THUMBS_DOWN_ICON, + ns.schema('DisagreeAction'), + message.doc(), + [ns.schema('AgreeAction')] + ) + ) + } + // Reply buttton + + if (store.any(message, ns.dct('created'))) { // Looks like a messsage? Bar can be used for other things + div.appendChild(widgets.button(dom, icons.iconBase + REPLY_ICON, 'Reply in thread', async () => { + await replyInThread() + })) + } + // X button to remove the tool UI itself + const cancelButton = div.appendChild(widgets.cancelButton(dom)) + cancelButton.style.float = 'right' + cancelButton.firstChild.style.opacity = '0.3' + cancelButton.addEventListener('click', closeToolbar) + return div +} diff --git a/src/chat/signature.ts b/src/chat/signature.ts new file mode 100644 index 000000000..1b74a6a88 --- /dev/null +++ b/src/chat/signature.ts @@ -0,0 +1,123 @@ +import { schnorr } from '@noble/curves/secp256k1.js' +import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js' +import { sha256 } from '@noble/hashes/sha2.js' + +// import {utf8Encoder} from './utils' +// import { getPublicKey } from './keys' + +export const utf8Decoder = new TextDecoder('utf-8') +export const utf8Encoder = new TextEncoder() + +export const SEC = 'https://w3id.org/security#' // Proof, VerificationMethod +// export const CERT = 'http://www.w3.org/ns/auth/cert#' // PrivateKey, PublicKey, key + +/* export enum Kind { + Metadata = 0, + Text = 1, + RecommendRelay = 2, + Contacts = 3, + EncryptedDirectMessage = 4, + EventDeletion = 5, + Reaction = 7, + BadgeAward = 8, + ChannelCreation = 40, + ChannelMetadata = 41, + ChannelMessage = 42, + ChannelHideMessage = 43, + ChannelMuteUser = 44, + Report = 1984, + ZapRequest = 9734, + Zap = 9735, + RelayList = 10002, + ClientAuth = 22242, + BadgeDefinition = 30008, + ProfileBadge = 30009, + Article = 30023 +} */ + +export type MsgTemplate = { + id: string + created: string + dateDeleted: string + content: string + maker: string + sig: string +} + +export type UnsignedMsg = MsgTemplate & { + pubkey: string +} + +export type Message = UnsignedMsg & { + id: string + sig: string +} + +export function getBlankMsg (): MsgTemplate { + return { + id: '', + created: '', + dateDeleted: '', // TODO to remove if not used + content: '', + maker: '', + sig: '' // TODO to remove if not used + } +} + +/* export function finishMsg (t: MsgTemplate, privateKey: string): Message { + // to update to chat message triples + const message = t as Message + // message.pubkey = getPublicKey(privateKey) + message.id = getMsgHash(message) + message.sig = signMsg(message, privateKey) + return message +} */ + +export function serializeMsg (msg: UnsignedMsg): string { + // to update to chat messages triples + /* if (!validateMsg(msg)) + throw new Error("can't serialize message with wrong or missing properties") */ + + return JSON.stringify(msg) +} + +export function getMsgHash (message: UnsignedMsg) { + const msgHash = sha256(utf8Encoder.encode(serializeMsg(message))) + return bytesToHex(msgHash) +} + +// const isRecord = (obj: unknown): obj is Record => obj instanceof Object + +/* export function validateMsg (message: T): message is T & UnsignedMsg { + if (!isRecord(message)) return false + if (typeof message.kind !== 'number') return false + if (typeof message.content !== 'string') return false + if (typeof message.created_at !== 'number') return false + if (typeof message.pubkey !== 'string') return false + if (!message.pubkey.match(/^[a-f0-9]{64}$/)) return false + + if (!Array.isArray(message.tags)) return false + for (let i = 0; i < message.tags.length; i++) { + let tag = message.tags[i] + if (!Array.isArray(tag)) return false + for (let j = 0; j < tag.length; j++) { + if (typeof tag[j] === 'object') return false + } + } + + return true +} */ + +export function verifySignature (sig: string, message: Message, pubKey: string): boolean { + return schnorr.verify( + hexToBytes(sig), + hexToBytes(getMsgHash(message)), + hexToBytes(pubKey) + ) +} + +export function signMsg (message: UnsignedMsg, key: string): string { + return bytesToHex( + schnorr.sign(hexToBytes(getMsgHash(message)), hexToBytes(key)) + ) +} diff --git a/src/chat/thread.js b/src/chat/thread.js new file mode 100644 index 000000000..ea569637a --- /dev/null +++ b/src/chat/thread.js @@ -0,0 +1,415 @@ +/** + * Contains the [[thread]] function + * @packageDocumentation + */ + +import { icons } from '../iconBase' +import { store } from 'solid-logic' +import { media } from '../media/index' +import ns from '../ns' +import * as login from '../login/login' +import * as pad from '../pad' +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +import { style } from '../style' +import * as utils from '../utils' +import * as widgets from '../widgets' + +const UI = { icons, ns, media, pad, style, utils, widgets } + +/** + * HTML component for a chat thread + */ +export function thread (dom, kb, subject, messageStore, options) { + kb = kb || store + messageStore = messageStore.doc() // No hash + const ns = UI.ns + const WF = $rdf.Namespace('http://www.w3.org/2005/01/wf/flow#') + const DCT = $rdf.Namespace('http://purl.org/dc/terms/') + + options = options || {} + + const newestFirst = !!options.newestFirst + + const messageBodyStyle = + 'white-space: pre-wrap; width: 90%; font-size:100%; border: 0.07em solid #eee; padding: .2em 0.5em; margin: 0.1em 1em 0.1em 1em;' + // 'font-size: 100%; margin: 0.1em 1em 0.1em 1em; background-color: white; white-space: pre-wrap; padding: 0.1em;' + + const div = dom.createElement('div') + // eslint-disable-next-line prefer-const + let messageTable + + let me + + const updater = store.updater + + const anchor = function (text, term) { + // If there is no link return an element anyway + const a = dom.createElement('a') + if (term && term.uri) { + a.setAttribute('href', term.uri) + a.addEventListener('click', UI.widgets.openHrefInOutlineMode, true) + a.setAttribute('style', 'color: #3B5998; text-decoration: none; ') // font-weight: bold + } + a.textContent = text + return a + } + + const mention = function mention (message, style) { + const pre = dom.createElement('pre') + pre.setAttribute('style', style || 'color: grey') + div.appendChild(pre) + pre.appendChild(dom.createTextNode(message)) + return pre + } + + const announce = { + log: function (message) { + mention(message, 'color: #111;') + }, + warn: function (message) { + mention(message, 'color: #880;') + }, + error: function (message) { + mention(message, 'color: #800;') + } + } + + /** + * Form for a new message + */ + const newMessageForm = function () { + const form = dom.createElement('tr') + const lhs = dom.createElement('td') + const middle = dom.createElement('td') + const rhs = dom.createElement('td') + form.appendChild(lhs) + form.appendChild(middle) + form.appendChild(rhs) + form.AJAR_date = '9999-01-01T00:00:00Z' // ISO format for field sort + + const sendMessage = async function () { + // titlefield.setAttribute('class','pendingedit') + // titlefield.disabled = true + field.setAttribute('class', 'pendingedit') + field.disabled = true + const { message, dateStamp, sts } = await appendMsg(field.value) + + const sendComplete = async function (uri, success, body) { + if (!success) { + form.appendChild( + UI.widgets.errorMessageBlock(dom, 'Error writing message: ' + body) + ) + } else { + const bindings = { + '?msg': message, + '?content': store.literal(field.value), + '?date': dateStamp, + '?creator': me + } + renderMessage(bindings, false) // not green + + field.value = '' // clear from out for reuse + field.setAttribute('class', '') + field.disabled = false + } + } + await updater.updateMany([], sts, sendComplete) + } + form.appendChild(dom.createElement('br')) + + let field, sendButton + const turnOnInput = function () { + creatorAndDate(lhs, me, '', null) + + field = dom.createElement('textarea') + middle.innerHTML = '' + middle.appendChild(field) + field.rows = 3 + // field.cols = 40 + field.setAttribute('style', messageBodyStyle + 'background-color: #eef;') + + field.addEventListener( + 'keyup', + async function (e) { + // User preference? + if (e.keyCode === 13) { + if (!e.altKey) { + // Alt-Enter just adds a new line + await sendMessage() + } + } + }, + false + ) + + rhs.innerHTML = '' + sendButton = UI.widgets.button( + dom, + UI.icons.iconBase + 'noun_383448.svg', + 'Send' + ) + sendButton.setAttribute('style', UI.style.buttonStyle + 'float: right;') + sendButton.addEventListener('click', sendMessage, false) + rhs.appendChild(sendButton) + } + + const context = { div: middle, dom } + login.ensureLoggedIn(context).then(context => { + me = context.me + turnOnInput() + }) + + return form + } + + const appendMsg = async function (fieldValue, oldMsg = {}, options = '') { // alain + const sts = [] + const now = new Date() + const timestamp = '' + now.getTime() + const dateStamp = $rdf.term(now) + // http://www.w3schools.com/jsref/jsref_obj_date.asp + const message = store.sym(messageStore.uri + '#' + 'Msg' + timestamp) + + if (options === 'edit' || options === 'delete') { + sts.push( + new $rdf.Statement(await mostRecentVersion(oldMsg), DCT('isReplacedBy'), message, messageStore) + ) + } else { + sts.push( + new $rdf.Statement(subject, ns.wf('message'), message, messageStore) + ) + } + // sts.push(new $rdf.Statement(message, ns.dc('title'), store.literal(titlefield.value), messageStore)) + const msgBody = options !== 'delete' ? fieldValue : `message deleted\nby ${nick(me)}` + sts.push( + new $rdf.Statement( + message, + ns.sioc('content'), + store.literal(msgBody), + messageStore + ) + ) + sts.push( + new $rdf.Statement(message, DCT('created'), dateStamp, messageStore) + ) + if (me) { + sts.push( + new $rdf.Statement(message, ns.foaf('maker'), me, messageStore) + ) + } + return { message, dateStamp, sts } + } + + function nick (person) { + const s = store.any(person, UI.ns.foaf('nick')) + if (s) return '' + s.value + return '' + utils.label(person) + } + + function creatorAndDate (td1, creator, date, message) { + const nickAnchor = td1.appendChild(anchor(nick(creator), creator)) + if (creator.uri) { + store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function ( + _ok, + _body + ) { + nickAnchor.textContent = nick(creator) + }) + } + td1.appendChild(dom.createElement('br')) + td1.appendChild(anchor(date, message)) + } + + // /////////////////////////////////////////////////////////////////////// + + function syncMessages (about, messageTable) { + const displayed = {} + let ele, ele2 + for (ele = messageTable.firstChild; ele; ele = ele.nextSibling) { + if (ele.AJAR_subject) { + displayed[ele.AJAR_subject.uri] = true + } + } + const messages = store.each(about, ns.wf('message')) + const stored = {} + messages.forEach(function (m) { + stored[m.uri] = true + if (!displayed[m.uri]) { + addMessage(m) + } + }) + + for (ele = messageTable.firstChild; ele;) { + ele2 = ele.nextSibling + if (ele.AJAR_subject && !stored[ele.AJAR_subject.uri]) { + messageTable.removeChild(ele) + } + ele = ele2 + } + } + + const mostRecentVersion = function (message) { + let msg = message + // const listMsg = [] + while (msg) { + message = msg + // listMsg.push(msg) + msg = store.statementsMatching(message, DCT('isReplacedBy')) + } + return message + } + + // eslint-disable-next-line no-unused-vars + async function deleteMessage (message) { // alain: must delete message and all linked with isReplacedBy + // alain: check that me is not the author and ask for confirmation. + const deletions = await store.connectedStatements(message, messageStore) + await updater.updateMany(deletions, [], function (uri, ok, body) { + if (!ok) { + announce.error('Cant delete messages:' + body) + } else { + syncMessages(subject, messageTable) + } + }) + } + + const addMessage = async function (message) { + const bindings = { + '?msg': message, + '?creator': store.any(message, ns.foaf('maker')), + '?date': store.any(message, DCT('created')), + '?content': store.any(message, ns.sioc('content')) + } + await renderMessage(bindings, true) // fresh from elsewhere + } + + const renderMessage = async function (bindings, fresh) { + const creator = bindings['?creator'] + const message = bindings['?msg'] + const date = bindings['?date'] + const content = bindings['?content'] + + const dateString = date.value + const tr = dom.createElement('tr') + tr.AJAR_date = dateString + tr.AJAR_subject = message + + let done = false + for (let ele = messageTable.firstChild; ; ele = ele.nextSibling) { + if (!ele) { + // empty + break + } + if ( + (dateString > ele.AJAR_date && newestFirst) || + (dateString < ele.AJAR_date && !newestFirst) + ) { + messageTable.insertBefore(tr, ele) + done = true + break + } + } + if (!done) { + messageTable.appendChild(tr) + } + + const td1 = dom.createElement('td') + tr.appendChild(td1) + creatorAndDate(td1, creator, UI.widgets.shortDate(dateString), message) + + const td2 = dom.createElement('td') + tr.appendChild(td2) + const pre = dom.createElement('p') + pre.setAttribute( + 'style', + messageBodyStyle + + (fresh ? 'background-color: #e8ffe8;' : 'background-color: #white;') + ) + td2.appendChild(pre) + pre.textContent = content.value + + const td3 = dom.createElement('td') + tr.appendChild(td3) + + const delButton = dom.createElement('button') + td3.appendChild(delButton) + delButton.textContent = '-' + + tr.setAttribute('class', 'hoverControl') // See tabbedtab.css (sigh global CSS) + delButton.setAttribute('class', 'hoverControlHide') + delButton.setAttribute('style', 'color: red;') + delButton.addEventListener( + 'click', + async function (_event) { + td3.removeChild(delButton) // Ask -- are you sure? + const cancelButton = dom.createElement('button') + cancelButton.textContent = 'cancel' + td3.appendChild(cancelButton).addEventListener( + 'click', + function (_event) { + td3.removeChild(sureButton) + td3.removeChild(cancelButton) + td3.appendChild(delButton) + }, + false + ) + const sureButton = dom.createElement('button') + sureButton.textContent = 'Delete message' + td3.appendChild(sureButton).addEventListener( + 'click', + async function (_event) { // alain: test for delete or edit depending on me = maker + td3.removeChild(sureButton) + td3.removeChild(cancelButton) + // deleteMessage(message) // alain or sendMessage(message, 'delete' or 'edit') //alain + if (me.value === store.any(message, ns.foaf('maker')).value) { + const { sts } = await appendMsg() // alain + await updater.updateMany([], sts) // alain + } + }, + false + ) + }, + false + ) + } + + // Messages with date, author etc + + messageTable = dom.createElement('table') + messageTable.fresh = false + div.appendChild(messageTable) + messageTable.setAttribute('style', 'width: 100%;') // fill that div! + + const tr = newMessageForm() + if (newestFirst) { + messageTable.insertBefore(tr, messageTable.firstChild) // If newestFirst + } else { + messageTable.appendChild(tr) // not newestFirst + } + + let query + // Do this with a live query to pull in messages from web + if (options.query) { + query = options.query + } else { + query = new $rdf.Query('Messages') + const v = {} // semicolon needed + const vs = ['msg', 'date', 'creator', 'content'] + vs.forEach(function (x) { + query.vars.push((v[x] = $rdf.variable(x))) + }) + query.pat.add(subject, WF('message'), v.msg) + query.pat.add(v.msg, ns.dct('created'), v.date) + query.pat.add(v.msg, ns.foaf('maker'), v.creator) + query.pat.add(v.msg, ns.sioc('content'), v.content) + } + + function doneQuery () { + messageTable.fresh = true // any new are fresh and so will be greenish + } + store.query(query, renderMessage, undefined, doneQuery) + div.refresh = function () { + syncMessages(subject, messageTable) + } + // syncMessages(subject, messageTable) // no the query will do this async + return div +} diff --git a/src/convert.sed b/src/convert.sed deleted file mode 100644 index 7e4f2f63a..000000000 --- a/src/convert.sed +++ /dev/null @@ -1,15 +0,0 @@ -# A note of the changes between the tabulator library and the solid-ui library -# -s/tabulator\.ns/UI.ns/g -s/tabulator\.Util/UI.utils/g -s/tabulator\.panes.utils/UI.widgets/g -s/tabulator\.kb/UI.store/g -s/tabulator\.panes.utils/UI.widgets/g -s/tabulator\.kb/UI.store/g -s/tabulator\.sf/UI.store.fetcher/g -s/tabulator\.fetcher/UI.store.fetcher/g -s/tabulator\.lb.label/UI.utils.label/g -s/tabulator\.log/UI.log/g -s/tabulator\.rdf/UI.rdf/g -s/tabulator.sparql/UI.store.updater/g -s/tabulator.outline/UI.outline/g diff --git a/src/create.js b/src/create.js deleted file mode 100644 index 60291dc8c..000000000 --- a/src/create.js +++ /dev/null @@ -1,236 +0,0 @@ -/* create.js UI to craete new objects in the solid-app-set world -** -*/ -// const error = require('./widgets/error') -// const widgets = require('./widgets/index') -// const utils = require('./utils') - -// const UI = require('solid-ui') - -const UI = { - authn: require('./signin'), - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - store: require('./store'), - style: require('./style'), - utils: require('./utils'), - widgets: require('./widgets') -} - -const kb = UI.store - -module.exports = { - newThingUI -} - -/* newThingUI -- return UI for user to select a new object, folder, etc -** -** context must include: dom, div, -** optional: folder: NamedNode -- the folder where the thing is bring put -** (suppresses asking for a full URI or workspace) -** -*/ -function newThingUI (context, thePanes) { - const dom = context.dom - const div = context.div - if (context.me && !context.me.uri) throw new Error('newThingUI: Invalid userid: ' + context.me) - - var iconStyle = 'padding: 0.7em; width: 2em; height: 2em;' // was: 'padding: 1em; width: 3em; height: 3em;' - var star = div.appendChild(dom.createElement('img')) - var visible = false // the inividual tools tools - // noun_272948.svg = black star - // noun_34653_green.svg = green plus - star.setAttribute('src', UI.icons.iconBase + 'noun_34653_green.svg') - star.setAttribute('style', iconStyle) - star.setAttribute('title', 'Add another tool to the meeting') - - var complain = function complain (message) { - var pre = div.appendChild(dom.createElement('pre')) - pre.setAttribute('style', 'background-color: pink') - pre.appendChild(dom.createTextNode(message)) - } - - var selectNewTool = function (event) { - visible = !visible - star.setAttribute('style', iconStyle + (visible ? 'background-color: yellow;' : '')) - styleTheIcons(visible ? '' : 'display: none;') - } - - star.addEventListener('click', selectNewTool) - - function makeNewAppInstance (options) { - return new Promise(function (resolve, reject) { - var selectUI // , selectUIParent - function callbackWS (ws, newBase) { - UI.authn.logInLoadProfile(context).then(context => { - var newPaneOptions = { - newBase: newBase, - workspace: ws - } - for (var opt in options) { // get div, dom, me, folder, pane, refreshTable - newPaneOptions[opt] = options[opt] - } - console.log('newThingUI: Minting new ' + newPaneOptions.pane.name + ' at ' + newPaneOptions.newBase) - options.pane.mintNew(newPaneOptions) - .then(function (newPaneOptions) { - if (!newPaneOptions || !newPaneOptions.newInstance) { - throw new Error('Cannot mint new - missing newInstance') - } - if (newPaneOptions.folder) { - kb.add(newPaneOptions.folder, UI.ns.ldp('contains'), kb.sym(newPaneOptions.newBase), - newPaneOptions.folder.doc()) // Ping the patch system? - if (newPaneOptions.refreshTarget) { - newPaneOptions.refreshTarget.refresh() // Refresh the cntaining display - } - // selectUI.parentNode.removeChild(selectUI) It removes itself - } else { - var p = options.div.appendChild(dom.createElement('p')) - p.setAttribute('style', 'font-size: 120%;') - // Make link to new thing - p.innerHTML = - "Your new " + options.noun + ' is ready to be set up. ' + - "

Go to your new " + options.noun + '.' - // selectUI.parentNode.removeChild(selectUI) // Clean up - // selectUIParent.removeChild(selectUI) // Clean up - } - selectNewTool() // toggle star to plain and menu vanish again - }) - .catch(function (err) { - complain(err) - reject(err) - }) - }, err => { // login fails - complain('Error logging on: ' + err) - }) - } // callbackWS - - var pa = options.pane - options.appPathSegment = 'edu.mit.solid.pane.' + pa.name - options.noun = pa.mintClass ? UI.utils.label(pa.mintClass) : pa.name - - if (!options.folder) { // No folder given? Ask user for full URI - selectUI = UI.authn.selectWorkspace(dom, options, callbackWS) - options.div.appendChild(selectUI) - // selectUIParent = options.div - } else { - var gotName = function (name) { - if (!name) { - // selectUIParent.removeChild(selectUI) itremves itself if cancelled - selectNewTool() // toggle star to plain and menu vanish again - } else { - var uri = options.folder.uri - if (!uri.endsWith('/')) { - uri = uri + '/' - } - uri = uri + encodeURIComponent(name) + '/' - callbackWS(null, uri) - } - } - UI.widgets.askName(dom, UI.store, options.div, UI.ns.foaf('name'), null, options.noun).then(gotName) - // selectUI = getNameForm(dom, UI.store, options.noun, gotName) - // options.div.appendChild(selectUI) - // selectUIParent = options.div - } - } - ) - } // makeNewAppInstance - - var iconArray = [] - for (var pn in thePanes) { - var pane = thePanes[pn] - if (pane.mintNew) { - var icon = context.div.appendChild(dom.createElement('img')) - icon.setAttribute('src', pane.icon) - var noun = pane.mintClass ? UI.utils.label(pane.mintClass) : (pane.name + ' @@') - icon.setAttribute('title', 'Make new ' + noun) - icon.setAttribute('style', iconStyle + 'display: none;') - iconArray.push(icon) - var foo = function (pane, icon, noun) { - var iconEle = icon - var thisPane = pane - var thisNoun = noun - if (!icon.disabled) { - icon.addEventListener('click', function (e) { - selectTool(iconEle) - var options = { - event: e, - folder: context.folder, - iconEle: iconEle, - pane: thisPane, - noun: thisNoun, - noIndexHTML: true, // do NOT @@ for now write a HTML file - div: context.div, - me: context.me, - dom: context.dom, - refreshTarget: context.refreshTarget - } - makeNewAppInstance(options) - }) - } - } // foo - foo(pane, icon, noun) - } - } - - var styleTheIcons = function (style) { - for (var i = 0; i < iconArray.length; i++) { - var st = iconStyle + style - if (iconArray[i].disabled) { // @@ unused - st += 'opacity: 0.3;' - } - iconArray[i].setAttribute('style', st) // eg 'background-color: #ccc;' - } - } - var selectTool = function (icon) { - styleTheIcons('display: none;') // 'background-color: #ccc;' - icon.setAttribute('style', iconStyle + 'background-color: yellow;') - } -} - -// Form to get the name of a new thing before we create it -// -// Used in contacts for new groups, individuals. -// -/* -function getNameForm (dom, kb, classLabel, gotNameCallback) { - var form = dom.createElement('div') // form is broken as HTML behaviour can resurface on js error - form.innerHTML = '

Name of new ' + classLabel + ':

' - var namefield = dom.createElement('input') - namefield.setAttribute('type', 'text') - namefield.setAttribute('size', '30') - namefield.setAttribute('style', UI.style.textInputStyle) - namefield.setAttribute('maxLength', '2048') // No arbitrary limits - namefield.select() // focus next user input - - var gotName = function () { - namefield.setAttribute('class', 'pendingedit') - namefield.disabled = true - continueButton.disabled = true - cancel.disabled = true - gotNameCallback(true, namefield.value) - } - - namefield.addEventListener('keyup', function (e) { - if (e.keyCode === 13) { - gotName() - } - }, false) - form.appendChild(namefield) - - form.appendChild(dom.createElement('br')) - - var cancel = form.appendChild(UI.widgets.cancelButton(dom)) - cancel.addEventListener('click', function (e) { - form.parentNode.removeChild(form) - gotNameCallback(false) - }, false) - - var continueButton = form.appendChild(UI.widgets.continueButton(dom)) - continueButton.addEventListener('click', function (e) { - gotName() - }, false) - - return form -} -*/ diff --git a/src/create/create.ts b/src/create/create.ts new file mode 100644 index 000000000..6d0c6ad06 --- /dev/null +++ b/src/create/create.ts @@ -0,0 +1,288 @@ +/* create.js UI to craete new objects in the solid-app-set world + ** + */ + +import { DataBrowserContext, NewPaneOptions, PaneDefinition } from 'pane-registry' +import { solidLogicSingleton } from 'solid-logic' +import * as debug from '../debug' +import { icons } from '../iconBase' +import { ensureLoadedProfile, selectWorkspace } from '../login/login' +import ns from '../ns' +import * as utils from '../utils' +import * as widgets from '../widgets' +import { CreateContext, NewAppInstanceOptions } from './types' + +const kb = solidLogicSingleton.store + +/* newThingUI -- return UI for user to select a new object, folder, etc + ** + ** context must include: dom, div, + ** optional: folder: NamedNode -- the folder where the thing is bring put + ** (suppresses asking for a full URI or workspace) + ** + */ +export function newThingUI ( + createContext: CreateContext, + dataBrowserContext: DataBrowserContext, + thePanes: Array +): void { + const dom = createContext.dom + const div = createContext.div + if (createContext.me && !createContext.me.uri) { + throw new Error('newThingUI: Invalid userid: ' + createContext.me) + } + + const iconStyle = 'padding: 0.7em; width: 2em; height: 2em;' // was: 'padding: 1em; width: 3em; height: 3em;' + const star = div.appendChild(dom.createElement('img')) + let visible = false // the inividual tools tools + // noun_272948.svg = black star + // noun_34653_green.svg = green plus + star.setAttribute('src', icons.iconBase + 'noun_34653_green.svg') + star.setAttribute('style', iconStyle) + star.setAttribute('title', 'Add another tool') + + const complain = function complain (message) { + const pre = div.appendChild(dom.createElement('pre')) + pre.setAttribute('style', 'background-color: pink') + pre.appendChild(dom.createTextNode(message)) + } + + function styleTheIcons (style) { + for (let i = 0; i < iconArray.length; i++) { + let st = iconStyle + style + if (iconArray[i].disabled) { + // @@ unused + st += 'opacity: 0.3;' + } + iconArray[i].setAttribute('style', st) // eg 'background-color: #ccc;' + } + } + + function selectTool (icon) { + styleTheIcons('display: none;') // 'background-color: #ccc;' + icon.setAttribute('style', iconStyle + 'background-color: yellow;') + } + + function selectNewTool (_event?) { + visible = !visible + star.setAttribute( + 'style', + iconStyle + (visible ? 'background-color: yellow;' : '') + ) + styleTheIcons(visible ? '' : 'display: none;') + } + + star.addEventListener('click', selectNewTool) + + function makeNewAppInstance (options: NewAppInstanceOptions) { + return new Promise(function (resolve, reject) { + let selectUI // , selectUIParent + function callbackWS (ws, newBase) { + ensureLoadedProfile(createContext).then( + _context => { + const newPaneOptions: NewPaneOptions = Object.assign({ + newBase, + folder: options.folder || undefined, + workspace: ws + }, options) + for (const opt in options) { + // get div, dom, me, folder, pane, refreshTable + newPaneOptions[opt] = options[opt] + } + debug.log(`newThingUI: Minting new ${newPaneOptions.pane.name} at ${newPaneOptions.newBase}`) + options.pane + .mintNew!(dataBrowserContext, newPaneOptions) + .then(function (newPaneOptions) { + if (!newPaneOptions || !newPaneOptions.newInstance) { + throw new Error('Cannot mint new - missing newInstance') + } + if (newPaneOptions.folder) { + const tail = newPaneOptions.newInstance.uri.slice( + newPaneOptions.folder.uri.length + ) + const isPackage = tail.includes('/') + debug.log(' new thing is packge? ' + isPackage) + if (isPackage) { + kb.add( + newPaneOptions.folder, + ns.ldp('contains'), + kb.sym(newPaneOptions.newBase), + newPaneOptions.folder.doc() + ) + } else { + // single file + kb.add( + newPaneOptions.folder, + ns.ldp('contains'), + newPaneOptions.newInstance, + newPaneOptions.folder.doc() + ) // Ping the patch system? + } + // @ts-ignore @@ TODO check whether refresh can exist here. Either fix type or remove unreachable code + if (newPaneOptions.refreshTarget && newPaneOptions.refreshTarget.refresh) { + // @@ TODO Remove the need to cast as any + ;(newPaneOptions.refreshTarget as any).refresh() // Refresh the containing display + } + // selectUI.parentNode.removeChild(selectUI) It removes itself + } else { + const p = options.div.appendChild(dom.createElement('p')) + p.setAttribute('style', 'font-size: 120%;') + // Make link to new thing + p.innerHTML = + 'Your new ' + + options.noun + + ' is ready to be set up. ' + + '

Go to your new ' + + options.noun + + '.' + // selectUI.parentNode.removeChild(selectUI) // Clean up + // selectUIParent.removeChild(selectUI) // Clean up + } + selectNewTool() // toggle star to plain and menu vanish again + }) + .catch(function (err) { + complain(err) + reject(err) + }) + }, + err => { + // login fails + complain('Error logging on: ' + err) + } + ) + } // callbackWS + + const pa = options.pane + // options.appPathSegment = pa.name // was 'edu.mit.solid.pane.' + options.noun = pa.mintClass ? utils.label(pa.mintClass) : pa.name + options.appPathSegment = options.noun.slice(0, 1).toUpperCase() + options.noun.slice(1) + + if (!options.folder) { + // No folder given? Ask user for full URI + selectUI = selectWorkspace(dom, { + noun: options.noun, + appPathSegment: options.appPathSegment + }, callbackWS) + options.div.appendChild(selectUI) + // selectUIParent = options.div + } else { + const gotName = function (name) { + if (!name) { + // selectUIParent.removeChild(selectUI) itremves itself if cancelled + selectNewTool() // toggle star to plain and menu vanish again + } else { + let uri = options.folder!.uri + if (!uri.endsWith('/')) { + uri = uri + '/' + } + uri = uri + encodeURIComponent(name) + '/' + callbackWS(null, uri) + } + } + widgets + .askName( + dom, + kb, + options.div, + ns.foaf('name'), + null, + options.noun + ) + .then(gotName) + // selectUI = getNameForm(dom, kb, options.noun, gotName) + // options.div.appendChild(selectUI) + // selectUIParent = options.div + } + }) + } // makeNewAppInstance + + const iconArray: Array = [] + const mintingPanes = Object.values(thePanes).filter(pane => pane.mintNew) + const mintingClassMap = mintingPanes.reduce((classMap, pane) => { + if (pane.mintClass) { + classMap[pane.mintClass.uri] = (classMap[pane.mintClass.uri] || 0) + 1 + } + return classMap + }, {}) + mintingPanes.forEach(pane => { + // @@ TODO Remove the need to cast to any + const icon: any = createContext.div.appendChild(dom.createElement('img')) + icon.setAttribute('src', pane.icon) + const noun = pane.mintClass + ? mintingClassMap[pane.mintClass.uri] > 1 + ? `${utils.label(pane.mintClass)} (using ${pane.name} pane)` + : utils.label(pane.mintClass) + : pane.name + ' @@' + icon.setAttribute('title', 'Make new ' + noun) + icon.setAttribute('style', iconStyle + 'display: none;') + iconArray.push(icon) + if (!icon.disabled) { + icon.addEventListener('click', function (e) { + selectTool(icon) + makeNewAppInstance({ + event: e, + folder: createContext.folder || null, + iconEle: icon, + pane, + noun, + noIndexHTML: true, // do NOT @@ for now write a HTML file + div: createContext.div, + me: createContext.me, + dom: createContext.dom, + refreshTarget: createContext.refreshTarget + }) + }) + } + }) +} + +// Form to get the name of a new thing before we create it +// +// Used in contacts for new groups, individuals. +// +/* +function getNameForm (dom, kb, classLabel, gotNameCallback) { + const form = dom.createElement('div') // form is broken as HTML behaviour can resurface on js error + form.innerHTML = '

Name of new ' + classLabel + ':

' + const namefield = dom.createElement('input') + namefield.setAttribute('type', 'text') + namefield.setAttribute('size', '30') + namefield.setAttribute('style', style.textInputStyle) + namefield.setAttribute('maxLength', '2048') // No arbitrary limits + namefield.select() // focus next user input + + const gotName = function () { + namefield.setAttribute('class', 'pendingedit') + namefield.disabled = true + continueButton.disabled = true + cancel.disabled = true + gotNameCallback(true, namefield.value) + } + + namefield.addEventListener('keyup', function (e) { + if (e.keyCode === 13) { + gotName() + } + }, false) + form.appendChild(namefield) + + form.appendChild(dom.createElement('br')) + + const cancel = form.appendChild(widgets.cancelButton(dom)) + cancel.addEventListener('click', function (e) { + form.parentNode.removeChild(form) + gotNameCallback(false) + }, false) + + const continueButton = form.appendChild(widgets.continueButton(dom)) + continueButton.addEventListener('click', function (e) { + gotName() + }, false) + + return form +} +*/ diff --git a/src/create/index.ts b/src/create/index.ts new file mode 100644 index 000000000..5f83c9316 --- /dev/null +++ b/src/create/index.ts @@ -0,0 +1,7 @@ +import { + newThingUI +} from './create' + +export const create = { + newThingUI +} diff --git a/src/create/types.ts b/src/create/types.ts new file mode 100644 index 000000000..be51c650b --- /dev/null +++ b/src/create/types.ts @@ -0,0 +1,25 @@ +import { NamedNode } from 'rdflib' +import { PaneDefinition } from 'pane-registry' + +export type CreateContext = { + div: HTMLElement + dom: HTMLDocument + folder?: NamedNode + me: NamedNode + refreshTarget?: HTMLTableElement + statusArea: HTMLElement +} + +export interface NewAppInstanceOptions { + appPathSegment?: string + event: any + folder: NamedNode | null + iconEle: HTMLImageElement + pane: PaneDefinition + noun: string + noIndexHTML: boolean + div: HTMLElement, + me: NamedNode, + dom: HTMLDocument, + refreshTarget?: HTMLTableElement +} diff --git a/src/debug.ts b/src/debug.ts new file mode 100644 index 000000000..5dcc73ef0 --- /dev/null +++ b/src/debug.ts @@ -0,0 +1,15 @@ +export function log (...args: any[]) { + console.log(...args) +} + +export function warn (...args: any[]) { + console.warn(...args) +} + +export function error (...args: any[]) { + console.error(...args) +} + +export function trace (...args: any[]) { + console.trace(...args) +} diff --git a/src/folders.js b/src/folders.js new file mode 100644 index 000000000..474b1e645 --- /dev/null +++ b/src/folders.js @@ -0,0 +1,130 @@ +/** UI To Delete Folder and content + * + */ +/* global confirm */ + +import * as debug from './debug' +import { icons } from './iconBase' +import { solidLogicSingleton } from 'solid-logic' +import ns from './ns' +import * as rdf from 'rdflib' // pull in first avoid cross-refs +import { style } from './style' +import * as widgets from './widgets' + +const UI = { icons, ns, rdf, style, widgets } + +export function deleteRecursive (kb, folder) { + return new Promise(function (resolve, _reject) { + kb.fetcher.load(folder).then(function () { + const promises = kb.each(folder, ns.ldp('contains')).map(file => { + if (kb.holds(file, ns.rdf('type'), ns.ldp('BasicContainer'))) { + return deleteRecursive(kb, file) + } else { + debug.log('deleteRecirsive file: ' + file) + if (!confirm(' Really DELETE File ' + file)) { + throw new Error('User aborted delete file') + } + return kb.fetcher.webOperation('DELETE', file.uri) + } + }) + debug.log('deleteRecirsive folder: ' + folder) + if (!confirm(' Really DELETE folder ' + folder)) { + throw new Error('User aborted delete file') + } + promises.push(kb.fetcher.webOperation('DELETE', folder.uri)) + Promise.all(promises).then(_res => { + resolve() + }) + }) + }) +} + +/** Iterate over files depth first + * + * @param folder - The folder whose contents we iterate over + * @param store - The quadstore + * @param action - returns a promise. All the promises must be resolved + */ +function forAllFiles (folder, kb, action) { + return new Promise(function (resolve, _reject) { + kb.fetcher.load(folder).then(function () { + const promises = kb.each(folder, ns.ldp('contains')).map(file => { + if (kb.holds(file, ns.rdf('type'), ns.ldp('BasicContainer'))) { + return forAllFiles(file, kb, action) + } else { + return action(file) + } + }) + promises.push(action(folder)) + Promise.all(promises).then(_res => { + resolve() + }) + }) + }) +} + +/** Delete Folder and contents + * + * @param {NamedNode} folder - The LDP container to be deleted + * @param {DOMElement} containingElement - Where to put the user interface + * @param {IndexedForumula} store - Quadstore (optional) + * @param {Document} dom - The browser 'document' gloabl or equivalent (or iuse global) + * @returns {DOMElement} - The control which has eben inserted in the + */ +/* global document */ +export function deleteFolder (folder, store, dom) { + store = store || solidLogicSingleton.store + if (typeof docuent !== 'undefined') { + dom = dom || document + } + const div = dom.createElement('div') + const table = div.appendChild(dom.createElement('table')) + const mainTR = table.appendChild(dom.createElement('tr')) + mainTR.appendChild(dom.createElement('td')) // mainTD + + const p = mainTR.appendChild(dom.createElement('p')) + p.textContent = `Are you sure you want to delete the folder ${folder}? This cannot be undone.` + const buttonsTR = table.appendChild(dom.createElement('tr')) + const buttonsTD1 = buttonsTR.appendChild(dom.createElement('td')) + buttonsTR.appendChild(dom.createElement('td')) // buttonsTD2 + const buttonsTD3 = buttonsTR.appendChild(dom.createElement('td')) + + const cancel = buttonsTD1.appendChild(UI.widgets.cancelButton(dom)) + cancel.addEventListener( + 'click', + function (_event) { + div.parentNode.removeChild(div) + }, + false + ) + + const doit = buttonsTD3.appendChild( + UI.widgets.button(dom, UI.icons.iconBase + 'noun_925021.svg', 'Yes, delete') + ) + doit.addEventListener( + 'click', + function (_event) { + deleteThem(folder).then(() => { + debug.log('All deleted.') + }) + }, + false + ) + + function deleteThem (folder) { + return forAllFiles(folder, file => + store.fetcher.webOperation('DELETE', file.uri) + ) + } + let count = 0 + forAllFiles(folder, store, () => { + count += 1 + }) // Count files + .then(() => { + const msg = ' Files to delete: ' + count + debug.log(msg) + p.textContent += msg + }) + + return div +} diff --git a/src/footer/index.ts b/src/footer/index.ts new file mode 100644 index 000000000..fb927c06c --- /dev/null +++ b/src/footer/index.ts @@ -0,0 +1,95 @@ +/* + This file was copied from mashlib/src/global/footer.ts file. It is modified to + work in solid-ui by adjusting where imported functions are found. + */ +import { LiveStore, NamedNode } from 'rdflib' +import { authn, authSession } from 'solid-logic' +import { style } from '../style' +import { getName, getPod, getPodOwner } from '../utils/headerFooterHelpers' + +const DEFAULT_SOLID_PROJECT_URL = 'https://solidproject.org' +const DEFAULT_SOLID_PROJECT_NAME = 'solidproject.org' + +/* + FooterOptions allow for customizing the link and name of the link part of the footer. + */ +export type FooterOptions = { + solidProjectUrl?: string, + solidProjectName?: string +} + +/** + * Initialize footer component, the footer object returned depends on whether the user is authenticated. + * @param store the data store + * @returns the footer + */ +export async function initFooter (store: LiveStore, options?: FooterOptions) { + const footer = document.getElementById('PageFooter') + if (!footer) { + return + } + const pod = getPod() + const podOwner = await getPodOwner(pod, store) + rebuildFooter(footer, store, pod, podOwner, options)() + authSession.events.on('login', rebuildFooter(footer, store, pod, podOwner, options)) + authSession.events.on('logout', rebuildFooter(footer, store, pod, podOwner, options)) +} +/** + * @ignore exporting this only for the unit test + */ +export function rebuildFooter (footer: HTMLElement, store: LiveStore, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions) { + return async () => { + const user = authn.currentUser() + footer.innerHTML = '' + footer.appendChild(await createControllerInfoBlock(store, user, pod, podOwner, options)) + } +} +/** + * @ignore exporting this only for the unit test + */ +export function createControllerInfoBlock (store: LiveStore, user: NamedNode | null, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions): HTMLElement { + const profileLinkContainer = document.createElement('div') + profileLinkContainer.setAttribute('style', style.footer) + + const solidProjectLink = document.createElement('a') + solidProjectLink.href = options && options.solidProjectUrl ? options.solidProjectUrl : DEFAULT_SOLID_PROJECT_URL + solidProjectLink.innerText = options && options.solidProjectName ? options.solidProjectName : DEFAULT_SOLID_PROJECT_NAME + + if (!pod || !podOwner || (user && user.equals(podOwner))) { + const defaultPrefix = document.createElement('span') + defaultPrefix.innerText = 'Powered by ' + profileLinkContainer.appendChild(defaultPrefix) + profileLinkContainer.appendChild(solidProjectLink) + return profileLinkContainer + } + + const podLinkPre = document.createElement('span') + podLinkPre.innerText = 'You\'re visiting ' + + const podLink = document.createElement('a') + podLink.href = pod.uri + podLink.innerText = 'the Pod' + + const profileLinkPre = document.createElement('span') + profileLinkPre.innerText = ' controlled by ' + + const profileLink = document.createElement('a') + profileLink.href = podOwner.uri + profileLink.innerText = getName(store, podOwner) + + const solidProjectLinkPre = document.createElement('span') + solidProjectLinkPre.innerText = '. For more info, check out ' + + const solidProjectLinkPost = document.createElement('span') + solidProjectLinkPost.innerText = '.' + + profileLinkContainer.appendChild(podLinkPre) + profileLinkContainer.appendChild(podLink) + profileLinkContainer.appendChild(profileLinkPre) + profileLinkContainer.appendChild(profileLink) + profileLinkContainer.appendChild(solidProjectLinkPre) + profileLinkContainer.appendChild(solidProjectLink) + profileLinkContainer.appendChild(solidProjectLinkPost) + + return profileLinkContainer +} diff --git a/src/header/empty-profile.ts b/src/header/empty-profile.ts new file mode 100644 index 000000000..d9c1dd1dc --- /dev/null +++ b/src/header/empty-profile.ts @@ -0,0 +1,10 @@ +export const emptyProfile = ` + + + + + + + + +` diff --git a/src/header/index.ts b/src/header/index.ts new file mode 100644 index 000000000..1f5f21144 --- /dev/null +++ b/src/header/index.ts @@ -0,0 +1,308 @@ +/* global EventListenerOrEventListenerObject */ +/* + This file was copied from mashlib/src/global/header.ts file. It is modified to + work in solid-ui by adjusting where imported functions are found. + */ +import { IndexedFormula, NamedNode } from 'rdflib' +import { icons } from '../index' +import { authn, authSession } from 'solid-logic' +import { loginStatusBox } from '../login/login' +// import { loginStatusBox, authSession, currentUser } from '../authn/authn' +import * as widgets from '../widgets' +import { style } from '../style' +import { emptyProfile } from './empty-profile' +import { getPod, throttle } from '../utils/headerFooterHelpers' + +/** + * menu icons +*/ +const DEFAULT_HELP_MENU_ICON = icons.iconBase + 'noun_help.svg' +const DEFAUL_SOLID_ICON_URL = 'https://solidproject.org/assets/img/solid-emblem.svg' + +export type MenuItemLink = { + label: string, + url: string, + target?: string +} + +export type MenuItemButton = { + label: string, + onclick: () => void +} + +export type MenuItems = MenuItemLink | MenuItemButton + +/* + HeaderOptions allow for customizing the logo and menu list. If a logo is not provided the default + is solid. Menulist will always show a link to logout and to the users profile. + */ +export type HeaderOptions = { + logo?: string, + helpIcon?: string, + helpMenuList?: MenuItems[] +} + +/** + * Initialize header component, the header object returned depends on whether the user is authenticated. + * @param store the data store + * @param userMenuList a list of menu items when the user is logged in + * @param options allow the header to be customized with a personalized logo, help icon and a help menu list of links or buttons. + * @returns a header for an authenticated user with menu items given or a login screen + */ +export async function initHeader (store: IndexedFormula, userMenuList: MenuItems[], options?: HeaderOptions) { + const header = document.getElementById('PageHeader') + if (!header) { + return + } + + const pod = getPod() + rebuildHeader(header, store, pod, userMenuList, options)() + authSession.events.on('logout', rebuildHeader(header, store, pod, userMenuList, options)) + authSession.events.on('login', rebuildHeader(header, store, pod, userMenuList, options)) +} +/** + * @ignore exporting this only for the unit test + */ +export function rebuildHeader (header: HTMLElement, store: IndexedFormula, pod: NamedNode, userMenuList: MenuItems[], options?: HeaderOptions) { + return async () => { + const user = authn.currentUser() + header.innerHTML = '' + header.appendChild(await createBanner(store, pod, user, userMenuList, options)) + } +} +/** + * @ignore exporting this only for the unit test + */ +export async function createBanner (store: IndexedFormula, pod: NamedNode, user: NamedNode | null, userMenuList: MenuItems[], options?: HeaderOptions): Promise { + const podLink = document.createElement('a') + podLink.href = pod.uri + podLink.setAttribute('style', style.headerBannerLink) + const image = document.createElement('img') + if (options) { + image.src = options.logo ? options.logo : DEFAUL_SOLID_ICON_URL + } + image.setAttribute('style', style.headerBannerIcon) + podLink.appendChild(image) + + const userMenu = user + ? await createUserMenu(store, user, userMenuList) + : createLoginSignUpButtons() + + const banner = document.createElement('div') + banner.setAttribute('style', style.headerBanner) + banner.appendChild(podLink) + + const leftSideOfHeader = document.createElement('div') + leftSideOfHeader.setAttribute('style', style.headerBannerRightMenu) + leftSideOfHeader.appendChild(userMenu) + + if (options && options.helpMenuList) { + const helpMenu = createHelpMenu(options, options.helpMenuList) + leftSideOfHeader.appendChild(helpMenu as HTMLDivElement) + } + + banner.appendChild(leftSideOfHeader) + + return banner +} +/** + * @ignore exporting this only for the unit test + */ +export function createHelpMenu (options: HeaderOptions, helpMenuItems: MenuItems[]) { + if (!helpMenuItems) return + const helpMenuList = document.createElement('ul') + helpMenuList.setAttribute('style', style.headerUserMenuList) + helpMenuItems.forEach(function (menuItem) { + const menuItemType: string = (menuItem as MenuItemLink).url ? 'url' : 'onclick' + if (menuItemType === 'url') { + helpMenuList.appendChild(createUserMenuItem(createUserMenuLink(menuItem.label, (menuItem as MenuItemLink).url, (menuItem as MenuItemLink).target))) + } else { + helpMenuList.appendChild(createUserMenuItem(createUserMenuButton(menuItem.label, (menuItem as MenuItemButton).onclick))) + } + }) + + const helpMenu = document.createElement('nav') + + helpMenu.setAttribute('style', style.headerUserMenuNavigationMenuNotDisplayed) + helpMenu.setAttribute('aria-hidden', 'true') + helpMenu.setAttribute('id', 'helperNav') + helpMenu.appendChild(helpMenuList) + + const helpMenuContainer = document.createElement('div') + helpMenuContainer.setAttribute('style', style.headerBannerUserMenu) + helpMenuContainer.appendChild(helpMenu) + + const helpMenuTrigger = document.createElement('button') + helpMenuTrigger.setAttribute('style', style.headerUserMenuTrigger) + helpMenuTrigger.type = 'button' + + const helpMenuIcon = document.createElement('img') + helpMenuIcon.src = (options && options.helpIcon) ? options.helpIcon : icons.iconBase + DEFAULT_HELP_MENU_ICON + helpMenuIcon.setAttribute('style', style.headerUserMenuTriggerImg) + helpMenuContainer.appendChild(helpMenuTrigger) + helpMenuTrigger.appendChild(helpMenuIcon) + + const throttledMenuToggle = throttle((event: Event) => toggleMenu(event, helpMenuTrigger, helpMenu), 50) + helpMenuTrigger.addEventListener('click', throttledMenuToggle) + let timer = setTimeout(() => null, 0) + helpMenuContainer.addEventListener('mouseover', event => { + clearTimeout(timer) + throttledMenuToggle(event) + const nav = document.getElementById('helperNav') + nav?.setAttribute('style', style.headerUserMenuNavigationMenu) + }) + helpMenuContainer.addEventListener('mouseout', event => { + timer = setTimeout(() => throttledMenuToggle(event), 200) + const nav = document.getElementById('helperNav') + nav?.setAttribute('style', style.headerUserMenuNavigationMenuNotDisplayed) + }) + + return helpMenuContainer +} +/** + * @ignore exporting this only for the unit test + */ +export function createLoginSignUpButtons () { + const profileLoginButtonPre = document.createElement('div') + profileLoginButtonPre.setAttribute('style', style.headerBannerLogin) + profileLoginButtonPre.appendChild(loginStatusBox(document, null, {})) + return profileLoginButtonPre +} +/** + * @ignore exporting this only for the unit test + */ +export function createUserMenuButton (label: string, onClick: EventListenerOrEventListenerObject): HTMLElement { + const button = document.createElement('button') + button.setAttribute('style', style.headerUserMenuButton) + button.onmouseover = function () { + button.setAttribute('style', style.headerUserMenuButtonHover) + } + button.onmouseout = function () { + button.setAttribute('style', style.headerUserMenuButton) + } + button.addEventListener('click', onClick) + button.innerText = label + return button +} +/** + * @ignore exporting this only for the unit test + */ +export function createUserMenuLink (label: string, href: string, target?: string): HTMLElement { + const link = document.createElement('a') + link.setAttribute('style', style.headerUserMenuLink) + link.onmouseover = function () { + link.setAttribute('style', style.headerUserMenuLinkHover) + } + link.onmouseout = function () { + link.setAttribute('style', style.headerUserMenuLink) + } + link.href = href + link.innerText = label + if (target) link.target = target + return link +} + +/** + * @ignore exporting this only for the unit test + */ +export async function createUserMenu (store: IndexedFormula, user: NamedNode, userMenuList: MenuItems[]): Promise { + const fetcher = (store).fetcher + if (fetcher) { + // Making sure that Profile is loaded before building menu + await fetcher.load(user) + } + + const loggedInMenuList = document.createElement('ul') + loggedInMenuList.setAttribute('style', style.headerUserMenuList) + if (userMenuList) { + userMenuList.forEach(function (menuItem) { + const menuItemType: string = (menuItem as MenuItemLink).url ? 'url' : 'onclick' + if (menuItemType === 'url') { + loggedInMenuList.appendChild(createUserMenuItem(createUserMenuLink(menuItem.label, (menuItem as MenuItemLink).url, (menuItem as MenuItemLink).target))) + } else { + loggedInMenuList.appendChild(createUserMenuItem(createUserMenuButton(menuItem.label, (menuItem as MenuItemButton).onclick))) + } + }) + } + const loggedInMenu = document.createElement('nav') + + loggedInMenu.setAttribute('style', style.headerUserMenuNavigationMenuNotDisplayed) + loggedInMenu.setAttribute('aria-hidden', 'true') + loggedInMenu.setAttribute('id', 'loggedInNav') + loggedInMenu.appendChild(loggedInMenuList) + + const loggedInMenuTrigger = document.createElement('button') + loggedInMenuTrigger.setAttribute('style', style.headerUserMenuTrigger) + loggedInMenuTrigger.type = 'button' + const profileImg = getProfileImg(store, user) + if (typeof profileImg === 'string') { + loggedInMenuTrigger.innerHTML = profileImg + } else { + loggedInMenuTrigger.appendChild(profileImg) + } + + const loggedInMenuContainer = document.createElement('div') + loggedInMenuContainer.setAttribute('style', style.headerBannerUserMenuNotDisplayed) + loggedInMenuContainer.appendChild(loggedInMenuTrigger) + loggedInMenuContainer.appendChild(loggedInMenu) + + const throttledMenuToggle = throttle((event: Event) => toggleMenu(event, loggedInMenuTrigger, loggedInMenu), 50) + loggedInMenuTrigger.addEventListener('click', throttledMenuToggle) + let timer = setTimeout(() => null, 0) + loggedInMenuContainer.addEventListener('mouseover', event => { + clearTimeout(timer) + throttledMenuToggle(event) + const nav = document.getElementById('loggedInNav') + nav?.setAttribute('style', style.headerUserMenuNavigationMenu) + }) + loggedInMenuContainer.addEventListener('mouseout', event => { + timer = setTimeout(() => throttledMenuToggle(event), 200) + const nav = document.getElementById('loggedInNav') + nav?.setAttribute('style', style.headerUserMenuNavigationMenuNotDisplayed) + }) + + return loggedInMenuContainer +} + +/** + * @ignore exporting this only for the unit test + */ +export function createUserMenuItem (child: HTMLElement): HTMLElement { + const menuProfileItem = document.createElement('li') + menuProfileItem.setAttribute('style', style.headerUserMenuListItem) + menuProfileItem.appendChild(child) + return menuProfileItem +} +/** + * @ignore exporting this only for the unit test + */ +export function getProfileImg (store: IndexedFormula, user: NamedNode): string | HTMLElement { + let profileUrl = null + try { + profileUrl = widgets.findImage(user) + if (!profileUrl) { + return emptyProfile + } + } catch { + return emptyProfile + } + + const profileImage = document.createElement('div') + profileImage.setAttribute('style', style.headerUserMenuPhoto) + profileImage.style.backgroundImage = `url(${profileUrl})` + return profileImage +} + +/** + * @internal + */ +function toggleMenu (event: Event, trigger: HTMLButtonElement, menu: HTMLElement): void { + const isExpanded = trigger.getAttribute('aria-expanded') === 'true' + const expand = event.type === 'mouseover' + const close = event.type === 'mouseout' + if ((isExpanded && expand) || (!isExpanded && close)) { + return + } + trigger.setAttribute('aria-expanded', (!isExpanded).toString()) + menu.setAttribute('aria-hidden', isExpanded.toString()) +} diff --git a/src/iconBase.js b/src/iconBase.js deleted file mode 100644 index 98355b374..000000000 --- a/src/iconBase.js +++ /dev/null @@ -1,20 +0,0 @@ - -// Works in FF extension - what about browserify?? - -if (module.scriptURI) { // FF extension - module.exports.iconBase = '' + - module.scriptURI.slice(0, module.scriptURI.lastIndexOf('/')) + '/icons/' - module.exports.originalIconBase = '' + - module.scriptURI.slice(0, module.scriptURI.lastIndexOf('/')) + '/originalIcons/' -} else { // Node or browserify - var iconsOnGithub = 'https://solid.github.io/solid-ui/src' - - if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.iconBase) { - module.exports.iconBase = $SolidTestEnvironment.iconBase - module.exports.originalIconBase = $SolidTestEnvironment.originalIconBase - } else { - module.exports.iconBase = iconsOnGithub + '/icons/' - module.exports.originalIconBase = iconsOnGithub + '/originalIcons/' - } -} -console.log(' Icon base is: ' + module.exports.iconBase) diff --git a/src/iconBase.ts b/src/iconBase.ts new file mode 100644 index 000000000..776fc0c2b --- /dev/null +++ b/src/iconBase.ts @@ -0,0 +1,46 @@ +// Works in FF extension - what about browserify?? +// 2021-04-08 Convert to TS + +/* The Firefox case is left for historical record, as we don't currenly + * have a FF extension for mashlib, but we could. This is sthepoint to + * hack the place it can find its icons internally + * + * The $SolidTestEnvironment is important and is used for + * example when testing on localhost to specify a place the icons be found + * in your test set up. + * + * You can also use it if you want to just run a mashlib whhich takes its + * icons seved by other than github. + */ + +import { log } from './debug' + +declare let $SolidTestEnvironment + +// Do not export. Always us this module to find the icons, as they vary +const iconsOnGithub = 'https://solidos.github.io/solid-ui/src' // changed org 2022-05 + +export const icons = (module as any).scriptURI // Firefox extension + ? { + iconBase: + (module as any).scriptURI.slice(0, (module as any).scriptURI.lastIndexOf('/')) + '/icons/', + originalIconBase: + (module as any).scriptURI.slice(0, (module as any).scriptURI.lastIndexOf('/')) + + '/originalIcons/' + } + : typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.iconBase // Test environemnt + ? { + iconBase: $SolidTestEnvironment.iconBase, + originalIconBase: $SolidTestEnvironment.originalIconBase + } + : { + // Normal case: + iconBase: iconsOnGithub + '/icons/', + originalIconBase: iconsOnGithub + '/originalIcons/' + } + +log(' icons.iconBase is set to : ' + icons.iconBase) + +// allow tests etc named-import this directly from this module +export const iconBase = icons.iconBase +export const originalIconBase = icons.originalIconBase diff --git a/src/icons/auto-play-next-tbl.svg b/src/icons/auto-play-next-tbl.svg new file mode 100644 index 000000000..c6ee1f67a --- /dev/null +++ b/src/icons/auto-play-next-tbl.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/icons/class-rectangle.svg b/src/icons/class-rectangle.svg new file mode 100644 index 000000000..f7ba52093 --- /dev/null +++ b/src/icons/class-rectangle.svg @@ -0,0 +1,7 @@ + diff --git a/src/icons/emptyProfileAvatar.png b/src/icons/emptyProfileAvatar.png new file mode 100644 index 000000000..ad5875a11 Binary files /dev/null and b/src/icons/emptyProfileAvatar.png differ diff --git a/src/icons/markdown.svg b/src/icons/markdown.svg new file mode 100644 index 000000000..939c549be --- /dev/null +++ b/src/icons/markdown.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/icons/newperson.svg b/src/icons/newperson.svg new file mode 100644 index 000000000..82397b81b --- /dev/null +++ b/src/icons/newperson.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/newpersonInCircle.svg b/src/icons/newpersonInCircle.svg new file mode 100644 index 000000000..82397b81b --- /dev/null +++ b/src/icons/newpersonInCircle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/noun-reply-5506924.svg b/src/icons/noun-reply-5506924.svg new file mode 100644 index 000000000..32f490b0b --- /dev/null +++ b/src/icons/noun-reply-5506924.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/icons/noun_17020.svg b/src/icons/noun_17020.svg index 938d4fea5..5c3decc9f 100644 --- a/src/icons/noun_17020.svg +++ b/src/icons/noun_17020.svg @@ -1 +1,5 @@ -http://thenounproject.comThe Noun ProjectIcon TemplateRemindersStrokesTry to keep strokes at 4pxMinimum stroke weight is 2pxFor thicker strokes use even numbers: 6px, 8px etc.Remember to expand strokes before saving as an SVG SizeCannot be wider or taller than 100px (artboard size)Scale your icon to fill as much of the artboard as possibleUngroupIf your design has more than one shape, make sure to ungroupSave asSave as .SVG and make sure “Use Artboards” is checked100px.SVG \ No newline at end of file + + + + + diff --git a/src/icons/noun_17020_gray-tick.svg b/src/icons/noun_17020_gray-tick.svg new file mode 100644 index 000000000..2df5f410b --- /dev/null +++ b/src/icons/noun_17020_gray-tick.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/noun_17020_sans-tick.svg b/src/icons/noun_17020_sans-tick.svg new file mode 100644 index 000000000..e3a40b135 --- /dev/null +++ b/src/icons/noun_17020_sans-tick.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/noun_Cabinet_1434380.svg b/src/icons/noun_Cabinet_1434380.svg new file mode 100644 index 000000000..546df63a5 --- /dev/null +++ b/src/icons/noun_Cabinet_1434380.svg @@ -0,0 +1 @@ +48 diff --git a/src/icons/noun_Cabinet_251723.svg b/src/icons/noun_Cabinet_251723.svg new file mode 100644 index 000000000..bc7ffa34d --- /dev/null +++ b/src/icons/noun_Cabinet_251723.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_Camera_1618446_000000.svg b/src/icons/noun_Camera_1618446_000000.svg new file mode 100644 index 000000000..e80e6a90b --- /dev/null +++ b/src/icons/noun_Camera_1618446_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_Danger_1259514.svg b/src/icons/noun_Danger_1259514.svg new file mode 100644 index 000000000..267b81337 --- /dev/null +++ b/src/icons/noun_Danger_1259514.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_Document_998605.svg b/src/icons/noun_Document_998605.svg new file mode 100644 index 000000000..b738d5fd7 --- /dev/null +++ b/src/icons/noun_Document_998605.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_Download_76560_000000.svg b/src/icons/noun_Download_76560_000000.svg new file mode 100644 index 000000000..3edd0e3a9 --- /dev/null +++ b/src/icons/noun_Download_76560_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_Hash_2457016.svg b/src/icons/noun_Hash_2457016.svg new file mode 100644 index 000000000..48136bcc9 --- /dev/null +++ b/src/icons/noun_Hash_2457016.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_Robot_849764.svg b/src/icons/noun_Robot_849764.svg new file mode 100644 index 000000000..6341b4fc3 --- /dev/null +++ b/src/icons/noun_Robot_849764.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_Search_875351.svg b/src/icons/noun_Search_875351.svg new file mode 100644 index 000000000..03a28108b --- /dev/null +++ b/src/icons/noun_Search_875351.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_Share_29706_000000.svg b/src/icons/noun_Share_29706_000000.svg new file mode 100644 index 000000000..7f8b83a61 --- /dev/null +++ b/src/icons/noun_Share_29706_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_Sliders_341315_000000.svg b/src/icons/noun_Sliders_341315_000000.svg new file mode 100644 index 000000000..97340de9c --- /dev/null +++ b/src/icons/noun_Sliders_341315_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_T-Block_1114655_000000.svg b/src/icons/noun_T-Block_1114655_000000.svg new file mode 100644 index 000000000..73ba06da5 --- /dev/null +++ b/src/icons/noun_T-Block_1114655_000000.svg @@ -0,0 +1 @@ +T-downCreated with Sketch. \ No newline at end of file diff --git a/src/icons/noun_T-Block_1114657_000000.svg b/src/icons/noun_T-Block_1114657_000000.svg new file mode 100644 index 000000000..f60c4dbe5 --- /dev/null +++ b/src/icons/noun_T-Block_1114657_000000.svg @@ -0,0 +1 @@ +TCreated with Sketch. \ No newline at end of file diff --git a/src/icons/noun_Tag_3235488.svg b/src/icons/noun_Tag_3235488.svg new file mode 100644 index 000000000..fc4b0d085 --- /dev/null +++ b/src/icons/noun_Tag_3235488.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_Trade_1585569.svg b/src/icons/noun_Trade_1585569.svg new file mode 100644 index 000000000..16597061f --- /dev/null +++ b/src/icons/noun_Trade_1585569.svg @@ -0,0 +1 @@ +Created by bezier masterfrom the Noun Project \ No newline at end of file diff --git a/src/icons/noun_Upload_76574_000000.svg b/src/icons/noun_Upload_76574_000000.svg new file mode 100644 index 000000000..95f9ab7b6 --- /dev/null +++ b/src/icons/noun_Upload_76574_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_classification_1479198.svg b/src/icons/noun_classification_1479198.svg new file mode 100644 index 000000000..5f22c7b62 --- /dev/null +++ b/src/icons/noun_classification_1479198.svg @@ -0,0 +1 @@ +classification-divide-digest-separate-analytic-identify-list diff --git a/src/icons/noun_classification_260814.svg b/src/icons/noun_classification_260814.svg new file mode 100644 index 000000000..01e773df9 --- /dev/null +++ b/src/icons/noun_classification_260814.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_copy_2018813.svg b/src/icons/noun_copy_2018813.svg new file mode 100644 index 000000000..c6b3b25a8 --- /dev/null +++ b/src/icons/noun_copy_2018813.svg @@ -0,0 +1 @@ +Asset 288 \ No newline at end of file diff --git a/src/icons/noun_forward_390574_000000.svg b/src/icons/noun_forward_390574_000000.svg new file mode 100644 index 000000000..7bd83ff49 --- /dev/null +++ b/src/icons/noun_forward_390574_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_help.svg b/src/icons/noun_help.svg new file mode 100644 index 000000000..ce4976bc6 --- /dev/null +++ b/src/icons/noun_help.svg @@ -0,0 +1,17 @@ + + + help_outline + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/noun_lines_2626315.svg b/src/icons/noun_lines_2626315.svg new file mode 100644 index 000000000..be10c6d85 --- /dev/null +++ b/src/icons/noun_lines_2626315.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_list_638112.svg b/src/icons/noun_list_638112.svg new file mode 100644 index 000000000..9ecf52d17 --- /dev/null +++ b/src/icons/noun_list_638112.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_locked_2160665_000000.svg b/src/icons/noun_locked_2160665_000000.svg new file mode 100644 index 000000000..d5f113d52 --- /dev/null +++ b/src/icons/noun_locked_2160665_000000.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_mention_3203461.svg b/src/icons/noun_mention_3203461.svg new file mode 100644 index 000000000..25dff6e65 --- /dev/null +++ b/src/icons/noun_mention_3203461.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_photo album_668930_000000.svg b/src/icons/noun_photo album_668930_000000.svg new file mode 100644 index 000000000..cfc374da1 --- /dev/null +++ b/src/icons/noun_photo album_668930_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_photo library_230056_000000.svg b/src/icons/noun_photo library_230056_000000.svg new file mode 100644 index 000000000..6cd09343b --- /dev/null +++ b/src/icons/noun_photo library_230056_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_properties_402126.svg b/src/icons/noun_properties_402126.svg new file mode 100644 index 000000000..da7161063 --- /dev/null +++ b/src/icons/noun_properties_402126.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/noun_properties_98039.svg b/src/icons/noun_properties_98039.svg new file mode 100644 index 000000000..be9f3998f --- /dev/null +++ b/src/icons/noun_properties_98039.svg @@ -0,0 +1 @@ + diff --git a/src/icons/noun_rectangle_1722413.svg b/src/icons/noun_rectangle_1722413.svg new file mode 100644 index 000000000..46aee9fa5 --- /dev/null +++ b/src/icons/noun_rectangle_1722413.svg @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/icons/noun_rhombus_1722412.svg b/src/icons/noun_rhombus_1722412.svg new file mode 100644 index 000000000..7904bbe3f --- /dev/null +++ b/src/icons/noun_rhombus_1722412.svg @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/icons/noun_unlocked_2160671_000000.svg b/src/icons/noun_unlocked_2160671_000000.svg new file mode 100644 index 000000000..53e2937c7 --- /dev/null +++ b/src/icons/noun_unlocked_2160671_000000.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/padlock-timbl.svg b/src/icons/padlock-timbl.svg new file mode 100644 index 000000000..7f19bea7f --- /dev/null +++ b/src/icons/padlock-timbl.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/icons/property-diamond.svg b/src/icons/property-diamond.svg new file mode 100644 index 000000000..b25e62f36 --- /dev/null +++ b/src/icons/property-diamond.svg @@ -0,0 +1,7 @@ + diff --git a/src/icons/social/0CREDITS.txt b/src/icons/social/0CREDITS.txt new file mode 100644 index 000000000..3787a39f0 --- /dev/null +++ b/src/icons/social/0CREDITS.txt @@ -0,0 +1,3 @@ +These icons were downloaded from https://worldvectorlogo.com/ +They are beleived free to use without constraint. + diff --git a/src/icons/social/ORCID-1.svg b/src/icons/social/ORCID-1.svg new file mode 100644 index 000000000..25ca66545 --- /dev/null +++ b/src/icons/social/ORCID-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/bluesky-1.svg b/src/icons/social/bluesky-1.svg new file mode 100644 index 000000000..0f25b8b88 --- /dev/null +++ b/src/icons/social/bluesky-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/digg-icon.svg b/src/icons/social/digg-icon.svg new file mode 100644 index 000000000..916b08c35 --- /dev/null +++ b/src/icons/social/digg-icon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/icons/social/facebook-2020-2-1.svg b/src/icons/social/facebook-2020-2-1.svg new file mode 100644 index 000000000..898bbe8a0 --- /dev/null +++ b/src/icons/social/facebook-2020-2-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/github-icon.svg b/src/icons/social/github-icon.svg new file mode 100644 index 000000000..0f6b93868 --- /dev/null +++ b/src/icons/social/github-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/instagram-2016-5.svg b/src/icons/social/instagram-2016-5.svg new file mode 100644 index 000000000..278f024e6 --- /dev/null +++ b/src/icons/social/instagram-2016-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/linkedin-icon.svg b/src/icons/social/linkedin-icon.svg new file mode 100644 index 000000000..2b89b957e --- /dev/null +++ b/src/icons/social/linkedin-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/mastodon-2.svg b/src/icons/social/mastodon-2.svg new file mode 100644 index 000000000..35a181e46 --- /dev/null +++ b/src/icons/social/mastodon-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/matrix-logo-black.svg b/src/icons/social/matrix-logo-black.svg new file mode 100644 index 000000000..c132fe205 --- /dev/null +++ b/src/icons/social/matrix-logo-black.svg @@ -0,0 +1,18 @@ + + + + matrix logo white + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/social/medium-logo-wordmark-black.svg b/src/icons/social/medium-logo-wordmark-black.svg new file mode 100644 index 000000000..afc66135f --- /dev/null +++ b/src/icons/social/medium-logo-wordmark-black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/nostr-icon-purple-on-white.svg b/src/icons/social/nostr-icon-purple-on-white.svg new file mode 100644 index 000000000..a519b4cd9 --- /dev/null +++ b/src/icons/social/nostr-icon-purple-on-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/pinterest-2-1.svg b/src/icons/social/pinterest-2-1.svg new file mode 100644 index 000000000..e13cdd9b8 --- /dev/null +++ b/src/icons/social/pinterest-2-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/reddit-4.svg b/src/icons/social/reddit-4.svg new file mode 100644 index 000000000..222028aa8 --- /dev/null +++ b/src/icons/social/reddit-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/snapchat-0.svg b/src/icons/social/snapchat-0.svg new file mode 100644 index 000000000..08490beac --- /dev/null +++ b/src/icons/social/snapchat-0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/snapchat-1.svg b/src/icons/social/snapchat-1.svg new file mode 100644 index 000000000..80979fdf7 --- /dev/null +++ b/src/icons/social/snapchat-1.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/icons/social/strava-2.svg b/src/icons/social/strava-2.svg new file mode 100644 index 000000000..d94ac6a66 --- /dev/null +++ b/src/icons/social/strava-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/tiktok-icon-2.svg b/src/icons/social/tiktok-icon-2.svg new file mode 100644 index 000000000..619d3c67c --- /dev/null +++ b/src/icons/social/tiktok-icon-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/tumblr-icon.svg b/src/icons/social/tumblr-icon.svg new file mode 100644 index 000000000..75a012bcd --- /dev/null +++ b/src/icons/social/tumblr-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/social/umai.svg b/src/icons/social/umai.svg new file mode 100644 index 000000000..d5b5d1c52 --- /dev/null +++ b/src/icons/social/umai.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/x-2.svg b/src/icons/social/x-2.svg new file mode 100644 index 000000000..cc527fff7 --- /dev/null +++ b/src/icons/social/x-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/solid_logo.ts b/src/icons/solid_logo.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/icons/v2/clock.png b/src/icons/v2/clock.png new file mode 100644 index 000000000..5ed80e5fb Binary files /dev/null and b/src/icons/v2/clock.png differ diff --git a/src/icons/v2/close.png b/src/icons/v2/close.png new file mode 100644 index 000000000..44135e013 Binary files /dev/null and b/src/icons/v2/close.png differ diff --git a/src/icons/v2/discord.png b/src/icons/v2/discord.png new file mode 100644 index 000000000..c262fc979 Binary files /dev/null and b/src/icons/v2/discord.png differ diff --git a/src/icons/v2/dribbble.png b/src/icons/v2/dribbble.png new file mode 100644 index 000000000..9b1e5d507 Binary files /dev/null and b/src/icons/v2/dribbble.png differ diff --git a/src/icons/v2/facebook.png b/src/icons/v2/facebook.png new file mode 100644 index 000000000..6f8f66461 Binary files /dev/null and b/src/icons/v2/facebook.png differ diff --git a/src/icons/v2/folder.png b/src/icons/v2/folder.png new file mode 100644 index 000000000..b8d82696e Binary files /dev/null and b/src/icons/v2/folder.png differ diff --git a/src/icons/v2/graycamera.png b/src/icons/v2/graycamera.png new file mode 100644 index 000000000..542c40a6c Binary files /dev/null and b/src/icons/v2/graycamera.png differ diff --git a/src/icons/v2/graypaste.png b/src/icons/v2/graypaste.png new file mode 100644 index 000000000..6fa40f8e0 Binary files /dev/null and b/src/icons/v2/graypaste.png differ diff --git a/src/icons/v2/icons-svg/contactIcons.ts b/src/icons/v2/icons-svg/contactIcons.ts new file mode 100644 index 000000000..15a8cd70b --- /dev/null +++ b/src/icons/v2/icons-svg/contactIcons.ts @@ -0,0 +1,27 @@ +import { html } from 'lit-html' + +export const phoneIcon = html` + +` +export const emailIcon = html` + + ` diff --git a/src/icons/v2/icons-svg/headerIcons.ts b/src/icons/v2/icons-svg/headerIcons.ts new file mode 100644 index 000000000..ddf943e1e --- /dev/null +++ b/src/icons/v2/icons-svg/headerIcons.ts @@ -0,0 +1,245 @@ +import { html } from 'lit-html' + +export const profileIcon = html` + +` +export const friendsIcon = html` + +` +export const helpIcon = html` + + ` +export const solidIcon = html` + +` +export const dashboardIcon = html` + +` +export const chatIcon = html` + +` +export const sharingIcon = html` + +` +export const personIcon = html` + +` +export const downArrowIcon = html` + +` +export const checkBoxIcon = html` + +` +export const signOutIcon = html` + +` +export const mainEditIcon = html` + +` +export const myProfileIcon = html` + +` +export const emptyCircleIcon = html` + +` +export const grayPlusIcon = html` + +` +export const clockIcon = html` + +` +export const favStarIcon = html` + +` diff --git a/src/icons/v2/icons-svg/pngIcons.ts b/src/icons/v2/icons-svg/pngIcons.ts new file mode 100644 index 000000000..05820bf69 --- /dev/null +++ b/src/icons/v2/icons-svg/pngIcons.ts @@ -0,0 +1,5 @@ +const addMoreIconSvg = '' + +const addMoreIconAsset = `data:image/svg+xml;utf8,${encodeURIComponent(addMoreIconSvg)}` + +export { addMoreIconAsset } diff --git a/src/icons/v2/icons-svg/profileIcons.ts b/src/icons/v2/icons-svg/profileIcons.ts new file mode 100644 index 000000000..560fb0981 --- /dev/null +++ b/src/icons/v2/icons-svg/profileIcons.ts @@ -0,0 +1,318 @@ +import { html } from 'lit-html' + +export const birthdayIcon = html` + +` +export const locationIcon = html` + +` +export const checkMarkIcon = html` + +` +export const plusDarkIcon = html` + +` + +export const plusIcon = html` + +` +export const searchIcon = html` + +` +export const trashIcon = html` + +` +export const bentoIcon = html` + +` +export const starIcon = html` + +` +export const addIcon = html` + +` +export const personInCircleIcon = html` + +` +export const globeIcon = html` + +` +export const lighteningIcon = html` + +` +export const commentIcon = html` + +` +export const envelopeIcon = html` + +` +export const pasteIcon = html` + +` +export const closeIcon = html` + +` +export const editIcon = html` + +` +export const deleteIcon = html` + +` +export const purpleFilledCheckboxIcon = html` + +` +export const cameraIcon = html` + +` +export const twoDownArrowsIcon = html` + +` diff --git a/src/icons/v2/instagram.png b/src/icons/v2/instagram.png new file mode 100644 index 000000000..24f9bc25c Binary files /dev/null and b/src/icons/v2/instagram.png differ diff --git a/src/icons/v2/linkedin.png b/src/icons/v2/linkedin.png new file mode 100644 index 000000000..da5f708aa Binary files /dev/null and b/src/icons/v2/linkedin.png differ diff --git a/src/icons/v2/pinterest.png b/src/icons/v2/pinterest.png new file mode 100644 index 000000000..6d513088b Binary files /dev/null and b/src/icons/v2/pinterest.png differ diff --git a/src/icons/v2/purplecamera.png b/src/icons/v2/purplecamera.png new file mode 100644 index 000000000..863fb7ca1 Binary files /dev/null and b/src/icons/v2/purplecamera.png differ diff --git a/src/icons/v2/purplepaste.png b/src/icons/v2/purplepaste.png new file mode 100644 index 000000000..e144f3a31 Binary files /dev/null and b/src/icons/v2/purplepaste.png differ diff --git a/src/icons/v2/sharechat.png b/src/icons/v2/sharechat.png new file mode 100644 index 000000000..5ae64adcc Binary files /dev/null and b/src/icons/v2/sharechat.png differ diff --git a/src/icons/v2/signup.png b/src/icons/v2/signup.png new file mode 100644 index 000000000..2c029652f Binary files /dev/null and b/src/icons/v2/signup.png differ diff --git a/src/icons/v2/smallclose.png b/src/icons/v2/smallclose.png new file mode 100644 index 000000000..d582461da Binary files /dev/null and b/src/icons/v2/smallclose.png differ diff --git a/src/icons/v2/snapchat.png b/src/icons/v2/snapchat.png new file mode 100644 index 000000000..a4bbbea26 Binary files /dev/null and b/src/icons/v2/snapchat.png differ diff --git a/src/icons/v2/spotify.png b/src/icons/v2/spotify.png new file mode 100644 index 000000000..12743b6c8 Binary files /dev/null and b/src/icons/v2/spotify.png differ diff --git a/src/icons/v2/telegram.png b/src/icons/v2/telegram.png new file mode 100644 index 000000000..d46498ba9 Binary files /dev/null and b/src/icons/v2/telegram.png differ diff --git a/src/icons/v2/tiktok.png b/src/icons/v2/tiktok.png new file mode 100644 index 000000000..8ebeb3710 Binary files /dev/null and b/src/icons/v2/tiktok.png differ diff --git a/src/icons/v2/whatsapp.png b/src/icons/v2/whatsapp.png new file mode 100644 index 000000000..572db184f Binary files /dev/null and b/src/icons/v2/whatsapp.png differ diff --git a/src/icons/v2/x.png b/src/icons/v2/x.png new file mode 100644 index 000000000..700717387 Binary files /dev/null and b/src/icons/v2/x.png differ diff --git a/src/icons/v2/youtube.png b/src/icons/v2/youtube.png new file mode 100644 index 000000000..1287c0a9b Binary files /dev/null and b/src/icons/v2/youtube.png differ diff --git a/src/index.js b/src/index.js deleted file mode 100755 index 375f73bbe..000000000 --- a/src/index.js +++ /dev/null @@ -1,64 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2015-2016 Solid - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -If you would like to know more about the solid Solid project, please see -https://github.com/solid/solid -*/ -'use strict' -/** - * Provides a Solid client helper object (which exposes various static modules). - * @module solidUi.js - * @main solidUi.js - */ - -/** - * @class SolidUi - * @static - */ - -const rdf = require('rdflib') // pull in first avoid cross-refs -const ns = require('./ns') - -const UI = { - ns, - rdf, - acl: require('./acl'), - aclControl: require('./acl-control'), - authn: require('./signin'), - create: require('./create'), - icons: require('./iconBase'), - log: require('./log'), - matrix: require('./matrix'), - messageArea: require('./messageArea'), - infiniteMessageArea: require('./infiniteMessageArea'), - pad: require('./pad'), - preferences: require('./preferences'), - store: require('./store'), - style: require('./style'), - table: require('./table'), - tabs: require('./tabs'), - utils: require('./utils'), - widgets: require('./widgets') -} - -module.exports = UI diff --git a/src/index.ts b/src/index.ts new file mode 100755 index 000000000..2c8f1bcbd --- /dev/null +++ b/src/index.ts @@ -0,0 +1,132 @@ +/* +The MIT License (MIT) + +Copyright (c) 2015-2016 Solid + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +If you would like to know more about the solid Solid project, please see +https://github.com/solidos/solid +*/ +'use strict' +/** + * Provides a Solid client helper object (which exposes various static modules). + * @module UI.js + * @main UI.js + */ + +/** + * @class UI + * @static + */ + +// REMOVE @ts-ignore as you migrate files to TypeScript +// @ts-ignore +import ns from './ns' +import { acl, aclControl } from './acl/index' +import { create } from './create/index' +// @ts-ignore +import { icons } from './iconBase' +import * as language from './widgets/forms/autocomplete/language' +import * as log from './log' +import { matrix } from './matrix/index' +import { media } from './media/index' +// @ts-ignore +import { messageArea } from './messageArea' +// @ts-ignore +import { infiniteMessageArea } from './chat/infinite' +// @ts-ignore +import * as pad from './pad' +// @ts-ignore +import * as participation from './participation' +// @ts-ignore +import * as preferences from './preferences' +// @ts-ignore +import { style } from './style' +// @ts-ignore +import { renderTableViewPane as table } from './table' +import * as tabs from './tabs' +// @ts-ignore +import * as utils from './utils' +import * as login from './login/login' +import * as widgets from './widgets/index' +import { initHeader } from './header' +import { initFooter } from './footer' +import * as createTypes from './create/types' + +const dom = window ? window.document : null // Idea that UI.dom can be adapted in non-browser environments + +if (typeof window !== 'undefined') { + ;(window).UI = { + ns, + acl, + aclControl, + create, + createTypes, + dom, + icons, + language, + log, + login, + matrix, + media, + messageArea, + infiniteMessageArea, + pad, + participation, + preferences, + style, + table, + tabs, + utils, + widgets, + initHeader, + initFooter + } // Simpler access by non-node scripts +} + +// this variables are directly used in the storybook +export { + ns, + acl, + aclControl, + create, + createTypes, + dom, + icons, + language, + log, + login, + matrix, + media, + messageArea, + infiniteMessageArea, + pad, + participation, + preferences, + style, + table, + tabs, + utils, + widgets, + initHeader, + initFooter +} +// uses in solid-panes +export type { CreateContext, NewAppInstanceOptions } from './create/types' diff --git a/src/infiniteMessageArea.js b/src/infiniteMessageArea.js deleted file mode 100644 index 6189afc54..000000000 --- a/src/infiniteMessageArea.js +++ /dev/null @@ -1,534 +0,0 @@ -// Common code for a discussion are a of messages about something -// This version runs over a series of files for different time periods -// -// Parameters for the whole chat like its title are stred on -// index.ttl#this and the chats messages are stored in YYYY/MM/DD/chat.ttl -// -/* global alert */ -var UI = { - authn: require('./signin'), - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - pad: require('./pad'), - rdf: require('rdflib'), - store: require('./store'), - style: require('./style'), - widgets: require('./widgets') -} - -const utils = require('./utils') - -module.exports = function (dom, kb, subject, options) { - kb = kb || UI.store - var ns = UI.ns - var WF = $rdf.Namespace('http://www.w3.org/2005/01/wf/flow#') - var DCT = $rdf.Namespace('http://purl.org/dc/terms/') - - options = options || {} - - var newestFirst = options.newestFirst === '1' || options.newestFirst === true // hack for now - var colorizeByAuthor = options.colorizeByAuthor === '1' || options.colorizeByAuthor === true - var menuButton - // var participation // An object tracking users use and prefs - - var messageBodyStyle = 'white-space: pre-wrap; width: 90%; font-size:100%; border: 0.07em solid #eee; padding: .2em 0.5em; margin: 0.1em 1em 0.1em 1em;' - // 'font-size: 100%; margin: 0.1em 1em 0.1em 1em; background-color: white; white-space: pre-wrap; padding: 0.1em;' - - var div = dom.createElement('div') - // var messageTable // Shared by initial build and addMessageFromBindings - var me - - var updater = UI.store.updater - - var anchor = function (text, term) { // If there is no link return an element anyway - var a = dom.createElement('a') - if (term && term.uri) { - a.setAttribute('href', term.uri) - a.addEventListener('click', UI.widgets.openHrefInOutlineMode, true) - a.setAttribute('style', 'color: #3B5998; text-decoration: none; ') // font-weight: bold - } - a.textContent = text - return a - } - - var mention = function mention (message, style) { - var pre = dom.createElement('pre') - pre.setAttribute('style', style || 'color: grey') - div.appendChild(pre) - pre.appendChild(dom.createTextNode(message)) - return pre - } - - var announce = { - log: function (message) { mention(message, 'color: #111;') }, - warn: function (message) { mention(message, 'color: #880;') }, - error: function (message) { mention(message, 'color: #800;') } - } - - function createIfNotExists (doc) { - return new Promise(function (resolve, reject) { - kb.fetcher.load(doc).then(response => { - // kb.fetcher.webOperation('HEAD', doc.uri).then(response => { - resolve(response) - }, err => { - if (err.response.status === 404) { - kb.fetcher.webOperation('PUT', doc.uri, {data: '', contentType: 'text/turtle'}).then(response => { - resolve(response) - }, err => { - reject(err) - }) - } else { - reject(err) - } - }) - }) - } - - // Form for a new message - // - function newMessageForm () { - var form = dom.createElement('tr') - var lhs = dom.createElement('td') - var middle = dom.createElement('td') - var rhs = dom.createElement('td') - form.appendChild(lhs) - form.appendChild(middle) - form.appendChild(rhs) - form.AJAR_date = '9999-01-01T00:00:00Z' // ISO format for field sort - var field, sendButton - - function sendMessage (text) { - var now = addNewTableIfNeeded() - - if (!text) { - field.setAttribute('style', messageBodyStyle + 'color: #bbb;') // pendingedit - field.disabled = true - } - var sts = [] - var timestamp = '' + now.getTime() - var dateStamp = $rdf.term(now) - let chatDocument = chatDocumentFromDate(now) - - var message = kb.sym(chatDocument.uri + '#' + 'Msg' + timestamp) - var content = kb.literal(text || field.value) - // if (text) field.value = text No - don't destroy half-finsihed user input - - sts.push(new $rdf.Statement(subject, ns.wf('message'), message, chatDocument)) - sts.push(new $rdf.Statement(message, ns.sioc('content'), content, chatDocument)) - sts.push(new $rdf.Statement(message, DCT('created'), dateStamp, chatDocument)) - if (me) sts.push(new $rdf.Statement(message, ns.foaf('maker'), me, chatDocument)) - - var sendComplete = function (uri, success, body) { - if (!success) { - form.appendChild(UI.widgets.errorMessageBlock( - dom, 'Error writing message: ' + body)) - } else { - var bindings = { '?msg': message, - '?content': content, - '?date': dateStamp, - '?creator': me} - renderMessage(messageTable, bindings, false) // not green - - if (!text) { - field.value = '' // clear from out for reuse - field.setAttribute('style', messageBodyStyle) - field.disabled = false - } - } - } - updater.update([], sts, sendComplete) - } - form.appendChild(dom.createElement('br')) - - // DRAG AND DROP - function droppedFileHandler (files) { - UI.widgets.uploadFiles(kb.fetcher, files, chatDocument.dir().uri + 'Files', chatDocument.dir().uri + 'Pictures', - function (theFile, destURI) { // @@@@@@ Wait for eachif several - sendMessage(destURI) - }) - } - - // When a set of URIs are dropped on the field - var droppedURIHandler = function (uris) { - sendMessage(uris[0]) // @@@@@ wait - /* - Promise.all(uris.map(function (u) { - return sendMessage(u) // can add to meetingDoc but must be sync - })).then(function (a) { - saveBackMeetingDoc() - }) - */ - } - - // When we are actually logged on - function turnOnInput () { - if (options.menuHandler && menuButton) { - let menuOptions = { me, dom, div, newBase: messageTable.chatDocument.dir().uri } - menuButton.addEventListener('click', - event => { options.menuHandler(event, subject, menuOptions) } - , false) - } - creatorAndDate(lhs, me, '', null) - - field = dom.createElement('textarea') - middle.innerHTML = '' - middle.appendChild(field) - field.rows = 3 - // field.cols = 40 - field.setAttribute('style', messageBodyStyle + 'background-color: #eef;') - - // Trap the Enter BEFORE it is used ti make a newline - field.addEventListener('keydown', function (e) { // User preference? - if (e.keyCode === 13) { - if (!e.altKey) { // Alt-Enter just adds a new line - sendMessage() - } - } - }, false) - UI.widgets.makeDropTarget(field, droppedURIHandler, droppedFileHandler) - - rhs.innerHTML = '' - sendButton = UI.widgets.button(dom, UI.icons.iconBase + 'noun_383448.svg', 'Send') - sendButton.setAttribute('style', UI.style.buttonStyle + 'float: right;') - sendButton.addEventListener('click', ev => sendMessage(), false) - rhs.appendChild(sendButton) - - UI.pad.recordParticipation(subject, subject.doc()) // participation = - } // turn on inpuut - - let context = {div: middle, dom: dom} - UI.authn.logIn(context).then(context => { - me = context.me - turnOnInput() - }) - - return form - } - - function nick (person) { - var s = UI.store.any(person, UI.ns.foaf('nick')) - if (s) return '' + s.value - return '' + utils.label(person) - } - - function creatorAndDate (td1, creator, date, message) { - var nickAnchor = td1.appendChild(anchor(nick(creator), creator)) - if (creator.uri) { - UI.store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function (ok, body) { - nickAnchor.textContent = nick(creator) - }) - } - td1.appendChild(dom.createElement('br')) - td1.appendChild(anchor(date, message)) - } - - // /////////////////////////////////////////////////////////////////////// - - function syncMessages (about, messageTable) { - var displayed = {} - var ele, ele2 - for (ele = messageTable.firstChild; ele; ele = ele.nextSibling) { - if (ele.AJAR_subject) { - displayed[ele.AJAR_subject.uri] = true - } - } - - var messages = kb.statementsMatching( - about, ns.wf('message'), null, messageTable.chatDocument).map(st => { return st.object }) - var stored = {} - messages.map(function (m) { - stored[m.uri] = true - if (!displayed[m.uri]) { - addMessage(m, messageTable) - } - }) - - for (ele = messageTable.firstChild; ele;) { - ele2 = ele.nextSibling - if (ele.AJAR_subject && !stored[ele.AJAR_subject.uri]) { - messageTable.removeChild(ele) - } - ele = ele2 - } - } - - var deleteMessage = function (message) { - var deletions = kb.statementsMatching(message).concat( - kb.statementsMatching(undefined, undefined, message)) - updater.update(deletions, [], function (uri, ok, body) { - if (!ok) { - announce.error('Cant delete messages:' + body) - } else { - syncMessages(subject, messageTable) - } - }) - } - - var addMessage = function (message, messageTable) { - var bindings = { - '?msg': message, - '?creator': kb.any(message, ns.foaf('maker')), - '?date': kb.any(message, DCT('created')), - '?content': kb.any(message, ns.sioc('content')) - } - renderMessage(messageTable, bindings, messageTable.fresh) // fresh from elsewhere - } - - function elementForImageURI (imageUri, options) { - let img = dom.createElement('img') - let height = '10' - if (options.inlineImageHeightEms) { - height = ('' + options.inlineImageHeightEms).trim() - } - img.setAttribute('style', 'max-height: ' + height + 'em; border-radius: 1em; margin: 0.7em;') - // UI.widgets.makeDropTarget(img, handleURIsDroppedOnMugshot, droppedFileHandler) - if (imageUri) img.setAttribute('src', imageUri) - let anchor = dom.createElement('a') - anchor.setAttribute('href', imageUri) - anchor.setAttribute('target', 'images') - anchor.appendChild(img) - UI.widgets.makeDraggable(img, $rdf.sym(imageUri)) - return anchor - } - - function renderMessage (messageTable, bindings, fresh) { - var creator = bindings['?creator'] - var message = bindings['?msg'] - var date = bindings['?date'] - var content = bindings['?content'] - - var dateString = date.value - var tr = dom.createElement('tr') - tr.AJAR_date = dateString - tr.AJAR_subject = message - - var done = false - for (var ele = messageTable.firstChild; ; ele = ele.nextSibling) { - if (!ele) { // empty - break - } - if (((dateString > ele.AJAR_date) && newestFirst) || - ((dateString < ele.AJAR_date) && !newestFirst)) { - messageTable.insertBefore(tr, ele) - done = true - break - } - } - if (!done) { - messageTable.appendChild(tr) - } - - var td1 = dom.createElement('td') - tr.appendChild(td1) - creatorAndDate(td1, creator, UI.widgets.shortDate(dateString), message) - - var td2 = dom.createElement('td') - let text = content.value - tr.appendChild(td2) - var isImage = (/\.(gif|jpg|jpeg|tiff|png|svg)$/i).test(text) // @@ Should use content-type not URI - if (isImage && options.expandImagesInline) { - let img = elementForImageURI(text, options) - td2.appendChild(img) - } else { // text - var pre = dom.createElement('p') - var bgcolor = colorizeByAuthor - ? UI.pad.lightColorHash(creator) - : (fresh ? '#e8ffe8' : 'white') - pre.setAttribute('style', messageBodyStyle + 'background-color: ' + bgcolor + ';') - td2.appendChild(pre) - pre.textContent = text - } - - var td3 = dom.createElement('td') - tr.appendChild(td3) - - var delButton = dom.createElement('button') - td3.appendChild(delButton) - delButton.textContent = '-' - - tr.setAttribute('class', 'hoverControl') // See tabbedtab.css (sigh global CSS) - delButton.setAttribute('class', 'hoverControlHide') - delButton.setAttribute('style', 'color: red;') - delButton.addEventListener('click', function (e) { - td3.removeChild(delButton) // Ask -- are you sure? - var cancelButton = dom.createElement('button') - cancelButton.textContent = 'cancel' - td3.appendChild(cancelButton).addEventListener('click', function (e) { - td3.removeChild(sureButton) - td3.removeChild(cancelButton) - td3.appendChild(delButton) - }, false) - var sureButton = dom.createElement('button') - sureButton.textContent = 'Delete message' - td3.appendChild(sureButton).addEventListener('click', function (e) { - td3.removeChild(sureButton) - td3.removeChild(cancelButton) - deleteMessage(message) - }, false) - }, false) - } - - function insertPreviousMessages (event, messageTable) { - let date = new Date(messageTable.date.getTime() - 86400000) // day in mssecs - let newMessageTable = createMessageTable(date, false) // not live - if (newestFirst) { // put on bottom - div.appendChild(newMessageTable) - } else { // put on top as we scroll back - div.insertBefore(newMessageTable, div.firstChild) - } - } - function removePreviousMessages (event, messageTable) { - if (newestFirst) { // it was put on bottom - while (messageTable.nextSibling) { - div.removeChild(messageTable.nextSibling) - } - } else { // it was put on top as we scroll back - while (messageTable.previousSibling) { - div.removeChild(messageTable.previousSibling) - } - } - } - - function loadMessageTable2 (messageTable, chatDocument) { - kb.fetcher.load(chatDocument).then(response => { - let sts = kb.statementsMatching(null, WF('message'), null, chatDocument) - sts.forEach(st => { - addMessage(st.object, messageTable) - }) - messageTable.fresh = true - }, err => { - let statusTR = messageTable.appendChild(dom.createElement('tr')) - if (err.response && err.response.status && err.response.status === 404) { - statusTR.appendChild(UI.widgets.errorMessageBlock(dom, 'no messages', 'white')) - } else { - statusTR.appendChild(UI.widgets.errorMessageBlock(dom, err, 'pink')) - } - }) - } - - function chatDocumentFromDate (date) { - let isoDate = date.toISOString() // Like "2018-05-07T17:42:46.576Z" - var path = isoDate.split('T')[0].replace(/-/g, '/') // Like "2018/05/07" - path = subject.dir().uri + path + '/chat.ttl' - return $rdf.sym(path) - } - - function createMessageTable (date, live) { - var moreButton - function moreButtonHandler (event) { - let sense = messageTable.extended ^ newestFirst - let moreIcon = !sense ? 'noun_1369241.svg' : 'noun_1369237.svg' - moreButton.firstChild.setAttribute('src', UI.icons.iconBase + moreIcon) - if (messageTable.extended) { - removePreviousMessages(event, messageTable) - } else { - insertPreviousMessages(event, messageTable) - } - messageTable.extended = !messageTable.extended // Toggle - } - var messageTable = dom.createElement('table') - // var messageButton - messageTable.date = date - var chatDocument = chatDocumentFromDate(date) - messageTable.chatDocument = chatDocument - - messageTable.fresh = false - messageTable.setAttribute('style', 'width: 100%;') // fill that div! - - if (live) { - var tr = newMessageForm() - if (newestFirst) { - messageTable.insertBefore(tr, messageTable.firstChild) // If newestFirst - } else { - messageTable.appendChild(tr) // not newestFirst - } - messageTable.inputRow = tr - } - - /// ///// Infinite scroll - // - // @@ listen for swipe past end event not just button - if (options.infinite) { - let moreButtonTR = dom.createElement('tr') - // up traingles: noun_1369237.svg - // down triangles: noun_1369241.svg - let moreIcon = newestFirst ? 'noun_1369241.svg' : 'noun_1369237.svg' // down and up arrows respoctively - moreButton = UI.widgets.button(dom, UI.icons.iconBase + moreIcon, 'Previous messages ...') - // moreButton.setAttribute('style', UI.style.buttonStyle) - let moreButtonCell = moreButtonTR.appendChild(dom.createElement('td')) - moreButtonCell.appendChild(moreButton) - moreButtonCell.style = 'width:3em; height:3em;' - - let dateCell = moreButtonTR.appendChild(dom.createElement('td')) - dateCell.style = 'text-align: center; vertical-align: middle; color: #888; font-style: italic;' - dateCell.textContent = UI.widgets.shortDate(date.toISOString(), true) // no time, only date - - if (options.menuHandler && live) { // A high level handles calls for a menu - let menuIcon = 'noun_897914.svg' // or maybe dots noun_243787.svg - menuButton = UI.widgets.button(dom, UI.icons.iconBase + menuIcon, 'Menu ...') // wider var - // menuButton.setAttribute('style', UI.style.buttonStyle) - // menuButton.addEventListener('click', event => { menuHandler(event, menuOptions)}, false) // control side menu - let menuButtonCell = moreButtonTR.appendChild(dom.createElement('td')) - menuButtonCell.appendChild(menuButton) - menuButtonCell.style = 'width:3em; height:3em;' - } - moreButton.addEventListener('click', moreButtonHandler, false) - messageTable.extended = false - if (!newestFirst) { // opposite end from the entry field - messageTable.insertBefore(moreButtonTR, messageTable.firstChild) // If not newestFirst - } else { - messageTable.appendChild(moreButtonTR) // newestFirst - } - } - loadMessageTable2(messageTable, chatDocument) - messageTable.fresh = false - return messageTable - } // createMessageTable - - var messageTable - var chatDocument - - function addNewTableIfNeeded () { - let now = new Date() - let newChatDocument = chatDocumentFromDate(now) - if (!newChatDocument.sameTerm(chatDocument)) { // It is a new day - if (messageTable.inputRow) { - messageTable.removeChild(messageTable.inputRow) - delete messageTable.inputRow - } - var oldChatDocument = chatDocument - appendCurrentMessages() - // Adding a link in the document will ping listeners to add the new block too - if (!kb.holds(oldChatDocument, ns.rdfs('seeAlso'), newChatDocument, oldChatDocument)) { - let sts = [$rdf.st(oldChatDocument, ns.rdfs('seeAlso'), newChatDocument, oldChatDocument)] - updater.update([], sts, function (ok, body) { - if (!ok) { - alert('Unable to link old message block to new one.' + body) - } - }) - } - } - return now - } - - function appendCurrentMessages () { - var now = new Date() - chatDocument = chatDocumentFromDate(now) - createIfNotExists(chatDocument).then(respopnse => { - messageTable = createMessageTable(now, true) - div.appendChild(messageTable) - div.refresh = function () { // only the last messageTable is live - addNewTableIfNeeded() - syncMessages(subject, messageTable) - } // The short chat version fors live update in the pane but we do it in the widget - kb.updater.addDownstreamChangeListener(chatDocument, div.refresh) // Live update - // @@ Remove listener from previous table as it is now static - }, err => { - div.appendChild(UI.widgets.errorMessageBlock( - dom, 'Problem accessing chat log file: ' + err)) - }) - } - appendCurrentMessages() - return div -} diff --git a/src/log.js b/src/log.js deleted file mode 100644 index 27d0a4ffe..000000000 --- a/src/log.js +++ /dev/null @@ -1,98 +0,0 @@ -// Log of diagnostics -- node module version - -/* global alert */ -var wrapper = function () { - var logger = {} - - // /////////////////////// Logging - // - // bitmask levels - // var TNONE = 0 - var TERROR = 1 - var TWARN = 2 - var TMESG = 4 - var TSUCCESS = 8 - var TINFO = 16 - var TDEBUG = 32 - var TALL = 63 - - logger.level = TERROR + TWARN + TMESG - logger.ascending = false - - logger.msg = function (str, type, typestr) { - if (!type) { - type = TMESG - typestr = 'mesg' - } - - if (!(logger.level & type)) return // bitmask - - if (typeof document !== 'undefined') { -// Not AJAX environment - - var logArea = document.getElementById('status') - if (!logArea) return - - // Local version to reduce dependencies - var escapeForXML = function (str) { // don't use library one in case ithasn't been loaded yet - return str.replace(/&/g, '&').replace(/' - if (!logger.ascending) { - logArea.appendChild(addendum) - } else { - logArea.insertBefore(addendum, logArea.firstChild) - } - } else if (typeof console !== 'undefined') { // node.js - console.log(str) - /* - } else { - var f = dump // || print - if (!f) throw new Error('log: No way to output message: ' + str) - f('Log: ' + str + '\n') - */ - } - } // logger.msg - - logger.warn = function (msg) { logger.msg(msg, TWARN, 'warn') } - logger.debug = function (msg) { logger.msg(msg, TDEBUG, 'dbug') } - logger.info = function (msg) { logger.msg(msg, TINFO, 'info') } - logger.error = function (msg) { logger.msg(msg, TERROR, 'eror') } - logger.success = function (msg) { logger.msg(msg, TSUCCESS, 'good') } - - if (typeof alert !== 'undefined') { - logger.alert = alert - } else { - logger.alert = logger.warn - } - - /** clear the log window **/ - logger.clear = function () { - var x = document.getElementById('status') - if (!x) return - x.innerHTML = '' - // emptyNode(x); - } // clearStatus - - /** set the logging level **/ - logger.setLevel = function (x) { - logger.level = TALL - logger.debug('Log level is now ' + x) - logger.level = x - } - - logger.dumpHTML = function () { - var l = logger.level - logger.level = TALL - logger.debug(document.innerHTML) - logger.level = l - } - return logger -}// wrapper - -module.exports = wrapper() diff --git a/src/log.ts b/src/log.ts new file mode 100644 index 000000000..c2f2dd1e4 --- /dev/null +++ b/src/log.ts @@ -0,0 +1,191 @@ +// /////////////////////// Logging +// +// bitmask levels +// const TNONE = 0 +/** @internal */ +const TERROR = 1 +/** @internal */ +const TWARN = 2 +/** @internal */ +const TMESG = 4 +/** @internal */ +const TSUCCESS = 8 +/** @internal */ +const TINFO = 16 +/** @internal */ +const TDEBUG = 32 +/** @internal */ +const TALL = 63 + +/** @internal */ +export enum LogLevel { + Error = TERROR, + Warning = TWARN, + Message = TMESG, + Success = TSUCCESS, + Info = TINFO, + Debug = TDEBUG, + All = TALL +} + +/** @internal */ +let _level: number = TERROR + TWARN + TMESG +/** @internal */ +let _ascending: boolean = false +/** @internal */ +let _dom: HTMLDocument = document // must be able to override for tests +/** @internal */ +let _window: Window = window // must be able to override for tests + +/** @internal */ +function log (str: string, type: number = TMESG, typestr: string = 'mesg') { + if (!(_level & type)) return // bitmask + + if (typeof _dom !== 'undefined') { + const logArea = _dom.getElementById('status') + if (!logArea) return + + const addendum = _dom.createElement('span') + addendum.setAttribute('class', typestr) + const now = new Date() + addendum.innerHTML = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} [${typestr}] ${escapeForXML(str)}
` + if (_ascending) { + logArea.insertBefore(addendum, logArea.firstChild) + } else { + logArea.appendChild(addendum) + } + } else if (typeof console !== 'undefined') { + console.log(str) + } +} + +/** + * Adds a message to the element with id "status". The messages are prepended with + * time and type of message, in this case [mesg]. + */ +export function msg (message: string) { + log(message) +} + +/** + * Adds a warning message to the element with id "status". The messages are + * prepended with time and type of message, in this case [warn]. + */ +export function warn (message: string): void { + log(message, TWARN, 'warn') +} + +/** + * Adds a debugging message to the element with id "status". The messages are + * prepended with time and type of message, in this case [dbug]. + */ +export function debug (message: string): void { + log(message, TDEBUG, 'dbug') +} + +/** + * Adds a info message to the element with id "status". The messages are + * prepended with time and type of message, in this case [info]. + */ +export function info (message: string): void { + log(message, TINFO, 'info') +} + +/** + * Adds a error to the element with id "status". The messages are + * prepended with time and type of message, in this case [eror]. + */ +export function error (message: string): void { + log(message, TERROR, 'eror') +} + +/** + * Adds a success message to the element with id "status". The messages are + * prepended with time and type of message, in this case [good]. + */ +export function success (message: string): void { + log(message, TSUCCESS, 'good') +} + +/** + * Uses the global alert to send an alert. If global alert is not available, it + * will output the message using the method [[warning]]s. + */ +export function alert (message: string): void { + if (_window && typeof _window.alert !== 'undefined') { + _window.alert(message) + } else { + warn(message) + } +} + +/** + * Will clear the content of the element with id "status". + */ +export function clear (): void { + const logArea = _dom?.getElementById('status') + if (!logArea) return + logArea.innerHTML = '' +} + +/** + * Lets you configure which types of messages will be shown. The module uses + * [bitmask](https://en.wikipedia.org/wiki/Mask_(computing)) to filter which + * types of messages should be shown. E.g. if you only want warning messages + * to be shown, pass 2 to the function, if you want warning and success to be + * shown, pass 10 (2+8). By passing the sum of all, 63, you'll show all + * types of messages. + * + * - Error: 1 + * - Warning: 2 + * - Message: 4 + * - Success: 8 + * - Info: 16 + * - Debug: 32 + */ +export function setLevel (level: number): void { + _level = TALL + debug('Log level is now ' + level) + _level = level +} + +/** + * Will dump the current HTML using the [[debug]] method. + */ +export function dumpHTML (): void { + if (!_dom) return + const level = _level + _level = TALL + debug(_dom?.body?.innerHTML || '') + _level = level +} + +/** + * Will start prepending messages the list of log messages. + */ +export function logAscending () { + _ascending = true +} + +/** + * Will start appending messages the list of log messages. (This is default + * behavior.) + */ +export function logDescending () { + _ascending = false +} + +/** @internal */ +export function escapeForXML (str: string): string { + // can be replaced with function utils module when migrating + return str + .replace(/&/g, '&') + .replace(//g, '>') +} + +/** @internal */ +export function setInternals (window, document) { + _window = window + _dom = document +} diff --git a/src/login/login.ts b/src/login/login.ts new file mode 100644 index 000000000..4360d5e1b --- /dev/null +++ b/src/login/login.ts @@ -0,0 +1,1091 @@ +/* eslint-disable camelcase */ +/** + * Signing in, signing up, profile and preferences reloading + * Type index management + * + * Many functions in this module take a context object which + * holds various RDF symbols, add to it, and return a promise of it. + * + * * `me` RDF symbol for the user's WebID + * * `publicProfile` The user's public profile, iff loaded + * * `preferencesFile` The user's personal preference file, iff loaded + * * `index.public` The user's public type index file + * * `index.private` The user's private type index file + * + * Not RDF symbols: + * * `noun` A string in english for the type of thing -- like "address book" + * * `instance` An array of nodes which are existing instances + * * `containers` An array of nodes of containers of instances + * * `div` A DOM element where UI can be displayed + * * `statusArea` A DOM element (opt) progress stuff can be displayed, or error messages + * * + * * Vocabulary: "load" loads a file if it exists; + * * 'Ensure" CREATES the file if it does not exist (if it can) and then loads it. + * @packageDocumentation + */ +import { PaneDefinition } from 'pane-registry' +import { BlankNode, NamedNode, st } from 'rdflib' + +import { Quad_Object } from 'rdflib/lib/tf-types' +import { + AppDetails, + AuthenticationContext, + authn, + authSession, + CrossOriginForbiddenError, + FetchError, + getSuggestedIssuers, + NotEditableError, + offlineTestID, + SameOriginForbiddenError, + solidLogicSingleton, + UnauthorizedError, + WebOperationError +} from 'solid-logic' +import * as debug from '../debug' +import { style } from '../style' +import { alert } from '../log' +import ns from '../ns' +import { Signup } from '../signup/signup.js' +import * as utils from '../utils' +import * as widgets from '../widgets' + +const store = solidLogicSingleton.store + +const { + loadPreferences, + loadProfile +} = solidLogicSingleton.profile + +const { + getScopedAppInstances, + getRegistrations, + loadAllTypeIndexes, + getScopedAppsFromIndex, + deleteTypeIndexRegistration +} = solidLogicSingleton.typeIndex + +/** + * Resolves with the logged in user's WebID + * + * @param context + */ +// used to be logIn +export function ensureLoggedIn (context: AuthenticationContext): Promise { + const me = authn.currentUser() + if (me) { + authn.saveUser(me, context) + return Promise.resolve(context) + } + + return new Promise((resolve) => { + authn.checkUser().then((webId) => { + // Already logged in? + if (webId) { + debug.log(`logIn: Already logged in as ${webId}`) + return resolve(context) + } + if (!context.div || !context.dom) { + return resolve(context) + } + const box = loginStatusBox(context.dom, (webIdUri) => { + authn.saveUser(webIdUri, context) + resolve(context) // always pass growing context + }) + context.div.appendChild(box) + }) + }) +} + +/** + * Loads preference file + * Do this after having done log in and load profile + * + * @private + * + * @param context + */ +// used to be logInLoadPreferences +export async function ensureLoadedPreferences ( + context: AuthenticationContext +): Promise { + if (context.preferencesFile) return Promise.resolve(context) // already done + + // const statusArea = context.statusArea || context.div || null + let progressDisplay + /* COMPLAIN FUNCTION NOT USED/TAKING IT OUT FOR NOW + function complain (message) { + message = `ensureLoadedPreferences: ${message}` + if (statusArea) { + // statusArea.innerHTML = '' + statusArea.appendChild(widgets.errorMessageBlock(context.dom, message)) + } + debug.log(message) + // reject(new Error(message)) + } */ + try { + context = await ensureLoadedProfile(context) + + // console.log('back in Solid UI after logInLoadProfile', context) + const preferencesFile = await loadPreferences(context.me as NamedNode) + if (progressDisplay) { + progressDisplay.parentNode.removeChild(progressDisplay) + } + context.preferencesFile = preferencesFile + } catch (err) { + let m2: string + if (err instanceof UnauthorizedError) { + m2 = + 'Oops — you are not authenticated (properly logged in), so SolidOS cannot read your preferences file. Try logging out and then logging back in.' + alert(m2) + } else if (err instanceof CrossOriginForbiddenError) { + m2 = `Unauthorized: Assuming preference file blocked for origin ${window.location.origin}` + context.preferencesFileError = m2 + return context + } else if (err instanceof SameOriginForbiddenError) { + m2 = + 'You are not authorized to read your preference file. This may be because you are using an untrusted web app.' + debug.warn(m2) + return context + } else if (err instanceof NotEditableError) { + m2 = + 'You are not authorized to edit your preference file. This may be because you are using an untrusted web app.' + debug.warn(m2) + return context + } else if (err instanceof WebOperationError) { + m2 = + 'You are not authorized to edit your preference file. This may be because you are using an untrusted web app.' + debug.warn(m2) + } else if (err instanceof FetchError) { + m2 = `Strange: Error ${err.status} trying to read your preference file.${err.message}` + alert(m2) + } else { + throw new Error(`(via loadPrefs) ${err}`) + } + + context.preferencesFileError = m2 + } + return context +} + +/** + * Logs the user in and loads their WebID profile document into the store + * + * @param context + * + * @returns Resolves with the context after login / fetch + */ +// used to be logInLoadProfile +export async function ensureLoadedProfile ( + context: AuthenticationContext +): Promise { + if (context.publicProfile) { + return context + } // already done + try { + const logInContext = await ensureLoggedIn(context) + if (!logInContext.me) { + throw new Error('Could not log in') + } + context.publicProfile = await loadProfile(logInContext.me) + } catch (err) { + if (context.div && context.dom) { + context.div.appendChild(widgets.errorMessageBlock(context.dom, err.message)) + } + throw new Error(`Can't log in: ${err}`) + } + return context +} + +/** + * Returns promise of context with arrays of symbols + * + * leaving the `isPublic` param undefined will bring in community index things, too + */ +export async function findAppInstances ( + context: AuthenticationContext, + theClass: NamedNode, + isPublic?: boolean +): Promise { + let items = context.me ? await getScopedAppInstances(theClass, context.me) : [] + if (isPublic === true) { // old API - not recommended! + items = items.filter(item => item.scope.label === 'public') + } else if (isPublic === false) { + items = items.filter(item => item.scope.label === 'private') + } + context.instances = items.map(item => item.instance) + return context +} + +export function scopeLabel (context, scope) { + const mine = context.me && context.me.sameTerm(scope.agent) + const name = mine ? '' : utils.label(scope.agent) + ' ' + return `${name}${scope.label}` +} +/** + * UI to control registration of instance + */ +export async function registrationControl ( + context: AuthenticationContext, + instance, + theClass +): Promise { + function registrationStatements (index) { + const registrations = getRegistrations(instance, theClass) + const reg = registrations.length ? registrations[0] : widgets.newThing(index) + return [ + st(reg, ns.solid('instance'), instance, index), + st(reg, ns.solid('forClass'), theClass, index) + ] + } + + function renderScopeCheckbox (scope) { + const statements = registrationStatements(scope.index) + const name = scopeLabel(context, scope) + const label = `${name} link to this ${context.noun}` + return widgets.buildCheckboxForm( + context.dom, + solidLogicSingleton.store, + label, + null, + statements, + form, + scope.index + ) + } + /// / body of registrationControl + const dom = context.dom + if (!dom || !context.div) { + throw new Error('registrationControl: need dom and div') + } + const box = dom.createElement('div') + context.div.appendChild(box) + context.me = authn.currentUser() // @@ + const me = context.me + if (!me) { + box.innerHTML = '

(Log in to save a link to this)

' + return context + } + + let scopes // @@ const + try { + scopes = await loadAllTypeIndexes(me) + } catch (e) { + let msg + if (context.div && context.preferencesFileError) { + msg = '(Lists of stuff not available)' + context.div.appendChild(dom.createElement('p')).textContent = msg + } else if (context.div) { + msg = `registrationControl: Type indexes not available: ${e}` + context.div.appendChild(widgets.errorMessageBlock(context.dom, e)) + } + debug.log(msg) + return context + } + + box.innerHTML = '
' // tbody will be inserted anyway + box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid gray 0.05em;') + const tbody = box.children[0].children[0] + const form = new BlankNode() // @@ say for now + + for (const scope of scopes) { + const row = tbody.appendChild(dom.createElement('tr')) + row.appendChild(renderScopeCheckbox(scope)) // @@ index + } + return context +} + +export function renderScopeHeadingRow (context, store, scope) { + const backgroundColor = { private: '#fee', public: '#efe' } + const { dom } = context + const name = scopeLabel(context, scope) + const row = dom.createElement('tr') + const cell = row.appendChild(dom.createElement('td')) + cell.setAttribute('colspan', '3') + cell.style.backgoundColor = backgroundColor[scope.label] || 'white' + const header = cell.appendChild(dom.createElement('h3')) + header.textContent = name + ' links' + header.style.textAlign = 'left' + return row +} +/** + * UI to List at all registered things + */ +export async function registrationList (context: AuthenticationContext, options: { + private?: boolean + public?: boolean + type?: NamedNode +}): Promise { + const dom = context.dom as HTMLDocument + const div = context.div as HTMLElement + + const box = dom.createElement('div') + div.appendChild(box) + context.me = authn.currentUser() // @@ + if (!context.me) { + box.innerHTML = '

(Log in list your stuff)

' + return context + } + + const scopes = await loadAllTypeIndexes(context.me) // includes community indexes + + // console.log('@@ registrationList ', scopes) + box.innerHTML = '
' // tbody will be inserted anyway + box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid #eee 0.5em;') + const table = box.firstChild as HTMLElement + const tbody = table.firstChild as HTMLElement + + for (const scope of scopes) { // need some predicate for listing/adding agents + const headingRow = renderScopeHeadingRow(context, store, scope) + tbody.appendChild(headingRow) + const items = await getScopedAppsFromIndex(scope, options.type || null) // any class + if (items.length === 0) headingRow.style.display = 'none' + // console.log(`registrationList: @@ instance items for class ${options.type || 'undefined' }:`, items) + for (const item of items) { + const row = widgets.personTR(dom, ns.solid('instance'), item.instance, { + deleteFunction: async () => { + await deleteTypeIndexRegistration(item) + tbody.removeChild(row) + } + }) + row.children[0].style.paddingLeft = '3em' + + tbody.appendChild(row) + } + } + return context +} // registrationList + +/** + * Bootstrapping identity + * (Called by `loginStatusBox()`) + * + * @param dom + * @param setUserCallback + * + * @returns + */ +function signInOrSignUpBox ( + dom: HTMLDocument, + setUserCallback: (user: string) => void, + options: { + buttonStyle?: string; + } = {} +): HTMLElement { + options = options || {} + const signInButtonStyle = options.buttonStyle || style.signInAndUpButtonStyle + + const box: any = dom.createElement('div') + const magicClassName = 'SolidSignInOrSignUpBox' + debug.log('widgets.signInOrSignUpBox') + box.setUserCallback = setUserCallback + box.setAttribute('class', magicClassName) + box.setAttribute('style', 'display:flex;') + + // Sign in button with PopUP + const signInPopUpButton = dom.createElement('input') // multi + box.appendChild(signInPopUpButton) + signInPopUpButton.setAttribute('type', 'button') + signInPopUpButton.setAttribute('value', 'Log in') + signInPopUpButton.setAttribute('style', `${signInButtonStyle}${style.headerBannerLoginInput}` + style.signUpBackground) + + authSession.events.on('login', () => { + const me = authn.currentUser() + // const sessionInfo = authSession.info + // if (sessionInfo && sessionInfo.isLoggedIn) { + if (me) { + // const webIdURI = sessionInfo.webId + const webIdURI = me.uri + // setUserCallback(webIdURI) + const divs = dom.getElementsByClassName(magicClassName) + debug.log(`Logged in, ${divs.length} panels to be serviced`) + // At the same time, satisfy all the other login boxes + for (let i = 0; i < divs.length; i++) { + const div: any = divs[i] + // @@ TODO Remove the need to manipulate HTML elements + if (div.setUserCallback) { + try { + div.setUserCallback(webIdURI) + const parent = div.parentNode + if (parent) { + parent.removeChild(div) + } + } catch (e) { + debug.log(`## Error satisfying login box: ${e}`) + div.appendChild(widgets.errorMessageBlock(dom, e)) + } + } + } + } + }) + + signInPopUpButton.addEventListener( + 'click', + () => { + const offline = offlineTestID() + if (offline) return setUserCallback(offline.uri) + + renderSignInPopup(dom) + }, + false + ) + + // Sign up button + const signupButton = dom.createElement('input') + box.appendChild(signupButton) + signupButton.setAttribute('type', 'button') + signupButton.setAttribute('value', 'Sign Up for Solid') + signupButton.setAttribute('style', `${signInButtonStyle}${style.headerBannerLoginInput}` + style.signInBackground) + + signupButton.addEventListener( + 'click', + function (_event) { + const signupMgr = new Signup() + signupMgr.signup().then(function (uri) { + debug.log('signInOrSignUpBox signed up ' + uri) + setUserCallback(uri) + }) + }, + false + ) + return box +} + +export function renderSignInPopup (dom: HTMLDocument) { + /** + * Issuer Menu + */ + const issuerPopup = dom.createElement('div') + issuerPopup.setAttribute( + 'style', + 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; display: flex; justify-content: center; align-items: center;' + ) + dom.body.appendChild(issuerPopup) + const issuerPopupBox = dom.createElement('div') + issuerPopupBox.setAttribute( + 'style', + ` + background-color: white; + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); + border-radius: 4px; + min-width: 400px; + padding: 10px; + z-index : 10; + ` + ) + issuerPopup.appendChild(issuerPopupBox) + const issuerPopupBoxTopMenu = dom.createElement('div') + issuerPopupBoxTopMenu.setAttribute( + 'style', + ` + border-bottom: 1px solid #DDD; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + ` + ) + issuerPopupBox.appendChild(issuerPopupBoxTopMenu) + const issuerPopupBoxLabel = dom.createElement('label') + issuerPopupBoxLabel.setAttribute('style', 'margin-right: 5px; font-weight: 800') + issuerPopupBoxLabel.innerText = 'Select an identity provider' + const issuerPopupBoxCloseButton = dom.createElement('button') + issuerPopupBoxCloseButton.innerHTML = + '' + issuerPopupBoxCloseButton.setAttribute('style', 'background-color: transparent; border: none;') + issuerPopupBoxCloseButton.addEventListener('click', () => { + issuerPopup.remove() + }) + issuerPopupBoxTopMenu.appendChild(issuerPopupBoxLabel) + issuerPopupBoxTopMenu.appendChild(issuerPopupBoxCloseButton) + + const loginToIssuer = async (issuerUri: string) => { + try { + // clear authorization metadata from store + solidLogicSingleton.store.updater.flagAuthorizationMetadata() as any + // Save hash + const preLoginRedirectHash = new URL(window.location.href).hash + if (preLoginRedirectHash) { + window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash) + } + window.localStorage.setItem('loginIssuer', issuerUri) + // Login + const locationUrl = new URL(window.location.href) + locationUrl.hash = '' // remove hash part + await authSession.login({ + redirectUrl: locationUrl.href, + oidcIssuer: issuerUri + }) + } catch (err) { + alert(err.message) + } + } + + /** + * Text-based idp selection + */ + const issuerTextContainer = dom.createElement('div') + issuerTextContainer.setAttribute( + 'style', + ` + border-bottom: 1px solid #DDD; + display: flex; + flex-direction: column; + padding-top: 10px; + ` + ) + const issuerTextInputContainer = dom.createElement('div') + issuerTextInputContainer.setAttribute( + 'style', + ` + display: flex; + flex-direction: row; + ` + ) + const issuerTextLabel = dom.createElement('label') + issuerTextLabel.innerText = 'Enter the URL of your identity provider:' + issuerTextLabel.setAttribute('style', 'color: #888') + const issuerTextInput = dom.createElement('input') + issuerTextInput.setAttribute('type', 'text') + issuerTextInput.setAttribute( + 'style', + 'margin-left: 0 !important; flex: 1; margin-right: 5px !important' + ) + issuerTextInput.setAttribute('placeholder', 'https://example.com') + issuerTextInput.value = localStorage.getItem('loginIssuer') || '' + const issuerTextGoButton = dom.createElement('button') + issuerTextGoButton.innerText = 'Go' + issuerTextGoButton.setAttribute('style', 'margin-top: 12px; margin-bottom: 12px;') + issuerTextGoButton.addEventListener('click', () => { + loginToIssuer(issuerTextInput.value) + }) + issuerTextContainer.appendChild(issuerTextLabel) + issuerTextInputContainer.appendChild(issuerTextInput) + issuerTextInputContainer.appendChild(issuerTextGoButton) + issuerTextContainer.appendChild(issuerTextInputContainer) + issuerPopupBox.appendChild(issuerTextContainer) + + /** + * Button-based idp selection + */ + const issuerButtonContainer = dom.createElement('div') + issuerButtonContainer.setAttribute( + 'style', + ` + display: flex; + flex-direction: column; + padding-top: 10px; + ` + ) + const issuerBottonLabel = dom.createElement('label') + issuerBottonLabel.innerText = 'Or pick an identity provider from the list below:' + issuerBottonLabel.setAttribute('style', 'color: #888') + issuerButtonContainer.appendChild(issuerBottonLabel) + getSuggestedIssuers().forEach((issuerInfo) => { + const issuerButton = dom.createElement('button') + issuerButton.innerText = issuerInfo.name + issuerButton.setAttribute('style', 'height: 38px; margin-top: 10px') + issuerButton.addEventListener('click', () => { + loginToIssuer(issuerInfo.uri) + }) + issuerButtonContainer.appendChild(issuerButton) + }) + issuerPopupBox.appendChild(issuerButtonContainer) +} + +/** + * Login status box + * + * A big sign-up/sign in box or a logout box depending on the state + * + * @param dom + * @param listener + * + * @returns + */ +export function loginStatusBox ( + dom: HTMLDocument, + listener: ((uri: string | null) => void) | null = null, + options: { + buttonStyle?: string; + } = {} +): HTMLElement { + // 20190630 + let me = offlineTestID() + // @@ TODO Remove the need to cast HTML element to any + const box: any = dom.createElement('div') + + function setIt (newidURI) { + if (!newidURI) { + return + } + + // const uri = newidURI.uri || newidURI + // me = sym(uri) + me = authn.saveUser(newidURI) + box.refresh() + if (listener) listener(me!.uri) + } + + function logoutButtonHandler (_event) { + const oldMe = me + authSession.logout().then( + function () { + const message = `Your WebID was ${oldMe}. It has been forgotten.` + me = null + try { + alert(message) + } catch (_e) { + window.alert(message) + } + box.refresh() + if (listener) listener(null) + }, + (err) => { + alert('Fail to log out:' + err) + } + ) + } + + function logoutButton (me, options) { + const signInButtonStyle = options.buttonStyle || style.signInAndUpButtonStyle + let logoutLabel = 'WebID logout' + if (me) { + const nick = + solidLogicSingleton.store.any(me, ns.foaf('nick')) || + solidLogicSingleton.store.any(me, ns.foaf('name')) + if (nick) { + logoutLabel = 'Logout ' + nick.value + } + } + const signOutButton = dom.createElement('input') + // signOutButton.className = 'WebIDCancelButton' + signOutButton.setAttribute('type', 'button') + signOutButton.setAttribute('value', logoutLabel) + signOutButton.setAttribute('style', `${signInButtonStyle}`) + signOutButton.addEventListener('click', logoutButtonHandler, false) + return signOutButton + } + + box.refresh = function () { + const sessionInfo = authSession.info + if (sessionInfo && sessionInfo.webId && sessionInfo.isLoggedIn) { + me = solidLogicSingleton.store.sym(sessionInfo.webId) + } else { + me = null + } + if ((me && box.me !== me.uri) || (!me && box.me)) { + widgets.clearElement(box) + if (me) { + box.appendChild(logoutButton(me, options)) + } else { + box.appendChild(signInOrSignUpBox(dom, setIt, options)) + } + } + box.me = me ? me.uri : null + } + box.refresh() + + function trackSession () { + me = authn.currentUser() + box.refresh() + } + trackSession() + + authSession.events.on('login', trackSession) + authSession.events.on('logout', trackSession) + box.me = '99999' // Force refresh + box.refresh() + return box +} + +authSession.events.on('logout', async () => { + const issuer = window.localStorage.getItem('loginIssuer') + if (issuer) { + try { + // clear authorization metadata from store + solidLogicSingleton.store.updater.flagAuthorizationMetadata() as any + + const wellKnownUri = new URL(issuer) + wellKnownUri.pathname = '/.well-known/openid-configuration' + const wellKnownResult = await fetch(wellKnownUri.toString()) + if (wellKnownResult.status === 200) { + const openidConfiguration = await wellKnownResult.json() + if (openidConfiguration && openidConfiguration.end_session_endpoint) { + await fetch(openidConfiguration.end_session_endpoint, { credentials: 'include' }) + } + } + + try { + await fetch('/.well-known/solid/logout', { credentials: 'include' }) + } catch (_err) { + // Not all deployments expose NSS-compatible well-known logout endpoint. + } + } catch (_err) { + // Do nothing + } + } + window.location.reload() +}) + +/** + * Workspace selection etc + * See https://github.com/solidos/userguide/issues/16 + */ + +/** + * Returns a UI object which, if it selects a workspace, + * will callback(workspace, newBase). + * See https://github.com/solidos/userguide/issues/16 for more info on workspaces. + * + * If necessary, will get an account, preference file, etc. In sequence: + * + * - If not logged in, log in. + * - Load preference file + * - Prompt user for workspaces + * - Allows the user to just type in a URI by hand + * + * Calls back with the workspace and the base URI + * + * @param dom + * @param appDetails + * @param callbackWS + */ +export function selectWorkspace ( + dom: HTMLDocument, + appDetails: AppDetails, + callbackWS: (workspace: string | null, newBase: string) => void +): HTMLElement { + const noun = appDetails.noun + const appPathSegment = appDetails.appPathSegment + + const me = offlineTestID() + const box = dom.createElement('div') + const context: AuthenticationContext = { me, dom, div: box } + + function say (s, background?) { + box.appendChild(widgets.errorMessageBlock(dom, s, background)) + } + + function figureOutBase (ws) { + const newBaseNode: NamedNode = solidLogicSingleton.store.any( + ws, + ns.space('uriPrefix') + ) as NamedNode + let newBaseString: string + if (!newBaseNode) { + newBaseString = ws.uri.split('#')[0] + } else { + newBaseString = newBaseNode.value + } + if (newBaseString.slice(-1) !== '/') { + debug.log(`${appPathSegment}: No / at end of uriPrefix ${newBaseString}`) // @@ paramater? + newBaseString = `${newBaseString}/` + } + const now = new Date() + newBaseString += `${appPathSegment}/id${now.getTime()}/` // unique id + return newBaseString + } + + function displayOptions (context) { + // console.log('displayOptions!', context) + async function makeNewWorkspace (_event) { + const row = table.appendChild(dom.createElement('tr')) + const cell = row.appendChild(dom.createElement('td')) + cell.setAttribute('colspan', '3') + cell.style.padding = '0.5em' + const newBase = encodeURI( + await widgets.askName( + dom, + solidLogicSingleton.store, + cell, + ns.solid('URL'), + ns.space('Workspace'), + 'Workspace' + ) + ) + const newWs = widgets.newThing(context.preferencesFile) + const newData = [ + st(context.me, ns.space('workspace'), newWs, context.preferencesFile), + + st( + newWs, + ns.space('uriPrefix'), + newBase as unknown as Quad_Object, + context.preferencesFile + ) + ] + if (!solidLogicSingleton.store.updater) { + throw new Error('store has no updater') + } + await solidLogicSingleton.store.updater.update([], newData) + // @@ now refresh list of workspaces + } + + // const status = '' + const id = context.me + const preferencesFile = context.preferencesFile + let newBase: any = null + + // A workspace specifically defined in the private preference file: + let w: any = solidLogicSingleton.store.each( + id, + ns.space('workspace'), + undefined, + preferencesFile + ) // Only trust preference file here + + // A workspace in a storage in the public profile: + const storages = solidLogicSingleton.store.each(id, ns.space('storage')) // @@ No provenance requirement at the moment + if (w.length === 0 && storages) { + say( + `You don't seem to have any workspaces. You have ${storages.length} storage spaces.`, + 'white' + ) + storages + .map(function (s: any) { + w = w.concat(solidLogicSingleton.store.each(s, ns.ldp('contains'))) + return w + }) + .filter((file) => { + return file.id ? ['public', 'private'].includes(file.id().toLowerCase()) : '' + }) + } + + if (w.length === 1) { + say(`Workspace used: ${w[0].uri}`, 'white') // @@ allow user to see URI + newBase = figureOutBase(w[0]) + // callbackWS(w[0], newBase) + // } else if (w.length === 0) { + } + + // Prompt for ws selection or creation + // say( w.length + " workspaces for " + id + "Choose one."); + const table = dom.createElement('table') + table.setAttribute('style', 'border-collapse:separate; border-spacing: 0.5em;') + + // const popup = window.open(undefined, '_blank', { height: 300, width:400 }, false) + box.appendChild(table) + + // Add a field for directly adding the URI yourself + + // const hr = box.appendChild(dom.createElement('hr')) // @@ + box.appendChild(dom.createElement('hr')) // @@ + + const p = box.appendChild(dom.createElement('p')) + p.setAttribute('style', style.commentStyle) + p.textContent = `Where would you like to store the data for the ${noun}? + Give the URL of the folder where you would like the data stored. + It can be anywhere in solid world - this URI is just an idea.` + // @@ TODO Remove the need to cast baseField to any + const baseField: any = box.appendChild(dom.createElement('input')) + baseField.setAttribute('type', 'text') + baseField.setAttribute('style', style.textInputStyle) + baseField.size = 80 // really a string + baseField.label = 'base URL' + baseField.autocomplete = 'on' + if (newBase) { + // set to default + baseField.value = newBase + } + + context.baseField = baseField + + box.appendChild(dom.createElement('br')) // @@ + + const button = box.appendChild(dom.createElement('button')) + button.setAttribute('style', style.buttonStyle) + button.textContent = `Start new ${noun} at this URI` + button.addEventListener('click', function (_event) { + let newBase = baseField.value.replace(' ', '%20') // do not re-encode in general, as % encodings may exist + if (newBase.slice(-1) !== '/') { + newBase += '/' + } + callbackWS(null, newBase) + }) + + // Now go set up the table of spaces + + // const row = 0 + w = w.filter(function (x) { + return !solidLogicSingleton.store.holds( + x, + ns.rdf('type'), // Ignore master workspaces + ns.space('MasterWorkspace') + ) + }) + let col1, col2, col3, tr, ws, localStyle, comment + const cellStyle = 'height: 3em; margin: 1em; padding: 1em white; border-radius: 0.3em;' + const deselectedStyle = `${cellStyle}border: 0px;` + // const selectedStyle = cellStyle + 'border: 1px solid black;' + for (let i = 0; i < w.length; i++) { + ws = w[i] + tr = dom.createElement('tr') + if (i === 0) { + col1 = dom.createElement('td') + col1.setAttribute('rowspan', `${w.length}`) + col1.textContent = 'Choose a workspace for this:' + col1.setAttribute('style', 'vertical-align:middle;') + tr.appendChild(col1) + } + col2 = dom.createElement('td') + localStyle = solidLogicSingleton.store.anyValue(ws, ns.ui('style')) + if (!localStyle) { + // Otherwise make up arbitrary colour + const hash = function (x) { + return x.split('').reduce(function (a, b) { + a = (a << 5) - a + b.charCodeAt(0) + return a & a + }, 0) + } + const bgcolor = `#${((hash(ws.uri) & 0xffffff) | 0xc0c0c0).toString(16)}` // c0c0c0 forces pale + localStyle = `color: black ; background-color: ${bgcolor};` + } + col2.setAttribute('style', deselectedStyle + localStyle) + tr.target = ws.uri + let label = solidLogicSingleton.store.any(ws, ns.rdfs('label')) + if (!label) { + label = ws.uri.split('/').slice(-1)[0] || ws.uri.split('/').slice(-2)[0] + } + col2.textContent = label || '???' + tr.appendChild(col2) + if (i === 0) { + col3 = dom.createElement('td') + col3.setAttribute('rowspan', `${w.length}1`) + // col3.textContent = '@@@@@ remove'; + col3.setAttribute('style', 'width:50%;') + tr.appendChild(col3) + } + table.appendChild(tr) + + comment = solidLogicSingleton.store.any(ws, ns.rdfs('comment')) + comment = comment ? comment.value : 'Use this workspace' + col2.addEventListener( + 'click', + function (_event) { + col3.textContent = comment ? comment.value : '' + col3.setAttribute('style', deselectedStyle + localStyle) + const button = dom.createElement('button') + button.textContent = 'Continue' + // button.setAttribute('style', style); + const newBase = figureOutBase(ws) + baseField.value = newBase // show user proposed URI + + button.addEventListener( + 'click', + function (_event) { + button.disabled = true + callbackWS(ws, newBase) + button.textContent = '---->' + }, + true + ) // capture vs bubble + col3.appendChild(button) + }, + true + ) // capture vs bubble + } + + // last line with "Make new workspace" + const trLast = dom.createElement('tr') + col2 = dom.createElement('td') + col2.setAttribute('style', cellStyle) + col2.textContent = '+ Make a new workspace' + col2.addEventListener('click', makeNewWorkspace) + trLast.appendChild(col2) + table.appendChild(trLast) + } // displayOptions + + // console.log('kicking off async operation') + ensureLoadedPreferences(context) // kick off async operation + .then(displayOptions) + .catch((err) => { + // console.log("err from async op") + box.appendChild(widgets.errorMessageBlock(context.dom, err)) + }) + + return box // return the box element, while login proceeds +} // selectWorkspace + +/** + * Creates a new instance of an app. + * + * An instance of an app could be e.g. an issue tracker for a given project, + * or a chess game, or calendar, or a health/fitness record for a person. + * + * Note that this use of the term 'app' refers more to entries in the user's + * type index than to actual software applications that use the personal data + * to which these entries point. + * + * @param dom + * @param appDetails + * @param callback + * + * @returns A div with a button in it for making a new app instance + */ +export function newAppInstance ( + dom: HTMLDocument, + appDetails: AppDetails, + callback: (workspace: string | null, newBase: string) => void +): HTMLElement { + const gotWS = function (ws, base) { + // log.debug("newAppInstance: Selected workspace = " + (ws? ws.uri : 'none')) + callback(ws, base) + } + const div = dom.createElement('div') + const b = dom.createElement('button') + b.setAttribute('type', 'button') + div.appendChild(b) + b.innerHTML = `Make new ${appDetails.noun}` + b.addEventListener( + 'click', + (_event) => { + div.appendChild(selectWorkspace(dom, appDetails, gotWS)) + }, + false + ) + div.appendChild(b) + return div +} +/** + * Retrieves whether the currently logged in user is a power user + * and/or a developer + */ +export async function getUserRoles (): Promise> { + try { + const { me, preferencesFile, preferencesFileError } = await ensureLoadedPreferences({}) + if (!preferencesFile || preferencesFileError) { + throw new Error(preferencesFileError) + } + return solidLogicSingleton.store.each( + me, + ns.rdf('type'), + null, + preferencesFile.doc() + ) as NamedNode[] + } catch (error) { + debug.warn('Unable to fetch your preferences - this was the error: ', error) + } + return [] +} + +/** + * Filters which panes should be available, based on the result of [[getUserRoles]] + */ +export async function filterAvailablePanes ( + panes: Array +): Promise> { + const userRoles = await getUserRoles() + return panes.filter((pane) => isMatchingAudience(pane, userRoles)) +} + +function isMatchingAudience (pane: PaneDefinition, userRoles: Array): boolean { + const audience = pane.audience || [] + return audience.reduce( + (isMatch, audienceRole) => isMatch && !!userRoles.find((role) => role.equals(audienceRole)), + true as boolean + ) +} diff --git a/src/matrix/index.ts b/src/matrix/index.ts new file mode 100644 index 000000000..ad3897760 --- /dev/null +++ b/src/matrix/index.ts @@ -0,0 +1,7 @@ +import { + matrixForQuery +} from './matrix' + +export const matrix = { + matrixForQuery +} diff --git a/src/matrix.js b/src/matrix/matrix.ts similarity index 50% rename from src/matrix.js rename to src/matrix/matrix.ts index d0831b9c2..93ebf2183 100644 --- a/src/matrix.js +++ b/src/matrix/matrix.ts @@ -9,8 +9,8 @@ // // Options: // cellFunction(td, x, y, value) fill the TD element of a single cell -// xDecreasing set true for x axis to be in decreasiong order. -// yDecreasing set true for y axis to be in decreasiong order. +// xDecreasing set true for x axis to be in decreasing order. +// yDecreasing set true for y axis to be in decreasing order. // set_x array of X values to be define initial rows (order irrelevant) // set_y array of Y values to be define initial columns // @@ -19,31 +19,35 @@ // Extra rows and columns are inserted as needed to hold new data points // matrix.refresh() will re-run the query and adjust the display -var UI = { - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - pad: require('./'), - rdf: require('rdflib'), - store: require('./store'), - widgets: require('./widgets') -} - -const utils = require('./utils') -const kb = UI.store - -module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, whenDone) { - var matrix = dom.createElement('table') - var header = dom.createElement('tr') - var corner = header.appendChild(dom.createElement('td')) +import * as utils from '../utils' +import * as $rdf from 'rdflib' +import { MatrixOptions } from './types' +import { solidLogicSingleton } from 'solid-logic' + +const kb = solidLogicSingleton.store + +export function matrixForQuery ( + dom: HTMLDocument, + query: $rdf.Query, + vx: $rdf.Variable, + vy: $rdf.Variable, + vvalue: $rdf.Variable, + options: MatrixOptions, + whenDone: () => void +) { + // @@ TODO Remove need to cast to any + const matrix: any = dom.createElement('table') + const header = dom.createElement('tr') + const corner = header.appendChild(dom.createElement('td')) corner.setAttribute('class', 'MatrixCorner') matrix.appendChild(header) // just one for now matrix.lastHeader = header // Element before data - var columns = [] // Vector - var rows = [] // Associative array + let columns: any[] = [] // Vector + const rows: any[] = [] // Associative array - var setCell = function (cell, x, y, value) { - while (cell.firstChild) { // Empty any previous + const setCell = function (cell, x, y, value) { + while (cell.firstChild) { + // Empty any previous cell.removeChild(cell.firstChild) } cell.setAttribute('style', '') @@ -58,44 +62,62 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w delete cell.old } - var rowFor = function (y1) { - var y = y1.toNT() + const rowFor = function (y1) { + const y = y1.toNT() if (rows[y]) return rows[y] - var tr = dom.createElement('tr') - var header = tr.appendChild(dom.createElement('td')) + // @@ TODO Remove need for casting to any + const tr: any = dom.createElement('tr') + const header = tr.appendChild(dom.createElement('td')) header.setAttribute('style', 'padding: 0.3em;') header.textContent = utils.label(y1) // first approximation if (y1.termType === 'NamedNode') { - kb.fetcher.nowOrWhenFetched(y1.uri.split('#')[0], undefined, function (ok, body, response) { + kb.fetcher!.nowOrWhenFetched(y1.uri.split('#')[0], undefined, function ( + ok, + _body, + _response + ) { if (ok) header.textContent = utils.label(y1) }) } - for (var i = 0; i < columns.length; i++) { - setCell(tr.appendChild(dom.createElement('td')), $rdf.fromNT(columns[i]), y1, null) + for (let i = 0; i < columns.length; i++) { + setCell( + tr.appendChild(dom.createElement('td')), + $rdf.fromNT(columns[i]), + y1, + null + ) } tr.dataValueNT = y rows[y] = tr - for (var ele = matrix.lastHeader.nextSibling; ele; ele = ele.nextSibling) { // skip header - if (((y > ele.dataValueNT) && options && options.yDecreasing) || - ((y < ele.dataValueNT) && !(options && options.yDecreasing))) { + for (let ele = matrix.lastHeader.nextSibling; ele; ele = ele.nextSibling) { + // skip header + if ( + (y > ele.dataValueNT && options && options.yDecreasing) || + (y < ele.dataValueNT && !(options && options.yDecreasing)) + ) { return matrix.insertBefore(tr, ele) // return the tr } } return matrix.appendChild(tr) // return the tr } - var columnNumberFor = function (x1) { - var xNT = x1.toNT() // xNT is a NT string - var col = null + const columnNumberFor = function (x1): number { + const xNT: any = x1.toNT() // xNT is a NT string + let col: any = null // These are data columns (not headings) - for (var i = 0; i < columns.length; i++) { + for (let i = 0; i < columns.length; i++) { if (columns[i] === xNT) { return i } - if (((xNT > columns[i]) && options.xDecreasing) || - ((xNT < columns[i]) && !options.xDecreasing)) { - columns = columns.slice(0, i).concat([xNT]).concat(columns.slice(i)) + if ( + (xNT > columns[i] && options.xDecreasing) || + (xNT < columns[i] && !options.xDecreasing) + ) { + columns = columns + .slice(0, i) + .concat([xNT]) + .concat(columns.slice(i)) col = i break } @@ -107,9 +129,10 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w } // col is the number of the new column, starting from 0 - for (var row = matrix.firstChild; row; row = row.nextSibling) { // For every row header or not - var y = row.dataValueNT - var td = dom.createElement('td') // Add a new cell + for (let row = matrix.firstChild; row; row = row.nextSibling) { + // For every row header or not + const y = row.dataValueNT + const td = dom.createElement('td') // Add a new cell td.style.textAlign = 'center' if (row === matrix.firstChild) { td.textContent = utils.label(x1) @@ -119,8 +142,9 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w if (col === columns.length - 1) { row.appendChild(td) } else { - var t = row.firstChild - for (var j = 0; j < col + 1; j++) { // Skip header col too + let t = row.firstChild + for (let j = 0; j < col + 1; j++) { + // Skip header col too t = t.nextSibling } row.insertBefore(td, t) @@ -129,27 +153,28 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w return col } - var markOldCells = function () { - for (var i = 1; i < matrix.children.length; i++) { - var row = matrix.children[i] - for (var j = 1; j < row.children.length; j++) { + const markOldCells = function () { + for (let i = 1; i < matrix.children.length; i++) { + const row = matrix.children[i] + for (let j = 1; j < row.children.length; j++) { row.children[j].old = true } } } - var clearOldCells = function () { - var row, cell - var colsUsed = [] - var rowsUsed = [] + const clearOldCells = function () { + let row, cell + const colsUsed: any[] = [] + const rowsUsed: any[] = [] - if (options.set_y) { // Knows y values create rows - for (var k = 0; k < options.set_y.length; k++) { + if (options.set_y) { + // Knows y values create rows + for (let k = 0; k < options.set_y.length; k++) { rowsUsed[options.set_y[k]] = true } } if (options.set_x) { - for (k = 0; k < options.set_x.length; k++) { + for (let k = 0; k < options.set_x.length; k++) { colsUsed[columnNumberFor(options.set_x[k]) + 1] = true } } @@ -159,8 +184,8 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w for (let j = 1; j < row.children.length; j++) { cell = row.children[j] if (cell.old) { - var y = $rdf.fromNT(row.dataValueNT) - var x = $rdf.fromNT(columns[j - 1]) + const y = $rdf.fromNT(row.dataValueNT) + const x = $rdf.fromNT(columns[j - 1]) setCell(cell, x, y, null) } else { rowsUsed[row.dataValueNT] = true @@ -175,15 +200,16 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w delete rows[row.dataValueNT] matrix.removeChild(row) } else { - for (var j = row.children.length - 1; j > 0; j--) { // backwards - let cell = row.children[j] + for (let j = row.children.length - 1; j > 0; j--) { + // backwards + const cell = row.children[j] if (!colsUsed[j]) { row.removeChild(cell) } } } } - var newcolumns = [] + const newcolumns: any[] = [] for (let j = 0; j < columns.length; j++) { if (colsUsed[j + 1]) { newcolumns.push(columns[j]) @@ -194,30 +220,31 @@ module.exports.matrixForQuery = function (dom, query, vx, vy, vvalue, options, w matrix.refresh = function () { markOldCells() - kb.query(query, addCellFromBindings, undefined, clearOldCells) + kb.query(query as any, addCellFromBindings, undefined, clearOldCells) } - var addCellFromBindings = function (bindings) { - var x = bindings[vx] - var y = bindings[vy] - var value = bindings[vvalue] - var row = rowFor(y) - var colNo = columnNumberFor(x) - var cell = row.children[colNo + 1] // number of Y axis headings + const addCellFromBindings = function (bindings) { + const x = bindings[vx.toString()] + const y = bindings[vy.toString()] + const value = bindings[(vvalue.toString())] + const row = rowFor(y) + const colNo = columnNumberFor(x) + const cell = row.children[colNo + 1] // number of Y axis headings setCell(cell, x, y, value) } - if (options.set_y) { // Knows y values create rows - for (var k = 0; k < options.set_y.length; k++) { + if (options.set_y) { + // Knows y values create rows + for (let k = 0; k < options.set_y.length; k++) { rowFor(options.set_y[k]) } } if (options.set_x) { - for (k = 0; k < options.set_x.length; k++) { + for (let k = 0; k < options.set_x.length; k++) { columnNumberFor(options.set_x[k]) } } - kb.query(query, addCellFromBindings, undefined, whenDone) // Populate the matrix + kb.query(query as any, addCellFromBindings, undefined, whenDone) // Populate the matrix return matrix } diff --git a/src/matrix/types.ts b/src/matrix/types.ts new file mode 100644 index 000000000..2c9545534 --- /dev/null +++ b/src/matrix/types.ts @@ -0,0 +1,9 @@ +export type MatrixOptions = { + cellFunction?: (td, x, y, value) => string + xDecreasing?: boolean + yDecreasing?: boolean + + set_x: any[] + + set_y: any[] +} diff --git a/src/media-capture.js b/src/media-capture.js deleted file mode 100644 index 03fa84d3f..000000000 --- a/src/media-capture.js +++ /dev/null @@ -1,68 +0,0 @@ - -/// ///////////////////////////////////////////// -// -// Media input widget -// -// In future this will be really simple to do when -// the HTML5 input "image capture" input element is actually deployed -// In the meantime (2017-01) this seems to be the state of the art. -// -// Workflow: -// The HTML5 functionality (on mobille) is to prompt for either -// a realtime camera capture , OR a selection from images already ont the device -// (eg camera roll). The solid alternative is to either take a phtoto -// or access cemra roll (etc) OR to access solid cloud storage of favorite photo almbums. -// (Especially latest taken ones) -// -/* global alert */ -var $rdf = require('rdflib') -var media = module.exports = {} - -var UI = { - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - pad: require('./pad'), - media: media, - rdf: $rdf, - store: require('./store'), - utils: require('./utils'), - widgets: require('./widgets') -} - -// Put up a video stream and take a picture -// In: context.div, dom - -UI.media.camera = function (context, gotBlob) { - function takeSnapshot () { - var dom = context.dom - var img = dom.createElement('img') - var ctx - var width = video.offsetWidth - var height = video.offsetHeight - - var canvas = context.canvas || document.createElement('canvas') - canvas.width = width - canvas.height = height - - ctx = canvas.getContext('2d') - ctx.drawImage(video, 0, 0, width, height) - - img.src = canvas.toDataURL('image/png') // @@@ - context.div.appendChild(img) - } - - var video = context.dom.createElement('video') - context.div.appendChild(video) - // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia - // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob - navigator.mediaDevices.getUserMedia({video: true}) - .then(function (stream) { - video.src = window.URL.createObjectURL(stream) - video.addEventListener('click', takeSnapshot) - }) - .catch(function (error) { - alert('Could not access the camera. Error: ' + error.name) - }) - return video -} diff --git a/src/media/index.ts b/src/media/index.ts new file mode 100644 index 000000000..c20654c5c --- /dev/null +++ b/src/media/index.ts @@ -0,0 +1,9 @@ +import { + cameraCaptureControl, + cameraButton +} from './media-capture' + +export const media = { + cameraCaptureControl, + cameraButton +} diff --git a/src/media/media-capture.ts b/src/media/media-capture.ts new file mode 100644 index 000000000..192e083ff --- /dev/null +++ b/src/media/media-capture.ts @@ -0,0 +1,207 @@ +// +// Media input widget +// +// +// Workflow: +// The HTML5 functionality (on mobile) is to prompt for either +// a realtime camera capture, OR a selection from images already on the device +// (eg camera roll). +// +// The solid alternative is to either take a photo +// or access camera roll (etc) OR to access solid cloud storage of favorite photo albums. +// (Especially latest taken ones) +// +import * as debug from '../debug' + +/** @module mediaCapture */ + +import { icons } from '../iconBase' +import { style } from '../style' +import * as widgets from '../widgets' +import { IndexedFormula, NamedNode } from 'rdflib' + +const cameraIcon = icons.iconBase + 'noun_Camera_1618446_000000.svg' // Get it from github +const retakeIcon = icons.iconBase + 'noun_479395.svg' // Get it from github + +const contentType = 'image/png' + +/** A control to capture a picture using camera + * @param {Docuemnt} dom - The Document object + * @param {IndexedForumla} store - The quadstore to store data in + * @param {NamedNode} getImageDoc() - NN of the image file to be created + * @param {function} doneCallback - Called when a picture has been taken + */ +export function cameraCaptureControl ( + dom: HTMLDocument, + store: IndexedFormula, + getImageDoc: () => NamedNode, + doneCallback: (imageDoc) => Promise +) { + const div = dom.createElement('div') + let destination, imageBlob, player, canvas + + const table = div.appendChild(dom.createElement('table')) + const mainTR = table.appendChild(dom.createElement('tr')) + const main = mainTR.appendChild(dom.createElement('td')) + main.setAttribute('colspan', '4') + + const buttons = table.appendChild(dom.createElement('tr')) + + buttons + .appendChild(dom.createElement('td')) // Cancel button + .appendChild(widgets.cancelButton(dom)) + .addEventListener('click', _event => { + stopVideo() + doneCallback(null) + }) + + const retakeButton = buttons + .appendChild(dom.createElement('td')) // Retake button + .appendChild(widgets.button(dom, retakeIcon, 'Retake')) + retakeButton.addEventListener('click', _event => { + retake() + }) + retakeButton.style.visibility = 'collapse' // Hide for now + + const shutterButton = buttons + .appendChild(dom.createElement('td')) // Trigger capture button + .appendChild( + widgets.button(dom, icons.iconBase + 'noun_10636.svg', 'Snap') + ) + shutterButton.addEventListener('click', grabCanvas) + shutterButton.style.visibility = 'collapse' // Hide for now + + const sendButton = buttons + .appendChild(dom.createElement('td')) // Confirm and save button + .appendChild(widgets.continueButton(dom)) // @@ or send icon?? + sendButton.addEventListener('click', _event => { + saveBlob(imageBlob, destination) + }) + sendButton.style.visibility = 'collapse' // Hide for now + + function displayPlayer () { + player = main.appendChild(dom.createElement('video')) + player.setAttribute('controls', '1') + player.setAttribute('autoplay', '1') + player.setAttribute('style', style.controlStyle) + if (!navigator.mediaDevices) { + throw new Error('navigator.mediaDevices not available') + } + navigator.mediaDevices.getUserMedia(constraints).then(stream => { + player.srcObject = stream + shutterButton.style.visibility = 'visible' // Enable + sendButton.style.visibility = 'collapse' + retakeButton.style.visibility = 'collapse' + }) + } + + const constraints = { + video: true + } + + function retake () { + main.removeChild(canvas) + displayPlayer() // Make new one as old one is stuck black + } + + function grabCanvas () { + // Draw the video frame to the canvas. + canvas = dom.createElement('canvas') + canvas.setAttribute('width', style.canvasWidth) + canvas.setAttribute('height', style.canvasHeight) + canvas.setAttribute('style', style.controlStyle) + main.appendChild(canvas) + + const context = canvas.getContext('2d') + context.drawImage(player, 0, 0, canvas.width, canvas.height) + + player.parentNode.removeChild(player) + + canvas.toBlob(blob => { + const msg = `got blob type ${blob.type} size ${blob.size}` + debug.log(msg) + destination = getImageDoc() + imageBlob = blob // save for review + reviewImage() + // alert(msg) + }, contentType) // toBlob + } + + function reviewImage () { + sendButton.style.visibility = 'visible' + retakeButton.style.visibility = 'visible' + shutterButton.style.visibility = 'collapse' // Hide for now + } + + function stopVideo () { + if (player && player.srcObject) { + player.srcObject.getVideoTracks().forEach(track => track.stop()) + } + } + function saveBlob (blob, destination) { + const contentType = blob.type + // if (!confirm('Save picture to ' + destination + ' ?')) return + debug.log( + 'Putting ' + blob.size + ' bytes of ' + contentType + ' to ' + destination + ) + // @@ TODO Remove casting + ;(store as any).fetcher + .webOperation('PUT', destination.uri, { + data: blob, + contentType + }) + .then( + _resp => { + debug.log('ok saved ' + destination) + stopVideo() + doneCallback(destination) + }, + err => { + stopVideo() + alert(err) + } + ) + } + + // Attach the video stream to the video element and autoplay. + displayPlayer() + return div +} + +/** A button to capture a picture using camera + * @param {Docuemnt} dom - The Document object + * @param {IndexedForumla} store - The quadstore to store data in + * @param {fuunction} getImageDoc - returns NN of the image file to be created + * @param {function} doneCallback - called with the image taken + * @returns {DomElement} - A div element with the button in it + * + * This expands the button to a large control when it is pressed + */ + +export function cameraButton ( + dom: HTMLDocument, + store: IndexedFormula, + getImageDoc: () => NamedNode, + doneCallback: (imageDoc) => Promise +): HTMLElement { + const div = dom.createElement('div') + const but = widgets.button(dom, cameraIcon, 'Take picture') + let control + async function restoreButton (imageDoc) { + div.removeChild(control) + div.appendChild(but) + doneCallback(imageDoc) + } + div.appendChild(but) + but.addEventListener('click', _event => { + div.removeChild(but) + control = cameraCaptureControl( + dom, + store, + getImageDoc, + restoreButton + ) + div.appendChild(control) + }) + return div +} diff --git a/src/messageArea.js b/src/messageArea.js index 8bd7b958f..9b3478491 100644 --- a/src/messageArea.js +++ b/src/messageArea.js @@ -1,44 +1,43 @@ // Common code for a discussion are a of messages about something // -var UI = { - authn: require('./signin'), - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - pad: require('./'), - rdf: require('rdflib'), - store: require('./store'), - style: require('./style'), - widgets: require('./widgets') -} -const utils = require('./utils') +import { icons } from './iconBase' +import * as login from './login/login' +import { solidLogicSingleton } from 'solid-logic' +import ns from './ns' +import * as rdf from 'rdflib' // pull in first avoid cross-refs +import { style } from './style' +import * as utils from './utils' +import * as widgets from './widgets' -// var buttonStyle = 'font-size: 100%; margin: 0.8em; padding:0.5em; background-color: white;' +const UI = { icons, ns, rdf, style, widgets } -module.exports = function (dom, kb, subject, messageStore, options) { - kb = kb || UI.store +export function messageArea (dom, kb, subject, messageStore, options) { + kb = kb || solidLogicSingleton.store messageStore = messageStore.doc() // No hash - var ns = UI.ns - var WF = $rdf.Namespace('http://www.w3.org/2005/01/wf/flow#') - var DCT = $rdf.Namespace('http://purl.org/dc/terms/') + const ns = UI.ns + const WF = rdf.Namespace('http://www.w3.org/2005/01/wf/flow#') + const DCT = rdf.Namespace('http://purl.org/dc/terms/') options = options || {} - var newestFirst = !!options.newestFirst + const newestFirst = !!options.newestFirst - var messageBodyStyle = 'white-space: pre-wrap; width: 90%; font-size:100%; border: 0.07em solid #eee; padding: .2em 0.5em; margin: 0.1em 1em 0.1em 1em;' + const messageBodyStyle = + 'white-space: pre-wrap; width: 90%; font-size:100%; border: 0.07em solid #eee; padding: .2em 0.5em; margin: 0.1em 1em 0.1em 1em;' // 'font-size: 100%; margin: 0.1em 1em 0.1em 1em; background-color: white; white-space: pre-wrap; padding: 0.1em;' - var div = dom.createElement('div') - var messageTable // Shared by initial build and addMessageFromBindings + const div = dom.createElement('div') + // eslint-disable-next-line prefer-const + let messageTable // Shared by initial build and addMessageFromBindings - var me + let me - var updater = UI.store.updater + const updater = solidLogicSingleton.store.updater - var anchor = function (text, term) { // If there is no link return an element anyway - var a = dom.createElement('a') + const anchor = function (text, term) { + // If there is no link return an element anyway + const a = dom.createElement('a') if (term && term.uri) { a.setAttribute('href', term.uri) a.addEventListener('click', UI.widgets.openHrefInOutlineMode, true) @@ -48,59 +47,82 @@ module.exports = function (dom, kb, subject, messageStore, options) { return a } - var mention = function mention (message, style) { - var pre = dom.createElement('pre') + const mention = function mention (message, style) { + const pre = dom.createElement('pre') pre.setAttribute('style', style || 'color: grey') div.appendChild(pre) pre.appendChild(dom.createTextNode(message)) return pre } - var announce = { - log: function (message) { mention(message, 'color: #111;') }, - warn: function (message) { mention(message, 'color: #880;') }, - error: function (message) { mention(message, 'color: #800;') } + const announce = { + log: function (message) { + mention(message, 'color: #111;') + }, + warn: function (message) { + mention(message, 'color: #880;') + }, + error: function (message) { + mention(message, 'color: #800;') + } } // Form for a new message // - var newMessageForm = function () { - var form = dom.createElement('tr') - var lhs = dom.createElement('td') - var middle = dom.createElement('td') - var rhs = dom.createElement('td') + const newMessageForm = function () { + const form = dom.createElement('tr') + const lhs = dom.createElement('td') + const middle = dom.createElement('td') + const rhs = dom.createElement('td') form.appendChild(lhs) form.appendChild(middle) form.appendChild(rhs) form.AJAR_date = '9999-01-01T00:00:00Z' // ISO format for field sort - var sendMessage = function () { + const sendMessage = function () { // titlefield.setAttribute('class','pendingedit') // titlefield.disabled = true field.setAttribute('class', 'pendingedit') field.disabled = true - var sts = [] - var now = new Date() - var timestamp = '' + now.getTime() - var dateStamp = $rdf.term(now) + const sts = [] + const now = new Date() + const timestamp = '' + now.getTime() + const dateStamp = rdf.term(now) // http://www.w3schools.com/jsref/jsref_obj_date.asp - var message = kb.sym(messageStore.uri + '#' + 'Msg' + timestamp) - - sts.push(new $rdf.Statement(subject, ns.wf('message'), message, messageStore)) - // sts.push(new $rdf.Statement(message, ns.dc('title'), kb.literal(titlefield.value), messageStore)) - sts.push(new $rdf.Statement(message, ns.sioc('content'), kb.literal(field.value), messageStore)) - sts.push(new $rdf.Statement(message, DCT('created'), dateStamp, messageStore)) - if (me) sts.push(new $rdf.Statement(message, ns.foaf('maker'), me, messageStore)) + const message = kb.sym(messageStore.uri + '#' + 'Msg' + timestamp) + + sts.push( + new rdf.Statement(subject, ns.wf('message'), message, messageStore) + ) + sts.push( + new rdf.Statement( + message, + ns.sioc('content'), + kb.literal(field.value), + messageStore + ) + ) + sts.push( + new rdf.Statement(message, DCT('created'), dateStamp, messageStore) + ) + if (me) { + sts.push( + new rdf.Statement(message, ns.foaf('maker'), me, messageStore) + ) + } - var sendComplete = function (uri, success, body) { + const sendComplete = function (uri, success, body) { if (!success) { - form.appendChild(UI.widgets.errorMessageBlock( - dom, 'Error writing message: ' + body)) + form.appendChild( + UI.widgets.errorMessageBlock(dom, 'Error writing message: ' + body) + ) } else { - var bindings = { '?msg': message, + const bindings = { + '?msg': message, '?content': kb.literal(field.value), '?date': dateStamp, - '?creator': me} + '?creator': me + } renderMessage(bindings, false) // not green field.value = '' // clear from out for reuse @@ -112,8 +134,8 @@ module.exports = function (dom, kb, subject, messageStore, options) { } form.appendChild(dom.createElement('br')) - var field, sendButton - var turnOnInput = function () { + let field, sendButton + const turnOnInput = function () { creatorAndDate(lhs, me, '', null) field = dom.createElement('textarea') @@ -123,23 +145,33 @@ module.exports = function (dom, kb, subject, messageStore, options) { // field.cols = 40 field.setAttribute('style', messageBodyStyle + 'background-color: #eef;') - field.addEventListener('keyup', function (e) { // User preference? - if (e.keyCode === 13) { - if (!e.altKey) { // Alt-Enter just adds a new line - sendMessage() + field.addEventListener( + 'keyup', + function (e) { + // User preference? + if (e.keyCode === 13) { + if (!e.altKey) { + // Alt-Enter just adds a new line + sendMessage() + } } - } - }, false) + }, + false + ) rhs.innerHTML = '' - sendButton = UI.widgets.button(dom, UI.icons.iconBase + 'noun_383448.svg', 'Send') + sendButton = UI.widgets.button( + dom, + UI.icons.iconBase + 'noun_383448.svg', + 'Send' + ) sendButton.setAttribute('style', UI.style.buttonStyle + 'float: right;') sendButton.addEventListener('click', sendMessage, false) rhs.appendChild(sendButton) } - let context = {div: middle, dom: dom} - UI.authn.logIn(context).then(context => { + const context = { div: middle, dom } + login.ensureLoggedIn(context).then(context => { me = context.me turnOnInput() }) @@ -148,15 +180,18 @@ module.exports = function (dom, kb, subject, messageStore, options) { } function nick (person) { - var s = UI.store.any(person, UI.ns.foaf('nick')) + const s = solidLogicSingleton.store.any(person, UI.ns.foaf('nick')) if (s) return '' + s.value return '' + utils.label(person) } function creatorAndDate (td1, creator, date, message) { - var nickAnchor = td1.appendChild(anchor(nick(creator), creator)) + const nickAnchor = td1.appendChild(anchor(nick(creator), creator)) if (creator.uri) { - UI.store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function (ok, body) { + solidLogicSingleton.store.fetcher.nowOrWhenFetched(creator.doc(), undefined, function ( + _ok, + _body + ) { nickAnchor.textContent = nick(creator) }) } @@ -167,16 +202,16 @@ module.exports = function (dom, kb, subject, messageStore, options) { // /////////////////////////////////////////////////////////////////////// function syncMessages (about, messageTable) { - var displayed = {} - var ele, ele2 + const displayed = {} + let ele, ele2 for (ele = messageTable.firstChild; ele; ele = ele.nextSibling) { if (ele.AJAR_subject) { displayed[ele.AJAR_subject.uri] = true } } - var messages = kb.each(about, ns.wf('message')) - var stored = {} - messages.map(function (m) { + const messages = kb.each(about, ns.wf('message')) + const stored = {} + messages.forEach(function (m) { stored[m.uri] = true if (!displayed[m.uri]) { addMessage(m) @@ -192,9 +227,10 @@ module.exports = function (dom, kb, subject, messageStore, options) { } } - var deleteMessage = function (message) { - var deletions = kb.statementsMatching(message).concat( - kb.statementsMatching(undefined, undefined, message)) + const deleteMessage = function (message) { + const deletions = kb + .statementsMatching(message) + .concat(kb.statementsMatching(undefined, undefined, message)) updater.update(deletions, [], function (uri, ok, body) { if (!ok) { announce.error('Cant delete messages:' + body) @@ -204,8 +240,8 @@ module.exports = function (dom, kb, subject, messageStore, options) { }) } - var addMessage = function (message) { - var bindings = { + const addMessage = function (message) { + const bindings = { '?msg': message, '?creator': kb.any(message, ns.foaf('maker')), '?date': kb.any(message, DCT('created')), @@ -214,24 +250,27 @@ module.exports = function (dom, kb, subject, messageStore, options) { renderMessage(bindings, true) // fresh from elsewhere } - var renderMessage = function (bindings, fresh) { - var creator = bindings['?creator'] - var message = bindings['?msg'] - var date = bindings['?date'] - var content = bindings['?content'] + const renderMessage = function (bindings, fresh) { + const creator = bindings['?creator'] + const message = bindings['?msg'] + const date = bindings['?date'] + const content = bindings['?content'] - var dateString = date.value - var tr = dom.createElement('tr') + const dateString = date.value + const tr = dom.createElement('tr') tr.AJAR_date = dateString tr.AJAR_subject = message - var done = false - for (var ele = messageTable.firstChild; ; ele = ele.nextSibling) { - if (!ele) { // empty + let done = false + for (let ele = messageTable.firstChild; ; ele = ele.nextSibling) { + if (!ele) { + // empty break } - if (((dateString > ele.AJAR_date) && newestFirst) || - ((dateString < ele.AJAR_date) && !newestFirst)) { + if ( + (dateString > ele.AJAR_date && newestFirst) || + (dateString < ele.AJAR_date && !newestFirst) + ) { messageTable.insertBefore(tr, ele) done = true break @@ -241,45 +280,60 @@ module.exports = function (dom, kb, subject, messageStore, options) { messageTable.appendChild(tr) } - var td1 = dom.createElement('td') + const td1 = dom.createElement('td') tr.appendChild(td1) creatorAndDate(td1, creator, UI.widgets.shortDate(dateString), message) - var td2 = dom.createElement('td') + const td2 = dom.createElement('td') tr.appendChild(td2) - var pre = dom.createElement('p') - pre.setAttribute('style', messageBodyStyle + - (fresh ? 'background-color: #e8ffe8;' : 'background-color: #white;')) + const pre = dom.createElement('p') + pre.setAttribute( + 'style', + messageBodyStyle + + (fresh ? 'background-color: #e8ffe8;' : 'background-color: #white;') + ) td2.appendChild(pre) pre.textContent = content.value - var td3 = dom.createElement('td') + const td3 = dom.createElement('td') tr.appendChild(td3) - var delButton = dom.createElement('button') + const delButton = dom.createElement('button') td3.appendChild(delButton) delButton.textContent = '-' tr.setAttribute('class', 'hoverControl') // See tabbedtab.css (sigh global CSS) delButton.setAttribute('class', 'hoverControlHide') delButton.setAttribute('style', 'color: red;') - delButton.addEventListener('click', function (e) { - td3.removeChild(delButton) // Ask -- are you sure? - var cancelButton = dom.createElement('button') - cancelButton.textContent = 'cancel' - td3.appendChild(cancelButton).addEventListener('click', function (e) { - td3.removeChild(sureButton) - td3.removeChild(cancelButton) - td3.appendChild(delButton) - }, false) - var sureButton = dom.createElement('button') - sureButton.textContent = 'Delete message' - td3.appendChild(sureButton).addEventListener('click', function (e) { - td3.removeChild(sureButton) - td3.removeChild(cancelButton) - deleteMessage(message) - }, false) - }, false) + delButton.addEventListener( + 'click', + function (_event) { + td3.removeChild(delButton) // Ask -- are you sure? + const cancelButton = dom.createElement('button') + cancelButton.textContent = 'cancel' + td3.appendChild(cancelButton).addEventListener( + 'click', + function (_event) { + td3.removeChild(sureButton) + td3.removeChild(cancelButton) + td3.appendChild(delButton) + }, + false + ) + const sureButton = dom.createElement('button') + sureButton.textContent = 'Delete message' + td3.appendChild(sureButton).addEventListener( + 'click', + function (_event) { + td3.removeChild(sureButton) + td3.removeChild(cancelButton) + deleteMessage(message) + }, + false + ) + }, + false + ) } // Messages with date, author etc @@ -289,28 +343,28 @@ module.exports = function (dom, kb, subject, messageStore, options) { div.appendChild(messageTable) messageTable.setAttribute('style', 'width: 100%;') // fill that div! - var tr = newMessageForm() + const tr = newMessageForm() if (newestFirst) { messageTable.insertBefore(tr, messageTable.firstChild) // If newestFirst } else { messageTable.appendChild(tr) // not newestFirst } - var query + let query // Do this with a live query to pull in messages from web if (options.query) { query = options.query } else { - query = new $rdf.Query('Messages') - var v = {} // semicolon needed - var vs = ['msg', 'date', 'creator', 'content'] - vs.map(function (x) { - query.vars.push(v[x] = $rdf.variable(x)) + query = new rdf.Query('Messages') + const v = {} // semicolon needed + const vs = ['msg', 'date', 'creator', 'content'] + vs.forEach(function (x) { + query.vars.push((v[x] = rdf.variable(x))) }) - query.pat.add(subject, WF('message'), v['msg']) - query.pat.add(v['msg'], ns.dct('created'), v['date']) - query.pat.add(v['msg'], ns.foaf('maker'), v['creator']) - query.pat.add(v['msg'], ns.sioc('content'), v['content']) + query.pat.add(subject, WF('message'), v.msg) + query.pat.add(v.msg, ns.dct('created'), v.date) + query.pat.add(v.msg, ns.foaf('maker'), v.creator) + query.pat.add(v.msg, ns.sioc('content'), v.content) } function doneQuery () { messageTable.fresh = true // any new are fresh and so will be greenish diff --git a/src/newperson.js b/src/newperson.js new file mode 100644 index 000000000..5d7e1343f --- /dev/null +++ b/src/newperson.js @@ -0,0 +1 @@ +export default 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjAxNTcgOS4yNzM2M0MxNC4yOTU0IDguMzQwMzEgMTUuMTI4OCA2LjgyOTg0IDE1LjEyODggNS4xMjgyQzE1LjEyODggMi4zMDA1MSAxMi44MjgzIDAgMTAuMDAwNiAwQzcuMTcyODkgMCA0Ljg3MjM4IDIuMzAwNTEgNC44NzIzOCA1LjEyODJDNC44NzIzOCA2LjgyOTg0IDUuNzA1NyA4LjM0MDMxIDYuOTg1NDcgOS4yNzM2M0MzLjgwNDIyIDEwLjQ5MSAxLjUzOTA2IDEzLjU3NTQgMS41MzkwNiAxNy4xNzk1QzEuNTM5MDYgMTguNzM0NyAyLjgwNDM0IDIwIDQuMzU5NTcgMjBIMTUuNjQxNkMxNy4xOTY4IDIwIDE4LjQ2MjEgMTguNzM0NyAxOC40NjIxIDE3LjE3OTVDMTguNDYyMSAxMy41NzU0IDE2LjE5NyAxMC40OTEgMTMuMDE1NyA5LjI3MzYzWk02LjQxMDg2IDUuMTI4MkM2LjQxMDg2IDMuMTQ4ODMgOC4wMjEyMSAxLjUzODQ4IDEwLjAwMDYgMS41Mzg0OEMxMS45OCAxLjUzODQ4IDEzLjU5MDMgMy4xNDg4MyAxMy41OTAzIDUuMTI4MkMxMy41OTAzIDcuMTA3NTggMTEuOTggOC43MTc5NyAxMC4wMDA2IDguNzE3OTdDOC4wMjEyMSA4LjcxNzk3IDYuNDEwODYgNy4xMDc1OCA2LjQxMDg2IDUuMTI4MlpNMTUuNjQxNiAxOC40NjE1SDQuMzU5NTdDMy42NTI2NiAxOC40NjE1IDMuMDc3NTQgMTcuODg2NCAzLjA3NzU0IDE3LjE3OTVDMy4wNzc1NCAxMy4zNjIgNi4xODMxNiAxMC4yNTY0IDEwLjAwMDYgMTAuMjU2NEMxMy44MTgxIDEwLjI1NjQgMTYuOTIzNyAxMy4zNjIgMTYuOTIzNyAxNy4xNzk1QzE2LjkyMzcgMTcuODg2NCAxNi4zNDg2IDE4LjQ2MTUgMTUuNjQxNiAxOC40NjE1WiIgZmlsbD0iIzMxNDE1OCIvPgo8L3N2Zz4K' diff --git a/src/noun_Camera_1618446_000000.js b/src/noun_Camera_1618446_000000.js new file mode 100644 index 000000000..7c7a79f50 --- /dev/null +++ b/src/noun_Camera_1618446_000000.js @@ -0,0 +1 @@ +export default 'data:image/svg;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTAwIDEwMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBhdGggZD0iTTcyLjkyNiwzNC4zMzNINjIuNDc4bC0yLjUtNS42NjZINDAuMDIybC0yLjUsNS42NjZoLTIuMjc1di0zLjcwN2gtNnYzLjcwN2gtMi4xNzNjLTEuOTMsMC0zLjUsMS41Ny0zLjUsMy41djMwICAgYzAsMS45MywxLjU3LDMuNSwzLjUsMy41aDQ1Ljg1MmMxLjkzLDAsMy41LTEuNTcsMy41LTMuNXYtMzBDNzYuNDI2LDM1LjkwMyw3NC44NTUsMzQuMzMzLDcyLjkyNiwzNC4zMzN6IE03My40MjYsNjcuODMzICAgYzAsMC4yNzUtMC4yMjUsMC41LTAuNSwwLjVIMjcuMDc0Yy0wLjI3NSwwLTAuNS0wLjIyNS0wLjUtMC41di0zMGMwLTAuMjc1LDAuMjI1LTAuNSwwLjUtMC41aDEyLjQwM2wyLjUtNS42NjZoMTYuMDQ1bDIuNSw1LjY2NiAgIGgxMi40MDNjMC4yNzUsMCwwLjUsMC4yMjUsMC41LDAuNVY2Ny44MzN6Ij48L3BhdGg+PHBhdGggZD0iTTUwLDM4Ljc2NmMtNy4yOTgsMC0xMy4yMzQsNS45MzctMTMuMjM0LDEzLjIzNFM0Mi43MDIsNjUuMjM0LDUwLDY1LjIzNFM2My4yMzQsNTkuMjk4LDYzLjIzNCw1MlM1Ny4yOTgsMzguNzY2LDUwLDM4Ljc2NiAgIHogTTUwLDYyLjIzNGMtNS42NDQsMC0xMC4yMzQtNC41OTEtMTAuMjM0LTEwLjIzNFM0NC4zNTYsNDEuNzY2LDUwLDQxLjc2NlM2MC4yMzQsNDYuMzU2LDYwLjIzNCw1MlM1NS42NDQsNjIuMjM0LDUwLDYyLjIzNHoiPjwvcGF0aD48cGF0aCBkPSJNNTAuMDAxLDQzLjI0MmMtNC44MywwLTguNzYsMy45MjktOC43Niw4Ljc1OHMzLjkzLDguNzU4LDguNzYsOC43NThjNC44MjksMCw4Ljc1OC0zLjkyOSw4Ljc1OC04Ljc1OCAgIFM1NC44Myw0My4yNDIsNTAuMDAxLDQzLjI0MnogTTUwLjAwMSw1OS43NThjLTQuMjc4LDAtNy43Ni0zLjQ4LTcuNzYtNy43NThzMy40ODEtNy43NTgsNy43Ni03Ljc1OCAgIGM0LjI3NywwLDcuNzU4LDMuNDgsNy43NTgsNy43NThTNTQuMjc4LDU5Ljc1OCw1MC4wMDEsNTkuNzU4eiI+PC9wYXRoPjwvZz48L3N2Zz4=' diff --git a/src/ns.js b/src/ns.js index 422badf9f..b800bc0ff 100644 --- a/src/ns.js +++ b/src/ns.js @@ -1,54 +1,6 @@ -// Namespaces we commonly use and have acommon prefixes for around solid -// -var thisModule = {} +// Namespaces we commonly use and have common prefixes for around Solid -module.exports = thisModule +import solidNamespace from 'solid-namespace' // Delegate to this which takes RDFlib as param. +import * as $rdf from 'rdflib' -var $rdf = require('rdflib') - -// This used to be a faw function (no ".expand" but that caused the module exports all to be dropped) -thisModule.expand = function (prefixed) { - var pair = prefixed.split(':') - if (pair.length === 0) throw new Error('Prefixed name has no colon: ' + prefixed) - if (!(pair[0] in thisModule)) throw new Error('Unregistered namespace prefix in: ' + prefixed) - return thisModule[pair[0]](pair[1]) -} - -thisModule.auth = $rdf.Namespace('http://www.w3.org/ns/auth/acl#') // @@ obsolete - use acl: -thisModule.acl = $rdf.Namespace('http://www.w3.org/ns/auth/acl#') -thisModule.arg = $rdf.Namespace('http://www.w3.org/ns/pim/arg#') -thisModule.cal = $rdf.Namespace('http://www.w3.org/2002/12/cal/ical#') -thisModule.contact = $rdf.Namespace('http://www.w3.org/2000/10/swap/pim/contact#') -thisModule.dc = $rdf.Namespace('http://purl.org/dc/elements/1.1/') -thisModule.dct = $rdf.Namespace('http://purl.org/dc/terms/') -thisModule.doap = $rdf.Namespace('http://usefulinc.com/ns/doap#') -thisModule.foaf = $rdf.Namespace('http://xmlns.com/foaf/0.1/') -thisModule.http = $rdf.Namespace('http://www.w3.org/2007/ont/http#') -thisModule.httph = $rdf.Namespace('http://www.w3.org/2007/ont/httph#') -thisModule.icalTZ = $rdf.Namespace('http://www.w3.org/2002/12/cal/icaltzd#') // Beware: not cal: -thisModule.ldp = $rdf.Namespace('http://www.w3.org/ns/ldp#') -thisModule.link = thisModule.tab = thisModule.tabont = $rdf.Namespace('http://www.w3.org/2007/ont/link#') -thisModule.log = $rdf.Namespace('http://www.w3.org/2000/10/swap/log#') -thisModule.meeting = $rdf.Namespace('http://www.w3.org/ns/pim/meeting#') -thisModule.mo = $rdf.Namespace('http://purl.org/ontology/mo/') -thisModule.owl = $rdf.Namespace('http://www.w3.org/2002/07/owl#') -thisModule.pad = $rdf.Namespace('http://www.w3.org/ns/pim/pad#') -thisModule.patch = $rdf.Namespace('http://www.w3.org/ns/pim/patch#') -thisModule.qu = $rdf.Namespace('http://www.w3.org/2000/10/swap/pim/qif#') -thisModule.trip = $rdf.Namespace('http://www.w3.org/ns/pim/trip#') -thisModule.rdf = $rdf.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') -thisModule.rdfs = $rdf.Namespace('http://www.w3.org/2000/01/rdf-schema#') -thisModule.rss = $rdf.Namespace('http://purl.org/rss/1.0/') -thisModule.sched = $rdf.Namespace('http://www.w3.org/ns/pim/schedule#') -thisModule.schema = $rdf.Namespace('http:/schema.org/') // @@ beware confusion with documents no 303 -thisModule.sioc = $rdf.Namespace('http://rdfs.org/sioc/ns#') -// was - thisModule.xsd = $rdf.Namespace('http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dt-') -thisModule.solid = $rdf.Namespace('http://www.w3.org/ns/solid/terms#') -thisModule.space = $rdf.Namespace('http://www.w3.org/ns/pim/space#') -thisModule.stat = $rdf.Namespace('http://www.w3.org/ns/posix/stat#') -thisModule.ui = $rdf.Namespace('http://www.w3.org/ns/ui#') -thisModule.vcard = $rdf.Namespace('http://www.w3.org/2006/vcard/ns#') -thisModule.wf = $rdf.Namespace('http://www.w3.org/2005/01/wf/flow#') -thisModule.xsd = $rdf.Namespace('http://www.w3.org/2001/XMLSchema#') - -// ends +export default solidNamespace($rdf) diff --git a/src/pad.js b/src/pad.js deleted file mode 100644 index d9ff6aa47..000000000 --- a/src/pad.js +++ /dev/null @@ -1,754 +0,0 @@ - -/// ///////////////////////////////////////////// -// -// The pad widget -// -// See notepad for the main widget - -const $rdf = require('rdflib') -var padModule = module.exports = {} -var UI = { - authn: require('./signin'), - icons: require('./iconBase'), - log: require('./log'), - ns: require('./ns'), - pad: padModule, - rdf: $rdf, - store: require('./store'), - widgets: require('./widgets') -} -const kb = UI.store -const ns = UI.ns - -const utils = require('./utils') - -// Figure out a random color from my webid - -UI.pad.lightColorHash = function (author) { - var hash = function (x) { return x.split('').reduce(function (a, b) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a }, 0) } - return author && author.uri ? '#' + ((hash(author.uri) & 0xffffff) | 0xc0c0c0).toString(16) : '#ffffff' // c0c0c0 forces pale -} // no id -> white - -// Manage participation in this session -// -// This is more general tham the pad. -// -UI.pad.renderPartipants = function (dom, table, padDoc, subject, me, options) { - table.setAttribute('style', 'margin: 0.8em;') - - var newRowForParticpation = function (parp) { - var person = kb.any(parp, ns.wf('participant')) - var bg = kb.anyValue(parp, ns.ui('backgroundColor')) || 'white' - - var block = dom.createElement('div') - block.setAttribute('style', 'height: 1.5em; width: 1.5em; margin: 0.3em; border 0.01em solid #888; background-color: ' + bg) - var tr = UI.widgets.personTR(dom, null, person, options) - table.appendChild(tr) - var td = dom.createElement('td') - td.setAttribute('style', 'vertical-align: middle;') - td.appendChild(block) - tr.insertBefore(td, tr.firstChild) - return tr - } - - var syncTable = function () { - var parps = kb.each(subject, ns.wf('participation')).map(function (parp) { - return [kb.anyValue(parp, UI.ns.cal('dtstart')) || '9999-12-31', parp] - }) - parps.sort() // List in order of joining - var participations = parps.map(function (p) { return p[1] }) - utils.syncTableToArray(table, participations, newRowForParticpation) - } - table.refresh = syncTable - syncTable() - return table -} - -// Record or find an old Particpation objects -UI.pad.participationObject = function (subject, padDoc, me) { - return new Promise(function (resolve, reject) { - if (!me) { - throw new Error('Not user id') - } - - var parps = kb.each(subject, ns.wf('participation')).filter(function (pn) { - return kb.holds(pn, ns.wf('participant'), me) - }) - if (parps.length > 1) { - throw new Error('Multiple records of your participation') - } - if (parps.length) { // If I am not already recorded - resolve(parps[0]) // returns the particpation object - } else { - var participation = UI.widgets.newThing(padDoc) - var ins = [ - UI.rdf.st(subject, ns.wf('participation'), participation, padDoc), - - UI.rdf.st(participation, ns.wf('participant'), me, padDoc), - UI.rdf.st(participation, ns.cal('dtstart'), new Date(), padDoc), - UI.rdf.st(participation, ns.ui('backgroundColor'), UI.pad.lightColorHash(me), padDoc) - ] - kb.updater.update([], ins, function (uri, ok, errorMessage) { - if (!ok) { - reject(new Error('Error recording your partipation: ' + errorMessage)) - } else { - resolve(participation) - } - // UI.pad.renderPartipants(dom, table, padDoc, subject, me, options) - }) - resolve(participation) - } - }) -} - -// Record my participation and display participants -// -UI.pad.recordParticipation = function (subject, padDoc, refreshable) { - var me = UI.authn.currentUser() - if (!me) return // Not logged in - - var parps = kb.each(subject, ns.wf('participation')).filter(function (pn) { - return kb.holds(pn, ns.wf('participant'), me) - }) - if (parps.length > 1) { - throw new Error('Multiple records of your participation') - } - if (parps.length) { // If I am not already recorded - return parps[0] // returns the particpation object - } else { - var participation = UI.widgets.newThing(padDoc) - var ins = [ - UI.rdf.st(subject, ns.wf('participation'), participation, padDoc), - - UI.rdf.st(participation, ns.wf('participant'), me, padDoc), - UI.rdf.st(participation, UI.ns.cal('dtstart'), new Date(), padDoc), - UI.rdf.st(participation, ns.ui('backgroundColor'), UI.pad.lightColorHash(me), padDoc) - ] - kb.updater.update([], ins, function (uri, ok, errorMessage) { - if (!ok) { - throw new Error('Error recording your partipation: ' + errorMessage) - } - if (refreshable && refreshable.refresh) { - refreshable.refresh() - } - // UI.pad.renderPartipants(dom, table, padDoc, subject, me, options) - }) - return participation - } -} - -// Record my participation and display participants -// -UI.pad.manageParticipation = function (dom, container, padDoc, subject, me, options) { - var table = dom.createElement('table') - container.appendChild(table) - UI.pad.renderPartipants(dom, table, padDoc, subject, me, options) - try { - UI.pad.recordParticipation(subject, padDoc, table) - } catch (e) { - container.appendChild(UI.widgets.errorMessageBlock(dom, 'Error recording your partipation: ' + e)) // Clean up? - } - return table -} - -UI.pad.notepad = function (dom, padDoc, subject, me, options) { - options = options || {} - var exists = options.exists - var table = dom.createElement('table') - var kb = UI.store - var ns = UI.ns - - if (me && !me.uri) throw new Error('UI.pad.notepad: Invalid userid') - - var updater = UI.store.updater - - var PAD = $rdf.Namespace('http://www.w3.org/ns/pim/pad#') - - table.setAttribute('style', 'padding: 1em; overflow: auto; resize: horizontal; min-width: 40em;') - - var upstreamStatus = null - var downstreamStatus = null - - if (options.statusArea) { - var t = options.statusArea.appendChild(dom.createElement('table')) - var tr = t.appendChild(dom.createElement('tr')) - upstreamStatus = tr.appendChild(dom.createElement('td')) - downstreamStatus = tr.appendChild(dom.createElement('td')) - upstreamStatus.setAttribute('style', 'width:50%') - downstreamStatus.setAttribute('style', 'width:50%') - } - - var complain = function (message, upstream) { - console.log(message) - if (options.statusArea) { - (upstream ? upstreamStatus : downstreamStatus).appendChild( - UI.widgets.errorMessageBlock(dom, message, 'pink')) - } - } - - var clearStatus = function (upsteam) { - if (options.statusArea) { - options.statusArea.innerHTML = '' - } - } - - var setPartStyle = function (part, colors, pending) { - var chunk = part.subject - colors = colors || '' - var baseStyle = 'font-size: 100%; font-family: monospace; width: 100%; border: none; white-space: pre-wrap;' - var headingCore = 'font-family: sans-serif; font-weight: bold; border: none;' - var headingStyle = [ 'font-size: 110%; padding-top: 0.5em; padding-bottom: 0.5em; width: 100%;', - 'font-size: 120%; padding-top: 1em; padding-bottom: 1em; width: 100%;', - 'font-size: 150%; padding-top: 1em; padding-bottom: 1em; width: 100%;' ] - - var author = kb.any(chunk, ns.dc('author')) - if (!colors && author) { // Hash the user webid for now -- later allow user selection! - var bgcolor = UI.pad.lightColorHash(author) - colors = 'color: ' + (pending ? '#888' : 'black') + '; background-color: ' + bgcolor + ';' - } - - var indent = kb.any(chunk, PAD('indent')) - - indent = indent ? indent.value : 0 - var style = (indent >= 0) // - // baseStyle + 'padding-left: ' + (indent * 3) + 'em;' - ? baseStyle + 'text-indent: ' + (indent * 3) + 'em;' - : headingCore + headingStyle[ -1 - indent ] - part.setAttribute('style', style + colors) - } - - var removePart = function (part) { - var chunk = part.subject - if (!chunk) throw new Error('No chunk for line to be deleted!') // just in case - var prev = kb.any(undefined, PAD('next'), chunk) - var next = kb.any(chunk, PAD('next')) - if (prev.sameTerm(subject) && next.sameTerm(subject)) { // Last one - console.log("You can't delete the only line.") - return - } - - var del = kb.statementsMatching(chunk, undefined, undefined, padDoc) - .concat(kb.statementsMatching(undefined, undefined, chunk, padDoc)) - var ins = [ $rdf.st(prev, PAD('next'), next, padDoc) ] - var label = chunk.uri.slice(-4) - console.log('Deleting line ' + label) - - updater.update(del, ins, function (uri, ok, errorMessage, response) { - if (ok) { - var row = part.parentNode - var before = row.previousSibling - row.parentNode.removeChild(row) - console.log(' deleted line ' + label + ' ok ' + part.value) - if (before && before.firstChild) { - before.firstChild.focus() - } - } else if (response && response.status === 409) { // Conflict - setPartStyle(part, 'color: black; background-color: #ffd;') // yellow - part.state = 0 // Needs downstream refresh - utils.beep(0.5, 512) // Ooops clash with other person - setTimeout(function () { - updater.requestDownstreamAction(padDoc, reloadAndSync) - }, 1000) - } else { - console.log(' removePart FAILED ' + chunk + ': ' + errorMessage) - console.log(" removePart was deleteing :'" + del) - setPartStyle(part, 'color: black; background-color: #fdd;')// failed - let res = response ? response.status : ' [no response field] ' - complain('Error ' + res + ' saving changes: ' + errorMessage.true) // upstream, - // updater.requestDownstreamAction(padDoc, reloadAndSync); - }; - }) - }// removePart - - var changeIndent = function (part, chunk, delta) { - var del = kb.statementsMatching(chunk, PAD('indent')) - var current = del.length ? Number(del[0].object.value) : 0 - if (current + delta < -3) return // limit negative indent - var newIndent = current + delta - var ins = $rdf.st(chunk, PAD('indent'), newIndent, padDoc) - updater.update(del, ins, function (uri, ok, errorBody) { - if (!ok) { - console.log("Indent change FAILED '" + newIndent + "' for " + padDoc + ': ' + errorBody) - setPartStyle(part, 'color: black; background-color: #fdd;') // failed - updater.requestDownstreamAction(padDoc, reloadAndSync) - } else { - setPartStyle(part) // Implement the indent - } - }) - } - - // Use this sort of code to split the line when return pressed in the middle @@ -/* - function doGetCaretPosition doGetCaretPosition (oField) { - var iCaretPos = 0 - // IE Support - if (document.selection) { - // Set focus on the element to avoid IE bug - oField.focus() - - // To get cursor position, get empty selection range - var oSel = document.selection.createRange() - - // Move selection start to 0 position - oSel.moveStart('character', -oField.value.length) - - // The caret position is selection length - iCaretPos = oSel.text.length - - // Firefox suppor - } else if (oField.selectionStart || oField.selectionStart === '0') { - iCaretPos = oField.selectionStart - } - // Return results - return (iCaretPos) - } -*/ - var addListeners = function (part, chunk) { - part.addEventListener('keydown', function (event) { - var queueProperty, queue - // up 38; down 40; left 37; right 39 tab 9; shift 16; escape 27 - switch (event.keyCode) { - case 13: // Return - var before = event.shiftKey - console.log('enter') // Shift-return inserts before -- only way to add to top of pad. - if (before) { - queue = kb.any(undefined, PAD('next'), chunk) - queueProperty = 'newlinesAfter' - } else { - queue = kb.any(chunk, PAD('next')) - queueProperty = 'newlinesBefore' - } - queue[queueProperty] = queue[queueProperty] || 0 - queue[queueProperty] += 1 - if (queue[queueProperty] > 1) { - console.log(' queueing newline queue = ' + queue[queueProperty]) - return - } - console.log(' go ahead line before ' + queue[queueProperty]) - newChunk(part, before) // was document.activeElement - break - - case 8: // Delete - if (part.value.length === 0) { - console.log('Delete key line ' + chunk.uri.slice(-4) + ' state ' + part.state) - - switch (part.state) { - case 1: // contents being sent - case 2: // contents need to be sent again - part.state = 4 // delete me - return - case 3: // being deleted already - case 4: // already deleme state - return - case undefined: - case 0: - part.state = 3 // being deleted - removePart(part) - event.preventDefault() - break // continue - default: - throw new Error('pad: Unexpected state ' + part) - } - } - break - case 9: // Tab - var delta = event.shiftKey ? -1 : 1 - changeIndent(part, chunk, delta) - event.preventDefault() // default is to highlight next field - break - case 27: // ESC - console.log('escape') - updater.requestDownstreamAction(padDoc, reloadAndSync) - event.preventDefault() - break - - case 38: // Up - if (part.parentNode.previousSibling) { - part.parentNode.previousSibling.firstChild.focus() - event.preventDefault() - } - break - - case 40: // Down - if (part.parentNode.nextSibling) { - part.parentNode.nextSibling.firstChild.focus() - event.preventDefault() - } - break - - default: - } - }) - - var updateStore = function (part) { - var chunk = part.subject - setPartStyle(part, undefined, true) - var old = kb.any(chunk, ns.sioc('content')).value - var del = [ $rdf.st(chunk, ns.sioc('content'), old, padDoc) ] - var ins = [ $rdf.st(chunk, ns.sioc('content'), part.value, padDoc) ] - var newOne = part.value - - // DEBUGGING ONLY - if (part.lastSent) { - if (old !== part.lastSent) { - throw new Error("Out of order, last sent expected '" + old + - "' but found '" + part.lastSent + "'") - } - } - part.lastSent = newOne - - console.log(' Patch proposed to ' + chunk.uri.slice(-4) + " '" + old + "' -> '" + newOne + "' ") - updater.update(del, ins, function (uri, ok, errorBody, xhr) { - if (!ok) { - // alert("clash " + errorBody); - console.log(' patch FAILED ' + xhr.status + " for '" + old + "' -> '" + newOne + "': " + errorBody) - if (xhr.status === 409) { // Conflict - @@ we assume someone else - setPartStyle(part, 'color: black; background-color: #fdd;') - part.state = 0 // Needs downstream refresh - utils.beep(0.5, 512) // Ooops clash with other person - setTimeout(function () { - updater.requestDownstreamAction(padDoc, reloadAndSync) - }, 1000) - } else { - setPartStyle(part, 'color: black; background-color: #fdd;') // failed pink - part.state = 0 - complain(' Error ' + xhr.status + ' sending data: ' + errorBody, true) - utils.beep(1.0, 128) // Other - // @@@ Do soemthing more serious with other errors eg auth, etc - } - } else { - clearStatus(true)// upstream - setPartStyle(part) // synced - console.log(" Patch ok '" + old + "' -> '" + newOne + "' ") - - if (part.state === 4) { // delete me - part.state = 3 - removePart(part) - } else if (part.state === 3) { // being deleted - // pass - } else if (part.state === 2) { - part.state = 1 // pending: lock - updateStore(part) - } else { - part.state = 0 // clear lock - } - } - }) - } - - part.addEventListener('input', function inputChangeListener (event) { - // console.log("input changed "+part.value); - setPartStyle(part, undefined, true) // grey out - not synced - console.log('Input event state ' + part.state + " value '" + part.value + "'") - switch (part.state) { - case 3: // being deleted - return - case 4: // needs to be deleted - return - case 2: // needs content updating, we know - return - case 1: - part.state = 2 // lag we need another patch - return - case 0: - case undefined: - part.state = 1 // being upadted - updateStore(part) - } - }) // listener - } // addlisteners - - var newPartAfter = function (tr1, chunk, before) { // @@ take chunk and add listeners - var text = kb.any(chunk, ns.sioc('content')) - text = text ? text.value : '' - var tr = dom.createElement('tr') - if (before) { - table.insertBefore(tr, tr1) - } else { // after - if (tr1 && tr1.nextSibling) { - table.insertBefore(tr, tr1.nextSibling) - } else { - table.appendChild(tr) - } - } - var part = tr.appendChild(dom.createElement('input')) - part.subject = chunk - part.setAttribute('type', 'text') - part.value = text - if (me) { - setPartStyle(part, '') - addListeners(part, chunk) - } else { - setPartStyle(part, 'color: #222; background-color: #111;') - console.log("Note can't add listeners - not logged in") - } - return part - } - - var newChunk = function (ele, before) { // element of chunk being split - var kb = UI.store - var indent = 0 - var queueProperty = null - var here, prev, next, queue, tr1 - - if (ele) { - if (ele.tagName.toLowerCase() !== 'input') { - console.log('return pressed when current document is: ' + ele.tagName) - } - here = ele.subject - indent = kb.any(here, PAD('indent')) - indent = indent ? Number(indent.value) : 0 - if (before) { - prev = kb.any(undefined, PAD('next'), here) - next = here - queue = prev - queueProperty = 'newlinesAfter' - } else { - prev = here - next = kb.any(here, PAD('next')) - queue = next - queueProperty = 'newlinesBefore' - } - tr1 = ele.parentNode - } else { - prev = subject - next = subject - tr1 = undefined - } - - var chunk = UI.widgets.newThing(padDoc) - var label = chunk.uri.slice(-4) - - var del = [$rdf.st(prev, PAD('next'), next, padDoc)] - var ins = [$rdf.st(prev, PAD('next'), chunk, padDoc), - $rdf.st(chunk, PAD('next'), next, padDoc), - $rdf.st(chunk, ns.dc('author'), me, padDoc), - $rdf.st(chunk, ns.sioc('content'), '', padDoc)] - if (indent > 0) { // Do not inherit - ins.push($rdf.st(chunk, PAD('indent'), indent, padDoc)) - } - - console.log(' Fresh chunk ' + label + ' proposed') - updater.update(del, ins, function (uri, ok, errorBody, xhr) { - if (!ok) { - // alert("Error writing new line " + label + ": " + errorBody); - console.log(' ERROR writing new line ' + label + ': ' + errorBody) - } else { - var newPart = newPartAfter(tr1, chunk, before) - setPartStyle(newPart) - newPart.focus() // Note this is delayed - if (queueProperty) { - console.log(' Fresh chunk ' + label + ' updated, queue = ' + queue[queueProperty]) - queue[queueProperty] -= 1 - if (queue[queueProperty] > 0) { - console.log(' Implementing queued newlines = ' + next.newLinesBefore) - newChunk(newPart, before) - } - } - } - }) - } - - var consistencyCheck = function () { - var found = [] - var failed = 0 - function complain2 (msg) { - complain(msg) - failed++ - } - - if (!kb.the(subject, PAD('next'))) { - complain2('No initial next pointer') - return false // can't do linked list - } - // var chunk = kb.the(subject, PAD('next')) - var prev = subject - var chunk - for (;;) { - chunk = kb.the(prev, PAD('next')) - if (!chunk) { - complain2('No next pointer from ' + prev) - } - if (chunk.sameTerm(subject)) { - break - } - prev = chunk - var label = chunk.uri.split('#')[1] - if (found[chunk.uri]) { - complain2('Loop!') - return false - } - - found[chunk.uri] = true - var k = kb.each(chunk, PAD('next')).length - if (k !== 1) complain2('Should be 1 not ' + k + ' next pointer for ' + label) - - k = kb.each(chunk, PAD('indent')).length - if (k > 1) complain2('Should be 0 or 1 not ' + k + ' indent for ' + label) - - k = kb.each(chunk, ns.sioc('content')).length - if (k !== 1) complain2('Should be 1 not ' + k + ' contents for ' + label) - - k = kb.each(chunk, ns.dc('author')).length - if (k !== 1) complain2('Should be 1 not ' + k + ' author for ' + label) - - var sts = kb.statementsMatching(undefined, ns.sioc('contents')) - sts.map(function (st) { - if (!found[st.subject.uri]) { - complain2('Loose chunk! ' + st.subject.uri) - } - }) - } - return !failed - } - - // Ensure that the display matches the current state of the - var sync = function () { - // var first = kb.the(subject, PAD('next')) - if (kb.each(subject, PAD('next')).length !== 1) { - var msg = 'Pad: Inconsistent data - NEXT pointers: ' + - (kb.each(subject, PAD('next')).length) - console.log(msg) - if (options.statusAra) { - options.statusArea.textContent += msg - } - return - } - // var last = kb.the(undefined, PAD('previous'), subject) - // var chunk = first // = kb.the(subject, PAD('next')); - var row - - // First see which of the logical chunks have existing physical manifestations - var manif = [] - // Find which lines correspond to existing chunks - - for (let chunk = kb.the(subject, PAD('next')); - !chunk.sameTerm(subject); - chunk = kb.the(chunk, PAD('next'))) { - for (let i = 0; i < table.children.length; i++) { - var tr = table.children[i] - if (tr.firstChild.subject.sameTerm(chunk)) { - manif[chunk.uri] = tr.firstChild - } - } - } - - // Remove any deleted lines - for (let i = table.children.length - 1; i >= 0; i--) { - row = table.children[i] - if (!manif[row.firstChild.subject.uri]) { - table.removeChild(row) - } - } - // Insert any new lines and update old ones - row = table.firstChild // might be null - for (let chunk = kb.the(subject, PAD('next')); - !chunk.sameTerm(subject); - chunk = kb.the(chunk, PAD('next'))) { - var text = kb.any(chunk, ns.sioc('content')).value - // superstitious -- don't mess with unchanged input fields - // which may be selected by the user - if (row && manif[chunk.uri]) { - var part = row.firstChild - if (text !== part.value) { - part.value = text - } - setPartStyle(part) - part.state = 0 // Clear the state machine - delete part.lastSent // DEBUG ONLY - row = row.nextSibling - } else { - newPartAfter(row, chunk, true) // actually before - } - }; - } - - // Refresh the DOM tree - - var refreshTree = function (root) { - if (root.refresh) { - root.refresh() - return - } - for (var i = 0; i < root.children.length; i++) { - refreshTree(root.children[i]) - } - } - - var reloading = false - - var checkAndSync = function () { - console.log(' reloaded OK') - clearStatus() - if (!consistencyCheck()) { - complain('CONSITENCY CHECK FAILED') - } else { - refreshTree(table) - } - } - - var reloadAndSync = function () { - if (reloading) { - console.log(' Already reloading - stop') - return // once only needed - } - reloading = true - var retryTimeout = 1000 // ms - var tryReload = function () { - console.log('try reload - timeout = ' + retryTimeout) - updater.reload(updater.store, padDoc, function (ok, message, xhr) { - reloading = false - if (ok) { - checkAndSync() - } else { - if (xhr.status === 0) { - complain('Network error refreshing the pad. Retrying in ' + - retryTimeout / 1000) - reloading = true - retryTimeout = retryTimeout * 2 - setTimeout(tryReload, retryTimeout) - } else { - complain('Error ' + xhr.status + 'refreshing the pad:' + - message + '. Stopped. ' + padDoc) - } - } - }) - } - tryReload() - } - - table.refresh = sync // Catch downward propagating refresh events - table.reloadAndSync = reloadAndSync - - if (!me) console.log('Warning: must be logged in for pad to be edited') - - if (exists) { - console.log('Existing pad.') - if (consistencyCheck()) { - sync() - if (kb.holds(subject, PAD('next'), subject)) { // Empty list untenable - newChunk() // require at least one line - } - } else { - console.log(table.textContent = 'Inconsistent data. Abort') - } - } else { // Make new pad - console.log('No pad exists - making new one.') - var insertables = [ - $rdf.st(subject, ns.rdf('type'), PAD('Notepad'), padDoc), - $rdf.st(subject, ns.dc('author'), me, padDoc), - $rdf.st(subject, ns.dc('created'), new Date(), padDoc), - $rdf.st(subject, PAD('next'), subject, padDoc)] - - updater.update([], insertables, function (uri, ok, errorBody) { - if (!ok) { - complain(errorBody) - } else { - console.log('Initial pad created') - newChunk() // Add a first chunck - // getResults(); - } - }) - } - return table -} diff --git a/src/pad.ts b/src/pad.ts new file mode 100644 index 000000000..fca8f8736 --- /dev/null +++ b/src/pad.ts @@ -0,0 +1,908 @@ +/** ************** + * Notepad Widget + */ + +/** @module pad + */ +import ns from './ns' +import { Namespace, NamedNode, st, IndexedFormula } from 'rdflib' +import { newThing, errorMessageBlock } from './widgets' +import { beep } from './utils' +import { log } from './debug' +import { solidLogicSingleton } from 'solid-logic' +import { style } from './style' +export { + renderParticipants, + participationObject, + manageParticipation, + recordParticipation +} from './participation' + +const store = solidLogicSingleton.store + +const PAD = Namespace('http://www.w3.org/ns/pim/pad#') + +type notepadOptions = { + statusArea?: HTMLDivElement + exists?: boolean +} +/** + * @ignore + */ +class NotepadElement extends HTMLElement { + subject?: NamedNode +} +/** + * @ignore + */ +class NotepadPart extends HTMLElement { + subject?: NamedNode | string + value?: string + state?: Number + lastSent?: String +} +/** Figure out a random color from my webid + * + * @param {NamedNode} author - The author of text being displayed + * @returns {String} The CSS color generated, constrained to be light for a background color + */ +export function lightColorHash (author?: NamedNode): string { + const hash = function (x) { + return x.split('').reduce(function (a, b) { + a = (a << 5) - a + b.charCodeAt(0) + return a & a + }, 0) + } + return author && author.uri + ? '#' + ((hash(author.uri) & 0xffffff) | 0xc0c0c0).toString(16) + : '#ffffff' // c0c0c0 forces pale +} // no id -> white + +/** notepad + * + * @param {HTMLDocument} dom - the web page of the browser + * @param {NamedNode} padDoc - the document in which the participation should be shown + * @param {NamedNode} subject - the thing in which participation is happening + * @param {NamedNode} me - person who is logged into the pod + * @param {notepadOptions} options - the options that can be passed in consist of statusArea, exists + */ +export function notepad ( + dom: HTMLDocument, + padDoc: NamedNode, + subject: NamedNode, + me: NamedNode, + options?: notepadOptions +) { + options = options || {} + const exists = options.exists + const table: any = dom.createElement('table') + const kb = store + + if (me && !me.uri) throw new Error('UI.pad.notepad: Invalid userid') + + const updater = store.updater + + const PAD = Namespace('http://www.w3.org/ns/pim/pad#') + + table.setAttribute('style', style.notepadStyle) + + let upstreamStatus: HTMLElement | null = null + let downstreamStatus: HTMLElement | null = null + + if (options.statusArea) { + const t = options.statusArea.appendChild(dom.createElement('table')) + const tr = t.appendChild(dom.createElement('tr')) + upstreamStatus = tr.appendChild(dom.createElement('td')) + downstreamStatus = tr.appendChild(dom.createElement('td')) + + if (upstreamStatus) { + upstreamStatus.setAttribute('style', style.upstreamStatus) + } + if (downstreamStatus) { + downstreamStatus.setAttribute('style', style.downstreamStatus) + } + } + /* @@ TODO want to look into this, it seems upstream should be a boolean and default to false ? + * + */ + const complain = function (message: string, upstream: boolean = false) { + log(message) + if ((options as notepadOptions).statusArea) { + ;(upstream + ? (upstreamStatus as HTMLElement) + : (downstreamStatus as HTMLElement) + ).appendChild(errorMessageBlock(dom, message, 'pink')) + } + } + // @@ TODO need to refactor so that we don't have to type cast + const clearStatus = function (_upsteam?: any) { + if ((options as notepadOptions).statusArea) { + ;((options as notepadOptions).statusArea as HTMLElement).innerHTML = '' + } + } + + const setPartStyle = function ( + part: NotepadPart, + colors?: string, + pending?: any + ) { + const chunk = part.subject + colors = colors || '' + const baseStyle = style.baseStyle + const headingCore = style.headingCore + const headingStyle = style.headingStyle + + const author = kb.any(chunk as any, ns.dc('author')) + if (!colors && author) { + // Hash the user webid for now -- later allow user selection! + const bgcolor = lightColorHash(author as any) + colors = + 'color: ' + + (pending ? '#888' : 'black') + + '; background-color: ' + + bgcolor + + ';' + } + + // @@ TODO Need to research when this can be an object with the indent stored in value + // and when the indent is stored as a Number itself, not in an object. + let indent: any = kb.any(chunk as any, PAD('indent')) + + indent = indent ? indent.value : 0 + const localStyle = + indent >= 0 + ? baseStyle + 'text-indent: ' + indent * 3 + 'em;' + : headingCore + headingStyle[-1 - indent] + // ? baseStyle + 'padding-left: ' + (indent * 3) + 'em;' + part.setAttribute('style', localStyle + colors) + } + + const removePart = function (part: NotepadPart) { + const chunk = part.subject + if (!chunk) throw new Error('No chunk for line to be deleted!') // just in case + const prev: any = kb.any(undefined, PAD('next'), chunk as any) + const next: any = kb.any(chunk as any, PAD('next')) + if (prev.sameTerm(subject) && next.sameTerm(subject)) { + // Last one + log('You can\'t delete the only line.') + return + } + + const del = kb + .statementsMatching(chunk as any, undefined, undefined, padDoc) + .concat(kb.statementsMatching(undefined, undefined, chunk as any, padDoc)) + const ins = [st(prev, PAD('next'), next, padDoc)] + + // @@ TODO what should we do if chunk is not a NamedNode should we + // assume then it is a string? + if (chunk instanceof NamedNode) { + const label = chunk.uri.slice(-4) + + log('Deleting line ' + label) + } + if (!updater) { + throw new Error('have no updater') + } + // @@ TODO below you can see that before is redefined and not a boolean + updater.update(del, ins, function (uri, ok, errorMessage, response) { + if (ok) { + const row = part.parentNode + if (row) { + const before: any = row.previousSibling + if (row.parentNode) { + row.parentNode.removeChild(row) + } + // console.log(' deleted line ' + label + ' ok ' + part.value) + if (before && before.firstChild) { + // @@ TODO IMPORTANT FOCUS ISN'T A PROPERTY ON A CHILDNODE + before.firstChild.focus() + } + } + } else if (response && (response as any).status === 409) { + // Conflict + setPartStyle(part, 'color: black; background-color: #ffd;') // yellow + part.state = 0 // Needs downstream refresh + beep(0.5, 512) // Ooops clash with other person + setTimeout(function () { + // Ideally, beep! @@ + reloadAndSync() // Throw away our changes and + // updater.requestDownstreamAction(padDoc, reloadAndSync) + }, 1000) + } else { + log(' removePart FAILED ' + chunk + ': ' + errorMessage) + log(' removePart was deleting :\'' + del) + setPartStyle(part, 'color: black; background-color: #fdd;') // failed + const res = response + ? (response as any).status + : ' [no response field] ' + complain( + 'Error ' + res + ' saving changes: ' + String(errorMessage) + ) // upstream, + // updater.requestDownstreamAction(padDoc, reloadAndSync); + } + }) + } // removePart + + const changeIndent = function (part: NotepadPart, chunk: string, delta) { + const del = kb.statementsMatching(chunk as any, PAD('indent')) + const current = del.length ? Number(del[0].object.value) : 0 + if (current + delta < -3) return // limit negative indent + const newIndent = current + delta + const ins = st(chunk as any, PAD('indent'), newIndent, padDoc) + if (!updater) { + throw new Error('no updater') + } + updater.update(del, ins as any, function (uri, ok, errorBody) { + if (!ok) { + log( + 'Indent change FAILED \'' + + newIndent + + '\' for ' + + padDoc + + ': ' + + errorBody + ) + setPartStyle(part, 'color: black; background-color: #fdd;') // failed + updater.requestDownstreamAction(padDoc, reloadAndSync) + } else { + setPartStyle(part) // Implement the indent + } + }) + } + + const addListeners = function (part: any, chunk: any) { + let inputDebounceTimer: ReturnType | null = null + part.addEventListener('keydown', function (event) { + if (!updater) { + throw new Error('no updater') + } + + let queueProperty, queue + // up 38; down 40; left 37; right 39 tab 9; shift 16; escape 27 + switch (event.keyCode) { + case 13: { // Return + const before: NotepadElement = event.shiftKey + log('enter') // Shift-return inserts before -- only way to add to top of pad. + if (before) { + queue = kb.any(undefined, PAD('next'), chunk) + queueProperty = 'newlinesAfter' + } else { + queue = kb.any(chunk, PAD('next')) + queueProperty = 'newlinesBefore' + } + queue[queueProperty] = queue[queueProperty] || 0 + queue[queueProperty] += 1 + if (queue[queueProperty] > 1) { + log(' queueing newline queue = ' + queue[queueProperty]) + return + } + log(' go ahead line before ' + queue[queueProperty]) + newChunk(part, before) // was document.activeElement + break + } + case 8: // Delete + if (part.value.length === 0) { + log( + 'Delete key line ' + chunk.uri.slice(-4) + ' state ' + part.state + ) + + switch (part.state) { + case 1: // contents being sent + case 2: // contents need to be sent again + part.state = 4 // delete me + return + case 3: // already being deleted + case 4: // already deleted state + return + case undefined: + case 0: + part.state = 3 // being deleted + removePart(part) + event.preventDefault() + break // continue + default: + throw new Error('pad: Unexpected state ' + part) + } + } + break + case 9: { // Tab + const delta = event.shiftKey ? -1 : 1 + changeIndent(part, chunk, delta) + event.preventDefault() // default is to highlight next field + break + } + case 27: // ESC + log('escape') + updater.requestDownstreamAction(padDoc, reloadAndSync) + event.preventDefault() + break + + case 38: // Up + if (part.parentNode.previousSibling) { + part.parentNode.previousSibling.firstChild.focus() + event.preventDefault() + } + break + + case 40: // Down + if (part.parentNode.nextSibling) { + part.parentNode.nextSibling.firstChild.focus() + event.preventDefault() + } + break + + default: + } + }) + + const updateStore = function (part: NotepadPart) { + const chunk: any = part.subject + setPartStyle(part, undefined, true) + const old = (kb.any(chunk, ns.sioc('content')) as any).value + const del = [st(chunk, ns.sioc('content'), old, padDoc)] + let ins + if (part.value) { + ins = [st(chunk, ns.sioc('content'), part.value as any, padDoc)] + } + const newOne = part.value + + // DEBUGGING ONLY + if (part.lastSent) { + if (old !== part.lastSent) { + // Non-fatal: log a warning instead of throwing, to avoid crashing the pad UI. + console.warn( + 'Out of order, last sent expected \'' + + old + + '\' but found \'' + + part.lastSent + + '\'' + ) + } + } + part.lastSent = newOne + + /* console.log( + ' Patch proposed to ' + + chunk.uri.slice(-4) + + " '" + + old + + "' -> '" + + newOne + + "' " + ) */ + if (!updater) { + throw new Error('no updater') + } + + updater.update(del, ins, function (uri, ok, errorBody, xhr) { + if (!ok) { + // alert("clash " + errorBody); + log( + ' patch FAILED ' + + (xhr as any).status + + ' for \'' + + old + + '\' -> \'' + + newOne + + '\': ' + + errorBody + ) + if ((xhr as any).status === 409) { + // Conflict - @@ we assume someone else + setPartStyle(part, 'color: black; background-color: #fdd;') + part.state = 0 // Needs downstream refresh + beep(0.5, 512) // Ooops clash with other person + setTimeout(function () { + updater.requestDownstreamAction(padDoc, reloadAndSync) + }, 1000) + } else { + setPartStyle(part, 'color: black; background-color: #fdd;') // failed pink + const status = (xhr as any)?.status + if (!status || status === 502 || status === 503) { + // Transient server error – retry after a short delay + part.lastSent = undefined + part.state = 0 + setTimeout(() => { + if (part.state === 0 || part.state === undefined) { + part.state = 1 + updateStore(part) + } + }, 2000) + } else { + part.state = 0 + complain( + ' Error ' + status + ' sending data: ' + errorBody, + true + ) + beep(1.0, 128) // Other + // @@@ Do something more serious with other errors eg auth, etc + } + } + } else { + clearStatus(true) // upstream + setPartStyle(part) // synced + log(' Patch ok \'' + old + '\' -> \'' + newOne + '\' ') + + if (part.state === 4) { + // delete me + part.state = 3 + removePart(part) + } else if (part.state === 3) { + // being deleted + // pass + } else if (part.state === 2) { + part.state = 1 // pending: lock + updateStore(part) + } else { + part.state = 0 // clear lock + } + } + }) + } + + part.addEventListener('input', function inputChangeListener (_event) { + // debug.log("input changed "+part.value); + setPartStyle(part, undefined, true) // grey out - not synced + log('Input event state ' + part.state + ' value \'' + part.value + '\'') + switch (part.state) { + case 3: // being deleted + return + case 4: // needs to be deleted + return + case 2: // needs content updating, we know + return + case 1: + part.state = 2 // lag we need another patch + return + case 0: + case undefined: + // Debounce: wait for a pause in typing before sending PATCH + if (inputDebounceTimer !== null) clearTimeout(inputDebounceTimer) + inputDebounceTimer = setTimeout(() => { + inputDebounceTimer = null + if (part.state === 0 || part.state === undefined) { + part.state = 1 // being updated + updateStore(part) + } + }, 400) + } + }) // listener + } // addlisteners + + // @@ TODO Need to research before as it appears to be used as an Element and a boolean + const newPartAfter = function ( + tr1: HTMLTableElement, + chunk: String, + before?: NotepadElement | boolean + ) { + // @@ take chunk and add listeners + let text: any = kb.any(chunk as any, ns.sioc('content')) + text = text ? text.value : '' + const tr = dom.createElement('tr') + if (before) { + table.insertBefore(tr, tr1) + } else { + // after + if (tr1 && tr1.nextSibling) { + table.insertBefore(tr, tr1.nextSibling) + } else { + table.appendChild(tr) + } + } + const part: any = tr.appendChild(dom.createElement('input')) + part.subject = chunk + part.setAttribute('type', 'text') + part.value = text + if (me) { + setPartStyle(part, '') + addListeners(part, chunk) + } else { + setPartStyle(part, 'color: #222; background-color: #fff') + log('Note can\'t add listeners - not logged in') + } + return part + } + + /* @@ TODO we need to look at indent, it can be a Number or an Object this doesn't seem correct. + */ + const newChunk = function (ele?: NotepadElement, before?: NotepadElement) { + // element of chunk being split + const kb = store + let indent: any = 0 + let queueProperty: string | null = null + let here, prev, next, queue, tr1: any + + if (ele) { + if (ele.tagName.toLowerCase() !== 'input') { + log('return pressed when current document is: ' + ele.tagName) + } + here = ele.subject + indent = kb.any(here, PAD('indent')) + indent = indent ? Number(indent.value) : 0 + if (before) { + prev = kb.any(undefined, PAD('next'), here) + next = here + queue = prev + queueProperty = 'newlinesAfter' + } else { + prev = here + next = kb.any(here, PAD('next')) + queue = next + queueProperty = 'newlinesBefore' + } + tr1 = ele.parentNode + } else { + prev = subject + next = subject + tr1 = undefined + } + + const chunk = newThing(padDoc) + const label = chunk.uri.slice(-4) + + const del = [st(prev, PAD('next'), next, padDoc)] + const ins = [ + st(prev, PAD('next'), chunk, padDoc), + st(chunk, PAD('next'), next, padDoc), + st(chunk, ns.dc('author'), me, padDoc), + st(chunk, ns.sioc('content'), '' as any, padDoc) + ] + if (indent > 0) { + // Do not inherit + ins.push(st(chunk, PAD('indent'), indent, padDoc)) + } + + log(' Fresh chunk ' + label + ' proposed') + if (!updater) { + throw new Error('no updater') + } + updater.update(del, ins, function (uri, ok, errorBody, _xhr) { + if (!ok) { + // alert("Error writing new line " + label + ": " + errorBody); + log(' ERROR writing new line ' + label + ': ' + errorBody) + } else { + const newPart = newPartAfter(tr1, chunk, before) + setPartStyle(newPart) + newPart.focus() // Note this is delayed + if (queueProperty) { + log( + ' Fresh chunk ' + + label + + ' updated, queue = ' + + queue[queueProperty] + ) + queue[queueProperty] -= 1 + if (queue[queueProperty] > 0) { + log(' Implementing queued newlines = ' + next.newLinesBefore) + newChunk(newPart, before) + } + } + } + }) + } + + const consistencyCheck = function () { + const found: { [uri: string]: boolean } = {} + let failed = 0 + function complain2 (msg) { + complain(msg) + failed++ + } + + if (!kb.the(subject, PAD('next'))) { + complain2('No initial next pointer') + return false // can't do linked list + } + // var chunk = kb.the(subject, PAD('next')) + let prev = subject + let chunk + for (;;) { + chunk = kb.the(prev, PAD('next')) + if (!chunk) { + complain2('No next pointer from ' + prev) + } + if (chunk.sameTerm(subject)) { + break + } + prev = chunk + const label = chunk.uri.split('#')[1] + if (found[chunk.uri]) { + complain2('Loop!') + return false + } + + found[chunk.uri] = true + let k = kb.each(chunk, PAD('next')).length + if (k !== 1) { + complain2('Should be 1 not ' + k + ' next pointer for ' + label) + } + + k = kb.each(chunk, PAD('indent')).length + if (k > 1) { + complain2('Should be 0 or 1 not ' + k + ' indent for ' + label) + } + + k = kb.each(chunk, ns.sioc('content')).length + if (k !== 1) { + complain2('Should be 1 not ' + k + ' contents for ' + label) + } + + k = kb.each(chunk, ns.dc('author')).length + if (k !== 1) { + complain2('Should be 1 not ' + k + ' author for ' + label) + } + + const sts = kb.statementsMatching(undefined, ns.sioc('contents')) + sts.forEach(function (st) { + if (!found[st.subject.value]) { + complain2('Loose chunk! ' + st.subject.value) + } + }) + } + return !failed + } + + // Ensure that the display matches the current state of the + // @@ TODO really need to refactor this so that we don't need to cast types + const sync = function () { + // var first = kb.the(subject, PAD('next')) + if (kb.each(subject, PAD('next')).length !== 1) { + const msg = + 'Pad: Inconsistent data - NEXT pointers: ' + + kb.each(subject, PAD('next')).length + log(msg) + if ((options as notepadOptions).statusArea) { + ;((options as notepadOptions).statusArea as HTMLElement).textContent += + msg + } + return + } + let row + + // First see which of the logical chunks have existing physical manifestations + const manif: any = [] + // Find which lines correspond to existing chunks + + for ( + let chunk = kb.the(subject, PAD('next')) as unknown as any; + !chunk.sameTerm(subject); + chunk = kb.the(chunk, PAD('next')) + ) { + for (let i = 0; i < table.children.length; i++) { + const tr: any = table.children[i] + if (tr.firstChild) { + if (tr.firstChild.subject.sameTerm(chunk)) { + manif[chunk.uri] = tr.firstChild + } + } + } + } + + // Remove any deleted lines + for (let i = table.children.length - 1; i >= 0; i--) { + row = table.children[i] + if (!manif[row.firstChild.subject.uri]) { + table.removeChild(row) + } + } + // Insert any new lines and update old ones + row = table.firstChild // might be null + for ( + let chunk = kb.the(subject, PAD('next')) as unknown as any; + !chunk.sameTerm(subject); + chunk = kb.the(chunk, PAD('next')) + ) { + const text = (kb.any(chunk, ns.sioc('content')) as any).value + // superstitious -- don't mess with unchanged input fields + // which may be selected by the user + if (row && manif[chunk.uri]) { + const part = row.firstChild + if (text !== part.value) { + part.value = text + } + setPartStyle(part) + part.state = 0 // Clear the state machine + delete part.lastSent // DEBUG ONLY + row = row.nextSibling + } else { + newPartAfter(row, chunk, true) // actually before + } + } + } + + // Refresh the DOM tree + + const refreshTree = function (root) { + if (root.refresh) { + root.refresh() + return + } + for (let i = 0; i < root.children.length; i++) { + refreshTree(root.children[i]) + } + } + + let reloading = false + + const checkAndSync = function () { + log(' reloaded OK') + clearStatus() + if (!consistencyCheck()) { + complain('CONSISTENCY CHECK FAILED') + } else { + refreshTree(table) + } + } + + const reloadAndSync = function () { + if (reloading) { + log(' Already reloading - stop') + return // once only needed + } + reloading = true + let retryTimeout = 1000 // ms + const tryReload = function () { + log('try reload - timeout = ' + retryTimeout) + if (!updater) { + throw new Error('no updater') + } + updater.reload(updater.store, padDoc, function (ok, message, xhr) { + reloading = false + if (ok) { + checkAndSync() + } else { + if ((xhr as any).status === 0) { + complain( + 'Network error refreshing the pad. Retrying in ' + + retryTimeout / 1000 + ) + reloading = true + retryTimeout = retryTimeout * 2 + setTimeout(tryReload, retryTimeout) + } else { + complain( + 'Error ' + + (xhr as any).status + + 'refreshing the pad:' + + message + + '. Stopped. ' + + padDoc + ) + } + } + }) + } + tryReload() + } + + table.refresh = sync // Catch downward propagating refresh events + table.reloadAndSync = reloadAndSync + + if (!me) log('Warning: must be logged in for pad to be edited') + + if (exists) { + log('Existing pad.') + if (consistencyCheck()) { + sync() + if (kb.holds(subject, PAD('next'), subject)) { + // Empty list untenable + newChunk() // require at least one line + } + } else { + log((table.textContent = 'Inconsistent data. Abort')) + } + } else { + // Make new pad + log('No pad exists - making new one.') + const insertables = [ + st(subject, ns.rdf('type'), PAD('Notepad'), padDoc), + st(subject, ns.dc('author'), me, padDoc), + st(subject, ns.dc('created'), new Date() as any, padDoc), + st(subject, PAD('next'), subject, padDoc) + ] + + if (!updater) { + throw new Error('no updater') + } + updater.update( + [], + insertables, + function ( + uri: string | null | undefined, + ok: boolean, + errorBody?: string + ) { + if (!ok) { + complain(errorBody || '') + } else { + log('Initial pad created') + newChunk() // Add a first chunck + // getResults(); + } + } + ) + } + return table +} + +/** + * Get the chunks of the notepad + * They are stored in a RDF linked list + */ + +// @ignore exporting this only for the unit test +export function getChunks (subject: NamedNode, kb: IndexedFormula) { + const chunks: any[] = [] + for ( + let chunk: any = kb.the(subject, PAD('next')); + !chunk.sameTerm(subject); + chunk = kb.the(chunk, PAD('next')) + ) { + chunks.push(chunk) + } + return chunks +} + +/** + * Encode content to be put in XML or HTML elements + */ +// @ignore exporting this only for the unit test +export function xmlEncode (str) { + return str.replace('&', '&').replace('<', '<').replace('>', '>') +} + +/** + * Convert a notepad to HTML + * @param { } pad - the notepad + * @param {store} pad - the data store + */ +export function notepadToHTML (pad: any, kb: IndexedFormula) { + const chunks = getChunks(pad, kb) + let html = '\n \n' + const title = kb.anyValue(pad, ns.dct('title')) + if (title) { + html += ` ${xmlEncode(title)}\n` + } + html += ' \n \n' + let level = 0 + + function increaseLevel (indent) { + for (; level < indent; level++) { + html += '
    \n' + } + } + + function decreaseLevel (indent) { + for (; level > indent; level--) { + html += '
\n' + } + } + chunks.forEach((chunk) => { + const indent = kb.anyJS(chunk, PAD('indent')) + const rawContent = kb.anyJS(chunk, ns.sioc('content')) + if (!rawContent) return // seed chunk is dummy + const content = xmlEncode(rawContent) + if (indent < 0) { + // negative indent levels represent heading levels + decreaseLevel(0) + const h = indent >= -3 ? 4 + indent : 1 // -1 -> h4, -2 -> h3 + html += `\n${content}\n` + } else { + // >= 0 + if (indent > 0) { + // Lists + decreaseLevel(indent) + increaseLevel(indent) + html += `
  • ${content}
  • \n` + } else { + // indent 0 + decreaseLevel(indent) + html += `

    ${content}

    \n` + } + } + }) // foreach chunk + // At the end decreaseLevel any open ULs + decreaseLevel(0) + html += ' \n\n' + return html +} diff --git a/src/participation.ts b/src/participation.ts new file mode 100644 index 000000000..fd3ac40b3 --- /dev/null +++ b/src/participation.ts @@ -0,0 +1,223 @@ +/* Manage a UI for the participation of a person in any thing +*/ + +// import { currentUser } from './authn/authn' +import * as debug from './debug' +import { LiveStore, NamedNode, st, UpdateManager } from 'rdflib' +import ns from './ns' +import { personTR, newThing, errorMessageBlock } from './widgets' +import { syncTableToArray } from './utils' +import { lightColorHash } from './pad' +import { log } from './debug' +import { style } from './style' +import styleConstants from './styleConstants' +import { solidLogicSingleton, authn } from 'solid-logic' + +type ParticipationOptions = { + deleteFunction?: () => {} + link?: string + draggable?: boolean +} + +class ParticipationTableElement extends HTMLTableElement { + refresh?: () => void +} +const store = solidLogicSingleton.store as LiveStore + +/** Manage participation in this session +* +* @param {Document} dom - the web page loaded into the browser +* @param {HTMLTableElement} table - the table element +* @param {NamedNode} unused1/document - the document to render (this argument is no longer used, but left in for backwards compatibility) +* @param {NamedNode} subject - the thing in which the participation is happening +* @param {NamedNode} unused2/me - user that is logged into the pod (this argument is no longer used, but left in for backwards compatibility) +* @param {ParticipationOptions} options - the options that can be passed in are deleteFunction, link, and draggable; these are used by the personTR button +*/ +export function renderParticipants (dom: HTMLDocument, table: ParticipationTableElement, unused1: NamedNode, subject: NamedNode, unused2: NamedNode, options: ParticipationOptions) { + table.setAttribute('style', style.participantsStyle) + + const newRowForParticipation = function (parp) { + const person = store.any(parp, ns.wf('participant')) + + let tr + if (!person) { + tr = dom.createElement('tr') + tr.textContent = '???' // Don't crash - invalid part'n entry + return tr + } + const bg = store.anyValue(parp, ns.ui('backgroundColor')) || styleConstants.participationDefaultBackground + + const block = dom.createElement('div') + block.setAttribute( + 'style', style.participantsBlock) + block.style.backgroundColor = bg + + tr = personTR(dom, null, person, options) + table.appendChild(tr) + const td = dom.createElement('td') + td.setAttribute('style', style.personTableTD) + td.appendChild(block) + tr.insertBefore(td, tr.firstChild) + return tr + } + + const syncTable = function () { + const parps = store.each(subject, ns.wf('participation')).map(function (parp) { + log('in participants') + return [store.anyValue(parp as any, ns.cal('dtstart')) || '9999-12-31', parp] + }) + parps.sort() // List in order of joining + const participations = parps.map(function (p) { + return p[1] + }) + syncTableToArray(table, participations, newRowForParticipation) + } + table.refresh = syncTable + syncTable() + return table +} + +/** Record, or find old, Participation object + * + * A participation object is a place to record things specifically about + * subject and the user, such as preferences, start of membership, etc + * @param {NamedNode} subject - the thing in which the participation is happening + * @param {NamedNode} document - where to record the data + * @param {NamedNode} me - the logged in user + * + */ +export function participationObject (subject: NamedNode, padDoc: NamedNode, me: NamedNode) { + return new Promise(function (resolve, reject) { + if (!me) { + throw new Error('No user id') + } + + const parps = store.each(subject, ns.wf('participation')).filter(function (pn) { + return store.holds(pn, ns.wf('participant'), me) + }) + if (parps.length > 1) { // This can happen. https://github.com/solidos/chat-pane/issues/71 + const candidates: (string | NamedNode) [][] = [] + for (const participation of parps) { + const date = store.anyValue(participation as NamedNode, ns.cal('dtstart')) + if (date) { + candidates.push([date, participation as NamedNode]) + } + } + candidates.sort() // Pick the earliest + // @@ Possibly, for extra credit, delete the others, if we have write access + debug.warn('Multiple participation objects, picking earliest, in ' + padDoc) + resolve(candidates[0][1]) + // throw new Error('Multiple records of your participation') + } + if (parps.length) { + // If I am not already recorded + resolve(parps[0]) // returns the participation object + } else { + const participation = newThing(padDoc) + const ins = [ + st(subject, ns.wf('participation'), participation, padDoc), + + st(participation, ns.wf('participant'), me, padDoc), + st(participation, ns.cal('dtstart'), new Date() as any, padDoc), + st( + participation, + ns.ui('backgroundColor'), + lightColorHash(me) as any, + padDoc + ) + ]; + (store.updater as UpdateManager).update([], ins, function (uri: string | null | undefined, ok: boolean, errorMessage?: string) { + if (!ok) { + reject(new Error('Error recording your participation: ' + errorMessage)) + } else { + resolve(participation) + } + }) + resolve(participation) + } + }) +} + +/** Record my participation and display participants + * + * @param {NamedNode} subject - the thing in which participation is happening + * @param {NamedNode} padDoc - the document into which the participation should be recorded + * @param {DOMNode} refreshable - a DOM element whose refresh() is to be called if the change works + * + */ +export function recordParticipation (subject: NamedNode, padDoc: NamedNode, refreshable: any) { + const me = authn.currentUser() + if (!me) return // Not logged in + + const parps = store.each(subject, ns.wf('participation')).filter(function (pn) { + return store.holds(pn, ns.wf('participant'), me) + }) + if (parps.length > 1) { + throw new Error('Multiple records of your participation') + } + if (parps.length) { + // If I am not already recorded + return parps[0] // returns the participation object + } else { + if (!(store.updater as UpdateManager).editable(padDoc)) { + debug.log('Not recording participation, as no write access as ' + me + ' to ' + padDoc) + return null + } + const participation = newThing(padDoc) + const ins = [ + st(subject, ns.wf('participation'), participation, padDoc), + + st(participation, ns.wf('participant'), me, padDoc), + st(participation, ns.cal('dtstart'), new Date() as any, padDoc), + st( + participation, + ns.ui('backgroundColor'), + lightColorHash(me) as any, + padDoc + ) + ]; + (store.updater as UpdateManager).update([], ins, function (uri: string | null | undefined, ok: boolean, errorMessage?: string) { + if (!ok) { + throw new Error('Error recording your participation: ' + errorMessage) + } + if (refreshable && refreshable.refresh) { + refreshable.refresh() + } + }) + return participation + } +} + +/** Record my participation and display participants +* +* @param {Document} dom - the web page loaded into the browser +* @param {HTMLDivElement} container - the container element where the participants should be displayed +* @param {NamedNode} document - the document into which the participation should be shown +* @param {NamedNode} subject - the thing in which participation is happening +* @param {NamedNode} me - the logged in user +* @param {ParticipationOptions} options - the options that can be passed in are deleteFunction, link, and draggable; these are used by the personTR button +* +*/ +export function manageParticipation ( + dom: Document, + container: HTMLDivElement, + padDoc: NamedNode, + subject: NamedNode, + me: NamedNode, + options: ParticipationOptions +) { + const table = dom.createElement('table') + container.appendChild(table) + renderParticipants(dom, table, padDoc, subject, me, options) + try { + recordParticipation(subject, padDoc, table) + } catch (e) { + container.appendChild( + errorMessageBlock( + dom, + 'Error recording your participation: ' + e + ) + ) // Clean up? + } + return table +} diff --git a/src/preferences.js b/src/preferences.js index c486877fb..6f48963ed 100644 --- a/src/preferences.js +++ b/src/preferences.js @@ -1,44 +1,58 @@ -// Solid-UI temporary preferences -// ============================== +// Solid-UI preferences +// ===================== // -const kb = require('./store') -const ns = require('./ns') -const authn = require('./signin') -const widgets = require('./widgets') -const pad = require('./pad') + +import * as $rdf from 'rdflib' // pull in first avoid cross-refs +import { store } from 'solid-logic' +import * as debug from './debug' +import { ensureLoadedPreferences } from './login/login' +import ns from './ns' +import * as participation from './participation' // @ts-ignore +import * as widgets from './widgets' + +const kb = store // This was tabulator . preferences in the tabulator +// Is this functionality used anywhere? // -module.exports = { // used for storing user name - value: [], - get: function (k) { // original - return this.value[k] - }, - set: function (k, v) { - if (typeof v !== 'string') { - console.log('Non-string value of preference ' + k + ': ' + v) - throw new Error('Non-string value of preference ' + k + ': ' + v) - } - this.value[k] = v - }, - renderPreferencesForm, - recordSharedPreferences, - getPreferencesForClass + +// used for storing user name +// @@ Deprocate these functions. They were used for +// communication around the tabulator functionality about the user session + +export const value = [] +export function get (k) { + return value[k] } + +export function set (k, v) { + if (typeof v !== 'string') { + debug.log('Non-string value of preference ' + k + ': ' + v) + throw new Error('Non-string value of preference ' + k + ': ' + v) + } + this.value[k] = v +} + // In a solid world, Preferences are stored in the web // // Make an RDF node for recording the common view preferences for any object // (maybe make it in a separate file?) -function recordSharedPreferences (subject, context) { +export function recordSharedPreferences (subject, context) { return new Promise(function (resolve, reject) { - var sharedPreferences = kb.any(subject, ns.ui('sharedPreferences')) + const sharedPreferences = kb.any(subject, ns.ui('sharedPreferences')) if (!sharedPreferences) { - let sp = $rdf.sym(subject.doc().uri + '#SharedPreferences') - let ins = [$rdf.st(subject, ns.ui('sharedPreferences'), sp, subject.doc())] - console.log('Creating shared preferences ' + sp) + if (!kb.updater.editable(subject.doc())) { + debug.log(` Cant make shared preferences, may not change ${subject.doc}`) + resolve(context) + } + const sp = $rdf.sym(subject.doc().uri + '#SharedPreferences') + const ins = [ + $rdf.st(subject, ns.ui('sharedPreferences'), sp, subject.doc()) + ] + debug.log('Creating shared preferences ' + sp) kb.updater.update([], ins, function (uri, ok, errorMessage) { if (!ok) { - reject(new Error('create shard prefs: ' + errorMessage)) + reject(new Error('Error creating shared prefs: ' + errorMessage)) } else { context.sharedPreferences = sp resolve(context) @@ -53,73 +67,139 @@ function recordSharedPreferences (subject, context) { // Construct a personal defaults node in the preferences file for a given class of object // -function recordPersonalDefaults (klass, context) { +export function recordPersonalDefaults (theClass, context) { return new Promise(function (resolve, reject) { - authn.logInLoadPreferences(context).then(context => { - var regs = kb.each(null, ns.solid('forClass'), klass) - var ins = [] - var prefs - var reg - if (regs.length) { // Use existing node is we can - regs.forEach(r => { - prefs = prefs || kb.any(r, ns.solid('personalDefaults')) - }) - if (prefs) { - context.personalDefaults = prefs // Found one - resolve(context) - } else { - prefs = widgets.newThing(context.preferencesFile) - reg = regs[0] + ensureLoadedPreferences(context).then( + context => { + if (!context.preferencesFile) { + debug.log( + 'Not doing private class preferences as no access to preferences file. ' + + context.preferencesFileError + ) + return } - } else { // no regs fo class - reg = widgets.newThing(context.preferencesFile) - ins = [ $rdf.st(reg, ns.rdf('type'), ns.solid('Registration'), context.preferencesFile), - $rdf.st(reg, ns.solid('forClass'), klass, context.preferencesFile)] - } - prefs = widgets.newThing(context.preferencesFile) - ins.push($rdf.st(reg, ns.solid('personalDefaults'), prefs, context.preferencesFile)) - kb.updater.update([], ins, function (uri, ok, errm) { - if (!ok) { - reject(new Error('Setting preferences for ' + klass + ': ' + errm)) + const regs = kb.each( + null, + ns.solid('forClass'), + theClass, + context.preferencesFile + ) + let ins = [] + let prefs + let reg + if (regs.length) { + // Use existing node if we can + regs.forEach(r => { + prefs = prefs || kb.any(r, ns.solid('personalDefaults')) + }) + if (prefs) { + context.personalDefaults = prefs // Found one + resolve(context) + return + } else { + prefs = widgets.newThing(context.preferencesFile) + reg = regs[0] + } } else { - context.personalDefaults = prefs - resolve(context) + // no regs fo class + reg = widgets.newThing(context.preferencesFile) + ins = [ + $rdf.st( + reg, + ns.rdf('type'), + ns.solid('TypeRegistration'), + context.preferencesFile + ), + $rdf.st(reg, ns.solid('forClass'), theClass, context.preferencesFile) + ] } - }) - }, err => { - reject(err) - }) + prefs = widgets.newThing(context.preferencesFile) + ins.push( + $rdf.st( + reg, + ns.solid('personalDefaults'), + prefs, + context.preferencesFile + ) + ) + kb.updater.update([], ins, function (uri, ok, errm) { + if (!ok) { + reject(new Error('Setting preferences for ' + theClass + ': ' + errm)) + } else { + context.personalDefaults = prefs + resolve(context) + } + }) + }, + err => { + reject(err) + } + ) }) } -function renderPreferencesForm (subject, klass, preferencesForm, context) { - var prefContainer = context.dom.createElement('div') - pad.participationObject(subject, subject.doc(), context.me).then(participation => { - let dom = context.dom - function heading (text) { - prefContainer.appendChild(dom.createElement('h5')).textContent = text - } - heading('My view of this ' + context.noun) - widgets.appendForm(dom, prefContainer, {}, participation, preferencesForm, subject.doc(), - (ok, mes) => { if (!ok) widgets.complain(context, mes) }) +export function renderPreferencesForm (subject, theClass, preferencesForm, context) { + const prefContainer = context.dom.createElement('div') + participation.participationObject(subject, subject.doc(), context.me).then( + participation => { + const dom = context.dom + function heading (text) { + prefContainer.appendChild(dom.createElement('h5')).textContent = text + } + heading('My view of this ' + context.noun) + widgets.appendForm( + dom, + prefContainer, + {}, + participation, + preferencesForm, + subject.doc(), + (ok, mes) => { + if (!ok) widgets.complain(context, mes) + } + ) - heading('Everyone\'s view of this ' + context.noun) - recordSharedPreferences(subject, context).then(context => { - var sharedPreferences = context.sharedPreferences - widgets.appendForm(dom, prefContainer, {}, sharedPreferences, preferencesForm, subject.doc(), - (ok, mes) => { if (!ok) widgets.complain(context, mes) }) + heading('Everyone\'s view of this ' + context.noun) + recordSharedPreferences(subject, context).then(context => { + const sharedPreferences = context.sharedPreferences + widgets.appendForm( + dom, + prefContainer, + {}, + sharedPreferences, + preferencesForm, + subject.doc(), + (ok, mes) => { + if (!ok) widgets.complain(context, mes) + } + ) - heading('My default view of any ' + context.noun) - recordPersonalDefaults(klass, context).then(context => { - widgets.appendForm(dom, prefContainer, {}, context.personalDefaults, preferencesForm, context.preferencesFile, - (ok, mes) => { if (!ok) widgets.complain(context, mes) }) - }, err => { - widgets.complain(context, err) + heading('My default view of any ' + context.noun) + recordPersonalDefaults(theClass, context).then( + context => { + widgets.appendForm( + dom, + prefContainer, + {}, + context.personalDefaults, + preferencesForm, + context.preferencesFile, + (ok, mes) => { + if (!ok) widgets.complain(context, mes) + } + ) + }, + err => { + widgets.complain(context, err) + } + ) }) - }) - }, err => { // parp object fails - prefContainer.appendChild(widgets.errorMessageBlock(context.dom, err)) - }) + }, + err => { + // parp object fails + prefContainer.appendChild(widgets.errorMessageBlock(context.dom, err)) + } + ) return prefContainer } @@ -130,8 +210,10 @@ function toJS (term) { if (term.datatype.equals(ns.xsd('boolean'))) { return term.value === '1' } - if (term.datatype.equals(ns.xsd('dateTime')) || - term.datatype.equals(ns.xsd('date'))) { + if ( + term.datatype.equals(ns.xsd('dateTime')) || + term.datatype.equals(ns.xsd('date')) + ) { return new Date(term.value) } if ( @@ -147,29 +229,35 @@ function toJS (term) { // This is the function which acuakly reads and combines the preferences // // @@ make it much more tolerant of missing buts of prefernces -function getPreferencesForClass (subject, klass, predicates, context) { +export function getPreferencesForClass (subject, theClass, predicates, context) { return new Promise(function (resolve, reject) { recordSharedPreferences(subject, context).then(context => { - var sharedPreferences = context.sharedPreferences + const sharedPreferences = context.sharedPreferences if (context.me) { - pad.participationObject(subject, subject.doc(), context.me).then(participation => { - recordPersonalDefaults(klass, context).then(context => { - var results = [] - var personalDefaults = context.personalDefaults - predicates.forEach(pred => { - // Order of preference: My settings on object, Global settings on object, my settings on class - let v1 = kb.any(participation, pred) || kb.any(sharedPreferences, pred) || kb.any(personalDefaults, pred) - if (v1) { - results[pred.uri] = toJS(v1) - } - }) - resolve(results) + participation + .participationObject(subject, subject.doc(), context.me) + .then(participation => { + recordPersonalDefaults(theClass, context).then(context => { + const results = [] + const personalDefaults = context.personalDefaults + predicates.forEach(pred => { + // Order of preference: My settings on object, Global settings on object, my settings on class + const v1 = + kb.any(participation, pred) || + kb.any(sharedPreferences, pred) || + kb.any(personalDefaults, pred) + if (v1) { + results[pred.uri] = toJS(v1) + } + }) + resolve(results) + }, reject) }, reject) - }, reject) - } else { // no user defined, just use common prefs - var results = [] + } else { + // no user defined, just use common prefs + const results = [] predicates.forEach(pred => { - let v1 = kb.any(sharedPreferences, pred) + const v1 = kb.any(sharedPreferences, pred) if (v1) { results[pred.uri] = toJS(v1) } diff --git a/src/signin.js b/src/signin.js deleted file mode 100644 index 53427f83a..000000000 --- a/src/signin.js +++ /dev/null @@ -1,1151 +0,0 @@ -/** - * signin.js - * - * Signing in, signing up, profile and preferences reloading - * Type index management - * - * Many functions in this module take a context object, add to it, and return a promise of it. - */ - /* global $SOLID_GLOBAL_config localStorage confirm alert */ - -// const Solid = require('solid-client') -const SolidTls = require('solid-auth-tls') -const $rdf = require('rdflib') -const error = require('./widgets/error') -const widgets = require('./widgets/index') -// const utils = require('./utils') -const solidAuthClient = require('solid-auth-client') - -const UI = { - log: require('./log'), - ns: require('./ns'), - store: require('./store') -} - -module.exports = { - checkUser, // Async - currentUser, // Sync - defaultTestUser, // Sync - findAppInstances, - findOriginOwner, - loadTypeIndexes, - logIn, - logInLoadProfile, - logInLoadPreferences, - loginStatusBox, - newAppInstance, - offlineTestID, - registrationControl, - registrationList, - selectWorkspace, - setACLUserPublic, - saveUser, - solidAuthClient -} - -// const userCheckSite = 'https://databox.me/' - -// Look for and load the User who has control over it -function findOriginOwner (doc, callback) { - var uri = doc.uri || doc - var i = uri.indexOf('://') - if (i < 0) return false - var j = uri.indexOf('/', i + 3) - if (j < 0) return false - var origin = uri.slice(0, j + 1) // @@ TBC - return origin -} - -// Promises versions -// -// These pass a context object which hold various RDF symbols -// as they become available -// -// me RDF symbol for the users' webid -// publicProfile The user's public profile, iff loaded -// preferencesFile The user's personal preferences file, iff loaded -// index.public The user's public type index file -// index.private The user's private type index file -// not RDF symbols: -// noun A string in english for the type of thing -- like "address book" -// instance An array of nodes which are existing instances -// containers An array of nodes of containers of instances -// div A DOM element where UI can be displayed -// statusArea A DOM element (opt) progress stuff can be displayed, or error messages - -/** - * @param webId {NamedNode} - * @param context {Object} - * - * @returns {NamedNode|null} Returns the Web ID, after setting it - */ -function saveUser (webId, context) { - let webIdUri, me - if (webId) { - webIdUri = webId.uri || webId - let me = $rdf.namedNode(webIdUri) - if (context) { - context.me = me - } - return me - } - return me || null -} - -/** - * @returns {NamedNode|null} - */ -function defaultTestUser () { - // Check for offline override - let offlineId = offlineTestID() - - if (offlineId) { - return offlineId - } - - return null -} - -/** Checks syncronously whether user is logged in - * - * @returns Named Node or null -*/ -function currentUser () { - let str = localStorage['solid-auth-client'] - if (str) { - let da = JSON.parse(str) - if (da.session && da.session.webId) { - // @@ check has not expired - return $rdf.sym(da.session.webId) - } - } - return null - // JSON.parse(localStorage['solid-auth-client']).session.webId -} - -/** - * Resolves with the logged in user's Web ID - * - * @param context - * - * @returns {Promise} - */ -function logIn (context) { - let me = defaultTestUser() // me is a NamedNode or null - - if (me) { - context.me = me - return Promise.resolve(context) - } - - return new Promise((resolve) => { - checkUser().then(webId => { // Already logged in? - if (webId) { - context.me = $rdf.sym(webId) - console.log('logIn: Already logged in as ' + context.me) - resolve(context) - return - } - let box = loginStatusBox(context.dom, (webIdUri) => { - saveUser(webIdUri, context) - resolve(context) // always pass growing context - }) - context.div.appendChild(box) - }) - }) -} - -/** - * Logs the user in and loads their WebID profile document into the store - * - * @private - * - * @param context {Object} - * - * @returns {Promise} Resolves with the context after login / fetch - */ -function logInLoadProfile (context) { - if (context.publicProfile) { return Promise.resolve(context) } // already done - const fetcher = UI.store.fetcher - var profileDocument - return new Promise(function (resolve, reject) { - logIn(context) - .then(context => { - let webID = context.me - if (!webID) { - throw new Error('Could not log in') - } - profileDocument = webID.doc() - // Load the profile into the knowledge base (fetcher.store) - // withCredentials: Web arch should let us just load by turning off creds helps CORS - // reload: Gets around a specifc old Chrome bug caching/origin/cors - fetcher.load(profileDocument, {withCredentials: false, cache: 'reload'}).then(response => { - context.publicProfile = profileDocument - resolve(context) - }, err => { - let message = 'Logged in but cannot load profile ' + profileDocument + ' : ' + err - context.div.appendChild(error.errorMessageBlock(context.dom, message)) - reject(message) - }) - }, - err => { reject(new Error("Can't log in: " + err)) }) - }) -} - -/** - * Loads preferences file - * Do this after having done log in and load profile - * - * @private - * - * @param context - * - * @returns {Promise} - */ -function logInLoadPreferences (context) { - if (context.preferencesFile) return Promise.resolve(context) // already done - - const kb = UI.store - const statusArea = context.statusArea || context.div || null - var progressDisplay - return new Promise(function (resolve, reject) { - logInLoadProfile(context).then(context => { - let preferencesFile = kb.any(context.me, UI.ns.space('preferencesFile')) - function complain (message) { - message = 'logInLoadPreferences: ' + message - if (statusArea) { - // statusArea.innerHTML = '' - statusArea.appendChild(error.errorMessageBlock(context.dom, message)) - } - console.log(message) - reject(new Error(message)) - } - - if (!preferencesFile) { - let message = "Can't find a preferences file pointer in profile " + context.publicProfile - return reject(new Error(message)) - } - - // //// Load preferences file - kb.fetcher.load(preferencesFile, {withCredentials: true}) - .then(function () { - if (progressDisplay) { - progressDisplay.parentNode.removeChild(progressDisplay) - } - context.preferencesFile = preferencesFile - return resolve(context) - }, - function (err) { // Really important to look at why - let status = err.status - let message = err.message - console.log('HTTP status ' + status + ' for pref file ' + preferencesFile) - let m2 - if (status === 401) { - m2 = 'Strange - you are not authenticated (properly logged on) to read preferences file.' - } else if (status === 403) { - m2 = 'Strange - you are not authorized to read your preferences file.' - } else if (status === 404) { - if (confirm('You do not currently have a Preferences file. Ok for me to create an empty one? ' + preferencesFile)) { - // @@@ code me ... weird to have a name o fthe file but no file - return complain(new Error('Sorry No code yet to craete a preferences fille at ')) - } else { - reject(new Error('User declined to craete a preferences fille at ')) - } - } else { - m2 = 'Strange: Error ' + status + ' trying to read your preferences file.' + message - } - alert(m2) - }) // load prefs file then - }, err => { // Fail initial login load prefs - reject(new Error('(via loadPrefs) ' + err)) - }, err => reject(err)) - }) -} - -/** - * Resolves with the same context, outputting - * output: index.public, index.private - * - * @see https://github.com/solid/solid/blob/master/proposals/data-discovery.md#discoverability - * - * @param context - * - * @returns {Promise} - */ -function loadTypeIndexes (context) { - var ns = UI.ns - var kb = UI.store - - return new Promise(function (resolve, reject) { - logInLoadPreferences(context).then(context => { - var me = context.me - context.index = context.index || {} - context.index.private = kb.each(me, ns.solid('privateTypeIndex'), undefined, context.preferencesFile) - if (context.index.private.length === 0) { - return reject(new Error('Your preference file ' + context.preferencesFile + ' does not point to a private type index.')) - } - context.index.public = kb.each(me, ns.solid('publicTypeIndex'), undefined, context.publicProfile) - if (context.index.public.length === 0) { - return reject(new Error('Your preference file ' + context.preferencesFile + ' does not point to a public type index.')) - } - var ix = context.index.private.concat(context.index.public) - kb.fetcher.load(ix).then(responses => { - resolve(context) - }, err => { - reject(new Error('Error loading type indexes: ' + err)) - }) - }, err => { - reject(new Error('[LTI] ' + err)) - }) - }) -} - -/** - * Resolves with the same context, outputting - * @see https://github.com/solid/solid/blob/master/proposals/data-discovery.md#discoverability - * - * @private - * - * @param context {Object} - * @param context.me - * @param context.preferencesFile - * @param context.publicProfile - * @param context.index - * - * @returns {Promise} - */ -function ensureTypeIndexes (context) { - return new Promise(function (resolve, reject) { - return loadTypeIndexes(context) - .then(function (context) { - console.log('ensureTypeIndexes: Type indexes exist already') - resolve(context) - }, function (error) { - if (confirm('You don\'t have, or you couldn\'t acess, type indexes --lists of things of different types. Create new empty ones? ' + error)) { - var ns = UI.ns - var kb = UI.store - var me = context.me - var newIndex - - var makeIndexIfNecesary = function (context, visibility) { - return new Promise(function (resolve, reject) { - var relevant = {'private': context.preferencesFile, 'public': context.publicProfile}[visibility] - - function putIndex (newIndex) { - kb.fetcher.webOperation('PUT', newIndex.uri, { - data: '# ' + new Date() + ' Blank initial Type index\n', - contentType: 'text/turtle'}) - .then(function (xhr) { - resolve(context) - }, function (e) { - let msg = 'Error creating new index ' + e - widgets.complain(context, msg) - reject(new Error(msg)) - }) - } - - context.index = context.index || {} - context.index[visibility] = context.index[visibility] || [] - if (context.index[visibility].length === 0) { - newIndex = $rdf.sym(relevant.dir().uri + visibility + 'TypeIndex.ttl') - console.log('Linking to new fresh type index ' + newIndex) - if (!confirm('Ok to create a new empty index file at ' + newIndex + ', overwriting anything that was there?')) { - reject(new Error('cancelled by user')) - } - var addMe = [ $rdf.st(me, ns.solid(visibility + 'TypeIndex'), newIndex, relevant) ] - - UI.store.updater.update([], addMe, function (uri, ok, body) { - if (!ok) { - return reject(new Error('Error saving type index link saving back ' + uri + ': ' + body)) - } else { - context.index[visibility].push(newIndex) - console.log('Creating new fresh type index ' + newIndex) - putIndex(newIndex) - } - }) - } else { // officially exists - var ix = context.index[visibility][0] - kb.fetcher.load(ix).then(response => { // physically exists - resolve(context) - }, err => { - if (err.status === 404) { - if (!confirm('Ok to create a new empty index file at ' + ix + ', overwriting anything that was there?')) { - reject(new Error('cancelled by user')) - } - putIndex(ix) - } else { - reject(new Error('You should have a type index file ' + ix + ', but ' + err)) - } - }) - } - }) // promise - } // makeIndexIfNecesary - - var ps = [ makeIndexIfNecesary(context, 'private'), makeIndexIfNecesary(context, 'public') ] - - return Promise.all(ps) - .then(() => { - resolve(context) - }) - } else { // user cancel - // @@ code me - } - } - ) - }) // Promise -} - -/** - * Returns promise of context with arrays of symbols - * - * 2016-12-11 change to include forClass arc a la - * https://github.com/solid/solid/blob/master/proposals/data-discovery.md - * - * @param context - * @param context.instances - * @param context.containers - * @param klass - * @returns {Promise} of context - */ -function findAppInstances (context, klass) { - var kb = UI.store - var ns = UI.ns - var fetcher = UI.store.fetcher - - return new Promise(function (resolve, reject) { - loadTypeIndexes(context).then(indexes => { - var registrations = kb.each(undefined, ns.solid('forClass'), klass) - var instances = [] - var containers = [] - for (var r = 0; r < registrations.length; r++) { - instances = instances.concat(kb.each(klass, ns.solid('instance'))) - containers = containers.concat(kb.each(klass, ns.solid('instanceContainer'))) - } - if (!containers.length) { - context.instances = [] - context.containers = [] - resolve(context) - } - fetcher.load(containers) - .then(responses => { - for (var i = 0; i < containers.length; i++) { - var cont = containers[i] - instances = instances.concat(kb.each(cont, ns.ldp('contains'))) - } - context.instances = instances - context.containers = containers - resolve(context) - }, err => { - reject(new Error('[FAI] Unable to load containers' + err)) - }) - }, err => reject(new Error('Error looking for instances of ' + klass + ': ' + err))) - }) -} - -/** - * UI to control registration of instance - * - * @param context - * @param instance - * @param klass - * - * @returns {Promise} - */ -function registrationControl (context, instance, klass) { - var kb = UI.store - var ns = UI.ns - var dom = context.dom - - var box = dom.createElement('div') - context.div.appendChild(box) - - return ensureTypeIndexes(context) - .then(function (context) { - box.innerHTML = '
    ' // tbody will be inserted anyway - box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid gray 0.05em;') - var tbody = box.children[0].children[0] - var form = kb.bnode()// @@ say for now - - var registrationStatements = function (index) { - var registrations = kb.each(undefined, ns.solid('instance'), instance) - .filter(function (r) { return kb.holds(r, ns.solid('forClass'), klass) }) - var reg = registrations.length ? registrations[0] : widgets.newThing(index) - return [ $rdf.st(reg, ns.solid('instance'), instance, index), - $rdf.st(reg, ns.solid('forClass'), klass, index) ] - } - - var index, statements - - if (context.index.public && context.index.public.length > 0) { - index = context.index.public[0] - statements = registrationStatements(index) - tbody.children[0].appendChild(widgets.buildCheckboxForm( - context.dom, UI.store, 'Public link to this ' + context.noun, null, statements, form, index)) - } - - if (context.index.private && context.index.private.length > 0) { - index = context.index.private[0] - statements = registrationStatements(index) - tbody.children[1].appendChild(widgets.buildCheckboxForm( - context.dom, UI.store, 'Personal note of this ' + context.noun, null, statements, form, index)) - } - - // widgets.buildCheckboxForm(dom, kb, lab, del, ins, form, store) - return context - }, - function (e) { - var msg = 'registrationControl: Type indexes not available: ' + e - context.div.appendChild(UI.error.errorMessageBlock(context.dom, e)) - console.log(msg) - }) - .catch(function (e) { - var msg = 'registrationControl: Error making panel:' + e - context.div.appendChild(UI.error.errorMessageBlock(context.dom, e)) - console.log(msg) - }) -} - -/** - * UI to List at all registered things - * @param context - * @param options - * - * @returns {Promise} - */ -function registrationList (context, options) { - const kb = UI.store - const ns = UI.ns - const dom = context.dom - - var box = dom.createElement('div') - context.div.appendChild(box) - - return ensureTypeIndexes(context) - .then((indexes) => { - box.innerHTML = '
    ' // tbody will be inserted anyway - box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid #eee 0.5em;') - var table = box.firstChild - - var ix = [] - var sts = [] - var vs = ['private', 'public'] - vs.forEach(function (visibility) { - if (options[visibility]) { - ix = ix.concat(context.index[visibility][0]) - sts = sts.concat(kb.statementsMatching( - undefined, ns.solid('instance'), undefined, context.index[visibility][0])) - } - }) - - for (var i = 0; i < sts.length; i++) { - var statement = sts[i] - // var cla = statement.subject - var inst = statement.object - // if (false) { - // var tr = table.appendChild(dom.createElement('tr')) - // var anchor = tr.appendChild(dom.createElement('a')) - // anchor.setAttribute('href', inst.uri) - // anchor.textContent = utils.label(inst) - // } else { - // } - - var deleteInstance = function (x) { - kb.updater.update([statement], [], function (uri, ok, errorBody) { - if (ok) { - console.log('Removed from index: ' + statement.subject) - } else { - console.log('Error: Cannot delete ' + statement + ': ' + errorBody) - } - }) - } - var opts = { deleteFunction: deleteInstance } - var tr = widgets.personTR(dom, ns.solid('instance'), inst, opts) - table.appendChild(tr) - } - - /* - //var containers = kb.each(klass, ns.solid('instanceContainer')); - if (containers.length) { - fetcher.load(containers).then(function(xhrs){ - for (var i=0; i} eg ['Read', 'Write'] - * - * @returns {Promise} Resolves with aclDoc uri on successful write - */ -function setACLUserPublic (docURI, me, options) { - const kb = UI.store - let aclDoc = kb.any(kb.sym(docURI), - kb.sym('http://www.iana.org/assignments/link-relations/acl')) - - return Promise.resolve() - .then(() => { - if (aclDoc) { return aclDoc } - - return fetchACLRel(docURI) - .catch(err => { - throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`) - }) - }) - .then(aclDoc => { - let aclText = genACLText(docURI, me, aclDoc.uri, options) - - return kb.fetcher.webOperation('PUT', aclDoc.uri, - { data: aclText, contentType: 'text/turtle' }) - .then(result => { - if (!result.ok) { - throw new Error('Error writing ACL text: ' + result.error) - } - - return aclDoc - }) - }) -} - -/** - * @param docURI {string} - * @returns {Promise} - */ -function fetchACLRel (docURI) { - const kb = UI.store - const fetcher = kb.fetcher - - return fetcher.load(docURI) - .then(result => { - if (!result.ok) { - throw new Error('fetchACLRel: While loading:' + result.error) - } - - let aclDoc = kb.any(kb.sym(docURI), - kb.sym('http://www.iana.org/assignments/link-relations/acl')) - - if (!aclDoc) { - throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI) - } - - return aclDoc - }) -} - -/** - * @param docURI {string} - * @param me {NamedNode} - * @param aclURI {string} - * @param options {Object} - * - * @returns {string} Serialized ACL - */ -function genACLText (docURI, me, aclURI, options = {}) { - var optPublic = options.public || [] - var g = $rdf.graph() - var auth = $rdf.Namespace('http://www.w3.org/ns/auth/acl#') - var a = g.sym(aclURI + '#a1') - var acl = g.sym(aclURI) - var doc = g.sym(docURI) - g.add(a, UI.ns.rdf('type'), auth('Authorization'), acl) - g.add(a, auth('accessTo'), doc, acl) - if (options.defaultForNew) { - g.add(a, auth('defaultForNew'), doc, acl) - } - g.add(a, auth('agent'), me, acl) - g.add(a, auth('mode'), auth('Read'), acl) - g.add(a, auth('mode'), auth('Write'), acl) - g.add(a, auth('mode'), auth('Control'), acl) - - if (optPublic.length) { - a = g.sym(aclURI + '#a2') - g.add(a, UI.ns.rdf('type'), auth('Authorization'), acl) - g.add(a, auth('accessTo'), doc, acl) - g.add(a, auth('agentClass'), UI.ns.foaf('Agent'), acl) - for (let p = 0; p < optPublic.length; p++) { - g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc - } - } - return $rdf.serialize(acl, g, aclURI, 'text/turtle') -} - -/** - * @returns {NamedNode|null} - */ -function offlineTestID () { - if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.username) { // Test setup - console.log('Assuming the user is ' + $SolidTestEnvironment.username) - return $rdf.sym($SolidTestEnvironment.username) - } - - if (typeof document !== 'undefined' && - document.location && ('' + document.location).slice(0, 16) === 'http://localhost') { - var div = document.getElementById('appTarget') - if (!div) return null - var id = div.getAttribute('testID') - if (!id) return null - /* me = kb.any(subject, UI.ns.acl('owner')); // when testing on plane with no webid - */ - console.log('Assuming user is ' + id) - return $rdf.sym(id) - } - return null -} - -/** - * Bootstrapping identity - * (Called by `loginStatusBox()`) - * @private - * - * @param dom - * @param setUserCallback(user: object) - * - * @returns {Element} - */ -function signInOrSignUpBox (dom, setUserCallback) { - var box = dom.createElement('div') - const magicClassName = 'SolidSignInOrSignUpBox' - console.log('widgets.signInOrSignUpBox') - box.setUserCallback = setUserCallback - box.setAttribute('class', magicClassName) - - // Sign in button with PopUP - let signInPopUpButton = dom.createElement('input') // multi - box.appendChild(signInPopUpButton) - signInPopUpButton.setAttribute('type', 'button') - signInPopUpButton.setAttribute('value', 'Log in') - signInPopUpButton.setAttribute('style', - 'padding: 1em; border-radius:0.5em; margin: 2em;') - - signInPopUpButton.addEventListener('click', () => { - var offline = offlineTestID() - if (offline) return setUserCallback(offline.uri) - return solidAuthClient.popupLogin({ popupUri: $SOLID_GLOBAL_config.popupUri }) - .then(session => { - let webIdURI = session.webId - // setUserCallback(webIdURI) - var divs = dom.getElementsByClassName(magicClassName) - console.log('Logged in, ' + divs.length + ' panels to be serviced') - // At the same time, satiffy all the other login boxes - for (let i = 0; i < divs.length; i++) { - let div = divs[i] - if (div.setUserCallback) { - try { - div.setUserCallback(webIdURI) - let parent = div.parentNode - if (parent) { - parent.removeChild(div) - } - } catch (e) { - console.log('## Error satisfying login box: ' + e) - div.appendChild(UI.error.errorMessageBlock(dom, e)) - } - } - } - }) - }, false) - - // Sign up button - let signupButton = dom.createElement('input') - box.appendChild(signupButton) - signupButton.setAttribute('type', 'button') - signupButton.setAttribute('value', 'Sign Up') - signupButton.setAttribute('style', - 'padding: 1em; border-radius:0.5em; margin: 2em;') - - signupButton.addEventListener('click', function (e) { - let signupMgr = new SolidTls.Signup() - signupMgr.signup().then(function (uri) { - console.log('signInOrSignUpBox signed up ' + uri) - setUserCallback(uri) - }) - }, false) - return box -} - -/** - * @returns {Promise} Resolves with WebID URI or null - */ -function webIdFromSession (session) { - var webId = session ? session.webId : null - if (webId) { - saveUser(webId) - } - return webId -} - -/** - * @returns {Promise} Resolves with WebID URI or null - */ - /* -function checkCurrentUser () { - return checkUser() -} -*/ - -/** - * @param [setUserCallback] {Function} Optional callback, `setUserCallback(webId|null)` - * - * @returns {Promise} Resolves with web id uri, if no callback provided - */ -function checkUser (setUserCallback) { - // Check to see if already logged in / have the WebID - var me = defaultTestUser() - if (me) { - return Promise.resolve(setUserCallback ? setUserCallback(me) : me) - } - - // doc = kb.any(doc, UI.ns.link('userMirror')) || doc - - return solidAuthClient.currentSession() - - .then(webIdFromSession, - err => { - console.log('Error fetching currentSession:', err) - return null - }) - - .then(webId => { - // if (webId.startsWith('dns:')) { // legacy rww.io pseudo-users - // webId = null - // } - var me = saveUser(webId) - - if (me) { - console.log('(Logged in as ' + me + ' by authentication)') - } - - return setUserCallback ? setUserCallback(me) : me - }) -} - -/** - * Login status box - * - * A big sign-up/sign in box or a logout box depending on the state - * - * @param dom - * @param listener(uri) - * - * @returns {Element} - */ -function loginStatusBox (dom, listener) { - var me = defaultTestUser() - - var box = dom.createElement('div') - - var setIt = function (newidURI) { - if (!newidURI) { return } - - let uri = newidURI.uri || newidURI -// UI.preferences.set('me', uri) - me = $rdf.sym(uri) - box.refresh() - if (listener) listener(me.uri) - } - - var zapIt = function () { - // UI.preferences.set('me', '') - solidAuthClient.logout().then(function () { - var message = 'Your Web ID was ' + me + '. It has been forgotten.' - me = null - try { - UI.log.alert(message) - } catch (e) { - try { - window.alert(message) - } catch (e) { - } - } - box.refresh() - if (listener) listener(null) - }) - } - - var logoutButton = function (me) { - var logoutLabel = 'Web ID logout' - if (me) { - var nick = UI.store.any(me, UI.ns.foaf('nick')) || - UI.store.any(me, UI.ns.foaf('name')) - if (nick) { - logoutLabel = 'Logout ' + nick.value - } - } - var signOutButton = dom.createElement('input') - signOutButton.className = 'WebIDCancelButton' - signOutButton.setAttribute('type', 'button') - signOutButton.setAttribute('value', logoutLabel) - signOutButton.addEventListener('click', zapIt, false) - return signOutButton - } - - box.refresh = function () { - let me = defaultTestUser() - let meUri = me ? me.uri : '' - if (box.me !== meUri) { - widgets.clearElement(box) - if (me) { - box.appendChild(logoutButton(me)) - } else { - box.appendChild(signInOrSignUpBox(dom, setIt)) - } - } - box.me = meUri - } - - box.me = '99999' // Force refresh - box.refresh() - - return box -} - -/** - * Workspace selection etc - */ - -/** - * Returns a UI object which, if it selects a workspace, - * will callback(workspace, newBase). - * - * If necessary, will get an account, preferences file, etc. In sequence: - * - * - If not logged in, log in. - * - Load preferences file - * - Prompt user for workspaces - * - Allows the user to just type in a URI by hand - * - * Calls back with the ws and the base URI - * - * @param dom - * @param appDetails - * @param callbackWS - * @returns {Element} - */ -function selectWorkspace (dom, appDetails, callbackWS) { - var noun = appDetails.noun - var appPathSegment = appDetails.appPathSegment - - var me = defaultTestUser() - var kb = UI.store - var box = dom.createElement('div') - var context = { me: me, dom: dom, div: box } - - var say = function (s) { box.appendChild(error.errorMessageBlock(dom, s)) } - - var figureOutBase = function (ws) { - var newBase = kb.any(ws, UI.ns.space('uriPrefix')) - if (!newBase) { - newBase = ws.uri.split('#')[0] - } else { - newBase = newBase.value - } - if (newBase.slice(-1) !== '/') { - console.log(appPathSegment + ': No / at end of uriPrefix ' + newBase) // @@ paramater? - newBase = newBase + '/' - } - var now = new Date() - newBase += appPathSegment + '/id' + now.getTime() + '/' // unique id - return newBase - } - - var displayOptions = function (context) { - // var status = '' - var id = context.me - var preferencesFile = context.preferencesFile - var newBase = null - - // A workspace specifically defined in the private preferences file: - var w = kb.statementsMatching(id, UI.ns.space('workspace'), // Only trust prefs file here - undefined, preferencesFile).map(function (st) { return st.object }) - - // A workspace in a storage in the public profile: - var storages = kb.each(id, UI.ns.space('storage')) // @@ No provenance requirement at the moment - storages.map(function (s) { - w = w.concat(kb.each(s, UI.ns.ldp('contains'))) - }) - - if (w.length === 1) { - say('Workspace used: ' + w[0].uri) // @@ allow user to see URI - newBase = figureOutBase(w[0]) - // callbackWS(w[0], newBase) - } else if (w.length === 0) { - say("You don't seem to have any workspaces. You have " + storages.length + ' storages.') - } - - // Prompt for ws selection or creation - // say( w.length + " workspaces for " + id + "Chose one."); - var table = dom.createElement('table') - table.setAttribute('style', 'border-collapse:separate; border-spacing: 0.5em;') - - // var popup = window.open(undefined, '_blank', { height: 300, width:400 }, false) - box.appendChild(table) - - // Add a field for directly adding the URI yourself - - // var hr = box.appendChild(dom.createElement('hr')) // @@ - box.appendChild(dom.createElement('hr')) // @@ - - var p = box.appendChild(dom.createElement('p')) - p.textContent = 'Where would you like to store the data for the ' + noun + '? ' + - 'Give the URL of the directory where you would like the data stored.' - var baseField = box.appendChild(dom.createElement('input')) - baseField.setAttribute('type', 'text') - baseField.size = 80 // really a string - baseField.label = 'base URL' - baseField.autocomplete = 'on' - if (newBase) { // set to default - baseField.value = newBase - } - - context.baseField = baseField - - box.appendChild(dom.createElement('br')) // @@ - - var button = box.appendChild(dom.createElement('button')) - button.textContent = 'Start new ' + noun + ' at this URI' - button.addEventListener('click', function (e) { - var newBase = baseField.value - if (newBase.slice(-1) !== '/') { - newBase += '/' - } - callbackWS(null, newBase) - }) - - // Now go set up the table of spaces - - // var row = 0 - w = w.filter(function (x) { - return !(kb.holds(x, UI.ns.rdf('type'), // Ignore master workspaces - UI.ns.space('MasterWorkspace'))) - }) - var col1, col2, col3, tr, ws, style, comment - var cellStyle = 'height: 3em; margin: 1em; padding: 1em white; border-radius: 0.3em;' - var deselectedStyle = cellStyle + 'border: 0px;' - // var selectedStyle = cellStyle + 'border: 1px solid black;' - for (var i = 0; i < w.length; i++) { - ws = w[i] - tr = dom.createElement('tr') - if (i === 0) { - col1 = dom.createElement('td') - col1.setAttribute('rowspan', '' + w.length + 1) - col1.textContent = 'Chose a workspace for this:' - col1.setAttribute('style', 'vertical-align:middle;') - tr.appendChild(col1) - } - col2 = dom.createElement('td') - style = kb.any(ws, UI.ns.ui('style')) - if (style) { - style = style.value - } else { // Otherise make up arbitrary colour - var hash = function (x) { return x.split('').reduce(function (a, b) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a }, 0) } - var bgcolor = '#' + ((hash(ws.uri) & 0xffffff) | 0xc0c0c0).toString(16) // c0c0c0 forces pale - style = 'color: black ; background-color: ' + bgcolor + ';' - } - col2.setAttribute('style', deselectedStyle + style) - tr.target = ws.uri - var label = kb.any(ws, UI.ns.rdfs('label')) - if (!label) { - label = ws.uri.split('/').slice(-1)[0] || ws.uri.split('/').slice(-2)[0] - } - col2.textContent = label || '???' - tr.appendChild(col2) - if (i === 0) { - col3 = dom.createElement('td') - col3.setAttribute('rowspan', '' + w.length + 1) - // col3.textContent = '@@@@@ remove'; - col3.setAttribute('style', 'width:50%;') - tr.appendChild(col3) - } - table.appendChild(tr) - - var addMyListener = function (container, detail, style, ws1) { - container.addEventListener('click', function (e) { - col3.textContent = detail - col3.setAttribute('style', style) - col3.appendChild(addContinueButton(ws1)) - }, true) // capture vs bubble - } - - var addContinueButton = function (selectedWorkspace) { - var button = dom.createElement('button') - button.textContent = 'Continue' - // button.setAttribute('style', style); - var newBase = figureOutBase(selectedWorkspace) - baseField.value = newBase // show user proposed URI - - button.addEventListener('click', function (e) { - button.disabled = true - callbackWS(selectedWorkspace, newBase) - button.textContent = '---->' - }, true) // capture vs bubble - return button - } - - comment = kb.any(ws, UI.ns.rdfs('comment')) - comment = comment ? comment.value : 'Use this workspace' - addMyListener(col2, comment ? comment.value : '', deselectedStyle + style, ws) - } - - // last line with "Make new workspace" - var trLast = dom.createElement('tr') - col2 = dom.createElement('td') - col2.setAttribute('style', cellStyle) - col2.textContent = '+ Make a new workspace' - // addMyListener(col2, 'Set up a new workspace', '') // @@ TBD - trLast.appendChild(col2) - table.appendChild(trLast) - } // displayOptions - - logInLoadPreferences(context) // kick off async operation - .then(displayOptions, err => { - box.appendChild(UI.widgets.errorMessageBlock(err)) - }) - - return box // return the box element, while login proceeds -} // selectWorkspace - -/** - * Creates a new instance of an app. - * - * An instance of an app could be e.g. an issue tracker for a given project, - * or a chess game, or calendar, or a health/fitness record for a person. - * - * @param dom - * @param appDetails - * @param callback - * - * @returns {Element} A div with a button in it for making a new app instance - */ -function newAppInstance (dom, appDetails, callback) { - var gotWS = function (ws, base) { - // $rdf.log.debug("newAppInstance: Selected workspace = " + (ws? ws.uri : 'none')) - callback(ws, base) - } - var div = dom.createElement('div') - var b = dom.createElement('button') - b.setAttribute('type', 'button') - div.appendChild(b) - b.innerHTML = 'Make new ' + appDetails.noun - // b.setAttribute('style', 'float: right; margin: 0.5em 1em;'); // Caller should set - b.addEventListener('click', (e) => { - div.appendChild(selectWorkspace(dom, appDetails, gotWS)) - }, false) - div.appendChild(b) - return div -} diff --git a/src/signup/config-default.js b/src/signup/config-default.js new file mode 100644 index 000000000..2651e6d78 --- /dev/null +++ b/src/signup/config-default.js @@ -0,0 +1,41 @@ +/** + * Provides a simple configuration object for Solid web client and other + * modules. + * @module config-default + */ +export default { // @@ should not use export default + /** + * Primary authentication endpoint + */ + authEndpoint: '', + + /** + * Fallback authentication endpoint + */ + fallbackAuthEndpoint: 'https://databox.me/', + + /** + * Default signup endpoints (list of identity providers) + */ + signupEndpoint: 'https://solidproject.org/get_a_pod', + + /** + * Default height of the Signup popup window, in pixels + */ + signupWindowHeight: 600, + + /** + * Default width of the Signup popup window, in pixels + */ + signupWindowWidth: 1024, + + /** + * Path to the client private key (only needed when running within node) + */ + key: '', + + /** + * Path to the client certificate (only needed when running within node) + */ + cert: '' +} diff --git a/src/signup/signup.js b/src/signup/signup.js new file mode 100644 index 000000000..1d758f489 --- /dev/null +++ b/src/signup/signup.js @@ -0,0 +1,74 @@ +import defaultConfig from './config-default' + +/** + * Provides functionality for signing up with a Solid provider + * @module signup + */ + +/** + * Creates a Signup UI manager + * @class + */ +export function Signup (config) { + this.config = config || defaultConfig +} + +/** + * Sets up an event listener to monitor login messages from child window/iframe + * @method listen + * @return {Promise} Event listener promise, resolves to user's WebID + */ +Signup.prototype.listen = function listen () { + const promise = new Promise(function (resolve, reject) { + const eventMethod = window.addEventListener + ? 'addEventListener' + : 'attachEvent' + const eventListener = window[eventMethod] + const messageEvent = eventMethod === 'attachEvent' + ? 'onmessage' + : 'message' + eventListener(messageEvent, function (e) { + const u = e.data + if (u.slice(0, 5) === 'User:') { + const user = u.slice(5, u.length) + if (user && user.length > 0 && user.slice(0, 4) === 'http') { + return resolve(user) + } else { + return reject(user) + } + } + }, true) + }) + return promise +} + +/** + * Opens a signup popup window, sets up `listen()`. + * @method signup + * @static + * @param signupUrl {String} Location of a Solid server for user signup. + * @return {Promise} Returns a listener promise, resolves with signed + * up user's WebID. + */ +Signup.prototype.signup = function signup (signupUrl) { + signupUrl = signupUrl || this.config.signupEndpoint + const width = this.config.signupWindowWidth + const height = this.config.signupWindowHeight + // set borders + const leftPosition = (window.screen.width / 2) - ((width / 2) + 10) + // set title and status bars + const topPosition = (window.screen.height / 2) - ((height / 2) + 50) + const windowTitle = 'Solid signup' + const windowUrl = signupUrl + '?origin=' + + encodeURIComponent(window.location.origin) + const windowSpecs = 'resizable,scrollbars,status,width=' + width + ',height=' + + height + ',left=' + leftPosition + ',top=' + topPosition + window.open(windowUrl, windowTitle, windowSpecs) + const self = this + return new Promise(function (resolve) { + self.listen() + .then(function (webid) { + return resolve(webid) + }) + }) +} diff --git a/src/store.js b/src/store.js deleted file mode 100644 index 1e9a4608e..000000000 --- a/src/store.js +++ /dev/null @@ -1,11 +0,0 @@ -// This module of solid-ui has a main quadstore for the app to use -// - -var rdf = require('rdflib') -var store = module.exports = rdf.graph() // Make a Quad store -rdf.fetcher(store) // Attach a web I/O module, store.fetcher -store.updater = new rdf.UpdateManager(store) // Add real-time live updates store.updater - -console.log('Unique quadstore initialized.') - -// ends diff --git a/src/stories/Buttons.mdx b/src/stories/Buttons.mdx new file mode 100644 index 000000000..7472d023f --- /dev/null +++ b/src/stories/Buttons.mdx @@ -0,0 +1,69 @@ +import * as UI from '../../src/index' +import * as ButtonsStories from './Buttons.stories'; + +import { Canvas, Meta, Story } from '@storybook/blocks'; +import { action } from '@storybook/addon-actions' + + + +## Button with text (no border) + + + + + + + +## Button with text (needs border) + + + + + + + +## Continue & Cancel button + + + + + + + +## Delete button + + + + + +## Button with icon + + + + + +## File upload button + + + + + +## Link button + + + + + +## Link icon + + + + + + + +## Remove button + + + + diff --git a/src/stories/Buttons.stories.js b/src/stories/Buttons.stories.js new file mode 100644 index 000000000..38783fdce --- /dev/null +++ b/src/stories/Buttons.stories.js @@ -0,0 +1,129 @@ +import * as UI from '../../src/index' + +import { action } from '@storybook/addon-actions' + +export default { + title: 'Buttons', +} + +export const Primary = { + render: () => + UI.widgets.button(document, undefined, 'Primary', action('clicked')), + name: 'Primary', +} + +export const Secondary = { + render: () => + UI.widgets.button(document, undefined, 'Secondary', action('clicked'), { + buttonColor: 'Secondary', + }), + + name: 'Secondary', +} + +export const PrimaryNeedsBorder = { + render: () => + UI.widgets.button(document, undefined, 'Secondary', action('clicked'), { + needsBorder: true, + }), + + name: 'Primary (needs border)', +} + +export const SecondaryNeedsBorder = { + render: () => + UI.widgets.button(document, undefined, 'Secondary', action('clicked'), { + buttonColor: 'Secondary', + needsBorder: true, + }), + + name: 'Secondary (needs border)', +} + +export const ContinueButton = { + render: () => UI.widgets.continueButton(document, action('clicked')), + name: 'Continue button', +} + +export const CancelButton = { + render: () => UI.widgets.cancelButton(document, action('clicked')), + name: 'Cancel button', +} + +export const DeleteButton = { + render: () => { + const div = document.createElement('div') + const result = UI.widgets.deleteButtonWithCheck( + document, + div, + 'something', + action('deleted') + ) + return div + }, + + name: 'Delete button', +} + +export const ButtonWithIcon = { + render: () => + UI.widgets.button( + document, + 'https://solidproject.org/assets/img/solid-emblem.svg', + 'test', + action('clicked!') + ), + + name: 'Button with icon', +} + +export const FileUploadButton = { + render: () => UI.widgets.fileUploadButtonDiv(document, action('uploaded')), + name: 'File upload button', +} + +export const LinkButton = { + render: () => { + document.outlineManager = { + GotoSubject: action('go to subject'), + } + + return UI.widgets.linkButton( + document, + $rdf.namedNode('http://example.com/') + ) + }, + + name: 'Link button', +} + +export const LinkIcon = { + render: () => + UI.widgets.linkIcon(document, $rdf.namedNode('https://solidproject.org/')), + name: 'Link icon', +} + +export const LinkCustomIcon = { + render: () => + UI.widgets.linkIcon( + document, + $rdf.namedNode('https://solidproject.org/'), + 'https://solidproject.org/favicon.ico' + ), + + name: 'Link custom icon', +} + +export const RemoveButton = { + render: () => { + const div = document.createElement('div') + const p = document.createElement('p') + p.appendChild(document.createTextNode('click x to remove me')) + const button = UI.widgets.removeButton(document, p) + div.appendChild(p) + div.appendChild(button) + return div + }, + + name: 'Remove button', +} diff --git a/src/stories/DateTime.mdx b/src/stories/DateTime.mdx new file mode 100644 index 000000000..5f348dd37 --- /dev/null +++ b/src/stories/DateTime.mdx @@ -0,0 +1,64 @@ +import * as UI from '../../src/index' +import * as DateTimeStories from './DateTime.stories'; + +import { Canvas, Meta, Story } from "@storybook/blocks"; + + + +## formatDateTime + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#formatdatetime) + + + + + + + + + + + + + +## shortDate + +By default, converts e.g. '2020-02-19T19:35:28.557Z' to '19:35' if today is 19 Feb 2020, and to 'Feb 19' if not. + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#shortdate) + + + + + + + + + + + + + + + + + +## shortTime + +Get a short string representation of the current time + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#shorttime) + + + + + +## timestamp + +Get a string representation of the current time + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#timestamp) + + + + diff --git a/src/stories/DateTime.stories.js b/src/stories/DateTime.stories.js new file mode 100644 index 000000000..7d70dc1d7 --- /dev/null +++ b/src/stories/DateTime.stories.js @@ -0,0 +1,56 @@ +import * as UI from '../../src/index' + +export default { + title: 'Date & Time', +} + +export const FormatDateTime = { + render: () => + UI.widgets.formatDateTime( + new Date(), + '{FullYear}-{Month}-{Date}T{Hours}:{Minutes}:{Seconds}.{Milliseconds}' + ), + + name: 'formatDateTime', +} + +export const FormatDateTimeDate = { + render: () => UI.widgets.formatDateTime(new Date(), '{Date}.{Month}.{Year}'), + name: 'formatDateTime date', +} + +export const FormatDateTimeTime = { + render: () => + UI.widgets.formatDateTime(new Date(), '{Hours}:{Minutes}:{Seconds}'), + name: 'formatDateTime time', +} + +export const ShortDateNotTodayWithoutTime = { + render: () => UI.widgets.shortDate('2020-01-01T15:43', true), + name: 'shortDate (not today & without time)', +} + +export const ShortDateWithTimeButNotToday = { + render: () => UI.widgets.shortDate('2020-01-01T15:43', false), + name: 'shortDate (with time, but not today)', +} + +export const ShortDateTodayWithoutTime = { + render: () => UI.widgets.shortDate(new Date().toISOString(), true), + name: 'shortDate (today & without time)', +} + +export const ShortDateTodayWithTime = { + render: () => UI.widgets.shortDate(new Date().toISOString(), false), + name: 'shortDate (today & with time)', +} + +export const ShortTime = { + render: () => UI.widgets.shortTime(), + name: 'shortTime', +} + +export const Timestamp = { + render: () => UI.widgets.timestamp(), + name: 'timestamp', +} diff --git a/src/stories/Display.mdx b/src/stories/Display.mdx new file mode 100644 index 000000000..e9cfcfcfc --- /dev/null +++ b/src/stories/Display.mdx @@ -0,0 +1,32 @@ +import * as UI from '../../src/index' +import * as DisplayStories from './Display.stories'; + +import { Canvas, Meta, Story } from "@storybook/blocks"; + + + +## complain + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#complain) + + + + + +## errorMessageBlock + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_error_.html#errormessageblock) + + + + + +## setName + +Sets the best name we have and looks up a better one + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#setname) + + + + diff --git a/src/stories/Display.stories.js b/src/stories/Display.stories.js new file mode 100644 index 000000000..c99e14518 --- /dev/null +++ b/src/stories/Display.stories.js @@ -0,0 +1,43 @@ +import * as UI from '../../src/index' + +export default { + title: 'Display', +} + +export const Complain = { + render: () => { + const div = document.createElement('div') + + UI.widgets.complain( + { + div, + dom: document, + }, + 'not good!' + ) + + return div + }, + + name: 'complain', +} + +export const ErrorMessageBlock = { + render: () => { + return UI.widgets.errorMessageBlock(document, 'my error message', '#f0f') + }, + + name: 'errorMessageBlock', +} + +export const SetName = { + render: () => { + const div = document.createElement('div') + const jane = $rdf.namedNode('https://jane.example/person/card#me') + SolidLogic.store.add(jane, UI.ns.foaf('name'), 'Jane Doe') + UI.widgets.setName(div, jane) + return div + }, + + name: 'setName', +} diff --git a/src/stories/DomManipulation.mdx b/src/stories/DomManipulation.mdx new file mode 100644 index 000000000..7dbb7585a --- /dev/null +++ b/src/stories/DomManipulation.mdx @@ -0,0 +1,36 @@ +import * as UI from '../../src/index' +import * as DomManipulationStories from './DomManipulation.stories'; + +import { Canvas, Meta, Story } from "@storybook/blocks"; + + + +## addStyleSheet + +Stick a stylesheet link the document if not already there + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#addstylesheet) + + + + + +## clearElement + +Remove all the children of an HTML element + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#clearelement) + + + + + +## refreshTree + +Refresh a DOM tree recursively + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#refreshtree) + + + + diff --git a/src/stories/DomManipulation.stories.js b/src/stories/DomManipulation.stories.js new file mode 100644 index 000000000..8bd276d14 --- /dev/null +++ b/src/stories/DomManipulation.stories.js @@ -0,0 +1,66 @@ +import * as UI from '../../src/index' + +export default { + title: 'DOM manipulation', +} + +export const AddStyleSheet = { + render: () => { + UI.widgets.addStyleSheet( + document, + 'https://linkeddata.github.io/tabulator-firefox/content/tabbedtab.css' + ) + }, + + name: 'addStyleSheet', + withSource: 'open', + + decorators: [ + (Story) => { + Story() + const html = document.querySelector('link').outerHTML + const pre = document.createElement('pre') + const text = document.createTextNode(html) + pre.appendChild(text) + return pre + }, + ], +} + +export const ClearElement = { + render: () => { + let counter = 0 + const div = document.createElement('p') + + setInterval(() => { + if (counter++ % 2 === 0) { + const text = document.createTextNode('Now you see me') + div.appendChild(text) + } else { + UI.widgets.clearElement(div) + } + }, 1000) + + return div + }, + + name: 'clearElement', +} + +export const RefreshTree = { + render: () => { + setInterval(() => { + UI.widgets.refreshTree(document.body) + }, 1000) + + const refreshable = document.createElement('p') + + refreshable.refresh = () => { + refreshable.innerText = new Date().getTime() + } + + return refreshable + }, + + name: 'refreshTree', +} diff --git a/src/stories/DragAndDrop.mdx b/src/stories/DragAndDrop.mdx new file mode 100644 index 000000000..4c2b245ce --- /dev/null +++ b/src/stories/DragAndDrop.mdx @@ -0,0 +1,39 @@ +import * as UI from '../../src/index' +import * as DragAndDropStories from './DragAndDrop.stories'; + +import { Canvas, Meta, Story } from '@storybook/blocks'; +import { action } from '@storybook/addon-actions' + + + +## Drag & Drop + +DragAndDrop has three functions that can be used to handle dragging and dropping of uris, files, and images. + +`makeDraggable` is used to make an element Draggable. Along with the HTML Element, it is also necessary to pass an +object with a uri. This is used to set the data on the EventListener for 'dragstart'. + +`makeDropTarget` is used to make an element enabled as a drop target. Along with the HTML Element, it is also +necessary to pass in two callback functions; one to handle draggable uris and the other to handle draggable files and images. + +`uploadFiles` is used to process the files that a user is uploading. + +Drag the message from the "Draggable" story or drag any file or image and drop it on the element in the "Drop Target" story to see it +work. + + + + + + + + + +## uploadFiles + +The function `uploadFiles` could for example be used in the droppedFileHandler function which is passed to the +makeDropTarget function. + + + + diff --git a/src/stories/DragAndDrop.stories.js b/src/stories/DragAndDrop.stories.js new file mode 100644 index 000000000..9b7294b9a --- /dev/null +++ b/src/stories/DragAndDrop.stories.js @@ -0,0 +1,68 @@ +import * as UI from '../../src/index' + +import { action } from '@storybook/addon-actions' + +export default { + title: 'Drag & Drop', +} + +export const Draggable = { + render: () => { + const dragElement = document.createElement('div') + dragElement.appendChild(document.createTextNode('Drag me to the target!')) + const uri = new $rdf.NamedNode('https://exampleuser.inrupt.net') + UI.widgets.makeDraggable(dragElement, uri) + return dragElement + }, + + name: 'Draggable', +} + +export const DropTarget = { + render: () => { + const target = document.createElement('div') + target.style = + 'padding: 1em; text-align:center; border: 1px solid black; width: 100px; height: 100px' + target.appendChild( + document.createTextNode('Drop things (URIs, files, ...) here') + ) + UI.widgets.makeDropTarget( + target, + action('dropped uri'), + action('dropped file') + ) + return target + }, + + name: 'Drop Target', +} + +export const UploadFiles = { + render: ({ fileBase, pictureBase }) => { + const target = document.createElement('div') + target.style = + 'padding: 1em; text-align:center; border: 1px solid black; width: 100px; height: 100px' + target.appendChild( + document.createTextNode('Drop a file (document, picture, ...) here') + ) + + UI.widgets.makeDropTarget(target, action('dropped uri'), (files) => { + UI.widgets.uploadFiles( + SolidLogic.store.fetcher, + files, + fileBase, + pictureBase, + action('file uploaded successfully') + ) + }) + + return target + }, + + name: 'Upload Files', + + args: { + fileBase: 'https://pod.example/Files', + pictureBase: 'https://pod.example/Pictures', + }, +} diff --git a/src/stories/Events.mdx b/src/stories/Events.mdx new file mode 100644 index 000000000..e453b0dfe --- /dev/null +++ b/src/stories/Events.mdx @@ -0,0 +1,17 @@ +import * as UI from '../../src/index' +import * as EventsStories from './Events.stories'; + +import { Canvas, Meta, Story } from "@storybook/blocks"; +import { action } from "@storybook/addon-actions"; + + + +## openHrefInOutlineMode + +Event Handler for links within solid apps. + +[API docs](https://solidos.github.io/solid-ui/docs/api/modules/_widgets_buttons_.html#openhrefinoutlinemode) + + + + diff --git a/src/stories/Events.stories.js b/src/stories/Events.stories.js new file mode 100644 index 000000000..c222f99a0 --- /dev/null +++ b/src/stories/Events.stories.js @@ -0,0 +1,28 @@ +import * as UI from '../../src/index' + +import { action } from '@storybook/addon-actions' + +export default { + title: 'Events', +} + +export const OpenHrefInOutlineMode = { + render: () => { + document.outlineManager = { + GotoSubject: action('go to subject'), + } + + const anchor = document.createElement('a') + anchor.setAttribute('href', 'http://example.com') + + anchor.onclick = (e) => { + UI.widgets.openHrefInOutlineMode(e) + return false + } + + anchor.appendChild(document.createTextNode('click me')) + return anchor + }, + + name: 'openHrefInOutlineMode', +} diff --git a/src/stories/Header.mdx b/src/stories/Header.mdx new file mode 100644 index 000000000..b54481726 --- /dev/null +++ b/src/stories/Header.mdx @@ -0,0 +1,22 @@ +import * as UI from '../../src/index' +import * as HeaderStories from './Header.stories'; + +import { Canvas, Meta, Story } from "@storybook/blocks"; + + + +## Header + + + ` + } + + render () { + return html` + + + + ${this._popupOpen ? this._renderPopup() : ''} + + ` + } +} diff --git a/src/v2/components/auth/loginButton/README.md b/src/v2/components/auth/loginButton/README.md new file mode 100644 index 000000000..5c98bbf49 --- /dev/null +++ b/src/v2/components/auth/loginButton/README.md @@ -0,0 +1,121 @@ +# solid-ui-login-button component + +A Lit-based custom element that encapsulates the full Solid OIDC login flow. It renders a styled button that opens an identity provider (IDP) selection popup, handles the OIDC redirect, and emits a `login-success` event when the user is authenticated. + +Used automatically by `` when `auth-state="logged-out"` — see the [Header README](../header/README.md). + +## Installation + +```bash +npm install solid-ui +``` + +## Usage in a bundled project (webpack, Vite, Rollup, etc.) + +```javascript +import { LoginButton } from 'solid-ui/components/login-button' +``` + +```html + + + +``` + +## Usage in a plain HTML page (CDN / script tag) + +```html + + + +``` + +## TypeScript + +```typescript +import { LoginButton } from 'solid-ui/components/login-button' + +const btn = document.querySelector('solid-ui-login-button') as LoginButton +btn.label = 'Sign in to Solid' +btn.addEventListener('login-success', (e: CustomEvent) => { + const { webId } = e.detail +}) +``` + +## API + +### Properties / attributes + +| Property | Attribute | Type | Default | Description | +|-------------|---------------|--------------------|----------|-------------| +| `label` | `label` | `string` | `Log In` | Button text. Overridable via the default slot. | +| `issuerUrl` | `issuer-url` | `string` | `''` | Pre-fills the IDP URL input in the popup. If `localStorage.loginIssuer` is set it takes precedence. | +| `icon` | `icon` | `string` | `''` | URL of a decorative icon displayed on the left side of the button text. When used inside ``, the header suppresses the icon. | +| `layout` | `layout` | `'desktop' \| 'mobile'` | `'desktop'` | When set to `mobile`, removes the button border for a compact header appearance. | +| `theme` | `theme` | `'light' \| 'dark'` | `'light'` | Sets the colour theme. Use `'dark'` when placing the button on a dark background. | + +### Events + +| Event | Detail | Description | +|-----------------|-------------------------|-------------| +| `login-success` | `{ webId: string }` | Fired after a successful OIDC login. `webId` is the authenticated user's WebID URI. | + +### Slots + +| Slot | Description | +|-----------|-------------| +| (default) | Replaces the button label text. | + +### CSS custom properties + +The component inherits Header CSS variables automatically when used inside ``. When used standalone, these can be set on a parent or on `:root`: + +| Variable | Fallback | Description | +|-----------------------------------|-------------------------------------|-------------| +| `--login-button-background` | `--lavender-900` / `#7c4cff` | Login button background colour | +| `--login-button-text` | `--color-header-text` / `#ffffff` | Login button text colour | +| `--popup-background` | `--color-background` / `#F8F9FB` | Popup background colour | +| `--popup-text` | `--color-text` / `#1A1A1A` | Popup text colour | +| `--popup-border` | `--color-border` / `#E5E7EB` | Popup border colour | +| `--popup-shadow` | `--box-shadow-sm` / `0 1px 4px …` | Popup box shadow | +| `--popup-overlay-background` | `rgba(0, 0, 0, 0.6)` | Modal backdrop colour | +| `--issuer-input-background` | `--color-background` / `#F8F9FB` | IDP input background | +| `--issuer-input-text` | `--color-text` / `#1A1A1A` | IDP input text colour | +| `--issuer-input-border` | `--color-text` / `#1A1A1A` | IDP input border colour | +| `--issuer-button-hover-background`| `--lavender-900` / `#7c4cff` | Dropdown item hover background | +| `--issuer-label-color` | `--grey-purple-700` / `#1A1A1A` | IDP label text colour | +| `--issuer-placeholder-color` | `--grey-purple-700` / `#5e546d` | IDP input placeholder colour | +| `--error-text-color` | `--color-error` / `#B00020` | Validation error text colour | + +### Theming + +Set `theme="dark"` for dark backgrounds. The button background (`--primary-royal-lavender`) stays the same; the text colour switches to white. + +```html + +``` + +When used inside ``, the theme attribute is forwarded automatically. When the header is in `mobile` layout, its built-in login button suppresses the `icon`. When the `layout` attribute is set to `mobile`, the button renders without a border for a cleaner compact mobile/header presentation. + +## Popup behaviour + +- Opens a native `` via `showModal()`, placing it in the browser's **top layer** so it always renders above all other page content regardless of z-index stacking contexts. +- The backdrop is styled via `::backdrop`. +- Contains a text input pre-filled from `localStorage.loginIssuer` or the `issuer-url` attribute. +- If `solid-logic`'s `getSuggestedIssuers()` returns entries, a **▼ arrow button** inside the input reveals a dropdown list of suggested identity providers below the field. Selecting one fills the input. +- Footer row with **Cancel** (closes the popup) and **Login** (initiates the OIDC redirect) buttons centered at the bottom. The Login button is disabled while the input is empty. +- Closes on **Escape**, clicking the **Cancel** button, clicking the ✕ button, or clicking the backdrop. +- Saves the chosen issuer to `localStorage.loginIssuer` for future visits. +- Uses `offlineTestID()` from `solid-logic` for offline test environments — the popup is bypassed and `login-success` fires immediately. + +## Build + +```bash +npm run build +``` + +Webpack emits bundles to `dist/components/loginButton/index.*`. diff --git a/src/v2/components/auth/loginButton/downArrow.ts b/src/v2/components/auth/loginButton/downArrow.ts new file mode 100644 index 000000000..0578ecbe6 --- /dev/null +++ b/src/v2/components/auth/loginButton/downArrow.ts @@ -0,0 +1,10 @@ +import { html } from 'lit-html' + +export const phoneIcon = html` + + + +` diff --git a/src/v2/components/auth/loginButton/index.ts b/src/v2/components/auth/loginButton/index.ts new file mode 100644 index 000000000..0dff76088 --- /dev/null +++ b/src/v2/components/auth/loginButton/index.ts @@ -0,0 +1,9 @@ +import { LoginButton } from './LoginButton' + +export { LoginButton } + +const LOGIN_BUTTON_TAG_NAME = 'solid-ui-login-button' + +if (!customElements.get(LOGIN_BUTTON_TAG_NAME)) { + customElements.define(LOGIN_BUTTON_TAG_NAME, LoginButton) +} diff --git a/src/v2/components/auth/signupButton/README.md b/src/v2/components/auth/signupButton/README.md new file mode 100644 index 000000000..a26b37eb7 --- /dev/null +++ b/src/v2/components/auth/signupButton/README.md @@ -0,0 +1,91 @@ +# solid-ui-signup-button component + +A Lit-based custom element that renders a styled button which opens a Solid Pod signup page in a new browser tab. + +## Installation + +```bash +npm install solid-ui +``` + +## Usage in a bundled project (webpack, Vite, Rollup, etc.) + +```javascript +import { SignupButton } from 'solid-ui/components/signup-button' +``` + +```html + +``` +## Usage in a plain HTML page (CDN / script tag) + +```html + + + +``` + +## TypeScript + +```typescript +import { SignupButton } from 'solid-ui/components/signup-button' + +const btn = document.querySelector('solid-ui-signup-button') as SignupButton +btn.label = 'Create a Pod' +btn.signupUrl = 'https://solidproject.org/get_a_pod' +``` + +## API + +### Properties / attributes + +| Property | Attribute | Type | Default | Description | +|-------------|--------------|---------------------|--------------------------------------|-------------| +| `label` | `label` | `string` | `Sign Up` | Button text. Overridable via the default slot. | +| `signupUrl` | `signup-url` | `string` | `https://solidproject.org/get_a_pod` | URL opened in a new tab when the button is clicked. | +| `icon` | `icon` | `string` | `''` | URL of a decorative icon displayed on the left side of the label. | +| `layout` | `layout` | `'desktop' \| 'mobile'` | `'desktop'` | When set to `mobile`, removes the button border for a compact header appearance. | +| `theme` | `theme` | `'light' \| 'dark'` | `'light'` | Sets the colour theme. Use `'dark'` when placing the button on a dark background. | + +### Slots + +| Slot | Description | +|-----------|-------------| +| (default) | Replaces the button label text. | + +### CSS shadow parts + +| Part | Description | +|-----------------|-------------| +| `signup-button` | The inner ` + ` + } +} diff --git a/src/v2/components/auth/signupButton/index.ts b/src/v2/components/auth/signupButton/index.ts new file mode 100644 index 000000000..e3ea30c71 --- /dev/null +++ b/src/v2/components/auth/signupButton/index.ts @@ -0,0 +1,9 @@ +import { SignupButton } from './SignupButton' + +export { SignupButton } + +const SIGNUP_BUTTON_TAG_NAME = 'solid-ui-signup-button' + +if (!customElements.get(SIGNUP_BUTTON_TAG_NAME)) { + customElements.define(SIGNUP_BUTTON_TAG_NAME, SignupButton) +} diff --git a/src/v2/components/forms/combobox/Combobox.test.ts b/src/v2/components/forms/combobox/Combobox.test.ts new file mode 100644 index 000000000..cf792666f --- /dev/null +++ b/src/v2/components/forms/combobox/Combobox.test.ts @@ -0,0 +1,247 @@ +import { beforeEach, describe, expect, it, jest } from '@jest/globals' +import { Combobox } from './Combobox' +import './index' + +function getPortalRoot () { + const portalHost = document.querySelector('[data-solid-ui-combobox-portal]') as HTMLDivElement | null + return portalHost?.shadowRoot ?? null +} + +async function flushUpdates () { + await Promise.resolve() + await Promise.resolve() +} + +describe('SolidUICombobox', () => { + beforeEach(() => { + document.body.innerHTML = '' + }) + + it('is defined as a custom element', () => { + expect(customElements.get('solid-ui-combobox')).toBe(Combobox) + }) + + it('renders the input with label and placeholder', async () => { + const combobox = new Combobox() + combobox.label = 'Person' + combobox.placeholder = 'Search people' + + document.body.appendChild(combobox) + await combobox.updateComplete + + const label = combobox.shadowRoot?.querySelector('label.text-label') as HTMLLabelElement + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + const toggle = combobox.shadowRoot?.querySelector('button.dropdown-toggle') as HTMLButtonElement + + expect(label).not.toBeNull() + expect(label.textContent).toContain('Person') + expect(input).not.toBeNull() + expect(input.placeholder).toBe('Search people') + expect(input.getAttribute('part')).toBe('input') + expect(input.getAttribute('role')).toBe('combobox') + expect(input.getAttribute('aria-expanded')).toBe('false') + expect(toggle).not.toBeNull() + }) + + it('loads suggestions from suggestionProvider and emits input events', async () => { + const combobox = new Combobox() + const inputEvents = jest.fn() + const suggestionProvider = jest.fn(async (query: string) => [ + { label: `Alice ${query}`, value: 'alice' }, + { label: `Bob ${query}`, value: 'bob' } + ]) + + combobox.suggestionProvider = suggestionProvider + combobox.addEventListener('input', (event: Event) => { + inputEvents((event as CustomEvent).detail) + }) + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + input.value = 'al' + input.dispatchEvent(new Event('input', { bubbles: true, composed: true })) + + await flushUpdates() + await combobox.updateComplete + + const portalRoot = getPortalRoot() + const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf) + + expect(suggestionProvider).toHaveBeenCalledWith('al') + expect(inputEvents).toHaveBeenCalledWith({ value: 'al' }) + expect(combobox.inputValue).toBe('al') + expect(options).toHaveLength(2) + expect(options[0].textContent).toContain('Alice al') + }) + + it('renders the selected option first in the popup', async () => { + const combobox = new Combobox() + combobox.options = [ + { label: 'English', value: 'en' }, + { label: 'French', value: 'fr' }, + { label: 'Spanish', value: 'es' } + ] + combobox.value = 'fr' + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + input.dispatchEvent(new Event('focus')) + await combobox.updateComplete + + const portalRoot = getPortalRoot() + const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf) + + expect(options).toHaveLength(3) + expect(options[0].textContent).toContain('French') + expect(options[0].getAttribute('aria-selected')).toBe('true') + }) + + it('updates value and emits change when an option is clicked', async () => { + const combobox = new Combobox() + const changed = jest.fn() + + combobox.options = [ + { label: 'Alice', value: 'alice', publicId: 'https://example.com/alice' }, + { label: 'Bob', value: 'bob' } + ] + + combobox.addEventListener('change', (event: Event) => { + changed((event as CustomEvent).detail) + }) + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + input.dispatchEvent(new Event('focus')) + await combobox.updateComplete + + const portalRoot = getPortalRoot() + const options = portalRoot?.querySelectorAll('[role="option"]') as NodeListOf + options[1].click() + await combobox.updateComplete + + expect(combobox.value).toBe('bob') + expect(combobox.inputValue).toBe('Bob') + expect(input.getAttribute('aria-expanded')).toBe('false') + expect(changed).toHaveBeenCalledWith({ + value: 'bob', + label: 'Bob', + option: { label: 'Bob', value: 'bob' } + }) + }) + + it('opens the popup when clicking the dropdown toggle button', async () => { + const combobox = new Combobox() + combobox.options = [ + { label: 'Alice', value: 'alice' }, + { label: 'Bob', value: 'bob' } + ] + + document.body.appendChild(combobox) + await combobox.updateComplete + + const toggle = combobox.shadowRoot?.querySelector('button.dropdown-toggle') as HTMLButtonElement + + expect(toggle).not.toBeNull() + + toggle.click() + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + expect(input.getAttribute('aria-expanded')).toBe('true') + expect(getPortalRoot()?.querySelector('[role="listbox"]')).not.toBeNull() + }) + + it('supports keyboard selection from the input', async () => { + const combobox = new Combobox() + const changed = jest.fn() + + combobox.options = [ + { label: 'Alice', value: 'alice' }, + { label: 'Bob', value: 'bob' }, + { label: 'Carol', value: 'carol' } + ] + + combobox.addEventListener('change', (event: Event) => { + changed((event as CustomEvent).detail) + }) + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + + input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })) + await combobox.updateComplete + + expect(input.getAttribute('aria-expanded')).toBe('true') + expect(input.getAttribute('aria-activedescendant')).toBeTruthy() + + input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })) + await combobox.updateComplete + + input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })) + await combobox.updateComplete + + expect(combobox.value).toBe('bob') + expect(combobox.inputValue).toBe('Bob') + expect(changed).toHaveBeenCalledWith({ + value: 'bob', + label: 'Bob', + option: { label: 'Bob', value: 'bob' } + }) + }) + + it('does not treat space as a selection while typing', async () => { + const combobox = new Combobox() + + combobox.options = [ + { label: 'Self Employed', value: 'self-employed' }, + { label: 'Microsoft', value: 'microsoft' } + ] + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + + input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })) + await combobox.updateComplete + + const event = new KeyboardEvent('keydown', { key: ' ', bubbles: true, cancelable: true }) + input.dispatchEvent(event) + await combobox.updateComplete + + expect(event.defaultPrevented).toBe(false) + expect(combobox.value).toBe('') + expect(input.getAttribute('aria-expanded')).toBe('true') + }) + + it('closes the popup when clicking outside the component', async () => { + const combobox = new Combobox() + combobox.options = [ + { label: 'Alice', value: 'alice' }, + { label: 'Bob', value: 'bob' } + ] + + document.body.appendChild(combobox) + await combobox.updateComplete + + const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement + input.dispatchEvent(new Event('focus')) + await combobox.updateComplete + + expect(input.getAttribute('aria-expanded')).toBe('true') + expect(getPortalRoot()).not.toBeNull() + + document.body.dispatchEvent(new Event('pointerdown', { bubbles: true, composed: true })) + await combobox.updateComplete + + expect(input.getAttribute('aria-expanded')).toBe('false') + }) +}) diff --git a/src/v2/components/forms/combobox/Combobox.ts b/src/v2/components/forms/combobox/Combobox.ts new file mode 100644 index 000000000..13cb262d2 --- /dev/null +++ b/src/v2/components/forms/combobox/Combobox.ts @@ -0,0 +1,583 @@ +import { LitElement, html, css, nothing } from 'lit' +import { render as renderPortal } from 'lit/html.js' +import { downArrowIcon } from '../shared/downArrow' +import { listboxStyles } from '../shared/listboxStyles' +import { findOptionIndexByValue, getFirstEnabledIndex, getLastEnabledIndex, getListboxActionFromKey, getNextEnabledIndex } from '../shared/keyboard' +import { ComboboxSuggestion } from './comboboxTypes' +import { renderListbox } from '../shared/listboxTemplate' + +export class Combobox extends LitElement { + private static _nextId = 0 + private _popupPortalHost: HTMLDivElement | null = null + private _popupPortalRoot: ShadowRoot | null = null + private _popupPortalContainer: Element | null = null + private readonly _handleDocumentPointerDown = (event: Event) => { + const eventTarget = event.target + + if (!this._popupOpen || !(eventTarget instanceof Node)) { + return + } + + const eventPath = + 'composedPath' in event + ? (event as Event & { composedPath: () => EventTarget[] }).composedPath() + : [] + + if (eventPath.includes(this)) { + return + } + + if ( + (this._popupPortalHost && eventPath.includes(this._popupPortalHost)) || + (this._popupPortalRoot && eventPath.includes(this._popupPortalRoot)) + ) { + return + } + + if (!this.contains(eventTarget)) { + this._closePopup() + } + } + + private readonly _handleViewportChange = () => { + if (!this._popupOpen) return + this._updatePopupPosition() + } + + suggestionProvider?: (query: string) => Promise + + static properties = { + label: { type: String, reflect: true }, + placeholder: { type: String, reflect: true }, + theme: { type: String, reflect: true }, + layout: { type: String, reflect: true }, + value: { type: String, reflect: true }, + inputValue: { type: String }, + options: { type: Array, attribute: false }, + _popupOpen: { state: true }, + _activeIndex: { state: true } + } + + static styles = [ + listboxStyles, + css` + :host { + /* default theme */ + display: block; + width: 100%; + min-width: 0; + max-width: 100%; + position: relative; + box-sizing: border-box; + --popup-background: var(--color-background, #F8F9FB); + --popup-text: var(--color-text, #1A1A1A); + --popup-border: var(--color-border, #E5E7EB); + --popup-shadow: var(--box-shadow-sm, 0 1px 4px rgba(124,77,255,0.12)); + --input-background: var(--color-background, #F8F9FB); + --input-text: var(--color-text, #1A1A1A); + --input-border: var(--color-border-button-hover, var(--gray-400, #99A1AF)); + --label-color: var(--grey-purple-700, #1A1A1A); + --placeholder-color: var(--grey-purple-700, #5e546d); + --combobox-input-height: var(--select-trigger-height, var(--min-touch-target, 44px)); + --combobox-input-inline-padding: var(--select-trigger-inline-padding, var(--spacing-2xs, 0.625rem)); + --combobox-input-block-padding: var(--spacing-xxs, 0.3125rem); + } + + :host([theme='dark']) { + display: block; + width: 100%; + min-width: 0; + max-width: 100%; + position: relative; + box-sizing: border-box; + --popup-background: var(--color-background, #F8F9FB); + --popup-text: var(--color-text, #1A1A1A); + --popup-border: var(--color-border, #E5E7EB); + --popup-shadow: var(--box-shadow-sm, 0 1px 4px rgba(124,77,255,0.12)); + --input-background: var(--color-background, #F8F9FB); + --input-text: var(--color-text, #1A1A1A); + --input-border: var(--color-border-button-hover, var(--gray-400, #99A1AF)); + --label-color: var(--grey-purple-700, #1A1A1A); + --placeholder-color: var(--grey-purple-700, #5e546d); + --combobox-input-height: var(--select-trigger-height, var(--min-touch-target, 44px)); + --combobox-input-inline-padding: var(--select-trigger-inline-padding, var(--spacing-2xs, 0.625rem)); + --combobox-input-block-padding: var(--spacing-xxs, 0.3125rem); + } + + .popup-box { + position: absolute; + top: 0; + left: 0; + width: 100%; + background: var(--popup-background); + color: var(--popup-text); + box-shadow: var(--popup-shadow); + border: 1px solid var(--popup-border); + border-radius: var(--border-radius-md, 0.5rem); + min-width: 100%; + overflow: hidden; + box-sizing: border-box; + isolation: isolate; + } + + .select-options-section { + position: relative; + background: var(--popup-background); + border-radius: inherit; + isolation: isolate; + } + + .combobox-root { + display: flex; + flex-direction: column; + gap: 6px; + } + + .text-label { + color: var(--label-color); + margin-bottom: 6px; + } + + .input-field-row { + display: flex; + flex-direction: row; + position: relative; + width: 100%; + min-width: 0; + } + + .text-input { + display: block; + flex: 1; + width: 100%; + min-width: 0; + min-height: var(--combobox-input-height); + height: var(--combobox-input-height); + padding: var(--combobox-input-block-padding) calc(26px + (var(--combobox-input-inline-padding) * 2) + 6px) var(--combobox-input-block-padding) var(--combobox-input-inline-padding); + border: 1px solid var(--input-border); + border-radius: var(--border-radius-base, 0.3125rem); + background: var(--input-background); + color: var(--input-text); + font: inherit; + font-size: var(--font-size-sm, 0.875rem); + font-weight: var(--font-weight-md, 500); + line-height: normal; + appearance: none; + -webkit-appearance: none; + box-sizing: border-box; + } + + .text-input::placeholder { + color: var(--placeholder-color); + } + + .text-input:focus-visible { + outline: 2px solid var(--color-focus-ring, var(--color-primary, #7C4DFF)); + outline-offset: 2px; + } + + .dropdown-toggle { + position: absolute; + right: 6px; + top: 50%; + transform: translateY(-50%); + width: 26px; + height: 26px; + padding: 0; + border: none; + background: transparent; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: var(--border-radius-base, 0.3125rem); + } + + .dropdown-toggle:hover { + background: var(--color-header-menu-item-hover, #e6dcff); + } + + .input-field-row:focus-within .dropdown-toggle { + background: var(--color-header-menu-item-hover, #e6dcff); + } + + .dropdown-toggle:focus-visible { + outline: 2px solid var(--color-focus-ring, var(--color-primary, #7C4DFF)); + outline-offset: 2px; + background: var(--color-header-menu-item-hover, #e6dcff); + } + + .dropdown-toggle svg { + width: 14px; + height: 14px; + display: block; + } + } + ` + ] + + declare label: string + declare placeholder: string + declare theme: 'light' | 'dark' + declare options: Array + declare layout: 'desktop' | 'mobile' + declare value: string + declare inputValue: string + declare _popupOpen: boolean + declare _activeIndex: number + + private readonly _inputId = `solid-ui-combobox-input-${Combobox._nextId++}` + private readonly _listboxId = `solid-ui-combobox-listbox-${Combobox._nextId++}` + private _suggestionRequestId = 0 + + constructor () { + super() + this.label = 'Select an option' + this.placeholder = 'Type to search' + this.theme = 'light' + this.layout = 'desktop' + this.options = [] + this.value = '' + this.inputValue = '' + this._popupOpen = false + this._activeIndex = -1 + } + + connectedCallback () { + super.connectedCallback() + document.addEventListener('pointerdown', this._handleDocumentPointerDown) + window.addEventListener('resize', this._handleViewportChange) + window.addEventListener('scroll', this._handleViewportChange, true) + } + + disconnectedCallback () { + this._detachPopupPortal() + document.removeEventListener('pointerdown', this._handleDocumentPointerDown) + window.removeEventListener('resize', this._handleViewportChange) + window.removeEventListener('scroll', this._handleViewportChange, true) + super.disconnectedCallback() + } + + private _getPopupPortalContainer () { + return this.closest('dialog[open]') || document.body + } + + private _ensurePopupPortal () { + const nextContainer = this._getPopupPortalContainer() + + if ( + this._popupPortalHost && + this._popupPortalRoot && + this._popupPortalContainer === nextContainer + ) { + return + } + + this._detachPopupPortal() + + this._popupPortalHost = document.createElement('div') + this._popupPortalHost.setAttribute('data-solid-ui-combobox-portal', '') + this._popupPortalHost.style.position = 'fixed' + this._popupPortalHost.style.inset = '0 auto auto 0' + this._popupPortalHost.style.zIndex = '2147483647' + this._popupPortalHost.style.pointerEvents = 'none' + this._popupPortalHost.style.boxSizing = 'border-box' + + this._popupPortalRoot = this._popupPortalHost.attachShadow({ mode: 'open' }) + const styleSheets = (Array.isArray(Combobox.styles) ? Combobox.styles : [Combobox.styles]) + .map((style) => style?.styleSheet) + .filter((styleSheet): styleSheet is CSSStyleSheet => Boolean(styleSheet)) + + if (styleSheets.length > 0) { + this._popupPortalRoot.adoptedStyleSheets = styleSheets + } + + nextContainer.appendChild(this._popupPortalHost) + this._popupPortalContainer = nextContainer + } + + private _detachPopupPortal () { + if (this._popupPortalRoot) { + renderPortal(null, this._popupPortalRoot) + } + + if (this._popupPortalHost?.parentNode) { + this._popupPortalHost.parentNode.removeChild(this._popupPortalHost) + } + + this._popupPortalHost = null + this._popupPortalRoot = null + this._popupPortalContainer = null + } + + private _updatePopupPosition () { + this._ensurePopupPortal() + + const rect = this.getBoundingClientRect() + const maxHeight = Math.min(288, Math.max(120, window.innerHeight - rect.bottom - 12)) + + if (this._popupPortalHost) { + this._popupPortalHost.style.top = `${Math.round(rect.bottom + 2)}px` + this._popupPortalHost.style.left = `${Math.round(rect.left)}px` + this._popupPortalHost.style.width = `${Math.round(rect.width)}px` + this._popupPortalHost.style.maxHeight = `${Math.round(maxHeight)}px` + this._popupPortalHost.style.height = '0px' + } + } + + private _openPopup () { + const popupOptions = this._getDisplayedOptions() + + this._popupOpen = true + this._updatePopupPosition() + this._activeIndex = findOptionIndexByValue(popupOptions, this.value) + + if (this._activeIndex < 0) { + this._activeIndex = getFirstEnabledIndex(popupOptions) + } + } + + private _closePopup () { + this._popupOpen = false + if (this._popupPortalRoot) { + renderPortal(null, this._popupPortalRoot) + } + } + + protected updated (changedProperties: Map) { + if (this._popupOpen) { + this._updatePopupPosition() + if (this._popupPortalRoot) { + renderPortal(this._renderPopup(), this._popupPortalRoot) + } + } else if (this._popupPortalRoot) { + renderPortal(null, this._popupPortalRoot) + } + + if ((changedProperties.has('value') || changedProperties.has('options')) && this.value) { + const selectedOption = this.options.find((option) => option.value === this.value) + if (selectedOption && this.inputValue !== selectedOption.label) { + this.inputValue = selectedOption.label + } + } + } + + private _getSelectedIndex () { + return findOptionIndexByValue(this.options, this.value) + } + + private _getSelectedOption () { + const selectedIndex = this._getSelectedIndex() + + if (selectedIndex >= 0) { + return this.options[selectedIndex] + } + + return this.options[0] + } + + private _getDisplayedOptions () { + const selectedOption = this._getSelectedOption() + + if (!selectedOption) { + return this.options + } + + return [ + selectedOption, + ...this.options.filter((option) => option.value !== selectedOption.value) + ] + } + + private _getActiveOption () { + const popupOptions = this._getDisplayedOptions() + + if (this._activeIndex < 0) { + return undefined + } + + return popupOptions[this._activeIndex] + } + + private async _loadSuggestions (query: string) { + if (!this.suggestionProvider) { + this._openPopup() + return + } + + const requestId = ++this._suggestionRequestId + const suggestions = await this.suggestionProvider(query) + + if (requestId !== this._suggestionRequestId) { + return + } + + this.options = suggestions + this._openPopup() + } + + private async _handleInputChange (e: Event) { + const query = (e.target as HTMLInputElement).value + + this.inputValue = query + this.value = '' + this.dispatchEvent(new CustomEvent('input', { + detail: { value: query }, + bubbles: true, + composed: true + })) + await this._loadSuggestions(query) + } + + private _handleInputKeydown (e: KeyboardEvent) { + if (e.key === ' ' || e.key === 'Spacebar') { + return + } + + const popupOptions = this._getDisplayedOptions() + const action = getListboxActionFromKey(e.key) + + if (action === 'none') { + return + } + + e.preventDefault() + + switch (action) { + case 'close': + this._closePopup() + break + case 'first': + if (!this._popupOpen) { + this._openPopup() + } + this._activeIndex = getFirstEnabledIndex(popupOptions) + break + case 'last': + if (!this._popupOpen) { + this._openPopup() + } + this._activeIndex = getLastEnabledIndex(popupOptions) + break + case 'next': + if (!this._popupOpen) { + this._openPopup() + break + } + this._activeIndex = getNextEnabledIndex(this._activeIndex, popupOptions, 1) + break + case 'previous': + if (!this._popupOpen) { + this._openPopup() + break + } + this._activeIndex = getNextEnabledIndex(this._activeIndex, popupOptions, -1) + break + case 'select': + if (!this._popupOpen) { + this._openPopup() + break + } + this._selectActiveOption() + break + default: + break + } + } + + private _getOptionId (option: ComboboxSuggestion, index: number) { + return `${this._listboxId}-option-${index}-${option.value}` + } + + private _selectValueFromDropdown (value: string) { + const selectedOption = this.options.find(option => option.value === value) + + this.value = value + this.inputValue = selectedOption?.label ?? value + this.dispatchEvent(new CustomEvent('change', { + detail: { + value, + label: this.inputValue, + option: selectedOption + }, + bubbles: true, + composed: true + })) + this._closePopup() + } + + private _selectActiveOption () { + const activeOption = this._getActiveOption() + + if (activeOption && !activeOption.disabled) { + this._selectValueFromDropdown(activeOption.value) + } + } + + private _renderPopup () { + const popupOptions = this._getDisplayedOptions() + const selectedOption = this._getSelectedOption() + const activeOption = this._activeIndex >= 0 ? popupOptions[this._activeIndex] : undefined + + return html` + + ` + } + + render () { + const activeOption = this._getActiveOption() + const activeDescendant = this._popupOpen && activeOption + ? this._getOptionId(activeOption, this._activeIndex) + : undefined + const ariaLabel = this.label ? nothing : (this.getAttribute('aria-label') || this.placeholder || 'Combobox') + + return html` +
    + ${this.label + ? html`` + : null} +
    + + +
    +
    + ` + } +} diff --git a/src/v2/components/forms/combobox/README.md b/src/v2/components/forms/combobox/README.md new file mode 100644 index 000000000..5a585bf62 --- /dev/null +++ b/src/v2/components/forms/combobox/README.md @@ -0,0 +1,221 @@ +# solid-ui-combobox component + +A Lit-based custom element that renders a styled combobox with a text input and a custom popup listbox. It supports async suggestion loading through a consumer-provided `suggestionProvider`, keyboard navigation, `input` and `change` events, and keeps the currently selected option at the top of the popup when opened. + +## Installation + +```bash +npm install solid-ui +``` + +## Usage in a bundled project (webpack, Vite, Rollup, etc.) + +```javascript +import { Combobox } from 'solid-ui/components/forms/combobox' +``` + +The legacy flat import path `solid-ui/components/combobox` still works, but the grouped `forms/combobox` path is the preferred long-term entrypoint. + +```html + + + +``` + +## Usage in a plain HTML page (CDN / script tag) + +```html + + + + + +``` + +## TypeScript + +```typescript +import { Combobox } from 'solid-ui/components/forms/combobox' + +const combobox = document.querySelector('solid-ui-combobox') as Combobox + +combobox.suggestionProvider = async (query) => { + return [ + { label: `Result for ${query}`, value: query.toLowerCase() } + ] +} + +combobox.addEventListener( + 'change', + (e: CustomEvent<{ value: string; label: string; option?: { label: string; value: string } }>) => { + console.log(e.detail.value) + } +) +``` + +The component works with suggestion objects shaped like: + +```typescript +type ComboboxSuggestion = { + label: string + value: string + disabled?: boolean + publicId?: string + meta?: Record +} +``` + +## API + +### Properties / attributes + +| Property | Attribute | Type | Default | Description | +|----------|-----------|------|---------|-------------| +| `label` | `label` | `string` | `Select an option` | Visible label rendered above the input. If omitted, provide an `aria-label` for accessibility. | +| `placeholder` | `placeholder` | `string` | `Type to search` | Placeholder text shown inside the input when it is empty. | +| `theme` | `theme` | `'light' \| 'dark'` | `'light'` | Sets the colour theme. | +| `options` | `options` | `ComboboxSuggestion[]` | `[]` | Current list of suggestions shown in the popup. In practice this should be set as a property from JavaScript rather than as an HTML attribute. | +| `layout` | `layout` | `'desktop' \| 'mobile'` | `'desktop'` | Layout mode reserved for integration with other responsive components. | +| `value` | `value` | `string` | `''` | The currently selected suggestion value. If it matches a suggestion, that suggestion is shown in the input and moved to the top of the popup when opened. | +| `inputValue` | none | `string` | `''` | Current raw text shown in the input field. This updates as the user types. | +| `suggestionProvider` | none | `(query: string) => Promise` | `undefined` | Optional async function supplied by the consumer. It receives the current input text and returns normalized suggestions for the popup. | + +### Events + +| Event | Detail | Description | +|-------|--------|-------------| +| `input` | `{ value: string }` | Fired when the user types in the input. Useful when the consumer wants to observe free text in addition to providing a `suggestionProvider`. | +| `change` | `{ value: string; label: string; option?: ComboboxSuggestion }` | Fired when the user selects a suggestion from the popup or confirms a keyboard selection. | + +### CSS custom properties + +These can be set on `solid-ui-combobox`, on a container element, or on `:root`. + +| Variable | Fallback | Description | +|----------|----------|-------------| +| `--popup-background` | `--color-background` | Popup surface background. | +| `--popup-text` | `--color-text` | Popup text colour. | +| `--popup-border` | `--color-border` / `#E5E7EB` | Popup border colour. | +| `--popup-shadow` | `--box-shadow-sm` / `0 1px 4px ...` | Popup shadow. | +| `--input-background` | `--color-background` | Input and popup background. | +| `--input-text` | `--color-text` | Input text colour. | +| `--input-border` | `--color-text` | Input border colour. | +| `--label-color` | `--grey-purple-700` | Label text colour. | +| `--placeholder-color` | `--grey-purple-700` | Placeholder text colour. | +| `--item-text` | `--color-text` | Option text colour. | +| `--item-selected-text` | `--color-primary` / `#7c4dff` | Active option text colour. | +| `--item-hover-background` | `--lavender-300` / `#e6dcff` | Hover background for option rows. | +| `--item-selected-background` | `--lavender-400` / `#cbb9ff` | Active option background. | + +The component also inherits common design-system tokens such as `--border-radius-base`, `--border-radius-md`, `--color-background`, `--color-border`, `--color-text`, `--color-primary`, `--box-shadow-sm`, `--lavender-300`, and `--lavender-400`. + +### CSS shadow parts + +These parts can be styled from a consuming repo using `::part(...)`. + +| Part | Description | +|------|-------------| +| `input` | The text input inside the combobox field. | +| `listbox` | The `