diff --git a/.dockerignore b/.dockerignore
index 4e81ff3..f4c17db 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -4,6 +4,7 @@ dist/
client/dev/
client/dist/
client/node_modules/
+client/fluid-player/node_modules/
__pycache__
venv
.env
@@ -20,3 +21,4 @@ docker-compose*
node_modules
npm-debug.log
README.md
+.history
diff --git a/.flake8 b/.flake8
index 533d94a..a8fae70 100644
--- a/.flake8
+++ b/.flake8
@@ -6,6 +6,10 @@ ignore =
F401
# flake struggles with endpoints returning tuples on exceptions
E722
+ # apparently it's both an antipattern and a best practice:
+ # https://www.flake8rules.com/rules/W503.html
+ # just python things
+ W503
exclude =
.git,
__pycache__,
diff --git a/.gitignore b/.gitignore
index 46e04fc..6d3d19e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,6 @@ flask.cfg
/config.py
redis_map.py
-# Dev only files
-test/
.idea
dev_*
@@ -164,3 +162,5 @@ dmypy.json
# Cython debug symbols
cython_debug/
+
+.history
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 0a2c97d..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-repos:
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: 38b88246ccc552bffaaf54259d064beeee434539 # frozen: v4.0.1
- hooks:
- - id: trailing-whitespace
- - id: end-of-file-fixer
- - id: check-yaml
- - id: check-added-large-files
- - repo: https://github.com/pycqa/flake8
- rev: "cbeb4c9c4137cff1568659fcc48e8b85cddd0c8d" # frozen: 4.0.1
- hooks:
- - id: flake8
- - repo: https://github.com/pre-commit/mirrors-autopep8
- rev: "7d14f78422aef2153a90e33373d2515bcc99038d" # frozen: v1.5.7
- hooks:
- - id: autopep8
diff --git a/Dockerfile b/Dockerfile
index 0cb1a1a..2544391 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,25 +1,18 @@
-FROM nikolaik/python-nodejs:python3.12-nodejs18
-
-RUN apt-get update && apt-get install -y libpq-dev curl jq
-
-RUN curl -s -L $(curl https://api.github.com/repos/tus/tusd/releases/latest -s | jq '.assets[] | select(.name=="tusd_linux_amd64.tar.gz") | .browser_download_url' -r) | tar -xzvf - -C /usr/local/bin/ --strip-components=1 tusd_linux_amd64/tusd && chmod +x /usr/local/bin/tusd
+FROM python:3.12
WORKDIR /app
+RUN apt-get update && apt-get install -y libpq-dev curl jq
+
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
-RUN npm install -g npm
-
-RUN mkdir client
-COPY ./client /app/client
-
-RUN cd client && npm ci --also=dev && cd ..
-
COPY . /app
ENV LANG=C.UTF-8
ARG GIT_COMMIT_HASH
ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH:-undefined}
+ARG BUILD_DATE
+ENV BUILD_DATE=${BUILD_DATE:-undefined}
CMD python -m src daemon
diff --git a/Dockerfile-ci b/Dockerfile-ci
new file mode 100644
index 0000000..3c8dbf6
--- /dev/null
+++ b/Dockerfile-ci
@@ -0,0 +1,42 @@
+# Client build
+FROM node:22.13 AS client-builder
+
+WORKDIR /app/client
+
+# kind of retarded but such is a price for inlining dependencies
+COPY client/fluid-player/package.json client/fluid-player/package-lock.json ./fluid-player/
+
+COPY client/package.json client/package-lock.json ./
+
+RUN npm ci --include=dev
+
+COPY schema ../schema
+
+COPY config.json ../config.json
+
+COPY client ./
+
+RUN npm run build
+
+# Server build
+FROM python:3.12 AS server-builder
+
+RUN apt-get update \
+ && apt-get install -y libpq-dev
+
+WORKDIR /app
+
+COPY requirements.txt requirements.txt
+RUN pip3 install -r requirements.txt
+
+COPY . /app
+
+COPY --from=client-builder /app/client/dist ./client/dist
+
+ENV LANG=C.UTF-8
+ARG GIT_COMMIT_HASH
+ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH:-undefined}
+ARG BUILD_DATE
+ENV BUILD_DATE=${BUILD_DATE:-undefined}
+
+CMD python -m src daemon
diff --git a/Dockerfile-client b/Dockerfile-client
new file mode 100644
index 0000000..fae299a
--- /dev/null
+++ b/Dockerfile-client
@@ -0,0 +1,13 @@
+FROM node:22.13
+WORKDIR /app/client
+CMD [ "npm", "run", "build" ]
+
+RUN npm install -g npm
+COPY ./ /app
+RUN npm ci --include=dev
+
+ENV LANG=C.UTF-8
+ARG GIT_COMMIT_HASH
+ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH:-undefined}
+ARG BUILD_DATE
+ENV BUILD_DATE=${BUILD_DATE:-undefined}
diff --git a/client/configs/parse-config.mjs b/client/configs/parse-config.mjs
new file mode 100644
index 0000000..7433604
--- /dev/null
+++ b/client/configs/parse-config.mjs
@@ -0,0 +1,42 @@
+// @ts-check
+import path from "node:path";
+import fs from "node:fs";
+import Ajv from "ajv";
+
+const ajv = new Ajv();
+
+/**
+ * @returns {import("../../schema/config.ts").IConfiguration}
+ */
+export function parseConfiguration() {
+ const configSchemaPath = path.resolve(
+ __dirname,
+ "..",
+ "..",
+ "schema",
+ "config.schema.json"
+ );
+ const configPath = path.resolve(__dirname, "..", "..", "config.json");
+ const configFileSchemaContent = fs.readFileSync(configSchemaPath, {
+ encoding: "utf8",
+ });
+ const configFileContent = fs.readFileSync(configPath, { encoding: "utf8" });
+ const configSchema = JSON.parse(configFileSchemaContent);
+ /**
+ * @type {import("../../schema/config.ts").IConfiguration}
+ */
+ const config = JSON.parse(configFileContent);
+
+ const isValid = ajv.validate(configSchema, config);
+
+ if (!isValid) {
+ /**
+ * @type {import("ajv").ErrorObject, unknown>[]}
+ */
+ // @ts-expect-error
+ const errors = ajv.errors
+ throw new AggregateError(errors, "Failed to validate the config.")
+ }
+
+ return config;
+}
diff --git a/client/configs/vars.js b/client/configs/vars.js
deleted file mode 100644
index e5dac3b..0000000
--- a/client/configs/vars.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// @ts-check
-const path = require("path");
-const fs = require("fs");
-
-/**
- * @typedef IConfiguration
- * @property {string} site
- * @property {string} [sentry_dsn_js]
- * @property {boolean} development_mode
- * @property {boolean} automatic_migrations
- * @property {IServerConfig} webserver
- * @property {IArchiveServerConfig} [archive_server]
- */
-
-/**
- * @typedef IServerConfig
- * @property {IUIConfig} ui
- * @property {number} port
- * @property {string} [base_url]
- */
-
-/**
- * @typedef IUIConfig
- * @property {IHomeConfig} home
- * @property {{paysite_list: string[], artists_or_creators: string}} config
- * @property {IMatomoConfig} [matomo]
- * @property {ISidebarConfig} [sidebar]
- * @property {unknown[]} sidebar_items
- * @property {unknown[]} [footer_items]
- * @property {IBannerConfig} [banner]
- * @property {IAdsConfig} [ads]
- */
-
-/**
- * @typedef IMatomoConfig
- * @property {boolean} enabled
- * @property {string} plain_code b64-encoded string
- * @property {string} tracking_domain
- * @property {string} tracking_code
- * @property {string} site_id
- */
-
-/**
- * @typedef ISidebarConfig
- * @property {boolean} [disable_dms]
- * @property {boolean} [disable_faq]
- * @property {boolean} [disable_filehaus]
- */
-
-/**
- * @typedef IBannerConfig
- * @property {string} [global] b64-encoded string
- * @property {string} [welcome] b64-encoded string
- */
-
-/**
- * @typedef IHomeConfig
- * @property {string} [site_name]
- * @property {string} [mascot_path]
- * @property {string} [logo_path]
- * @property {string} [welcome_credits] b64-encoded string
- * @property {string} [home_background_image]
- * @property {{ title: string, date: string, content: string }[]} [announcements]
- */
-
-/**
- * @typedef IAdsConfig
- * @property {string} [header] b64-encoded string
- * @property {string} [middle] b64-encoded string
- * @property {string} [footer] b64-encoded string
- * @property {string} [slider] b64-encoded string
- * @property {string} [video] b64-encoded JSON string
- */
-
-/**
- * @typedef IArchiveServerConfig
- * @property {boolean} [enabled]
- */
-
-const configuration = getConfiguration();
-const apiServerBaseURL = configuration.webserver.base_url;
-const sentryDSN = configuration.sentry_dsn_js;
-const apiServerPort = !apiServerBaseURL
- ? undefined
- : configuration.webserver.port;
-const siteName = configuration.webserver.ui.home.site_name || "Kemono";
-const homeBackgroundImage =
- configuration.webserver.ui.home.home_background_image;
-const homeMascotPath = configuration.webserver.ui.home.mascot_path;
-const homeLogoPath = configuration.webserver.ui.home.logo_path;
-const homeWelcomeCredits = configuration.webserver.ui.home.welcome_credits;
-const homeAnnouncements = configuration.webserver.ui.home.announcements;
-// TODO: in development it should point to webpack server
-const kemonoSite = configuration.site || "http://localhost:5000";
-const paysiteList = configuration.webserver.ui.config.paysite_list;
-const artistsOrCreators =
- configuration.webserver.ui.config.artists_or_creators ?? "Artists";
-const disableDMs = configuration.webserver.ui.sidebar?.disable_dms ?? true;
-const disableFAQ = configuration.webserver.ui.sidebar?.disable_faq ?? true;
-const disableFilehaus =
- configuration.webserver.ui.sidebar?.disable_filehaus ?? true;
-const sidebarItems = configuration.webserver.ui.sidebar_items;
-const footerItems = configuration.webserver.ui.footer_items;
-const bannerGlobal = configuration.webserver.ui.banner?.global;
-const bannerWelcome = configuration.webserver.ui.banner?.welcome;
-const headerAd = configuration.webserver.ui.ads?.header;
-const middleAd = configuration.webserver.ui.ads?.middle;
-const footerAd = configuration.webserver.ui.ads?.footer;
-const sliderAd = configuration.webserver.ui.ads?.slider;
-const videoAd = configuration.webserver.ui.ads?.video;
-const isArchiveServerEnabled = configuration.archive_server?.enabled ?? false;
-const analyticsEnabled = configuration.webserver.ui.matomo?.enabled ?? false;
-const analyticsCode = configuration.webserver.ui.matomo?.plain_code;
-const iconsPrepend = process.env.ICONS_PREPEND || "";
-const bannersPrepend = process.env.BANNERS_PREPEND || "";
-const thumbnailsPrepend = process.env.THUMBNAILS_PREPEND || "";
-const creatorsLocation = process.env.CREATORS_LOCATION || "";
-
-/**
- * @TODO config validation
- * @returns {IConfiguration}
- */
-function getConfiguration() {
- const configPath = path.resolve(__dirname, "..", "..", "config.json");
- // TODO: async reading
- const fileContent = fs.readFileSync(configPath, { encoding: "utf8" });
- /**
- * @type {IConfiguration}
- */
- const config = JSON.parse(fileContent);
-
- return config;
-}
-
-module.exports = {
- kemonoSite,
- sentryDSN,
- siteName,
- iconsPrepend,
- bannersPrepend,
- thumbnailsPrepend,
- creatorsLocation,
- artistsOrCreators,
- disableDMs,
- disableFAQ,
- disableFilehaus,
- sidebarItems,
- footerItems,
- bannerGlobal,
- bannerWelcome,
- homeBackgroundImage,
- homeMascotPath,
- homeLogoPath,
- paysiteList,
- homeWelcomeCredits,
- homeAnnouncements,
- headerAd,
- middleAd,
- footerAd,
- sliderAd,
- videoAd,
- isArchiveServerEnabled,
- apiServerBaseURL,
- apiServerPort,
- analyticsEnabled,
- analyticsCode,
-};
diff --git a/client/configs/vars.mjs b/client/configs/vars.mjs
new file mode 100644
index 0000000..112686a
--- /dev/null
+++ b/client/configs/vars.mjs
@@ -0,0 +1,47 @@
+// @ts-check
+import { parseConfiguration } from "./parse-config.mjs";
+
+export const configuration = parseConfiguration();
+export const { webserver } = configuration;
+export const apiServerBaseURL = configuration.webserver.base_url;
+export const sentryDSN = configuration.sentry_dsn_js;
+export const apiServerPort = !apiServerBaseURL
+ ? undefined
+ : configuration.webserver.port;
+export const siteName = configuration.webserver.ui.home.site_name || "Kemono";
+export const homeBackgroundImage =
+ configuration.webserver.ui.home.home_background_image;
+export const homeMascotPath = configuration.webserver.ui.home.mascot_path;
+export const homeLogoPath = configuration.webserver.ui.home.logo_path;
+export const homeWelcomeCredits = configuration.webserver.ui.home.welcome_credits;
+export const homeAnnouncements = configuration.webserver.ui.home.announcements;
+// TODO: in development it should point to webpack server
+export const kemonoSite = configuration.site || "http://localhost:5000";
+export const paysiteList = configuration.webserver.ui.config.paysite_list;
+export const artistsOrCreators =
+ configuration.webserver.ui.config.artists_or_creators ?? "Artists";
+export const disableDMs = configuration.webserver.ui.sidebar?.disable_dms ?? true;
+export const disableFAQ = configuration.webserver.ui.sidebar?.disable_faq ?? true;
+export const disableFilehaus =
+ configuration.webserver.ui.sidebar?.disable_filehaus ?? true;
+export const sidebarItems = configuration.webserver.ui.sidebar_items;
+export const footerItems = configuration.webserver.ui.footer_items;
+export const bannerGlobal = configuration.webserver.ui.banner?.global;
+export const bannerWelcome = configuration.webserver.ui.banner?.welcome;
+export const headerAd = configuration.webserver.ui.ads?.header;
+export const middleAd = configuration.webserver.ui.ads?.middle;
+export const footerAd = configuration.webserver.ui.ads?.footer;
+export const sliderAd = configuration.webserver.ui.ads?.slider;
+export const videoAd = configuration.webserver.ui.ads?.video;
+export const isArchiveServerEnabled = configuration.archive_server?.enabled ?? false;
+export const analyticsEnabled = configuration.webserver.ui.matomo?.enabled ?? false;
+export const analyticsCode = configuration.webserver.ui.matomo?.plain_code;
+export const iconsPrepend = webserver.ui.files_url_prepend?.icons_base_url || "";
+export const bannersPrepend = webserver.ui.files_url_prepend?.banners_base_url || "";
+export const thumbnailsPrepend =
+ webserver.ui.files_url_prepend?.thumbnails_base_url || "";
+export const isFileServingEnabled = Boolean(
+ configuration.archive_server?.file_serving_enabled
+);
+export const gitCommitHash = process.env.GIT_COMMIT_HASH;
+export const buildDate = process.env.BUILD_DATE;
diff --git a/client/extra.d.ts b/client/extra.d.ts
index d675f08..f741f1f 100644
--- a/client/extra.d.ts
+++ b/client/extra.d.ts
@@ -1,7 +1,7 @@
// required for typescript not to choke on css modules
declare module '*.scss' {
- const content: Record;
- export default content;
+ const classes: { [key: string]: string };
+ export = classes;
}
declare module '*.yaml' {
diff --git a/client/fluid-player/.babelrc b/client/fluid-player/.babelrc
new file mode 100644
index 0000000..1320b9a
--- /dev/null
+++ b/client/fluid-player/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["@babel/preset-env"]
+}
diff --git a/client/fluid-player/.editorconfig b/client/fluid-player/.editorconfig
new file mode 100644
index 0000000..7d87ba5
--- /dev/null
+++ b/client/fluid-player/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[package.json]
+indent_size = 2
+
+[*.{js, css}]
+indent_size = 4
diff --git a/client/fluid-player/.github/ISSUE_TEMPLATE/bug_report.md b/client/fluid-player/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..7a4f71f
--- /dev/null
+++ b/client/fluid-player/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,41 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug, needs triage
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots or Links**
+If applicable, add screenshots or links to help explain your problem. **DO NOT** include links to NSFW webpages. Preferably create code to reproduce using https://jsfiddle.net
+
+**Desktop (please complete the following information if relevant):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information if relevant):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Affected version**
+For example, v3.0.0
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/client/fluid-player/.github/ISSUE_TEMPLATE/feature_request.md b/client/fluid-player/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..e2c46f1
--- /dev/null
+++ b/client/fluid-player/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: feature request, needs triage
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/client/fluid-player/.github/ISSUE_TEMPLATE/question.md b/client/fluid-player/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..1962d96
--- /dev/null
+++ b/client/fluid-player/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,13 @@
+---
+name: Question
+about: Question or clarification about Fluid Player or related technologies
+title: ''
+labels: question, needs triage
+assignees: ''
+
+---
+
+A clear and concise description of what the problem is.
+
+**Additional context**
+Add any other context or screenshots about the request here.
diff --git a/client/fluid-player/.github/pull_request_template.md b/client/fluid-player/.github/pull_request_template.md
new file mode 100644
index 0000000..ce16278
--- /dev/null
+++ b/client/fluid-player/.github/pull_request_template.md
@@ -0,0 +1,16 @@
+**IMPORTANT: Please do not create a Pull Request without creating an issue first.**
+
+*Any change needs to be discussed before proceeding. Failure to do so may result in the rejection of the pull request.*
+
+## Proposed Changes
+
+1. ...
+2. ...
+3. ...
+
+## Relevant issues
+
+Closes #...
+Closes #...
+Closes #...
+Related #...
diff --git a/client/fluid-player/.gitignore b/client/fluid-player/.gitignore
new file mode 100644
index 0000000..fa8c7d7
--- /dev/null
+++ b/client/fluid-player/.gitignore
@@ -0,0 +1,25 @@
+node_modules/
+dist/
+dist-cdn/
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# E2E
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
diff --git a/client/fluid-player/.npmignore b/client/fluid-player/.npmignore
new file mode 100644
index 0000000..73d1c4e
--- /dev/null
+++ b/client/fluid-player/.npmignore
@@ -0,0 +1,9 @@
+test
+.idea
+e2e
+.editorconfig
+yarn.lock
+webpack.config.js
+dist
+dist-cdn
+.github
diff --git a/client/fluid-player/CHANGELOG.md b/client/fluid-player/CHANGELOG.md
new file mode 100644
index 0000000..2216964
--- /dev/null
+++ b/client/fluid-player/CHANGELOG.md
@@ -0,0 +1,372 @@
+# CHANGELOG
+
+## 3.46.0 (2024-12-12)
+* [Pull #854](https://github.com/fluid-player/fluid-player/pull/854) Add support for automatic landscape screen orientation
+
+## 3.45.0 (2024-12-09)
+* [Pull #859](https://github.com/fluid-player/fluid-player/pull/859) Create E2E project for Fluid Player
+* [Pull #857](https://github.com/fluid-player/fluid-player/pull/857) Live Indicator
+
+## 3.44.0 (2024-11-14)
+* [Pull #851](https://github.com/fluid-player/fluid-player/pull/851) Mobile on click show control bar instead of pausing video
+
+## 3.43.0 (2024-11-13)
+* [Pull #855](https://github.com/fluid-player/fluid-player/pull/855) Fluidplayer doesn't play Wrapper ads
+
+## 3.42.0 (2024-11-05)
+* [Pull #836](https://github.com/fluid-player/fluid-player/pull/836) FallbackVastTags may not be working
+
+## 3.41.0 (2024-11-04)
+* [Pull #850](https://github.com/fluid-player/fluid-player/pull/850) New event system breaks current implementations
+
+## 3.40.0 (2024-10-24)
+* [Pull #844](https://github.com/fluid-player/fluid-player/pull/844) MiniPlayer Follow Up > Improving UX and be Google compliant
+* [Pull #846](https://github.com/fluid-player/fluid-player/pull/846) Rounded corners on player
+* [Pull #848](https://github.com/fluid-player/fluid-player/pull/848) Uncaught TypeError: Cannot read properties of undefined (reading 'Parser') when using subtitles
+
+## 3.39.0 (2024-10-15)
+* [Pull #842](https://github.com/fluid-player/fluid-player/pull/842) Ads events
+* [Pull #843](https://github.com/fluid-player/fluid-player/pull/843) Mid Roll is not working with Live stream videos
+
+## 3.38.0 (2024-10-02)
+* [Pull #838](https://github.com/fluid-player/fluid-player/pull/838) TheatreAdvanced is not working and breaks player
+
+## 3.37.0 (2024-09-17)
+* [Pull #821](https://github.com/fluid-player/fluid-player/pull/821) Added support for VAST ViewableImpression
+* [Pull #833](https://github.com/fluid-player/fluid-player/pull/833) doubleclickFullscreen not working
+
+## 3.36.0 (2024-09-05)
+* [Pull #832](https://github.com/fluid-player/fluid-player/pull/832) Show quality change icon in player when working with hls (m3u8)
+
+## 3.35.0 (2024-08-01)
+* [Pull #825](https://github.com/fluid-player/fluid-player/pull/825) Fix image freezing
+* [Pull #826](https://github.com/fluid-player/fluid-player/pull/826) Ads cannot be displayed when XML content has two Creative tags
+
+## 3.34.0 (2024-07-11)
+* [Pull #819](https://github.com/fluid-player/fluid-player/pull/819) When users don't have suggested videos, there's a console error
+
+## 3.33.0 (2024-07-02)
+* [Pull #818](https://github.com/fluid-player/fluid-player/pull/818) Suggested Videos Feature in Fluid Player
+
+## 3.32.0 (2024-03-21)
+* [Pull #804](https://github.com/fluid-player/fluid-player/pull/804) htmlOnPauseBlock not being displayed with last version of FP
+
+## 3.31.0 (2024-01-25)
+* [Pull #788](https://github.com/fluid-player/fluid-player/pull/788) Fluid Player doesn't work with Next.js
+* [Pull #791](https://github.com/fluid-player/fluid-player/pull/791) Impression events aren't called for some VAST tags within the VAST wrapper chain
+
+## 3.30.0 (2024-01-11)
+* [Pull #789](https://github.com/fluid-player/fluid-player/pull/789) Uncaught TypeError: Cannot set properties of null (setting 'slotIframe') while testing on VOD with VPAID Non Linear
+
+## 3.29.0 (2023-12-14)
+* [Pull #783](https://github.com/fluid-player/fluid-player/pull/783) Fix test cases in the development sever
+* [Pull #785](https://github.com/fluid-player/fluid-player/pull/785) FluidPlayer > Error > onPauseRoll In Video Banner VAST
+
+## 3.28.0 (2023-11-16)
+* [Pull #776](https://github.com/fluid-player/fluid-player/pull/776) Fluid Player doesn't work with shadow DOM
+
+## 3.27.0 (2023-10-19)
+* [Pull #771](https://github.com/fluid-player/fluid-player/pull/771) Method loadVpaid create frame without body
+
+## 3.26.0 (2023-10-12)
+* [Pull #768](https://github.com/fluid-player/fluid-player/pull/768) Stretch posterImage to playerwindow
+* [Pull #769](https://github.com/fluid-player/fluid-player/pull/769) Events don't differ from Ad and Main video
+
+## 3.25.0 (2023-09-21)
+* [Pull #766](https://github.com/fluid-player/fluid-player/pull/766) adClickable and CTA parameters don't work when 2 VAST ad is loaded
+
+## 3.24.0 (2023-09-08)
+* [Pull #763](https://github.com/fluid-player/fluid-player/pull/763) Player can't be restarted by destroying it and initializing it again
+
+## 3.23.0 (2023-08-28)
+* [Pull #757](https://github.com/fluid-player/fluid-player/pull/757) Preload doesn't work for .m3u8 files when the player is serving in-stream ads
+* [Pull #760](https://github.com/fluid-player/fluid-player/pull/760) Lighthouse says: Does not use passive listeners to improve scrolling performance
+
+## 3.22.0 (2023-08-17)
+* [Pull #755](https://github.com/fluid-player/fluid-player/pull/755) Percentages are not accepted for "timer" property
+
+## 3.21.0 (2023-08-08)
+* [Pull #748](https://github.com/fluid-player/fluid-player/pull/748) CurrentTime reset after switch HLS source on IOS
+* [Pull #752](https://github.com/fluid-player/fluid-player/pull/752) Add "controlForwardBackward" setting inside the player instead of the control bar
+
+## 3.20.0 (2023-07-24)
+* [Pull #749](https://github.com/fluid-player/fluid-player/pull/749) Mouse disappears
+* [Pull #750](https://github.com/fluid-player/fluid-player/pull/750) In mobile and when using .m3u8 files, user needs to click the player twice in order to play the video
+
+## 3.19.0 (2023-07-12)
+* [Pull #746](https://github.com/fluid-player/fluid-player/pull/746) Could not find a declaration file for module 'fluid-player'
+
+## 3.18.0 (2023-06-30)
+* [Pull #744](https://github.com/fluid-player/fluid-player/pull/744) Failed to resolve import "cheerio/lib/api/traversing"
+
+## 3.17.0 (2023-06-16)
+* [Pull #734](https://github.com/fluid-player/fluid-player/pull/734) MiniPlayer Mobile support
+* [Pull #735](https://github.com/fluid-player/fluid-player/pull/735) MiniPlayer position configuration
+* [Pull #739](https://github.com/fluid-player/fluid-player/pull/739) MiniPlayer Activate miniplayer when scrolling goes out of viewport
+* [Pull #740](https://github.com/fluid-player/fluid-player/pull/740) MiniPlayer Allowing trigger MiniPlayer by code
+* [Pull #736](https://github.com/fluid-player/fluid-player/pull/736) Fluid player doesn't track clicks on some sites
+
+## 3.16.0 (2023-05-31)
+* [Pull #721](https://github.com/fluid-player/fluid-player/pull/721) Fluid Player loads midRoll even if timer is longer than main video
+* [Pull #732](https://github.com/fluid-player/fluid-player/pull/732) MiniPlayer MVP
+
+## 3.15.0 (2023-05-09)
+* [Pull #727](https://github.com/fluid-player/fluid-player/pull/727) Player required 2 clicks to play video New Iphone 11 Pro Chrome
+
+## 3.14.0 (2023-04-27)
+* [Pull #722](https://github.com/fluid-player/fluid-player/pull/722) Support Video Waterfall VAST Response
+
+## 3.13.0 (2023-03-09)
+* [Pull #714](https://github.com/fluid-player/fluid-player/pull/714) Support Video Waterfall VAST Response
+
+## 3.12.0 (2023-01-10)
+* [Pull #707](https://github.com/fluid-player/fluid-player/pull/707) Decrease volumes & revenue on In-stream zones
+
+## 3.11.1 (2023-01-03)
+* Update dependencies
+
+## 3.11.0 (2023-01-03)
+* [Pull #614](https://github.com/fluid-player/fluid-player/pull/614) Add check for process being defined
+* [Pull #561](https://github.com/fluid-player/fluid-player/pull/561) Allow customizing playbackRates
+
+## 3.10.0 (2022-12-15)
+* [Pull #687](https://github.com/fluid-player/fluid-player/pull/687) LocalStorage not available in Chrome incognito mode is breaking JS
+* [Pull #704](https://github.com/fluid-player/fluid-player/pull/704) In ad serving, the skip button when is without time delay it should trigger immediately the "skip ad"
+
+## 3.9.0 (2022-10-18)
+* [Pull #688](https://github.com/fluid-player/fluid-player/pull/688) Selecting subtitle by default
+
+## 3.8.0 (2022-10-07)
+* [Pull #685](https://github.com/fluid-player/fluid-player/pull/685) Fluidplayer > 'autoHide' in Desktop only works when the cursor is on top of the player.
+* [Pull #689](https://github.com/fluid-player/fluid-player/pull/689) Mobile view_ Error in console and wrong positioning of the CTA text
+
+## 3.7.0 (2022-09-28)
+* [Pull #650](https://github.com/fluid-player/fluid-player/pull/650) Play main video after preRoll ends not work
+
+## 3.6.0 (2022-08-24)
+* [Pull #666](https://github.com/fluid-player/fluid-player/pull/666) CTA Overlay > cannot be removed by publisher
+
+## 3.5.0 (2022-07-20)
+* [Pull #669](https://github.com/fluid-player/fluid-player/pull/669) Video CTA / Fluid Player
+* [Pull #671](https://github.com/fluid-player/fluid-player/pull/671) Video CTA - update FP to support new CTA structure from VAST Tag
+
+## 3.4.0 (2022-07-05)
+* [Pull #652](https://github.com/fluid-player/fluid-player/pull/652) Video on demand and linear VPAID does not work on iOS Safari
+* [Pull #664](https://github.com/fluid-player/fluid-player/pull/664) Video CTA / Fluid Player
+
+## 3.3.0 (2022-06-22)
+* [Pull #656](https://github.com/fluid-player/fluid-player/pull/656) Video CTA / Fluid Player
+
+## 3.2.1 (2022-05-17)
+* Update dependencies
+
+## 3.2.0
+* [Pull #641](https://github.com/fluid-player/fluid-player/pull/641) FluidPlayer > Streaming files compatibility
+
+## 3.1.0
+* [Pull #619](https://github.com/fluid-player/fluid-player/pull/619) Looping videos show loading spinner for a split second before looping
+* [Pull #621](https://github.com/fluid-player/fluid-player/pull/621) FluidPlayer> Mouse disappears
+* [Pull #622](https://github.com/fluid-player/fluid-player/pull/622) contextMenu.links labels are not working after play
+* [Pull #628](https://github.com/fluid-player/fluid-player/pull/628) Overlay html over video (also in fullscreen)
+
+## 3.0.4
+* [Pull #489](https://github.com/fluid-player/fluid-player/pull/489) Fix issues with nonLinear ads not closing
+
+## 3.0.3
+* [Pull #478](https://github.com/fluid-player/fluid-player/pull/478) Ensure options is object, fix dash debug
+
+## 3.0.2
+* [Pull #473](https://github.com/fluid-player/fluid-player/pull/473) Responsive test case
+* [Pull #474](https://github.com/fluid-player/fluid-player/pull/474) Fix issues related to missing ended event
+* [Pull #472](https://github.com/fluid-player/fluid-player/pull/472) Small refactor, add auto-hide test case
+* [Pull #471](https://github.com/fluid-player/fluid-player/pull/471) Move X seconds forward/back
+* [Pull #470](https://github.com/fluid-player/fluid-player/pull/470) Custom context
+* [Pull #469](https://github.com/fluid-player/fluid-player/pull/469) Prevent hidden menus after cssmin optimization
+* [Pull #468](https://github.com/fluid-player/fluid-player/pull/468) Config callbacks
+
+## 3.0.1
+* [Pull #457](https://github.com/fluid-player/fluid-player/pull/430) Fix ad skip button not showing properly
+* [Pull #450](https://github.com/fluid-player/fluid-player/pull/430) Static thumbnail configuration
+* [Pull #458](https://github.com/fluid-player/fluid-player/pull/430) Fix dash.js initialization and swap Vtt.js to Videojs fork
+
+## 3.0.0
+* [Pull #441](https://github.com/fluid-player/fluid-player/pull/441) Major release - see pull request for full changelist.
+
+## 2.4.11
+* [Pull #430](https://github.com/fluid-player/fluid-player/pull/430) Add destroy function
+
+## 2.4.10
+* [Pull #399](https://github.com/fluid-player/fluid-player/pull/399) Adding VR Features to player (experimental)
+
+## 2.4.9
+* [Pull #398](https://github.com/fluid-player/fluid-player/pull/398) Add support for VPAID (2.0)
+
+## 2.4.8
+* [Pull #374](https://github.com/fluid-player/fluid-player/pull/374) Skip ad button on VAST preroll opening a new blank tab
+
+## 2.4.7
+* [Pull #361](https://github.com/fluid-player/fluid-player/pull/361) Adding subtitles, multiple ad-roll, fallback vast ad, fixing dash playback, double click to fullscreen
+* [Pull #354](https://github.com/fluid-player/fluid-player/pull/354) VAST Multiple mediafile support, announce proper error codes and some bug fixes
+* [Pull #356](https://github.com/fluid-player/fluid-player/pull/356) Seeked and ended html5 event listeners
+
+## 2.4.6
+* [Pull #358](https://github.com/fluid-player/fluid-player/pull/358) fix bug with dash js api
+
+## 2.4.5
+* [Pull #325](https://github.com/fluid-player/fluid-player/pull/325) Add poster image size option (posterImageSize)
+* [Pull #330](https://github.com/fluid-player/fluid-player/pull/330) Add showPlayButton config to display Play button on ad
+* [Pull #306](https://github.com/fluid-player/fluid-player/pull/306) Remove unsupported browser layout parts
+* [Pull #331](https://github.com/fluid-player/fluid-player/pull/331) Add ability to change controls titles
+* [Pull #332](https://github.com/fluid-player/fluid-player/pull/332) Fix multiple videos play
+* [Pull #335](https://github.com/fluid-player/fluid-player/pull/335) Improve timecode
+* [Pull #336](https://github.com/fluid-player/fluid-player/pull/336) Add title
+* [Pull #334](https://github.com/fluid-player/fluid-player/pull/334) Add ability to set preload value
+
+## 2.4.4
+* [Pull #289](https://github.com/fluid-player/fluid-player/pull/289) Fix window.getComputedStyle call on null
+* [Pull #290](https://github.com/fluid-player/fluid-player/pull/290) Prevent multi click event on download btn
+* [Pull #293](https://github.com/fluid-player/fluid-player/pull/293) Check if Hls already exposed in window
+
+## 2.4.3
+* [Pull #266](https://github.com/fluid-player/fluid-player/pull/266) Fix play pause issue on mobile
+* [Pull #268](https://github.com/fluid-player/fluid-player/pull/268) Fix iOS scrubbing bugs
+* [Pull #270](https://github.com/fluid-player/fluid-player/pull/270) Fix for iOS switching to unsupported file types
+
+## 2.4.2
+* [Pull #235](https://github.com/fluid-player/fluid-player/pull/235) [Pull #236](https://github.com/fluid-player/fluid-player/pull/236) Fix the controls randomly disappearing on scrubbing clicks
+
+## 2.4.1
+* [Pull #228](https://github.com/fluid-player/fluid-player/pull/228) Persistent volume settings from before mute on page navigation
+* [Pull #229](https://github.com/fluid-player/fluid-player/pull/229) Link to FP on menu button working correctly
+* [Pull #230](https://github.com/fluid-player/fluid-player/pull/230) Fix for right click on initial play button
+* [Pull #227](https://github.com/fluid-player/fluid-player/pull/227) Optional parameter to disable clickthrough layer on instream ads
+* [Pull #231](https://github.com/fluid-player/fluid-player/pull/231) Fixes for how thumbnails are drawn and mouse event detection
+
+## 2.4.0
+* [Pull #214](https://github.com/fluid-player/fluid-player/pull/241) Avoid looping VAST Ad
+* [Pull #206](https://github.com/fluid-player/fluid-player/pull/206) Fix tracking impression events for nonLinear ads
+* [Pull #221](https://github.com/fluid-player/fluid-player/pull/221) Fix VAST loading issue by AdBlock
+* [Pull #207](https://github.com/fluid-player/fluid-player/pull/207) Add support for HD icon on quality select
+* [Pull #209](https://github.com/fluid-player/fluid-player/pull/209) Advanced theatre mode
+* [Pull #208](https://github.com/fluid-player/fluid-player/pull/208) Compress files
+* [Pull #179](https://github.com/fluid-player/fluid-player/pull/179) Fix to prevent changing speed during ads
+* [Pull #217](https://github.com/fluid-player/fluid-player/pull/217) Prevent video size change on quality switch
+* [Pull #213](https://github.com/fluid-player/fluid-player/pull/213) Controls to stay working with adblock and fix for double event on mobile touch
+* [Pull #212](https://github.com/fluid-player/fluid-player/pull/212) Poster image to fit player size
+* [Pull #186](https://github.com/fluid-player/fluid-player/pull/186) Fix for source switch on Edge
+* [Pull #219](https://github.com/fluid-player/fluid-player/pull/219) Play / pause icon fix and progress bar to disappear correctly
+* [Pull #218](https://github.com/fluid-player/fluid-player/pull/218) Optional theatre settings
+
+## 2.3.0
+* [Pull #192](https://github.com/fluid-player/fluid-player/pull/191) Persist user settings across pages for volume, speed, quality and theatre mode
+* [Pull #194](https://github.com/fluid-player/fluid-player/pull/194) Fix for play event on video click for certain devices
+* [Pull #193](https://github.com/fluid-player/fluid-player/pull/193) Option to set adText and adTextPosition on a per ad basis
+* [Pull #184](https://github.com/fluid-player/fluid-player/pull/184) Fix for thumbnails appearing incorrectly on mobile
+* [Pull #181](https://github.com/fluid-player/fluid-player/pull/181) Fix for poster image for dash file
+* [Pull #195](https://github.com/fluid-player/fluid-player/pull/195) Loading icon while player is waiting
+* [Pull #200](https://github.com/fluid-player/fluid-player/pull/200) Ad text positioning fix
+* [Pull #196](https://github.com/fluid-player/fluid-player/pull/196) Fix for issue causing controls to hide incorrectly
+* [Pull #191](https://github.com/fluid-player/fluid-player/pull/191) Scrubbing to no longer trigger Fluid on.pause event
+
+## 2.2.2
+* [Pull #175](https://github.com/fluid-player/fluid-player/pull/175) Fullscreen mode variable correct place
+* [Pull #177](https://github.com/fluid-player/fluid-player/pull/177) Fix fadeOut/fadeIn opacity to correct values in the end of animation
+* [Pull #180](https://github.com/fluid-player/fluid-player/pull/180) Adding VASTAdTagURI support
+
+## 2.2.1
+* [Pull #153](https://github.com/fluid-player/fluid-player/pull/153) CDATA media file ignores whitespace correctly
+* [Pull #154](https://github.com/fluid-player/fluid-player/pull/154) onPauseRoll not showing on source switch
+* [Pull #155](https://github.com/fluid-player/fluid-player/pull/155) iOS native fullscreen
+* [Pull #156](https://github.com/fluid-player/fluid-player/pull/156) CSS fixes for progress bar and logo
+* [Pull #157](https://github.com/fluid-player/fluid-player/pull/157) Fix for onMainVideoEnded firing correctly
+* [Pull #158](https://github.com/fluid-player/fluid-player/pull/158) Play / Pause animation to not show when changing source
+* [Pull #159](https://github.com/fluid-player/fluid-player/pull/159) Theatre mode to not show in iframe
+* [Pull #148](https://github.com/fluid-player/fluid-player/pull/148) Fix for currentTime being set for iOS and safari for ads and source switch
+* [Pull #165](https://github.com/fluid-player/fluid-player/pull/165) Fix for video duration if passed as 00:00:00 in the VAST file
+* [Pull #167](https://github.com/fluid-player/fluid-player/pull/167) Allow for individual images to be set in .vtt file
+* [Pull #169](https://github.com/fluid-player/fluid-player/pull/169) Preview Thumbnail image locations - Ability to set relative path
+* [Pull #168](https://github.com/fluid-player/fluid-player/pull/168) Show custom error if XML content-type is wrong
+* [Pull #166](https://github.com/fluid-player/fluid-player/pull/166) Bug fix for Error 202 showing up periodically in the console
+* [Pull #149](https://github.com/fluid-player/fluid-player/pull/149) Bug fix to remove mainVideoReady eventListener after success
+
+## 2.2.0
+* [Pull #121](https://github.com/fluid-player/fluid-player/pull/121) 'Browser layout' VAST fixes
+* [Pull #122](https://github.com/fluid-player/fluid-player/pull/122) iOS fullscreen improvements, use native player
+* [Pull #125](https://github.com/fluid-player/fluid-player/pull/125) Fix for VAST tag: additional checks for CDATA node irregularity
+* [Pull #126](https://github.com/fluid-player/fluid-player/pull/126) Pause player when linear ad opens (ad video is clicked)
+* [Pull #127](https://github.com/fluid-player/fluid-player/pull/127) OnPause ad showing on source switch fix
+* [Pull #128](https://github.com/fluid-player/fluid-player/pull/128) [Pull #139](https://github.com/fluid-player/fluid-player/pull/139) Poster Image as a param
+* [Pull #130](https://github.com/fluid-player/fluid-player/pull/130) Create progressbar markers for nonLinear ads
+* [Pull #131](https://github.com/fluid-player/fluid-player/pull/131) [Pull #136](https://github.com/fluid-player/fluid-player/pull/136/) Additional logo parameters
+* [Pull #138](https://github.com/fluid-player/fluid-player/pull/138) Support for DASH and HLS streaming
+* [Pull #143](https://github.com/fluid-player/fluid-player/pull/143) Positioning of ad and cta text elements
+
+## 2.1.2
+* [Pull #108](https://github.com/fluid-player/fluid-player/pull/108) Fullscreen API call fix
+* [Pull #110](https://github.com/fluid-player/fluid-player/pull/110) Improvements for iOs safari (use default skin) and mobile screens
+* [Pull #111](https://github.com/fluid-player/fluid-player/pull/111) Adjust how iconClickThrough is gotten
+
+## 2.1.1
+* [Pull #107](https://github.com/fluid-player/fluid-player/pull/107) Download and Theatre fixes
+
+## 2.1
+* [Pull #101](https://github.com/fluid-player/fluid-player/pull/101) Quality indicator
+* [Pull #102](https://github.com/fluid-player/fluid-player/pull/102) API functions
+* [Pull #103](https://github.com/fluid-player/fluid-player/pull/103) Landing page displayed in In-Stream ads
+* [Pull #104](https://github.com/fluid-player/fluid-player/pull/104) Theater mode, download & playback rate
+
+## 2.0
+* [Pull #91](https://github.com/fluid-player/fluid-player/pull/91) Version 2 Changes:
+ * New default template
+ * Add play button
+ * Play pause animations
+ * Restructuring of optional parameters
+ * Remove templates
+ * General fixes
+
+## 1.2.2
+* [Pull #88](https://github.com/fluid-player/fluid-player/pull/88) Improve nonlinear ads
+
+## 1.2.1
+* [Pull #86](https://github.com/fluid-player/fluid-player/pull/86) [Pull #87](https://github.com/fluid-player/fluid-player/pull/87) Mid roll current time fix
+
+## 1.2.0
+* [Pull #68](https://github.com/fluid-player/fluid-player/pull/68) Controls remain fullscreen after escaping fullscreen
+* [Pull #66](https://github.com/fluid-player/fluid-player/pull/66) Optional logoUrl for clickable logo
+* [Pull #74](https://github.com/fluid-player/fluid-player/pull/74) Add ability to grab and slide the volume slider and timeline scrubber.
+* [Pull #75](https://github.com/fluid-player/fluid-player/pull/75) [Pull #77](https://github.com/fluid-player/fluid-player/pull/77) Adding mid/post roll support and initial VAST nonLinear support.
+* [Pull #67](https://github.com/fluid-player/fluid-player/pull/67) Adding key controls.
+* [Pull #69](https://github.com/fluid-player/fluid-player/pull/69) Adding controls hiding functionality.
+
+## 1.1.3
+* [Pull #50](https://github.com/fluid-player/fluid-player/pull/50) Fix for double double render of blank video on some browsers
+
+## 1.1.2
+* [Pull #43](https://github.com/fluid-player/fluid-player/pull/43) Add two new skins.
+
+## 1.1.1
+* [Pull #38](https://github.com/fluid-player/fluid-player/pull/38) Reset the CSS box-sizing settings.
+
+## 1.1.0
+* [Pull #34](https://github.com/fluid-player/fluid-player/pull/34) Various Improvements:
+ * Possibility to allow the user to switch between different video qualities. (Example, 720p, 1080p, etc...)
+ * Enable/Disable autoplay.
+ * Possibility to set a logo over the video player, with configurable position and opacity.
+ * Possibility to show a text when a video ad is being played. (Example : "Advertising")
+ * Possibility to show a call to action link when a video ad is being played. (Example : "Click here to learn more about this product.")
+ * Improved CSS management.
+ * Possibility to show a custom HTML code when the user pauses the video. (For example, a banner ad, or some related video links)
+ * The video player can be fully responsive.
+
+## 1.0.2
+* [Pull #18](https://github.com/fluid-player/fluid-player/pull/18) [Pull #19](https://github.com/fluid-player/fluid-player/pull/19) Update file names, add in min file versions
+
+## 1.0.1
+* [Pull #1](https://github.com/fluid-player/fluid-player/pull/1) Fix a Fluid Player crash when the ad video file is not available. Properly announcing errors if an Error tag is present in the VAST tag.
+* [Pull #3](https://github.com/fluid-player/fluid-player/pull/3) Demo layouts. Various bugfixes and improvements.
+* [Pull #10](https://github.com/fluid-player/fluid-player/pull/10) Thumbnail previews from vtt file can be overwritten.
+* [Pull #11](https://github.com/fluid-player/fluid-player/pull/11) Player shows current play time and video duration in 'default' template.
+* [Pull #14](https://github.com/fluid-player/fluid-player/pull/14) Fix a minor issue when playing the video from outside the Fluid Player code.
+
+## 1.0.0
+* Initial Release
diff --git a/client/fluid-player/CONTRIBUTING.md b/client/fluid-player/CONTRIBUTING.md
new file mode 100644
index 0000000..0fd8f48
--- /dev/null
+++ b/client/fluid-player/CONTRIBUTING.md
@@ -0,0 +1,54 @@
+# Contributing
+
+If you are interested in making a contribution there are a few ways you could help out the project.
+
+## Filing issues
+
+[GitHub Issues](https://github.com/fluid-player/fluid-player/issues) are used for all discussions around the codebase, including **bugs** and **features**.
+
+### Reporting a Bug
+
+Good bug reports can be very helpful. A bug is a demonstrable problem with the code.
+
+Guidelines for bug reports:
+
+1. Please use the [GitHub issue search](https://github.com/fluid-player/fluid-player/issues) — check if the issue has already been reported.
+1. Check if the issue has already been fixed — try to reproduce it using the uncompressed code from latest `master` branch in the repository.
+1. Create a small demo with the live example (reduced test case). You can possibly use [this codepen template](https://codepen.io/exadsleroy/pen/QWmWPeo) as a starting point -- don't forget to update it to the fluid-player version you use.
+
+A good bug report should be as detailed as possible, so that others won't have to follow up for the essential details.
+
+**[File a bug report](https://github.com/fluid-player/fluid-player/issues/new)**
+
+### Requesting a Feature
+
+1. [Search the issues](https://github.com/fluid-player/fluid-player/issues) for any previous requests for the same feature, and give a thumbs up or +1 on existing requests.
+1. If no previous requests exist, create a new issue. Please be as clear as possible about why the feature is needed and the intended use case.
+
+**[Request a feature](https://github.com/fluid-player/fluid-player/issues/new)**
+
+## Contributing code
+
+If you plan to propose code changes it is required you create an
+issue [issue](https://github.com/fluid-player/fluid-player/issues/new) with a brief proposal (as described in
+Requesting a Feature) and discuss it with us first.
+
+This is necessary to avoid more than one contributor working on the same feature/change and to avoid someone
+spending time on feature/change that would not be merged for some reason.
+
+For smaller contributions just use this workflow:
+
+* Create an issue describing the changes.
+* Await confirmation from contributors.
+* Fork the project.
+* Create a branch for your feature or bug fix.
+* Add code changes.
+* All new features or changes to the player settings or interface have to be documented in the
+[docs repo](https://github.com/fluid-player/fluid-player-docs), so that they are displayed
+on [https://docs.fluidplayer.com](https://docs.fluidplayer.com).
+If you have made changes like this, please fork fluid-player-docs as well and create a branch with the same
+name as the feature branch, adding necessary changes to documentation.
+* Send a pull request (both for fluid-player and fluid-player-docs)
+
+After one of the contributors has checked and approved the changes, they will be merged into master branch
+and will be included in the next release tag.
diff --git a/client/fluid-player/LICENSE b/client/fluid-player/LICENSE
new file mode 100644
index 0000000..0d1e312
--- /dev/null
+++ b/client/fluid-player/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Fluid Player and contributors
+
+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/client/fluid-player/README.md b/client/fluid-player/README.md
new file mode 100644
index 0000000..87057fe
--- /dev/null
+++ b/client/fluid-player/README.md
@@ -0,0 +1,23 @@
+# Fluid Player
+[](https://github.com/fluid-player/fluid-player/releases/latest)
+[](https://www.npmjs.com/package/fluid-player)
+
+## Version 3 released
+
+A [new major version](https://github.com/fluid-player/fluid-player/pull/441) of Fluid Player has been released on May 20, 2020. Existing version 2 users are recommended to upgrade. [See quick setup guide](https://docs.fluidplayer.com/docs/integration/quick-setup/).
+
+## Overview
+
+Fluid Player is a free HTML5 video player. It is lightweight, easy to integrate and has advanced VAST capabilities.
+The idea behind VAST, as well as the full VAST specification, can be found here: [VAST 4.0](https://www.iab.com/guidelines/digital-video-ad-serving-template-vast-4-0/).
+
+## Documentation
+The integration and configuration of Fluid Player is fully outlined in [Fluid Player Documentation](http://docs.fluidplayer.com)
+
+## License
+
+Fluid Player is licensed under the MIT License. View the [License File](LICENSE).
+
+## Changelog
+
+A full list of changes and updates can be found in the project [CHANGELOG](CHANGELOG.md).
diff --git a/client/fluid-player/e2e/ads_linear.spec.ts b/client/fluid-player/e2e/ads_linear.spec.ts
new file mode 100644
index 0000000..03bc050
--- /dev/null
+++ b/client/fluid-player/e2e/ads_linear.spec.ts
@@ -0,0 +1,181 @@
+import { test, expect } from '@playwright/test';
+import { waitForVideoToPlay, setVideoCurrentTime, getVideoCurrentTime } from './functions/video';
+import { waitForSpecificNetworkCall } from './functions/network';
+
+test.describe('desktop ads', () => {
+
+ test.beforeEach(async ({ page }) => {
+ console.log(`Running ${test.info().title}`);
+ await page.goto('/ads_linear.html');
+ });
+
+ test('should navigate to the publishers advertised website on click', async ({ page }) => {
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+ const video = page.locator('video');
+
+ // start the video
+ fullPlayer.click();
+
+ await waitForVideoToPlay(video);
+
+ // Set up a listener for the 'popup' event
+ // This listener listens for a new _blank tab to open
+ const [popupPromise] = await Promise.all([
+ page.waitForEvent('popup'), // Listen for the popup event
+ fullPlayer.click() // click ad to open advertisers link
+ ]);
+
+ // Prevent the tab from fully opening
+ const popup = popupPromise;
+
+ // Verify the URL of the popup
+ const popupUrl = popup.url();
+ console.log(`Popup URL: ${popupUrl}`);
+ expect(popupUrl).toBe('http://www.example.com/');
+
+ // Close the popup to prevent extra tabs, in case the above failed to prevent the opening of the new tab
+ await popup.close();
+ });
+
+ test('should fire pre-, mid- and postRoll based on time', async ({ page }) => {
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+ const skipButton = page.locator('.skip_button');
+ const video = page.locator('video');
+
+ // Start the video
+ fullPlayer.click();
+ await waitForVideoToPlay(video);
+
+ /**
+ * PREROLL
+ */
+ await expect(skipButton).toHaveText(/Skip ad in 2/);
+ // Wait for skip ad timer
+ await page.waitForTimeout(2500);
+ await expect(skipButton).toHaveText(/Skip Ad /);
+
+ // Skip the ad
+ await skipButton.click();
+
+ /**
+ * MIDROLL
+ */
+ await page.waitForFunction(() => {
+ const videoElement = document.querySelector('video') as HTMLVideoElement;
+ // 15 is the length of the ad
+ return videoElement && Math.floor(videoElement.duration) !== 15;
+ });
+
+ // Midrolls don't trigger if you seek less then 5 seconds before their time
+ await setVideoCurrentTime(video, 35);
+ await page.waitForTimeout(5500);
+ await expect(skipButton).toHaveText(/Skip ad in 2/);
+ // Wait for skip ad timer
+ await page.waitForTimeout(2500);
+ await expect(skipButton).toHaveText(/Skip Ad /);
+
+ // Skip the ad
+ await skipButton.click();
+
+ await page.waitForTimeout(500);
+
+ await waitForVideoToPlay(video);
+
+ const currentTime = await getVideoCurrentTime(video);
+
+ // Check if the video resumes after the midroll at the correct time
+ expect(Math.floor(currentTime)).toEqual(39);
+
+ /**
+ * POSTROLL
+ */
+
+ // Skip to the end
+ await page.waitForTimeout(500);
+ await video.evaluate((videoEl) => {
+ const vid = (videoEl as HTMLVideoElement);
+ vid.currentTime = Math.max(0, vid.duration) - 1;
+ });
+ await page.waitForTimeout(1000);
+ await expect(skipButton).toHaveText(/Skip ad in 2/);
+ // Wait for skip ad timer
+ await page.waitForTimeout(2500);
+ await expect(skipButton).toHaveText(/Skip Ad /);
+
+ await skipButton.waitFor({ state: 'visible', timeout: 5000 });
+ // Skip the ad
+ await skipButton.click();
+
+ // Check if video is marked as ended
+ await page.waitForFunction(() => {
+ const video = document.querySelector('video');
+ return video && !video.ended;
+ });
+ });
+
+ test('ad should not be skipped when the ad countdown is not done', async ({ page }) => {
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+ const skipButton = page.locator('.skip_button');
+ const video = page.locator('video');
+
+ // Start the video
+ fullPlayer.click();
+
+ await page.waitForFunction(() => {
+ const videoElement = document.querySelector('video');
+ return videoElement && videoElement.duration > 0;
+ }, { timeout: 5000 });
+
+ const adDuration = await video.evaluate((vid) => {
+ const videoElement = vid as HTMLVideoElement;
+ return videoElement.duration;
+ });
+
+ // Click the button but it should not be skipped
+ // NOTE: don't add 'await' because it will wait until it can skip
+ skipButton.click();
+
+ // If the ad still has the same video duration, that means the video is not skipped
+ const videoDurationAfterClick = await video.evaluate((vid) => {
+ const videoElement = vid as HTMLVideoElement;
+ return videoElement.duration;
+ });
+
+ expect(videoDurationAfterClick).not.toBeFalsy();
+ expect(adDuration).not.toBeFalsy();
+
+ expect(videoDurationAfterClick).toEqual(adDuration);
+
+ await page.waitForTimeout(2000);
+ // Skip Ad
+ await skipButton.click();
+ await page.waitForTimeout(500);
+
+ const videoDuration = await video.evaluate((vid) => {
+ const videoElement = vid as HTMLVideoElement;
+ return videoElement.duration;
+ });
+
+ expect(videoDuration).not.toBeFalsy();
+ expect(adDuration).not.toBeFalsy();
+
+ expect(videoDuration).not.toEqual(adDuration);
+ });
+
+ test('impression url should be called', async ({ page }) => {
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+
+ // start the video
+ fullPlayer.click();
+
+ const request = await waitForSpecificNetworkCall(
+ page,
+ 'http://www.example.com/impression',
+ 'GET'
+ );
+
+ expect(request.url()).toBe('http://www.example.com/impression');
+ });
+
+});
+
diff --git a/client/fluid-player/e2e/controls.spec.ts b/client/fluid-player/e2e/controls.spec.ts
new file mode 100644
index 0000000..348e9c6
--- /dev/null
+++ b/client/fluid-player/e2e/controls.spec.ts
@@ -0,0 +1,69 @@
+import { test, expect } from '@playwright/test';
+
+test.describe('desktop controls', () => {
+
+ test.beforeEach(async ({ page }) => {
+ console.log(`Running ${test.info().title}`);
+ await page.goto('/controls.html');
+ });
+
+ test('should toggle play/pause when clicking the player', async ({ page }) => {
+ // Selectors
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+ const playButton = page.locator('.fluid_button_play');
+ const pauseButton = page.locator('.fluid_button_pause');
+
+ // Initial state checks
+ await expect(playButton).toBeVisible();
+ await expect(pauseButton).not.toBeVisible();
+
+ // Video player should start playing
+ fullPlayer.click();
+
+ // Wait for video to start playing
+ await page.waitForFunction(() => {
+ const video = document.querySelector('video');
+ return video && !video.paused;
+ });
+
+ // Verify playing state
+ await expect(playButton).not.toBeVisible();
+ await expect(pauseButton).toBeVisible();
+
+ // Wait for 500ms so the browser doesn't reject the click
+ await page.waitForTimeout(1000);
+ // Video player should pause
+ fullPlayer.click();
+
+ // Wait for video to pause
+ await page.waitForFunction(() => {
+ const video = document.querySelector('video');
+ return video && video.paused;
+ });
+
+ // Verify paused state
+ await expect(playButton).toBeVisible();
+ await expect(pauseButton).not.toBeVisible();
+ });
+
+ test('mouse should disappear when hovering the video', async ({ page }) => {
+ const video = page.locator('video');
+ const playButton = page.locator('.fluid_button_play');
+
+ await playButton.click();
+
+ // Hover over the video
+ await video.hover();
+
+ await page.waitForTimeout(1500);
+
+ // Evaluate the cursor CSS property of the video element or its parent
+ const isCursorHidden = await video.evaluate((vid) => {
+ const computedStyle = window.getComputedStyle(vid);
+ return computedStyle.cursor === 'none';
+ });
+
+ expect(isCursorHidden).toBeTruthy(); // Assert that the cursor is hidden
+ });
+});
+
diff --git a/client/fluid-player/e2e/functions/network.ts b/client/fluid-player/e2e/functions/network.ts
new file mode 100644
index 0000000..4e84326
--- /dev/null
+++ b/client/fluid-player/e2e/functions/network.ts
@@ -0,0 +1,21 @@
+import { Page, Request } from 'playwright';
+
+/**
+ * Wait for a specific network request and log it.
+ *
+ * @param page - The Playwright page instance.
+ * @param url - The URL of the request to wait for.
+ * @param method - The HTTP method of the request (default is 'GET').
+ * @returns The intercepted request object.
+ */
+export async function waitForSpecificNetworkCall(
+ page: Page,
+ url: string,
+ method: string = 'GET'
+): Promise {
+ const request = await page.waitForRequest((req) =>
+ req.url() === url && req.method() === method
+ );
+
+ return request;
+}
\ No newline at end of file
diff --git a/client/fluid-player/e2e/functions/video.ts b/client/fluid-player/e2e/functions/video.ts
new file mode 100644
index 0000000..b3d8250
--- /dev/null
+++ b/client/fluid-player/e2e/functions/video.ts
@@ -0,0 +1,86 @@
+import { Locator, Page } from 'playwright';
+
+/**
+ * Seek to a given time in the video
+ *
+ * @param video - Playwright video locator
+ * @param time - The time you want to seek to
+ */
+export async function setVideoCurrentTime(video: Locator, time: number): Promise {
+ await video.page().waitForFunction(
+ (vid) => {
+ const videoElement = vid as HTMLVideoElement | null;
+ return videoElement && videoElement.readyState >= 2;
+ },
+ await video.elementHandle(),
+ { timeout: 10000 }
+ );
+
+ // Seek to the specified time
+ await video.evaluate((vid, t) => {
+ const videoElement = vid as HTMLVideoElement;
+ videoElement.currentTime = t;
+ }, time);
+}
+
+/**
+ * Wait until the video duration has changed
+ * This way you can detect if the ad or content is loaded in
+ *
+ * @param page - The Playwright page instance
+ * @param initialDuration - The initial duration of the video element
+ * @param timeout
+ */
+export async function waitForVideoDurationChange(
+ page: Page,
+ initialDuration: number,
+ timeout: number = 10000
+): Promise {
+ await page.waitForFunction(
+ (initialDur) => {
+ const videoElement = document.querySelector('video') as HTMLVideoElement;
+ return videoElement.duration !== initialDur;
+ },
+ initialDuration,
+ { timeout }
+ );
+}
+
+/**
+ * Get the current duration of the video
+ *
+ * @param video - Playwright video locator
+ * @returns video duration time
+ */
+export async function getVideoDuration(video: Locator): Promise {
+ return await video.evaluate((vid) => {
+ const videoElement = vid as HTMLVideoElement;
+ return videoElement.duration;
+ });
+}
+
+/**
+ * Get the current time of the video
+ *
+ * @param video - Playwright video locator
+ * @returns video current time
+ */
+export async function getVideoCurrentTime(video: Locator): Promise {
+ return await video.evaluate((vid) => {
+ const videoElement = vid as HTMLVideoElement;
+ return videoElement.currentTime;
+ });
+}
+
+/**
+ * Waits until the given video element starts playing.
+ *
+ * @param video - The Playwright Locator for the video element.
+ */
+export async function waitForVideoToPlay(video: Locator): Promise {
+ await video.evaluate((vid) => {
+ return new Promise((resolve) => {
+ vid.addEventListener('playing', () => resolve(), { once: true });
+ });
+ });
+}
\ No newline at end of file
diff --git a/client/fluid-player/e2e/snapshots/baseline-sv-grid.png b/client/fluid-player/e2e/snapshots/baseline-sv-grid.png
new file mode 100644
index 0000000..1c42404
Binary files /dev/null and b/client/fluid-player/e2e/snapshots/baseline-sv-grid.png differ
diff --git a/client/fluid-player/e2e/suggested_videos.spec.ts b/client/fluid-player/e2e/suggested_videos.spec.ts
new file mode 100644
index 0000000..47d365a
--- /dev/null
+++ b/client/fluid-player/e2e/suggested_videos.spec.ts
@@ -0,0 +1,37 @@
+import { test, expect } from '@playwright/test';
+import { waitForVideoToPlay, setVideoCurrentTime, getVideoDuration } from './functions/video';
+
+test.describe('suggested videos', () => {
+
+ test.beforeEach(async ({ page }) => {
+ console.log(`Running ${test.info().title}`);
+ });
+
+ test('should show up in 4x3 grid at the end of the video if it is configured and after postRoll', async ({ page }) => {
+ await page.goto('/suggested_videos_e2e.html');
+
+ const fullPlayer = page.locator('#fluid_video_wrapper_fluid-player-e2e-case');
+ const video = page.locator('video');
+
+ fullPlayer.click();
+ await waitForVideoToPlay(video);
+
+ const videoDuration = await getVideoDuration(video);
+ await setVideoCurrentTime(video, videoDuration - 5);
+
+ await waitForVideoToPlay(video);
+ await page.waitForTimeout(5500);
+
+ const suggestedVideosGrid = page.locator('.suggested_tile_grid');
+ await expect(suggestedVideosGrid).not.toBeVisible();
+
+ await page.waitForTimeout(3000);
+ const skipButton = page.locator('.skip_button');
+ skipButton.click();
+
+ await expect(suggestedVideosGrid).toBeVisible();
+ expect(await suggestedVideosGrid.screenshot()).toMatchSnapshot('baseline-sv-grid.png', { threshold: 0.02 });
+ });
+
+});
+
diff --git a/client/fluid-player/package-lock.json b/client/fluid-player/package-lock.json
new file mode 100644
index 0000000..97a0f14
--- /dev/null
+++ b/client/fluid-player/package-lock.json
@@ -0,0 +1,7233 @@
+{
+ "name": "fluid-player",
+ "version": "3.46.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "fluid-player",
+ "version": "3.46.0",
+ "license": "MIT",
+ "dependencies": {
+ "dashjs": "^4.5.2",
+ "es6-promise": "^4.2.8",
+ "hls.js": "^1.5.13",
+ "panolens": "^0.12.1",
+ "videojs-vtt.js": "^0.15.4"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.12",
+ "@babel/preset-env": "^7.20.2",
+ "@playwright/test": "^1.49.0",
+ "@types/node": "^22.9.1",
+ "babel-loader": "^9.1.2",
+ "cheerio": "^1.0.0-rc.3",
+ "copy-webpack-plugin": "^11.0.0",
+ "css-loader": "^6.7.3",
+ "html-webpack-plugin": "^5.5.0",
+ "semver": "^7.3.2",
+ "style-loader": "^3.3.1",
+ "webpack": "^5.75.0",
+ "webpack-cli": "^5.1.1",
+ "webpack-dev-server": "^4.11.1"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/highlight": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.20.14",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz",
+ "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
+ "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helpers": "^7.20.7",
+ "@babel/parser": "^7.20.7",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.12",
+ "@babel/types": "^7.20.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.20.14",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz",
+ "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
+ "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz",
+ "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-explode-assignable-expression": "^7.18.6",
+ "@babel/types": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+ "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
+ "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-member-expression-to-functions": "^7.20.7",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/helper-replace-supers": "^7.20.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
+ "@babel/helper-split-export-declaration": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz",
+ "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "regexpu-core": "^5.2.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz",
+ "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.17.7",
+ "@babel/helper-plugin-utils": "^7.16.7",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0-0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-explode-assignable-expression": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz",
+ "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz",
+ "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
+ "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.10",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz",
+ "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
+ "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-wrap-function": "^7.18.9",
+ "@babel/types": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz",
+ "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-member-expression-to-functions": "^7.20.7",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+ "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
+ "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.19.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz",
+ "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.20.5",
+ "@babel/types": "^7.20.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz",
+ "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.13",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.20.15",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz",
+ "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.18.6",
+ "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.18.6.tgz",
+ "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz",
+ "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
+ "@babel/plugin-proposal-optional-chaining": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz",
+ "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-remap-async-to-generator": "^7.18.9",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-static-block": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz",
+ "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.20.7",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-dynamic-import": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz",
+ "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz",
+ "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-json-strings": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz",
+ "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz",
+ "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
+ "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-numeric-separator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz",
+ "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
+ "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz",
+ "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-chaining": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz",
+ "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-methods": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz",
+ "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz",
+ "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-create-class-features-plugin": "^7.20.5",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
+ "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "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-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-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz",
+ "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "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-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-transform-arrow-functions": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz",
+ "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz",
+ "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-remap-async-to-generator": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz",
+ "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.20.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz",
+ "integrity": "sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz",
+ "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.18.6",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-optimise-call-expression": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-replace-supers": "^7.20.7",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz",
+ "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/template": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz",
+ "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz",
+ "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==",
+ "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-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz",
+ "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz",
+ "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.18.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz",
+ "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz",
+ "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.18.9",
+ "@babel/helper-function-name": "^7.18.9",
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz",
+ "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz",
+ "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz",
+ "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz",
+ "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-simple-access": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz",
+ "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-validator-identifier": "^7.19.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz",
+ "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz",
+ "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.20.5",
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz",
+ "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz",
+ "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6",
+ "@babel/helper-replace-supers": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz",
+ "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz",
+ "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
+ "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "regenerator-transform": "^0.15.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz",
+ "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz",
+ "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz",
+ "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz",
+ "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz",
+ "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz",
+ "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
+ "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz",
+ "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==",
+ "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-0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz",
+ "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.20.1",
+ "@babel/helper-compilation-targets": "^7.20.0",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-validator-option": "^7.18.6",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-async-generator-functions": "^7.20.1",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-proposal-class-static-block": "^7.18.6",
+ "@babel/plugin-proposal-dynamic-import": "^7.18.6",
+ "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
+ "@babel/plugin-proposal-json-strings": "^7.18.6",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
+ "@babel/plugin-proposal-numeric-separator": "^7.18.6",
+ "@babel/plugin-proposal-object-rest-spread": "^7.20.2",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
+ "@babel/plugin-proposal-optional-chaining": "^7.18.9",
+ "@babel/plugin-proposal-private-methods": "^7.18.6",
+ "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-import-assertions": "^7.20.0",
+ "@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",
+ "@babel/plugin-transform-arrow-functions": "^7.18.6",
+ "@babel/plugin-transform-async-to-generator": "^7.18.6",
+ "@babel/plugin-transform-block-scoped-functions": "^7.18.6",
+ "@babel/plugin-transform-block-scoping": "^7.20.2",
+ "@babel/plugin-transform-classes": "^7.20.2",
+ "@babel/plugin-transform-computed-properties": "^7.18.9",
+ "@babel/plugin-transform-destructuring": "^7.20.2",
+ "@babel/plugin-transform-dotall-regex": "^7.18.6",
+ "@babel/plugin-transform-duplicate-keys": "^7.18.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
+ "@babel/plugin-transform-for-of": "^7.18.8",
+ "@babel/plugin-transform-function-name": "^7.18.9",
+ "@babel/plugin-transform-literals": "^7.18.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.18.6",
+ "@babel/plugin-transform-modules-amd": "^7.19.6",
+ "@babel/plugin-transform-modules-commonjs": "^7.19.6",
+ "@babel/plugin-transform-modules-systemjs": "^7.19.6",
+ "@babel/plugin-transform-modules-umd": "^7.18.6",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1",
+ "@babel/plugin-transform-new-target": "^7.18.6",
+ "@babel/plugin-transform-object-super": "^7.18.6",
+ "@babel/plugin-transform-parameters": "^7.20.1",
+ "@babel/plugin-transform-property-literals": "^7.18.6",
+ "@babel/plugin-transform-regenerator": "^7.18.6",
+ "@babel/plugin-transform-reserved-words": "^7.18.6",
+ "@babel/plugin-transform-shorthand-properties": "^7.18.6",
+ "@babel/plugin-transform-spread": "^7.19.0",
+ "@babel/plugin-transform-sticky-regex": "^7.18.6",
+ "@babel/plugin-transform-template-literals": "^7.18.9",
+ "@babel/plugin-transform-typeof-symbol": "^7.18.9",
+ "@babel/plugin-transform-unicode-escapes": "^7.18.10",
+ "@babel/plugin-transform-unicode-regex": "^7.18.6",
+ "@babel/preset-modules": "^0.1.5",
+ "@babel/types": "^7.20.2",
+ "babel-plugin-polyfill-corejs2": "^0.3.3",
+ "babel-plugin-polyfill-corejs3": "^0.6.0",
+ "babel-plugin-polyfill-regenerator": "^0.4.1",
+ "core-js-compat": "^3.25.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
+ "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.17.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz",
+ "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.13.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz",
+ "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.20.13",
+ "@babel/types": "^7.20.7",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
+ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz",
+ "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@leichtgewicht/ip-codec": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
+ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@playwright/test": {
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz",
+ "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.49.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.2",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
+ "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/bonjour": {
+ "version": "3.5.10",
+ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz",
+ "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect-history-api-fallback": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz",
+ "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express-serve-static-core": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz",
+ "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "0.0.51",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
+ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.16",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.16.tgz",
+ "integrity": "sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.31",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.17.33",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz",
+ "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
+ "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/http-proxy": {
+ "version": "1.17.9",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz",
+ "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
+ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.10.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
+ "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/sockjs": {
+ "version": "0.3.33",
+ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz",
+ "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/ws": {
+ "version": "8.5.4",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz",
+ "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webpack-cli/configtest": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz",
+ "integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/info": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
+ "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/serve": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz",
+ "integrity": "sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "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/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-assertions": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
+ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "deprecated": "package has been renamed to acorn-import-attributes",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "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-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/ajv-keywords/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/ajv/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/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": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/babel-loader": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz",
+ "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-cache-dir": "^3.3.2",
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0",
+ "webpack": ">=5"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz",
+ "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.17.7",
+ "@babel/helper-define-polyfill-provider": "^0.3.3",
+ "semver": "^6.1.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz",
+ "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.3.3",
+ "core-js-compat": "^3.25.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz",
+ "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.3.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "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/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcp-47": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz",
+ "integrity": "sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/bcp-47-match": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz",
+ "integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/bcp-47-normalize": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz",
+ "integrity": "sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==",
+ "license": "MIT",
+ "dependencies": {
+ "bcp-47": "^1.0.0",
+ "bcp-47-match": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+ "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bonjour-service": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz",
+ "integrity": "sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-flatten": "^2.1.2",
+ "dns-equal": "^1.0.0",
+ "fast-deep-equal": "^3.1.3",
+ "multicast-dns": "^7.2.5"
+ }
+ },
+ "node_modules/bonjour-service/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/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": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.5",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
+ "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001449",
+ "electron-to-chromium": "^1.4.284",
+ "node-releases": "^2.0.8",
+ "update-browserslist-db": "^1.0.10"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "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/bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/caniuse-lite": {
+ "version": "1.0.30001450",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz",
+ "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
+ "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "css-select": "^4.3.0",
+ "css-what": "^6.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "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"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/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/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/clean-css": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
+ "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "~0.6.0"
+ },
+ "engines": {
+ "node": ">= 10.0"
+ }
+ },
+ "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/codem-isoboxer": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/codem-isoboxer/-/codem-isoboxer-0.3.6.tgz",
+ "integrity": "sha512-LuO8/7LW6XuR5ERn1yavXAfodGRhuY2yP60JTZIw5yNYMCE5lUVbk3NFUCJxjnphQH+Xemp5hOGb1LgUXm00Xw==",
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+ "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.5",
+ "bytes": "3.0.0",
+ "compressible": "~2.0.16",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.1.2",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/compression/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/compression/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/connect-history-api-fallback": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
+ "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-disposition/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==",
+ "dev": true,
+ "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/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/copy-webpack-plugin": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz",
+ "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-glob": "^3.2.11",
+ "glob-parent": "^6.0.1",
+ "globby": "^13.1.1",
+ "normalize-path": "^3.0.0",
+ "schema-utils": "^4.0.0",
+ "serialize-javascript": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ }
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.27.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz",
+ "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.21.4"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "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.7.3",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz",
+ "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.4.19",
+ "postcss-modules-extract-imports": "^3.0.0",
+ "postcss-modules-local-by-default": "^4.0.0",
+ "postcss-modules-scope": "^3.0.0",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
+ "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-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "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/dashjs": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/dashjs/-/dashjs-4.5.2.tgz",
+ "integrity": "sha512-WXPk0lPDSaHjiSVoVRh2jQPiMmB1alKUH8hV2CVmaI0vPUeT1wIY7madVE38SthfOmwS9IJViv1RrxrxdGjElg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "bcp-47-match": "^1.0.3",
+ "bcp-47-normalize": "^1.1.1",
+ "codem-isoboxer": "0.3.6",
+ "es6-promise": "^4.2.8",
+ "fast-deep-equal": "2.0.1",
+ "html-entities": "^1.2.1",
+ "imsc": "^1.0.2",
+ "localforage": "^1.7.1",
+ "ua-parser-js": "^1.0.2"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/default-gateway": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
+ "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "execa": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "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/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dns-packet": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz",
+ "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@leichtgewicht/ip-codec": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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-walk": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
+ },
+ "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/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.285",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.285.tgz",
+ "integrity": "sha512-47o4PPgxfU1KMNejz+Dgaodf7YTcg48uOfV1oM6cs3adrl2+7R+dHkt3Jpxqo0LRCbGJEzTKMUt0RdvByb/leg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
+ "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "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/envinfo": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
+ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
+ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es6-promise": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
+ "license": "MIT"
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "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": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/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=sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "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/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/esrecurse/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/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/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/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "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/express": {
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
+ "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.1",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.11.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/express/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==",
+ "dev": true,
+ "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/fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==",
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.12",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/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/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/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/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "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/follow-redirects": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz",
+ "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-monkey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
+ "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "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.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "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": "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/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/global": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
+ "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+ "license": "MIT",
+ "dependencies": {
+ "min-document": "^2.19.0",
+ "process": "^0.11.10"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby": {
+ "version": "13.1.3",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz",
+ "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.11",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/hls.js": {
+ "version": "1.5.15",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.15.tgz",
+ "integrity": "sha512-6cD7xN6bycBHaXz2WyPIaHn/iXFizE5au2yvY5q9aC4wfihxAr16C9fUy4nxh2a3wOw0fEgLRa9dN6wsYjlpNg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "node_modules/hpack.js/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "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/html-entities": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
+ "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
+ "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-webpack-plugin": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz",
+ "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==",
+ "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": {
+ "webpack": "^5.20.0"
+ }
+ },
+ "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/http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz",
+ "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-proxy-middleware": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
+ "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-proxy": "^1.17.8",
+ "http-proxy": "^1.18.1",
+ "is-glob": "^4.0.1",
+ "is-plain-obj": "^3.0.0",
+ "micromatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "@types/express": "^4.17.13"
+ },
+ "peerDependenciesMeta": {
+ "@types/express": {
+ "optional": true
+ }
+ }
+ },
+ "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/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "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/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "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/imsc": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/imsc/-/imsc-1.1.3.tgz",
+ "integrity": "sha512-IY0hMkVTNoqoYwKEp5UvNNKp/A5jeJUOrIO7judgOyhHT+xC6PA4VBOMAOhdtAYbMRHx9DTgI8p6Z6jhYQPFDA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "sax": "1.2.1"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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/ipaddr.js": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
+ "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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-core-module": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+ "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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-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-plain-obj": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
+ "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "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-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-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": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 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": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/jest-worker/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/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/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/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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": "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/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/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/lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/localforage": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
+ "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lie": "3.1.1"
+ }
+ },
+ "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/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "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": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memfs": {
+ "version": "3.4.13",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz",
+ "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==",
+ "dev": true,
+ "license": "Unlicense",
+ "dependencies": {
+ "fs-monkey": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/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/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/min-document": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+ "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
+ "dependencies": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "node_modules/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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/multicast-dns": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
+ "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dns-packet": "^5.2.2",
+ "thunky": "^1.0.2"
+ },
+ "bin": {
+ "multicast-dns": "cli.js"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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/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/node-forge": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
+ "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
+ "dev": true,
+ "license": "(BSD-3-Clause OR GPL-2.0)",
+ "engines": {
+ "node": ">= 6.13.0"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz",
+ "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-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/nth-check": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
+ "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+ "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "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.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz",
+ "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==",
+ "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/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/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/p-retry": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+ "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/panolens": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/panolens/-/panolens-0.12.1.tgz",
+ "integrity": "sha512-2hpjm+rRnDdaLD5Bak49K0Y9/X6vOr1OcyJx5piSA6sCOs1tsgchMgKIwpSGCMpBMHWZ10E/Cz4BIwyXYebt5g==",
+ "license": "MIT",
+ "dependencies": {
+ "three": "^0.105.2"
+ }
+ },
+ "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/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/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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-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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "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/playwright": {
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz",
+ "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.49.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz",
+ "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.21",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
+ "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.4",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-modules-extract-imports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
+ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-local-by-default": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
+ "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-scope": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
+ "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "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": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "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/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/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-addr/node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "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/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "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/raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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/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/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.1.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
+ "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.9",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz",
+ "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz",
+ "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.1.0",
+ "regjsgen": "^0.7.1",
+ "regjsparser": "^0.9.1",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz",
+ "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regjsparser": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
+ "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "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-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/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
+ "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.8.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "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/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "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": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/sax": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+ "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==",
+ "license": "ISC"
+ },
+ "node_modules/schema-utils": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
+ "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.8.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/selfsigned": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz",
+ "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-forge": "^1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver/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==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/send/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/serialize-javascript": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/serve-index/node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "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": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
+ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/sockjs": {
+ "version": "0.3.24",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
+ "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "faye-websocket": "^0.11.3",
+ "uuid": "^8.3.2",
+ "websocket-driver": "^0.7.4"
+ }
+ },
+ "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.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "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-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/style-loader": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
+ "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
+ "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": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.16.3",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz",
+ "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.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.3.6",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
+ "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.14",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.0",
+ "terser": "^5.14.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "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/terser-webpack-plugin/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/terser-webpack-plugin/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/terser-webpack-plugin/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/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "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/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/three": {
+ "version": "0.105.2",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.105.2.tgz",
+ "integrity": "sha512-L3Al37k4g3hVbgFFS251UVtIc25chhyN0/RvXzR0C+uIBToV6EKDG+MZzEXm9L2miGUVMK27W46/VkP6WUZXMg==",
+ "license": "MIT"
+ },
+ "node_modules/thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ua-parser-js": {
+ "version": "1.0.33",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz",
+ "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "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.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "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/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utila": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+ "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/videojs-vtt.js": {
+ "version": "0.15.4",
+ "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz",
+ "integrity": "sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "global": "^4.3.1"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/webpack": {
+ "version": "5.75.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
+ "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^0.0.51",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.7.6",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.10.0",
+ "es-module-lexer": "^0.9.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.1.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.1.3",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "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": "5.1.1",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz",
+ "integrity": "sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.1.0",
+ "@webpack-cli/info": "^2.0.1",
+ "@webpack-cli/serve": "^2.0.4",
+ "colorette": "^2.0.14",
+ "commander": "^10.0.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/webpack-dev-middleware": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
+ "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "colorette": "^2.0.10",
+ "memfs": "^3.4.3",
+ "mime-types": "^2.1.31",
+ "range-parser": "^1.2.1",
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/webpack-dev-server": {
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz",
+ "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/bonjour": "^3.5.9",
+ "@types/connect-history-api-fallback": "^1.3.5",
+ "@types/express": "^4.17.13",
+ "@types/serve-index": "^1.9.1",
+ "@types/serve-static": "^1.13.10",
+ "@types/sockjs": "^0.3.33",
+ "@types/ws": "^8.5.1",
+ "ansi-html-community": "^0.0.8",
+ "bonjour-service": "^1.0.11",
+ "chokidar": "^3.5.3",
+ "colorette": "^2.0.10",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^2.0.0",
+ "default-gateway": "^6.0.3",
+ "express": "^4.17.3",
+ "graceful-fs": "^4.2.6",
+ "html-entities": "^2.3.2",
+ "http-proxy-middleware": "^2.0.3",
+ "ipaddr.js": "^2.0.1",
+ "open": "^8.0.9",
+ "p-retry": "^4.5.0",
+ "rimraf": "^3.0.2",
+ "schema-utils": "^4.0.0",
+ "selfsigned": "^2.1.1",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.24",
+ "spdy": "^4.0.2",
+ "webpack-dev-middleware": "^5.3.1",
+ "ws": "^8.4.2"
+ },
+ "bin": {
+ "webpack-dev-server": "bin/webpack-dev-server.js"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.37.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/html-entities": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz",
+ "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "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/webpack/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/webpack/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/webpack/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/webpack/node_modules/schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "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/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8.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/wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz",
+ "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==",
+ "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/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/client/fluid-player/package.json b/client/fluid-player/package.json
new file mode 100644
index 0000000..d966999
--- /dev/null
+++ b/client/fluid-player/package.json
@@ -0,0 +1,60 @@
+{
+ "name": "fluid-player",
+ "version": "3.46.0",
+ "description": "Fluid Player is a free HTML5 video player",
+ "main": "src/index.js",
+ "scripts": {
+ "build": "webpack --mode=production",
+ "build-cdn": "webpack --mode=production --env dist='current' && webpack --mode=production --env dist='versioned'",
+ "build-dev": "webpack --mode=development",
+ "build-dev-debug": "webpack --mode=development --debug",
+ "dev-server": "webpack serve --mode=development --host 0.0.0.0",
+ "dev-server-debug": "webpack serve --mode=development --env debug --host 0.0.0.0",
+ "dev-server-test": "webpack serve --mode=production --no-live-reload --host 0.0.0.0",
+ "start": "npm run dev-server-debug",
+ "e2e-ui": "npx playwright test --ui",
+ "e2e-report": "npx playwright show-report",
+ "e2e": "npx playwright test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/fluid-player/fluid-player.git"
+ },
+ "author": "EXOGROUP ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/fluid-player/fluid-player/issues"
+ },
+ "homepage": "https://fluidplayer.com",
+ "com_fluidplayer": {
+ "cdn": "https://cdn.fluidplayer.com"
+ },
+ "browserslist": [
+ "> 0.25%",
+ "not dead",
+ "IE 11"
+ ],
+ "dependencies": {
+ "dashjs": "^4.5.2",
+ "es6-promise": "^4.2.8",
+ "hls.js": "^1.5.13",
+ "panolens": "^0.12.1",
+ "videojs-vtt.js": "^0.15.4"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.12",
+ "@babel/preset-env": "^7.20.2",
+ "@playwright/test": "^1.49.0",
+ "@types/node": "^22.9.1",
+ "babel-loader": "^9.1.2",
+ "cheerio": "^1.0.0-rc.3",
+ "copy-webpack-plugin": "^11.0.0",
+ "css-loader": "^6.7.3",
+ "html-webpack-plugin": "^5.5.0",
+ "semver": "^7.3.2",
+ "style-loader": "^3.3.1",
+ "webpack": "^5.75.0",
+ "webpack-cli": "^5.1.1",
+ "webpack-dev-server": "^4.11.1"
+ }
+}
diff --git a/client/fluid-player/playwright.config.ts b/client/fluid-player/playwright.config.ts
new file mode 100644
index 0000000..e71cea4
--- /dev/null
+++ b/client/fluid-player/playwright.config.ts
@@ -0,0 +1,73 @@
+import { defineConfig, devices } from '@playwright/test';
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Run tests in files in parallel */
+ fullyParallel: true,
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:8080',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ // {
+ // name: 'chromium',
+ // use: { ...devices['Desktop Chrome'] },
+ // },
+
+ {
+ name: 'firefox',
+ use: { ...devices['Desktop Firefox'] },
+ },
+
+ // {
+ // name: 'webkit',
+ // use: { ...devices['Desktop Safari'] },
+ // },
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: { ...devices['Pixel 5'] },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: { ...devices['iPhone 12'] },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: { ...devices['Desktop Edge'], channel: 'msedge' },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: { ...devices['Desktop Chrome'], channel: 'chrome' },
+ // },
+ ],
+
+ snapshotPathTemplate: '{testDir}/snapshots/{arg}{ext}', // Use the specified filename
+
+ /* Run your local dev server before starting the tests */
+ // webServer: {
+ // command: 'npm run start',
+ // url: 'http://127.0.0.1:3000',
+ // reuseExistingServer: !process.env.CI,
+ // },
+});
diff --git a/client/fluid-player/src/browser.js b/client/fluid-player/src/browser.js
new file mode 100644
index 0000000..9628126
--- /dev/null
+++ b/client/fluid-player/src/browser.js
@@ -0,0 +1,19 @@
+/**
+ * Build entry point for CDN builds.
+ * You SHOULD NOT import this file except if you plan to build browser distribution of Fluid Player.
+ */
+
+import fluidPlayerInitializer from './index';
+
+// Import CSS automatically in browser builds.
+import './css/fluidplayer.css';
+
+if (window) {
+ /**
+ * Register public interface.
+ */
+ if (!window.fluidPlayer) {
+ window.fluidPlayer = fluidPlayerInitializer;
+ }
+}
+
diff --git a/client/fluid-player/src/css/fluidplayer.css b/client/fluid-player/src/css/fluidplayer.css
new file mode 100644
index 0000000..7ed8fb6
--- /dev/null
+++ b/client/fluid-player/src/css/fluidplayer.css
@@ -0,0 +1,1590 @@
+@import "./suggestedVideos.css";
+
+.fluid_video_wrapper {
+ animation: none;
+ animation-delay: 0;
+ animation-direction: normal;
+ animation-duration: 0;
+ animation-fill-mode: none;
+ animation-iteration-count: 1;
+ animation-name: none;
+ animation-play-state: running;
+ animation-timing-function: ease;
+ backface-visibility: visible;
+ background: 0;
+ background-attachment: scroll;
+ background-clip: border-box;
+ background-color: transparent;
+ background-image: none;
+ background-origin: padding-box;
+ background-position: 0 0;
+ background-position-x: 0;
+ background-position-y: 0;
+ background-repeat: repeat;
+ background-size: auto auto;
+ border: 0;
+ border-style: none;
+ border-width: medium;
+ border-color: inherit;
+ border-bottom: 0;
+ border-bottom-color: inherit;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-style: none;
+ border-bottom-width: medium;
+ border-collapse: separate;
+ border-image: none;
+ border-left: 0;
+ border-left-color: inherit;
+ border-left-style: none;
+ border-left-width: medium;
+ border-radius: 0;
+ border-right: 0;
+ border-right-color: inherit;
+ border-right-style: none;
+ border-right-width: medium;
+ border-spacing: 0;
+ border-top: 0;
+ border-top-color: inherit;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-top-style: none;
+ border-top-width: medium;
+ bottom: auto;
+ box-shadow: none;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ caption-side: top;
+ clear: none;
+ clip: auto;
+ color: inherit;
+ columns: auto;
+ column-count: auto;
+ column-fill: balance;
+ column-gap: normal;
+ column-rule: medium none currentColor;
+ column-rule-color: currentColor;
+ column-rule-style: none;
+ column-rule-width: none;
+ column-span: 1;
+ column-width: auto;
+ content: normal;
+ counter-increment: none;
+ counter-reset: none;
+ cursor: auto;
+ direction: ltr;
+ display: inline;
+ empty-cells: show;
+ float: none;
+ font: normal;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-size: medium;
+ font-style: normal;
+ font-variant: normal;
+ font-weight: normal;
+ height: auto;
+ hyphens: none;
+ left: auto;
+ letter-spacing: normal;
+ line-height: normal;
+ list-style: none;
+ list-style-image: none;
+ list-style-position: outside;
+ list-style-type: disc;
+ margin: 0;
+ margin-bottom: 0;
+ margin-left: 0;
+ margin-right: 0;
+ margin-top: 0;
+ max-height: none;
+ max-width: none;
+ min-height: 0;
+ min-width: 0;
+ opacity: 1;
+ orphans: 0;
+ outline: 0;
+ outline-color: invert;
+ outline-style: none;
+ outline-width: medium;
+ overflow: visible;
+ overflow-x: visible;
+ overflow-y: visible;
+ padding: 0;
+ padding-bottom: 0;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0;
+ page-break-after: auto;
+ page-break-before: auto;
+ page-break-inside: auto;
+ perspective: none;
+ perspective-origin: 50% 50%;
+ position: static;
+ /* May need to alter quotes for different locales (e.g fr) */
+ quotes: '\201C' '\201D' '\2018' '\2019';
+ right: auto;
+ tab-size: 8;
+ table-layout: auto;
+ text-align: inherit;
+ text-align-last: auto;
+ text-decoration: none;
+ text-decoration-color: inherit;
+ text-decoration-line: none;
+ text-decoration-style: solid;
+ text-indent: 0;
+ text-shadow: none;
+ text-transform: none;
+ top: auto;
+ transform: none;
+ transform-style: flat;
+ transition: none;
+ transition-delay: 0s;
+ transition-duration: 0s;
+ transition-property: none;
+ transition-timing-function: ease;
+ unicode-bidi: normal;
+ vertical-align: baseline;
+ visibility: visible;
+ white-space: normal;
+ widows: 0;
+ width: auto;
+ word-spacing: normal;
+ z-index: auto;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.fluid_video_wrapper canvas {
+ pointer-events: none;
+}
+
+.fluid_video_wrapper,
+.fluid_video_wrapper * {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+.fluid_video_wrapper:after, .fluid_video_wrapper:before {
+ content: none;
+}
+
+.fluid_video_wrapper {
+ position: relative;
+ display: inline-block;
+}
+
+.fluid_video_wrapper video {
+ position: relative;
+ background-color: #000000;
+ display: block;
+}
+
+.fluid_video_wrapper .vast_video_loading {
+ display: table;
+ text-align: center;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ pointer-events: auto;
+ z-index: 1;
+}
+
+.fluid_video_wrapper .vast_video_loading:before {
+ background-image: url("../static/fluid-spinner.svg");
+ background-position: center, center;
+ background-repeat: no-repeat, repeat;
+ background-color: rgba(0, 0, 0, 0.2);
+ content: '';
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ top: 0;
+ left: 0;
+}
+
+.skip_button {
+ position: absolute;
+ bottom: 50px;
+ right: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ padding: 13px 21px 13px 21px;
+}
+
+.skip_button, .skip_button a {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+ z-index: 10;
+ font-size: 13px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ white-space: nowrap;
+ text-align: start;
+}
+
+.skip_button a span.skip_button_icon {
+ display: inline-block;
+ text-align: left;
+ width: 21px;
+ position: relative;
+ bottom: 20px;
+}
+
+.skip_button a span.skip_button_icon:before {
+ background: url('../static/fluid-icons.svg') no-repeat;
+ position: absolute;
+ height: 18px;
+ width: 18px;
+ top: 6px;
+ content: "";
+ opacity: 0.8;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -ms-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+ background-position: -122px -57px;
+}
+
+.skip_button a span.skip_button_icon:before:hover {
+ opacity: 1;
+}
+
+.skip_button_disabled {
+ cursor: default !important;
+ padding: 13px 21px 13px 21px;
+}
+
+.close_button {
+ position: absolute;
+ background: #000000 url("../static/close-icon.svg") no-repeat scroll center center;
+ height: 16px;
+ width: 16px;
+ top: 0;
+ right: 0;
+ background-size: 18px 18px;
+ cursor: pointer;
+ padding: 1px;
+ z-index: 31;
+}
+
+.close_button:hover {
+ background-color: #000000;
+ border: 1px solid #ffffff;
+}
+
+.vast_clickthrough_layer {
+ /*IE Fix*/
+ background-color: white;
+ opacity: 0;
+}
+
+.fluid_ad_playing {
+ position: absolute;
+ background-color: black;
+ opacity: 0.8;
+ border-radius: 1px;
+ color: #ffffff;
+ font-size: 13px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ white-space: nowrap;
+ text-align: start;
+ line-height: 18px;
+ z-index: 10;
+ padding: 13px 21px 13px 21px;
+}
+
+.fluid_ad_cta {
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.7);
+ color: #ffffff;
+ font-size: 13px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ text-align: right;
+ cursor: pointer;
+ z-index: 10;
+ padding: 13px 21px 13px 13px;
+ max-width: 50%;
+}
+
+.fluid_ad_cta.left {
+ text-align: left;
+}
+
+.fluid_ad_cta a {
+ text-decoration: none;
+ color: #ffffff;
+ line-height: 18px;
+}
+
+.fluid_ad_cta:hover,
+.skip_button:not(.skip_button_disabled):hover {
+ background-color: rgba(0, 0, 0, 1);
+}
+
+.fluid_html_on_pause,
+.fluid_html_on_pause_container,
+.fluid_pseudo_poster {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ margin: auto;
+ z-index: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ pointer-events: none;
+}
+
+.fluid_html_on_pause_container *,
+.fluid_html_on_pause * {
+ pointer-events: auto;
+}
+
+/*Mobile Layout*/
+.fluid_video_wrapper.mobile .skip_button {
+ bottom: 50px;
+}
+
+/*
+.fluid_video_wrapper.mobile .fluid_ad_cta {
+ bottom: 125px;
+}
+*/
+.fluid_initial_play {
+ width: 60px;
+ height: 60px;
+ border-radius: 50px;
+ cursor: pointer;
+}
+
+.fluid_initial_play_button {
+ margin-top: 15px;
+ margin-left: 23px;
+ border-style: solid;
+ border-width: 15px 0 15px 21px;
+ border-color: transparent transparent transparent #ffffff;
+}
+
+.fluid_initial_pause_button {
+ margin-top: 15px;
+ margin-left: 17px;
+ width: 8px;
+ height: 31px;
+ border: 9px solid white;
+ border-top: 0;
+ border-bottom: 0;
+}
+
+.fluid_timeline_preview {
+ bottom: 11px;
+ color: #ffffff;
+ font-size: 13px;
+ line-height: 18px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ text-align: start;
+ padding: 13px 21px 13px 21px;
+ background-color: rgba(0, 0, 0, 0.85);
+ border-radius: 1px;
+}
+
+/* Duration */
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_fluid_control_duration {
+ display: inline-block;
+ white-space: nowrap;
+ height: 24px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-size: 13px;
+ font-weight: normal;
+ font-style: normal;
+ text-align: left;
+ text-decoration: none;
+ line-height: 21px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_fluid_control_duration.cardboard_time {
+ left: 13px;
+ top: -15px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_fluid_control_duration.cardboard_time .ad_timer_prefix {
+ color: #F2C94C;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .ad_countdown .ad_timer_prefix {
+ color: #F2C94C;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .ad_countdown {
+ /*display: none;*/
+ position: absolute;
+ right: 0;
+ width: 75px;
+ bottom: 5px;
+ height: 24px;
+ color: red;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-size: 13px;
+ font-weight: normal;
+ font-style: normal;
+ text-align: left;
+ text-decoration: none;
+ line-height: 21px;
+}
+
+.initial_controls_show {
+ visibility: visible !important;
+ opacity: 1 !important;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container {
+ color: white;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* FF3.6-15 */
+ background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* Chrome10-25,Safari5.1-6 */
+ background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#ad000000', GradientType=0); /* IE6-9 */
+ height: 100%;
+ width: 100%;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel {
+ height: 96px;
+ width: 72px;
+ left: 10px;
+ top: 10px;
+ position: absolute;
+ background: rgba(0, 0, 0, 0.7);
+ text-align: center;
+ border-radius: 6px;
+ overflow: hidden;
+ pointer-events: auto;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_button {
+ cursor: pointer;
+ display: inline-block;
+ text-align: left;
+ height: 24px;
+ width: 24px;
+ position: relative;
+ background: url(../static/fluid-icons.svg) no-repeat;
+ opacity: 0.8;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_button:hover {
+ opacity: 1;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_up {
+ background-position: -336px -55px;
+ -webkit-transform: rotate(270deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(270deg); /* IE 9 */
+ transform: rotate(270deg); /* Firefox 16+, IE 10+, Opera */
+ display: block;
+ left: calc(50% - 12px);
+ top: 0;
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_left {
+ background-position: -336px -55px;
+ -webkit-transform: rotate(180deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(1890deg); /* IE 9 */
+ transform: rotate(180deg); /* Firefox 16+, IE 10+, Opera */
+ display: block;
+ left: 0;
+ top: 24px;
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_right {
+ background-position: -336px -55px;
+ -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(0deg); /* IE 9 */
+ transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
+ display: block;
+ right: 0;
+ top: 24px;
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_down {
+ background-position: -336px -55px;
+ -webkit-transform: rotate(90deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(90deg); /* IE 9 */
+ transform: rotate(90deg); /* Firefox 16+, IE 10+, Opera */
+ display: block;
+ left: calc(50% - 12px);
+ top: 48px;
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_zoomdefault {
+ background-position: -336px -17px;
+ top: 72px;
+ -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(0deg); /* IE 9 */
+ transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
+ position: absolute;
+ left: calc(50% - 12px);
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_zoomin {
+ background-position: -305px -55px;
+ top: 72px;
+ -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(0deg); /* IE 9 */
+ transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
+ position: absolute;
+ right: 0;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vr_container .fluid_vr_joystick_panel .fluid_vr_joystick_zoomout {
+ background-position: -305px -17px;
+ top: 72px;
+ -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
+ -ms-transform: rotate(0deg); /* IE 9 */
+ transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
+ position: absolute;
+ left: 0;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container.fluid_vr_controls_container {
+ width: 50% !important;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container.fluid_vr2_controls_container {
+ width: 50% !important;
+ left: 50%;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container {
+ color: white;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* FF3.6-15 */
+ background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* Chrome10-25,Safari5.1-6 */
+ background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#ad000000', GradientType=0); /* IE6-9 */
+ height: 53px;
+ z-index: 1;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vpaid_iframe {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ z-index: -10;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vpaid_nonlinear_slot_iframe {
+ z-index: 30;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_vpaid_slot {
+ position: absolute !important;
+ top: 0 !important;
+ width: 100% !important;
+ height: 100% !important;
+ left: 0 !important;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_subtitles_container {
+ color: white;
+ position: absolute;
+ bottom: 46px;
+ left: 0;
+ right: 0;
+ height: auto;
+ z-index: 1;
+ text-align: center;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_subtitles_container div {
+ display: inline;
+ background: black;
+ color: white;
+ font-size: 1em;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ padding: 0.25em;
+ border-radius: 4px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fade_out {
+ visibility: hidden;
+ opacity: 0;
+ -webkit-transition: visibility 0.5s, opacity 0.5s; /* Safari */
+ transition: visibility 0.5s, opacity 0.5s;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fade_in {
+ visibility: visible;
+ opacity: 1;
+ -webkit-transition: visibility 0.5s, opacity 0.5s; /* Safari */
+ transition: visibility 0.5s, opacity 0.5s;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default.pseudo_fullscreen {
+ width: 100% !important;
+ height: 100% !important;
+ top: 0;
+ left: 0;
+ position: fixed;
+ z-index: 99999;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default:-webkit-full-screen {
+ width: 100% !important;
+ height: 100% !important;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default:-ms-fullscreen {
+ width: 100% !important;
+ height: 100% !important;
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu {
+ background-color: #000000;
+ color: #ffffff;
+ font-size: 13px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ white-space: nowrap;
+ text-align: start;
+ z-index: 11;
+ opacity: 0.8;
+ border-radius: 1px;
+}
+
+/* IE 10+ */
+_:-ms-lang(x),
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu {
+ text-align: left;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu ul li {
+ padding: 13px 71px 13px 21px;
+ cursor: pointer;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu ul li + li {
+ border-top: 1px solid #000000;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_context_menu ul li:hover {
+ background-color: #1e1e1e;
+ color: #fbfaff;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_left {
+ width: 24px;
+ left: 20px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container.skip_controls .fluid_controls_left {
+ width: 80px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button {
+ width: 24px;
+ height: 24px;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_duration {
+ display: flex;
+ align-items: center;
+}
+
+.fluid_button_live_indicator {
+ margin-right: 10px;
+ display: inline-flex;
+ align-items: center;
+ padding: 2px 5px;
+ background-color: red;
+ color: white;
+ border-radius: 4px;
+ font-weight: bold;
+ font-size: 11px;
+ margin-bottom: 3px;
+}
+
+.live_circle {
+ position: relative;
+ display: inline-block;
+ width: 6px;
+ height: 6px;
+ background-color: transparent;
+ border: 1px solid #ffffff;
+ border-radius: 50%;
+ margin-left: 3px;
+}
+
+.live_circle::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 4px;
+ height: 4px;
+ background-color: #ffffff;
+ border-radius: 50%;
+}
+
+/* On smaller devices (mobile) */
+@media (max-width: 768px) {
+ .fluid_button_live_indicator {
+ position: absolute;
+ font-size: 8px;
+ top: -30px;
+ left: -40px;
+ padding: 2px 3px !important;
+ }
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right {
+ left: 60px;
+ right: 20px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container.skip_controls .fluid_controls_right {
+ left: 110px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_left,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right {
+ position: absolute;
+ height: 24px;
+ top: 23px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container {
+ height: 14px;
+ position: absolute;
+ left: 13px;
+ right: 13px;
+ z-index: 1;
+ top: 8px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress {
+ position: absolute;
+ top: 5px;
+ width: 100%;
+ height: 4px;
+ background-color: rgba(255, 255, 255, 0.25);
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_buffered {
+ position: absolute;
+ top: 5px;
+ width: 0;
+ height: 3px;
+ background-color: rgba(255, 255, 255, 0.5);
+ z-index: -1;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress .fluid_controls_currentprogress {
+ position: absolute;
+ height: 3px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container:hover .fluid_controls_progress,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container:hover .fluid_controls_buffered,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container:hover .fluid_controls_ad_markers_holder {
+ margin-top: -1px;
+ height: 5px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container:hover .fluid_controls_progress .fluid_controls_currentprogress {
+ height: 5px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_timeline_preview_container {
+ border: 1px solid #262626;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_timeline_preview_container, .fluid_timeline_preview_container_shadow {
+ bottom: 14px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container.fluid_slider .fluid_controls_progress .fluid_controls_currentprogress .fluid_controls_currentpos {
+ background-color: white;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container.fluid_slider .fluid_controls_progress .fluid_controls_currentprogress .fluid_controls_currentpos,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container.fluid_ad_slider .fluid_controls_progress .fluid_controls_currentprogress .fluid_controls_currentpos {
+ opacity: 0;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container.fluid_slider:hover .fluid_controls_progress .fluid_controls_currentprogress .fluid_controls_currentpos {
+ opacity: 1;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container.fluid_slider .fluid_controls_progress .fluid_controls_currentprogress .fluid_controls_currentpos {
+ -webkit-transition: opacity 0.3s; /* Safari */
+ transition: opacity 0.3s;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_ad_markers_holder {
+ position: absolute;
+ top: 5px;
+ width: 100%;
+ height: 3px;
+ z-index: 2;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_ad_marker {
+ position: absolute;
+ background-color: #FFCC00;
+ height: 100%;
+ width: 6px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container {
+ height: 24px;
+ width: 56px;
+ left: 25px;
+ top: -1px;
+ z-index: 2;
+ opacity: 0.8;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -ms-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+ display: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container:hover {
+ opacity: 1;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container .fluid_control_volume {
+ position: relative;
+ height: 3px;
+ width: 100%;
+ margin-top: 10px;
+ background-color: rgba(171, 172, 172, 0.68);
+ z-index: 3;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container .fluid_control_volume .fluid_control_currentvolume {
+ float: left;
+ background-color: white;
+ height: 3px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container .fluid_control_volume .fluid_control_currentvolume .fluid_control_volume_currentpos {
+ background-color: white;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress .fluid_controls_currentpos {
+ right: -4px;
+ z-index: 3;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container .fluid_control_volume .fluid_control_currentvolume .fluid_control_volume_currentpos,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress .fluid_controls_currentpos {
+ width: 11px;
+ height: 11px;
+ position: absolute;
+ top: -4px;
+ border-radius: 6px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_progress_container .fluid_controls_progress .fluid_controls_currentpos {
+ width: 13px;
+ height: 13px;
+ position: absolute;
+ top: -4px;
+ border-radius: 6px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container.no_volume_bar .fluid_controls_right .fluid_control_volume_container {
+ display: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_slider {
+ cursor: pointer;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container div div {
+ display: block;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_fullscreen,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_fullscreen_exit,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_mini_player {
+ float: right;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_cardboard {
+ font-size: 13px;
+ height: 24px;
+ line-height: 24px;
+ float: right;
+ cursor: pointer;
+ position: relative;
+ text-align: right;
+ -webkit-touch-callout: none; /* iOS Safari */
+ -webkit-user-select: none; /* Safari */
+ -khtml-user-select: none; /* Konqueror HTML */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* Internet Explorer/Edge */
+ user-select: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source .fluid_video_sources_title,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles .fluid_subtitles_title {
+ width: 80px;
+ overflow: hidden;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles .fluid_subtitles_list,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source .fluid_video_sources_list,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_video_playback_rates {
+ position: absolute;
+ bottom: 25px;
+ right: 3px;
+ z-index: 888888;
+ opacity: 99%;
+ background-color: rgba(0, 0, 0, 1);
+ border-radius: 2px;
+ color: #ffffff;
+ font-size: 13px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ white-space: nowrap;
+ text-align: start;
+ width: max-content;
+ padding: 0.5em;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles .fluid_subtitles_list .fluid_subtitle_list_item,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source .fluid_video_sources_list .fluid_video_source_list_item {
+ padding: 12px 34px 12px 24px;
+ line-height: 15px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source .fluid_video_sources_list .fluid_video_source_list_item:hover,
+.fluid_video_playback_rates_item:hover,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles .fluid_subtitles_list .fluid_subtitle_list_item:hover {
+ background-color: #3a3a3a;
+}
+
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_volume,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_mute {
+ position: absolute;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_volume,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button.fluid_button_mute {
+ left: -10px;
+}
+
+/* Button Icons */
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_live_indicator,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_play,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_pause,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_back,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_forward,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_volume,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mute,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen_exit,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mini_player {
+ display: inline-block;
+ text-align: left;
+ height: 24px;
+ width: 24px;
+ position: relative;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_play:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_pause:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_back:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_forward:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_volume:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mute:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen_exit:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mini_player:before{
+ background: url('../static/fluid-icons.svg') no-repeat;
+ position: absolute;
+ height: 24px;
+ width: 24px;
+ top: 1px;
+ left: 5px;
+ content: "";
+ opacity: 0.8;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -ms-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_play:before {
+ background-position: -15px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_pause:before {
+ background-position: -15px -57px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_volume:before {
+ background-position: -52px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mute:before {
+ background-position: -52px -57px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen:before {
+ background-position: -88px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen_exit:before {
+ background-position: -88px -57px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source:before {
+ background-position: -122px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate:before {
+ background-position: -232px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download:before {
+ background-position: -194px -18px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre:before {
+ background-position: -195px -56px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles:before {
+ background-position: -269px -19px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard:before {
+ background-position: -269px -56px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_back:before {
+ background: url('../static/skip-backward.svg') no-repeat;
+ background-position: -2px -2px;
+}
+
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_forward:before {
+ background: url('../static/skip-forward.svg') no-repeat;
+ background-position: -2px -2px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mini_player:before {
+ background: url('../static/miniplayer-toggle-on.svg') no-repeat 0 0;
+ background-size: 20px;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode .fluid_controls_container .fluid_button.fluid_button_mini_player:before {
+ background: url('../static/miniplayer-toggle-off.svg') no-repeat 0 0;
+ background-size: 20px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_back {
+ margin-left: 5px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen_exit:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mute:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_volume:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_pause:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_play:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_back:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_skip_forward:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard:hover:before,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mini_player:hover:before {
+ opacity: 1;
+}
+
+.fp_title {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ color: #ffffff;
+ font-size: 15px;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ font-weight: normal;
+ white-space: nowrap;
+}
+
+/* Pulse class and keyframe animation */
+.transform-active {
+ animation: flash 1s infinite;
+ display: inline-block !important;
+ opacity: 0;
+}
+
+@-webkit-keyframes flash {
+ 0% {
+ opacity: 0.6;
+ -webkit-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5);
+ }
+ 70% {
+ -webkit-box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
+ }
+ 100% {
+ opacity: 0;
+ display: none;
+ -webkit-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ }
+}
+
+@keyframes flash {
+ 0% {
+ opacity: 0.6;
+ -moz-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5);
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.6);
+ }
+ 70% {
+ -moz-box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
+ box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
+ }
+ 100% {
+ opacity: 0;
+ display: none;
+ -moz-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ }
+}
+
+.fluid_nonLinear_top, .fluid_nonLinear_middle, .fluid_nonLinear_bottom {
+ flex-direction: column;
+ align-items: center;
+ cursor: pointer;
+ display: flex;
+ vertical-align: middle;
+ align-content: center;
+ border: 1px solid #777777;
+ position: absolute;
+ left: 50%;
+ margin-right: -50%;
+ background-color: rgba(0, 0, 0, 0.7);
+}
+
+.fluid_nonLinear_top {
+ top: 20px;
+ transform: translate(-50%);
+}
+
+.fluid_nonLinear_middle {
+ top: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.fluid_nonLinear_bottom {
+ bottom: 50px;
+ transform: translate(-50%);
+}
+
+.fluid_vpaidNonLinear_top, .fluid_vpaidNonLinear_middle, .fluid_vpaidNonLinear_bottom {
+ flex-direction: column;
+ align-items: center;
+ cursor: pointer;
+ vertical-align: middle;
+ align-content: center;
+ position: absolute;
+ display: flex;
+}
+
+.fluid_vpaidNonLinear_frame {
+ margin: auto;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.fluid_vpaidNonLinear_top {
+ top: 20px;
+}
+
+.fluid_vpaidNonLinear_middle {
+ top: 50%;
+}
+
+.fluid_vpaidNonLinear_bottom {
+ bottom: 50px;
+}
+
+.add_icon_clickthrough {
+ color: #F2C94C;
+ line-height: 18px;
+ text-overflow: ellipsis;
+ max-width: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+ display: inline-block;
+}
+
+.add_icon_clickthrough:before {
+ background: url('../static/fluid-icons.svg') no-repeat;
+ height: 18px;
+ width: 18px;
+ top: 30px;
+ padding: 3px 22px 0 0;
+ content: "";
+ background-position: -162px -57px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard {
+ float: right;
+ padding-right: 5px;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_subtitles,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_cardboard {
+ display: none;
+}
+
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_subtitles .fluid_subtitles_list,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_button_video_source .fluid_video_sources_list,
+.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_video_playback_rates {
+ z-index: 888888 !important;
+ opacity: 0.9 !important;
+}
+
+.fluid_video_playback_rates_item {
+ padding: 9px 25px 9px 25px;
+ line-height: 15px;
+ text-align: center;
+}
+
+.fluid_theatre_mode {
+ position: fixed;
+ float: left;
+ top: 0;
+ z-index: 10;
+ box-shadow: 0px 15px 25px rgba(0, 0, 0, 0.8);
+}
+
+.fluid_mini_player_mode {
+ position: fixed;
+ bottom: 10px;
+ right: 10px;
+ z-index: 10;
+}
+
+.source_button_icon {
+ background: url('../static/fluid-icons.svg') no-repeat;
+ float: left;
+ cursor: pointer;
+ height: 18px;
+ width: 18px;
+ background-position: -164px -21px;
+ opacity: 0;
+}
+
+.subtitle_button_icon {
+ background: url('../static/fluid-icons.svg') no-repeat;
+ float: left;
+ cursor: pointer;
+ height: 18px;
+ width: 18px;
+ background-position: -164px -21px;
+ opacity: 0;
+}
+
+.source_selected {
+ opacity: 1 !important;
+}
+
+.subtitle_selected {
+ opacity: 1 !important;
+}
+
+@media only screen and (min-device-width: 375px) {
+ .fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_duration {
+ padding-left: 95px;
+ }
+
+ .fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_duration.no_volume_bar {
+ padding-left: 32px;
+ }
+
+ .fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_controls_right .fluid_control_volume_container {
+ display: block;
+ }
+}
+
+.fp_logo {
+ visibility: hidden;
+ opacity: 0;
+ -webkit-transition: visibility 0.3s ease-in-out, opacity 0.3s ease-in-out;
+ -moz-transition: visibility 0.3s ease-in-out, opacity 0.3s ease-in-out;
+ -ms-transition: visibility 0.3s ease-in-out, opacity 0.3s ease-in-out;
+ -o-transition: visibility 0.3s ease-in-out, opacity 0.3s ease-in-out;
+ transition: visibility 0.3s ease-in-out, opacity 0.3s ease-in-out;
+}
+
+.fp_hd_source::before {
+ font-weight: bolder;
+ font-size: 6pt;
+ content: 'HD';
+ padding-left: 3px;
+}
+
+/** MiniPlayer */
+
+.fluid_video_wrapper.fluid_player_layout_default .mini-player-close-button-wrapper {
+ display: none;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode .mini-player-close-button-wrapper {
+ position: absolute;
+ background: rgb(0,0,0);
+ background: linear-gradient(45deg, rgba(0,0,0,0) 90%, rgba(0,0,0,0.6) 110%);
+ height: 100%;
+ width: 100%;
+ top: 0;
+ right: 0;
+ z-index: 31;
+ display: block;
+ opacity: 0;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -ms-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+ pointer-events: none;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode .mini-player-close-button {
+ position: absolute;
+ background: transparent url("../static/close-icon.svg") no-repeat scroll center center;
+ height: 22px;
+ width: 22px;
+ top: 6px;
+ right: 6px;
+ background-size: 22px;
+ cursor: pointer;
+ z-index: 32;
+ display: block;
+ pointer-events: all;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode:hover .mini-player-close-button-wrapper {
+ opacity: 1;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode .disable-mini-player-mobile {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.fluidplayer-miniplayer-player-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ font-size: 1.5rem;
+ font-family: -apple-system, BlinkMacSystemFont, 'segoe ui', roboto, oxygen-sans, ubuntu, cantarell, 'helvetica neue', 'arial', sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol';
+ background: #000 url('../static/miniplayer-toggle-on.svg') no-repeat 50% calc(50% - 48px);
+ background-size: 48px;
+ cursor: pointer;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode.fluid_video_wrapper.fluid_mini_player_mode--top-left {
+ top: 10px;
+ left: 10px;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode.fluid_video_wrapper.fluid_mini_player_mode--top-right {
+ top: 10px;
+ right: 10px;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode.fluid_video_wrapper.fluid_mini_player_mode--bottom-left {
+ bottom: 10px;
+ left: 10px;
+}
+
+.fluid_video_wrapper.fluid_mini_player_mode.fluid_video_wrapper.fluid_mini_player_mode--bottom-right {
+ bottom: 10px;
+ right: 10px;
+}
+
+@media screen and (max-width: 768px) {
+ .fluid_video_wrapper.fluid_mini_player_mode > *:not(video, .ad_countdown, .fluid_nonLinear_ad, .disable-mini-player-mobile) {
+ display: none;
+ }
+
+ .fluid_video_wrapper.fluid_mini_player_mode .fluid_nonLinear_ad {
+ z-index: 100;
+ }
+
+ .fluid_video_wrapper.fluid_mini_player_mode .fluid_nonLinear_bottom {
+ bottom: 16px;
+ }
+
+ .fluid_video_wrapper.fluid_mini_player_mode .fluid_nonLinear_top {
+ top: 16px;
+ }
+
+ .fluid_video_wrapper.fluid_mini_player_mode .ad_countdown {
+ display: inline-block !important;
+ }
+
+ .fluid_video_wrapper.fluid_mini_player_mode .disable-mini-player-mobile {
+ display: block;
+ touch-action: none;
+ }
+
+ .fluidplayer-miniplayer-player-placeholder {
+ font-size: 1.25rem !important;
+ background-size: 32px !important;
+ background-position-y: calc(50% - 32px) !important;
+ }
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ pointer-events: none;
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset__backward {
+ display: flex;
+ align-items: center;
+ margin: 10% 10% 10% 0;
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset__backward-icon {
+ background: rgba(0, 0, 0, .5) url('../static/skip-backward.svg') no-repeat -2px 3px;
+ width: 150px;
+ height: 150px;
+ background-size: contain;
+ opacity: 0;
+ transition: opacity 400ms ease-in;
+ border-radius: 150px;
+ margin-left: 20%;
+ pointer-events: none;
+ background-origin: content-box;
+ padding: 10px;
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset__forward {
+ display: flex;
+ align-items: center;
+ flex-direction: row-reverse;
+ margin: 10% 0 10% 10%;
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset__forward-icon {
+ background: rgba(0, 0, 0, .5) url('../static/skip-forward.svg') no-repeat -2px 3px;
+ width: 150px;
+ height: 150px;
+ background-size: cover;
+ opacity: 0;
+ transition: opacity 400ms ease-in;
+ border-radius: 150px;
+ margin-right: 20%;
+ pointer-events: none;
+ background-origin: content-box;
+ padding: 10px;
+}
+
+.fluid_video_wrapper .fluid_player_skip_offset__backward-icon.animate,
+.fluid_video_wrapper .fluid_player_skip_offset__forward-icon.animate {
+ opacity: 1;
+ transition: opacity 150ms ease-out;
+}
+
+@media screen and (max-width: 768px) {
+ .fluid_video_wrapper .fluid_player_skip_offset__backward-icon,
+ .fluid_video_wrapper .fluid_player_skip_offset__forward-icon {
+ width: 50px;
+ height: 50px;
+ border-radius: 50px;
+ background-position-x: 0;
+ background-position-y: 0;
+ padding: 5px;
+ }
+}
diff --git a/client/fluid-player/src/css/suggestedVideos.css b/client/fluid-player/src/css/suggestedVideos.css
new file mode 100644
index 0000000..18c1126
--- /dev/null
+++ b/client/fluid-player/src/css/suggestedVideos.css
@@ -0,0 +1,143 @@
+.suggested_tile_grid {
+ --thumbnail-height: 120px;
+ }
+
+.suggested_tile_grid {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ z-index: 100;
+ display: flex;
+ height: var(--thumbnail-height);
+ overflow-x: auto;
+ overflow-y: hidden;
+ justify-content: flex-start;
+ bottom: 53px;
+ top: initial;
+ column-gap: 10px;
+ row-gap: 10px;
+ white-space: nowrap;
+}
+
+.suggested_tile {
+ aspect-ratio: 16/9;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ border-radius: 2px;
+ flex-shrink: 0;
+ width: calc(var(--thumbnail-height) * (16/9));
+ height: var(--thumbnail-height);
+
+ img {
+ height: -webkit-fill-available;
+ }
+}
+
+.suggested_tile_image {
+ max-width: 100%;
+ max-height: 100%;
+}
+
+.suggested_tile:first-child {
+ margin-left: 20px;
+}
+
+.suggested_tile:last-child {
+ margin-right: 20px;
+}
+
+.suggested_tile_overlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.6);
+ color: #ffffff;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ transition: opacity 0.25s;
+}
+
+.suggested_tile_overlay .suggested_tile_title {
+ position: absolute;
+ bottom: 0px;
+ left: 10px;
+}
+
+.suggested_tile_overlay--blur {
+ backdrop-filter: blur(5px);
+}
+
+.suggested_tile_overlay>* {
+ transform: translateY(20px);
+ transition: transform 0.25s;
+}
+
+.suggested_tile_overlay:hover {
+ opacity: 1;
+}
+
+.suggested_tile_overlay:hover>* {
+ transform: translateY(0);
+}
+
+.suggested_tile:hover {
+ cursor: pointer;
+}
+
+@media only screen and (max-width: 600px) and (orientation: portrait) {
+ .suggested_tile_grid {
+ display: none;
+ }
+}
+
+/* Medium devices like tablet portrait */
+@media only screen and (min-width: 992px) {
+ .suggested_tile_grid {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: calc(100% - 53px);
+ display: grid;
+ grid-template-columns: repeat(3, 20%);
+ grid-template-rows: min-content min-content;
+ column-gap: 40px;
+ row-gap: 10px;
+ z-index: 100;
+ align-content: center;
+ justify-content: center;
+ }
+
+ /* hide the last 6 video tiles */
+ .suggested_tile:nth-child(n+7) {
+ display: none;
+ }
+
+ .suggested_tile:first-child {
+ margin-left: 0px;
+ }
+
+ .suggested_tile:last-child {
+ margin-right: 0px;
+ }
+}
+
+/* Desktop */
+@media only screen and (min-width: 1200px) {
+ .suggested_tile_grid {
+ grid-template-columns: repeat(4, 20%);
+ column-gap: 10px;
+ }
+ .suggested_tile {
+ width: initial;
+ height: initial;
+ }
+ .suggested_tile:nth-child(n+7) {
+ display: flex;
+ }
+}
diff --git a/client/fluid-player/src/fluidplayer.js b/client/fluid-player/src/fluidplayer.js
new file mode 100644
index 0000000..2b334f8
--- /dev/null
+++ b/client/fluid-player/src/fluidplayer.js
@@ -0,0 +1,3469 @@
+// @ts-check
+'use strict';
+
+// Player modules
+import VPAIDModule from './modules/vpaid';
+import VASTModule from './modules/vast';
+import CardboardModule from './modules/cardboard';
+import SubtitleModule from './modules/subtitles';
+import TimelineModule from './modules/timeline';
+import AdSupportModule from './modules/adsupport';
+import StreamingModule from './modules/streaming';
+import UtilsModule from './modules/utils';
+import SuggestedVideosModule from './modules/suggestedVideos';
+import MiniPlayerModule from './modules/miniplayer';
+
+const FP_MODULES = [
+ VPAIDModule,
+ VASTModule,
+ CardboardModule,
+ SubtitleModule,
+ TimelineModule,
+ AdSupportModule,
+ StreamingModule,
+ UtilsModule,
+ SuggestedVideosModule,
+ MiniPlayerModule
+];
+
+// Determine build mode
+// noinspection JSUnresolvedVariable
+const FP_DEVELOPMENT_MODE = typeof FP_ENV !== 'undefined' && FP_ENV === 'development';
+
+// Are we running in debug mode?
+// noinspection JSUnresolvedVariable
+const FP_RUNTIME_DEBUG = typeof FP_DEBUG !== 'undefined' && FP_DEBUG === true;
+
+let playerInstances = 0;
+
+/**
+ * @this {import("./types").IFluidPlayer}
+ */
+const fluidPlayerClass = function () {
+ // "self" always points to current instance of the player within the scope of the instance
+ // This should help readability and context awareness slightly...
+ const self = this;
+
+ self.domRef = {
+ player: null
+ };
+
+ // noinspection JSUnresolvedVariable
+ self.version = typeof FP_BUILD_VERSION !== 'undefined' ? FP_BUILD_VERSION : '';
+ // noinspection JSUnresolvedVariable
+ self.homepage = typeof FP_HOMEPAGE !== 'undefined'
+ ? FP_HOMEPAGE + '/?utm_source=player&utm_medium=context_menu&utm_campaign=organic'
+ : '';
+ self.destructors = [];
+
+ self.init = (playerTarget, options) => {
+ // Install player modules and features
+ const moduleOptions = {
+ development: FP_DEVELOPMENT_MODE,
+ debug: FP_RUNTIME_DEBUG,
+ };
+
+ for (const playerModule of FP_MODULES) {
+ playerModule(self, moduleOptions);
+ }
+ /**
+ * @type {HTMLVideoElement}
+ */
+ let playerNode;
+ if (playerTarget instanceof HTMLVideoElement) {
+ playerNode = playerTarget;
+
+ // Automatically assign ID if none exists
+ if (!playerTarget.id) {
+ playerTarget.id = 'fluid_player_instance_' + (playerInstances++).toString();
+ }
+ } else if (typeof playerTarget === 'string' || playerTarget instanceof String) {
+ // @ts-expect-error
+ playerNode = document.getElementById(playerTarget);
+ } else {
+ throw 'Invalid initializer - player target must be HTMLVideoElement or ID';
+ }
+
+ if (!playerNode) {
+ throw 'Could not find a HTML node to attach to for target ' + playerTarget + '"';
+ }
+
+ if (playerNode.classList.contains('js-fluid-player')) {
+ throw 'Invalid initializer - player target already is initialized';
+ }
+
+ playerNode.setAttribute('playsinline', '');
+ playerNode.setAttribute('webkit-playsinline', '');
+ playerNode.classList.add('js-fluid-player');
+
+ self.domRef.player = playerNode;
+ self.vrROTATION_POSITION = 0.1;
+ self.vrROTATION_SPEED = 80;
+ self.vrMode = false;
+ self.vrPanorama = null;
+ self.vrViewer = null;
+ self.vpaidTimer = null;
+ self.vpaidAdUnit = null;
+ self.vastOptions = null;
+ /**
+ * Don't use this as a way to change the DOM. DOM manipulation should be done with domRef.
+ */
+ self.videoPlayerId = playerNode.id;
+ self.originalSrc = self.getCurrentSrc();
+ self.isCurrentlyPlayingAd = false;
+ self.recentWaiting = false;
+ self.latestVolume = 1;
+ self.currentVideoDuration = 0;
+ self.firstPlayLaunched = false;
+ self.suppressClickthrough = false;
+ self.timelinePreviewData = [];
+ self.mainVideoCurrentTime = 0;
+ self.mainVideoDuration = 0;
+ self.isTimer = false;
+ self.timer = null;
+ self.timerPool = {};
+ self.rollsById = {};
+ self.adPool = {};
+ self.adGroupedByRolls = {};
+ self.onPauseRollAdPods = [];
+ self.currentOnPauseRollAd = '';
+ self.preRollAdsResolved = false;
+ self.preRollAdPods = [];
+ self.preRollAdPodsLength = 0;
+ self.preRollVastResolved = 0;
+ self.temporaryAdPods = [];
+ self.availableRolls = ['preRoll', 'midRoll', 'postRoll', 'onPauseRoll'];
+ self.supportedNonLinearAd = ['300x250', '468x60', '728x90'];
+ self.autoplayAfterAd = true;
+ self.nonLinearDuration = 15;
+ self.supportedStaticTypes = ['image/gif', 'image/jpeg', 'image/png'];
+ self.inactivityTimeout = null;
+ self.isUserActive = null;
+ self.nonLinearVerticalAlign = 'bottom';
+ self.vpaidNonLinearCloseButton = true;
+ self.showTimeOnHover = true;
+ self.initialAnimationSet = true;
+ self.theatreMode = false;
+ self.theatreModeAdvanced = false;
+ self.fullscreenMode = false;
+ self.originalWidth = playerNode.offsetWidth;
+ self.originalHeight = playerNode.offsetHeight;
+ self.dashPlayer = false;
+ self.hlsPlayer = false;
+ self.dashScriptLoaded = false;
+ self.hlsScriptLoaded = false;
+ self.isPlayingMedia = false;
+ self.isSwitchingSource = false;
+ self.isLoading = false;
+ self.isInIframe = self.inIframe();
+ self.mainVideoReadyState = false;
+ self.xmlCollection = [];
+ self.inLineFound = null;
+ self.fluidStorage = {};
+ self.fluidPseudoPause = false;
+ self.mobileInfo = self.getMobileOs();
+ self.events = {};
+ self.timeSkipOffsetAmount = 10;
+ // Only for linear ads, non linear are not taken into account
+ self.currentMediaSourceType = 'source';
+
+ //Default options
+ self.displayOptions = {
+ layoutControls: {
+ mediaType: self.getCurrentSrcType(),
+ primaryColor: false,
+ posterImage: false,
+ posterImageSize: 'contain',
+ adProgressColor: '#f9d300',
+ playButtonShowing: true,
+ playPauseAnimation: true,
+ closeButtonCaption: 'Close', // Remove?
+ fillToContainer: false,
+ autoPlay: false,
+ preload: 'auto',
+ mute: false,
+ loop: null,
+ keyboardControl: true,
+ allowDownload: false,
+ playbackRateEnabled: false,
+ subtitlesEnabled: false,
+ subtitlesOnByDefault: true,
+ showCardBoardView: false,
+ showCardBoardJoystick: false,
+ allowTheatre: true,
+ doubleclickFullscreen: true,
+ autoRotateFullScreen: false,
+ theatreSettings: {
+ width: '100%',
+ height: '60%',
+ marginTop: 0,
+ horizontalAlign: 'center',
+ keepPosition: false
+ },
+ theatreAdvanced: {
+ theatreElement: null,
+ },
+ title: null,
+ logo: {
+ imageUrl: null,
+ position: 'top left',
+ clickUrl: null,
+ opacity: 1,
+ mouseOverImageUrl: null,
+ imageMargin: '2px',
+ hideWithControls: false,
+ showOverAds: false
+ },
+ controlBar: {
+ autoHide: false,
+ autoHideTimeout: 3,
+ animated: true,
+ playbackRates: ['x2', 'x1.5', 'x1', 'x0.5']
+ },
+ timelinePreview: {
+ spriteImage: false,
+ spriteRelativePath: false
+ },
+ htmlOnPauseBlock: {
+ html: null,
+ height: null,
+ width: null
+ },
+ layout: 'default', //options: 'default', ''
+ playerInitCallback: (function () {
+ }),
+ persistentSettings: {
+ volume: true,
+ quality: true,
+ speed: true,
+ theatre: true
+ },
+ controlForwardBackward: {
+ show: false,
+ doubleTapMobile: true
+ },
+ contextMenu: {
+ controls: true,
+ links: []
+ },
+ miniPlayer: {
+ enabled: true,
+ width: 400,
+ height: 225,
+ widthMobile: 50,
+ placeholderText: 'Playing in Miniplayer',
+ position: 'bottom right',
+ autoToggle: false,
+ },
+ roundedCorners: 0
+ },
+ suggestedVideos: {
+ configUrl: null
+ },
+ vastOptions: {
+ adList: {},
+ skipButtonCaption: 'Skip ad in [seconds]',
+ skipButtonClickCaption: 'Skip Ad ',
+ adText: null,
+ adTextPosition: 'top left',
+ adCTAText: 'Visit now!',
+ adCTATextPosition: 'bottom right',
+ adCTATextVast: false,
+ adClickable: true,
+ vastTimeout: 5000,
+ showProgressbarMarkers: false,
+ allowVPAID: false,
+ showPlayButton: false,
+ maxAllowedVastTagRedirects: 3,
+ vpaidTimeout: 3000,
+
+ vastAdvanced: {
+ vastLoadedCallback: (function () {
+ }),
+ noVastVideoCallback: (function () {
+ }),
+ vastVideoSkippedCallback: (function () {
+ }),
+ vastVideoEndedCallback: (function () {
+ })
+ }
+ },
+ hls: {
+ overrideNative: false
+ },
+ captions: {
+ play: 'Play',
+ pause: 'Pause',
+ mute: 'Mute',
+ unmute: 'Unmute',
+ fullscreen: 'Fullscreen',
+ subtitles: 'Subtitles',
+ exitFullscreen: 'Exit Fullscreen',
+ },
+ debug: FP_RUNTIME_DEBUG,
+ modules: {
+ configureHls: (options) => {
+ return options;
+ },
+ onBeforeInitHls: (hls) => {
+ },
+ onAfterInitHls: (hls) => {
+ },
+ configureDash: (options) => {
+ return options;
+ },
+ onBeforeInitDash: (dash) => {
+ },
+ onAfterInitDash: (dash) => {
+ }
+ },
+ onBeforeXMLHttpRequestOpen: (request) => {
+ },
+ onBeforeXMLHttpRequest: (request) => {
+ if (FP_RUNTIME_DEBUG || FP_DEVELOPMENT_MODE) {
+ console.debug('[FP_DEBUG] Request made', request);
+ }
+ }
+ };
+
+ if (!!options.hlsjsConfig) {
+ console.error('[FP_ERROR] player option hlsjsConfig is removed and has no effect. ' +
+ 'Use module callbacks instead!')
+ }
+
+ /**
+ * Replaces values from objects without replacing the default object
+ *
+ * @param defaults
+ * @param options
+ * @returns {object}
+ */
+ function overrideDefaults(defaults, options) {
+ Object.keys(options).forEach(defaultKey => {
+ if (
+ typeof options[defaultKey] === 'object' &&
+ options[defaultKey] !== null &&
+ !Array.isArray(options[defaultKey])
+ ) {
+ overrideDefaults(defaults[defaultKey], options[defaultKey]);
+ } else if (typeof options[defaultKey] !== 'undefined') {
+ defaults[defaultKey] = options[defaultKey];
+ }
+ });
+
+ return defaults;
+ }
+
+ overrideDefaults(self.displayOptions, options);
+
+ self.domRef.wrapper = self.setupPlayerWrapper();
+
+ playerNode.addEventListener('webkitfullscreenchange', self.recalculateAdDimensions);
+ playerNode.addEventListener('fullscreenchange', self.recalculateAdDimensions);
+ playerNode.addEventListener('waiting', self.onRecentWaiting);
+ playerNode.addEventListener('pause', self.onFluidPlayerPause);
+ playerNode.addEventListener('error', self.onErrorDetection);
+ playerNode.addEventListener('ended', self.onMainVideoEnded);
+ playerNode.addEventListener('durationchange', () => {
+ self.currentVideoDuration = self.getCurrentVideoDuration();
+ });
+
+ // 'loadedmetadata' inconsistently fires because the audio can already be loaded when the listener is added.
+ // Here we use readystate to see if metadata has already loaded
+ if (playerNode.readyState > 0) {
+ self.mainVideoReady();
+ } else {
+ playerNode.addEventListener('loadedmetadata', self.mainVideoReady);
+ }
+
+ if (self.displayOptions.layoutControls.showCardBoardView) {
+ // This fixes cross origin errors on three.js
+ playerNode.setAttribute('crossOrigin', 'anonymous');
+ }
+
+ //Manually load the video duration if the video was loaded before adding the event listener
+ self.currentVideoDuration = self.getCurrentVideoDuration();
+
+ if (isNaN(self.currentVideoDuration) || !isFinite(self.currentVideoDuration)) {
+ self.currentVideoDuration = 0;
+ }
+
+ self.setLayout();
+
+ //Set the volume control state
+ self.latestVolume = playerNode.volume;
+
+ // Set the default animation setting
+ self.initialAnimationSet = self.displayOptions.layoutControls.playPauseAnimation;
+
+ //Set the custom fullscreen behaviour
+ self.handleFullscreen();
+
+ self.initLogo();
+
+ self.initTitle();
+
+ self.initMute();
+
+ self.initLoop();
+
+ self.displayOptions.layoutControls.playerInitCallback();
+
+ self.createVideoSourceSwitch();
+
+ self.createSubtitles();
+
+ self.createCardboard();
+
+ self.userActivityChecker();
+
+ self.setVastList();
+
+ self.setPersistentSettings();
+
+ self.generateSuggestedVideoList();
+
+ // Previously prevented to be initialized if preRolls were set up
+ // but now the streamers support reinitialization
+ self.initialiseStreamers();
+ self.detectLiveStream();
+ self.showLiveIndicator();
+
+ const _play_videoPlayer = playerNode.play;
+
+ playerNode.play = function () {
+ let promise = null;
+
+ if (self.displayOptions.layoutControls.showCardBoardView) {
+ if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {
+ DeviceOrientationEvent.requestPermission()
+ .then(function (response) {
+ if (response === 'granted') {
+ self.debugMessage('DeviceOrientationEvent permission granted!');
+ }
+ })
+ .catch(console.error);
+ }
+ }
+
+ try {
+ promise = _play_videoPlayer.apply(this, arguments);
+
+ if (promise !== undefined && promise !== null) {
+ promise.then(() => {
+ self.isPlayingMedia = true;
+ clearTimeout(self.promiseTimeout);
+ }).catch(error => {
+ console.error('[FP_ERROR] Playback error', error);
+ const isAbortError = (typeof error.name !== 'undefined' && error.name === 'AbortError');
+ // Ignore abort errors which caused for example Safari or autoplay functions
+ // (example: interrupted by a new load request)
+ // (example: interrupted by a new load request)
+ if (isAbortError) {
+ // Ignore AbortError error reporting
+ } else {
+ self.announceLocalError(202, 'Failed to play video.');
+ }
+
+ clearTimeout(self.promiseTimeout);
+ });
+
+ self.promiseTimeout = setTimeout(function () {
+ if (self.isPlayingMedia === false) {
+ self.announceLocalError(204, '[FP_ERROR] Timeout error. Failed to play video?');
+ }
+ }, 5000);
+
+ }
+
+ return promise;
+ } catch (error) {
+ console.error('[FP_ERROR] Playback error', error);
+ self.announceLocalError(201, 'Failed to play video.');
+ }
+ };
+
+ const videoPauseOriginal = playerNode.pause;
+ playerNode.pause = function () {
+ if (self.isPlayingMedia === true) {
+ self.isPlayingMedia = false;
+ return videoPauseOriginal.apply(this, arguments);
+ }
+
+ // just in case
+ if (self.isCurrentlyPlayingVideo(self.domRef.player)) {
+ try {
+ self.isPlayingMedia = false;
+ return videoPauseOriginal.apply(this, arguments);
+ } catch (e) {
+ self.announceLocalError(203, 'Failed to play video.');
+ }
+ }
+ };
+
+ if (!!self.displayOptions.layoutControls.autoPlay && !self.dashScriptLoaded && !self.hlsScriptLoaded) {
+ //There is known issue with Safari 11+, will prevent autoPlay, so we wont try
+ const browserVersion = self.getBrowserVersion();
+
+ if ('Safari' === browserVersion.browserName) {
+ return;
+ }
+
+ playerNode.play();
+ }
+
+ if (!self.mobileInfo.userOs) {
+ if (!self.displayOptions.layoutControls.controlBar.autoHide) {
+ self.domRef.wrapper.addEventListener('mouseleave', self.handleMouseleave, false);
+ }
+ self.domRef.wrapper.addEventListener('mouseenter', self.showControlBar, false);
+ self.domRef.wrapper.addEventListener('mouseenter', self.showTitle, false);
+ } else {
+ //On mobile mouseleave behavior does not make sense, so it's better to keep controls, once the playback starts
+ //Autohide behavior on timer is a separate functionality
+ self.hideControlBar();
+ self.domRef.wrapper.addEventListener('touchstart', self.showControlBar, { passive: true });
+ }
+
+ //Keyboard Controls
+ if (self.displayOptions.layoutControls.keyboardControl) {
+ self.keyboardControl();
+ }
+
+ if (self.displayOptions.layoutControls.controlBar.autoHide) {
+ self.linkControlBarUserActivity();
+ }
+
+ // Hide the captions on init if user added subtitles track.
+ // We are taking captions track kind of as metadata
+ try {
+ if (!!self.domRef.player.textTracks) {
+ for (const textTrack of self.domRef.player.textTracks) {
+ textTrack.mode = 'hidden';
+ }
+ }
+ } catch (_ignored) {
+ }
+ };
+
+ self.getCurrentVideoDuration = () => {
+ if (self.domRef.player) {
+ return self.domRef.player.duration;
+ }
+
+ return 0;
+ };
+
+ self.toggleLoader = (showLoader) => {
+ self.isLoading = !!showLoader;
+
+ const loaderDiv = self.domRef.wrapper.querySelector('.vast_video_loading');
+
+ if (loaderDiv) {
+ loaderDiv.style.display = showLoader ? 'table' : 'none';
+ }
+ };
+
+ self.sendRequest = (url, withCredentials, timeout, functionReadyStateChange) => {
+ const xmlHttpReq = new XMLHttpRequest();
+
+ xmlHttpReq.onreadystatechange = functionReadyStateChange;
+
+ self.displayOptions.onBeforeXMLHttpRequestOpen(xmlHttpReq);
+
+ xmlHttpReq.open('GET', url, true);
+ xmlHttpReq.withCredentials = withCredentials;
+ xmlHttpReq.timeout = timeout;
+
+ self.displayOptions.onBeforeXMLHttpRequest(xmlHttpReq);
+
+ xmlHttpReq.send();
+ };
+
+ /**
+ * Makes a XMLHttpRequest encapsulated by a Promise
+ *
+ * @param url
+ * @param withCredentials
+ * @param timeout
+ * @returns {Promise}
+ */
+ self.sendRequestAsync = async (url, withCredentials, timeout) => {
+ return await new Promise((resolve, reject) => {
+ const xmlHttpReq = new XMLHttpRequest();
+
+ xmlHttpReq.onreadystatechange = (event) => {
+ const response = event.target;
+
+ if (response.readyState === 4 && response.status >= 200 && response.status < 300) {
+ resolve(response);
+ } else if (response.readyState === 4) {
+ reject(response);
+ }
+ };
+
+ self.displayOptions.onBeforeXMLHttpRequestOpen(xmlHttpReq);
+
+ xmlHttpReq.open('GET', url, true);
+ xmlHttpReq.withCredentials = withCredentials;
+ xmlHttpReq.timeout = timeout;
+
+ self.displayOptions.onBeforeXMLHttpRequest(xmlHttpReq);
+
+ xmlHttpReq.send();
+ })
+ };
+
+ // TODO: rename
+ self.announceLocalError = (code, msg) => {
+ const parsedCode = typeof (code) !== 'undefined' ? parseInt(code) : 900;
+ let message = '[Error] (' + parsedCode + '): ';
+ message += !msg ? 'Failed to load Vast' : msg;
+ console.warn(message);
+ };
+
+ // TODO: move this somewhere else and refactor
+ self.debugMessage = (...msg) => {
+ const style = 'color: #fff; font-weight: bold; background-color: #1a5e87; padding: 3px 6px; border-radius: 3px;';
+
+ if (self.displayOptions.debug) {
+ console.log('%cFP DEBUG', style, ...msg);
+ }
+ };
+
+ self.onMainVideoEnded = (event) => {
+ self.debugMessage('onMainVideoEnded is called');
+
+ if (self.isCurrentlyPlayingAd && self.autoplayAfterAd) { // It may be in-stream ending, and if it's not postroll then we don't execute anything
+ return;
+ }
+
+ //we can remove timer as no more ad will be shown
+ if (Math.floor(self.getCurrentTime()) >= Math.floor(self.mainVideoDuration)) {
+
+ // play pre-roll ad
+ // sometime pre-roll ad will be missed because we are clearing the timer
+ self.adKeytimePlay(Math.floor(self.mainVideoDuration));
+
+ clearInterval(self.timer);
+ }
+
+ if (!!self.displayOptions.layoutControls.loop) {
+ self.switchToMainVideo();
+ self.playPauseToggle();
+ }
+
+ // Event listener doesn't wait on flags to be flipped from post roll ads, needs small time out to compensate
+ setTimeout(() => {
+ if (!self.isCurrentlyPlayingAd && self.displayOptions.suggestedVideos.configUrl) {
+ self.displaySuggestedVideos();
+ }
+ }, 100);
+ };
+
+ self.getCurrentTime = () => {
+ return self.isCurrentlyPlayingAd
+ ? self.mainVideoCurrentTime
+ : self.domRef.player.currentTime;
+ };
+
+ /**
+ * Gets the src value of the first source element of the video tag.
+ *
+ * @returns string|null
+ */
+ self.getCurrentSrc = () => {
+ const sources = self.domRef.player.getElementsByTagName('source');
+
+ if (sources.length) {
+ return sources[0].getAttribute('src');
+ }
+
+ return null;
+ };
+
+ /**
+ * Src types required for streaming elements
+ */
+ self.getCurrentSrcType = () => {
+ const sources = self.domRef.player.getElementsByTagName('source');
+
+ if (!sources.length) {
+ return null;
+ }
+
+ for (let i = 0; i < sources.length; i++) {
+ if (sources[i].getAttribute('src') === self.originalSrc) {
+ return sources[i].getAttribute('type').toLowerCase();
+ }
+ }
+
+ return null;
+ };
+
+ self.onRecentWaiting = () => {
+ self.recentWaiting = true;
+
+ setTimeout(function () {
+ self.recentWaiting = false;
+ }, 1000);
+ };
+
+ /**
+ * Dispatches a custom pause event which is not present when seeking.
+ */
+ self.onFluidPlayerPause = () => {
+ setTimeout(function () {
+ if (self.recentWaiting) {
+ return;
+ }
+
+ const event = document.createEvent('CustomEvent');
+ event.initEvent('fluidplayerpause', false, true);
+ self.domRef.player.dispatchEvent(event);
+ }, 100);
+ };
+
+ self.checkShouldDisplayVolumeBar = () => {
+ return 'iOS' !== self.getMobileOs().userOs;
+ };
+
+ self.generateCustomControlTags = (options) => {
+ /**
+ * @type {CustomControls}
+ */
+ const controls = {};
+
+ // Loader
+ controls.loader = document.createElement('div');
+ controls.loader.className = 'vast_video_loading';
+ controls.loader.style.display = 'none';
+
+ // Root element
+ controls.root = document.createElement('div');
+ controls.root.className = 'fluid_controls_container';
+
+ if (!options.displayVolumeBar) {
+ controls.root.className = controls.root.className + ' no_volume_bar';
+ }
+
+ if (options.controlForwardBackward) {
+ controls.root.className = controls.root.className + ' skip_controls';
+ }
+
+ // Left container
+ controls.leftContainer = document.createElement('div');
+ controls.leftContainer.className = 'fluid_controls_left';
+ controls.root.appendChild(controls.leftContainer);
+
+ // Left container -> Play/Pause
+ controls.playPause = document.createElement('div');
+ controls.playPause.className = 'fluid_button fluid_button_play fluid_control_playpause';
+ controls.leftContainer.appendChild(controls.playPause);
+
+ if (options.controlForwardBackward) {
+ // Left container -> Skip backwards
+ controls.skipBack = document.createElement('div');
+ controls.skipBack.className = 'fluid_button fluid_button_skip_back';
+ controls.leftContainer.appendChild(controls.skipBack);
+
+ // Left container -> Skip forward
+ controls.skipForward = document.createElement('div');
+ controls.skipForward.className = 'fluid_button fluid_button_skip_forward';
+ controls.leftContainer.appendChild(controls.skipForward);
+ }
+
+ // Progress container
+ controls.progressContainer = document.createElement('div');
+ controls.progressContainer.className = 'fluid_controls_progress_container fluid_slider';
+ controls.root.appendChild(controls.progressContainer);
+
+ // Progress container -> Progress wrapper
+ controls.progressWrapper = document.createElement('div');
+ controls.progressWrapper.className = 'fluid_controls_progress';
+ controls.progressContainer.appendChild(controls.progressWrapper);
+
+ // Progress container -> Progress wrapper -> Current progress
+ controls.progressCurrent = document.createElement('div');
+ controls.progressCurrent.className = 'fluid_controls_currentprogress';
+ controls.progressCurrent.style.backgroundColor = options.primaryColor;
+ controls.progressWrapper.appendChild(controls.progressCurrent);
+
+ // Progress container -> Progress wrapper -> Current progress -> Marker
+ controls.progress_current_marker = document.createElement('div');
+ controls.progress_current_marker.className = 'fluid_controls_currentpos';
+ controls.progressCurrent.appendChild(controls.progress_current_marker);
+
+ // Progress container -> Buffered indicator
+ controls.bufferedIndicator = document.createElement('div');
+ controls.bufferedIndicator.className = 'fluid_controls_buffered';
+ controls.progressContainer.appendChild(controls.bufferedIndicator);
+
+ // Progress container -> Ad markers
+ controls.adMarkers = document.createElement('div');
+ controls.adMarkers.className = 'fluid_controls_ad_markers_holder';
+ controls.progressContainer.appendChild(controls.adMarkers);
+
+ // Right container
+ controls.rightContainer = document.createElement('div');
+ controls.rightContainer.className = 'fluid_controls_right';
+ controls.root.appendChild(controls.rightContainer);
+
+ // Right container -> Fullscreen
+ controls.fullscreen = document.createElement('div');
+ controls.fullscreen.className = 'fluid_button fluid_control_fullscreen fluid_button_fullscreen';
+ controls.rightContainer.appendChild(controls.fullscreen);
+
+ if (options.miniPlayer.enabled) {
+ // Right container -> MiniPlayer
+ controls.miniPlayer = document.createElement('div');
+ controls.miniPlayer.className = 'fluid_button fluid_control_mini_player fluid_button_mini_player';
+ controls.rightContainer.appendChild(controls.miniPlayer);
+ }
+
+ // Right container -> Theatre
+ controls.theatre = document.createElement('div');
+ controls.theatre.className = 'fluid_button fluid_control_theatre fluid_button_theatre';
+ controls.rightContainer.appendChild(controls.theatre);
+
+ // Right container -> Cardboard
+ controls.cardboard = document.createElement('div');
+ controls.cardboard.className = 'fluid_button fluid_control_cardboard fluid_button_cardboard';
+ controls.rightContainer.appendChild(controls.cardboard);
+
+ // Right container -> Subtitles
+ controls.subtitles = document.createElement('div');
+ controls.subtitles.className = 'fluid_button fluid_control_subtitles fluid_button_subtitles';
+ controls.rightContainer.appendChild(controls.subtitles);
+
+ // Right container -> Video source
+ controls.videoSource = document.createElement('div');
+ controls.videoSource.className = 'fluid_button fluid_control_video_source fluid_button_video_source';
+ controls.rightContainer.appendChild(controls.videoSource);
+
+ // Right container -> Playback rate
+ controls.playbackRate = document.createElement('div');
+ controls.playbackRate.className = 'fluid_button fluid_control_playback_rate fluid_button_playback_rate';
+ controls.rightContainer.appendChild(controls.playbackRate);
+
+ // Right container -> Download
+ controls.download = document.createElement('div');
+ controls.download.className = 'fluid_button fluid_control_download fluid_button_download';
+ controls.rightContainer.appendChild(controls.download);
+
+ // Right container -> Volume container
+ controls.volumeContainer = document.createElement('div');
+ controls.volumeContainer.className = 'fluid_control_volume_container fluid_slider';
+ controls.rightContainer.appendChild(controls.volumeContainer);
+
+ // Right container -> Volume container -> Volume
+ controls.volume = document.createElement('div');
+ controls.volume.className = 'fluid_control_volume';
+ controls.volumeContainer.appendChild(controls.volume);
+
+ // Right container -> Volume container -> Volume -> Current
+ controls.volumeCurrent = document.createElement('div');
+ controls.volumeCurrent.className = 'fluid_control_currentvolume';
+ controls.volume.appendChild(controls.volumeCurrent);
+
+ // Right container -> Volume container -> Volume -> Current -> position
+ controls.volumeCurrentPos = document.createElement('div');
+ controls.volumeCurrentPos.className = 'fluid_control_volume_currentpos';
+ controls.volumeCurrent.appendChild(controls.volumeCurrentPos);
+
+ // Right container -> Volume container
+ controls.mute = document.createElement('div');
+ controls.mute.className = 'fluid_button fluid_button_volume fluid_control_mute';
+ controls.rightContainer.appendChild(controls.mute);
+
+ // Right container -> Volume Control + Live Steam Button
+ const durationContainer = document.createElement('div');
+ durationContainer.className = 'fluid_control_duration';
+
+ controls.duration = document.createElement('div');
+ controls.duration.className = 'fluid_fluid_control_duration';
+ controls.duration.innerText = '00:00 / 00:00';
+
+ if (!options.displayVolumeBar) {
+ durationContainer.className = durationContainer.className + ' no_volume_bar';
+ }
+
+ controls.live_indicator = document.createElement('div');
+ controls.live_indicator.className = 'fluid_control_live_indicator';
+ durationContainer.append(controls.live_indicator, controls.duration);
+ controls.rightContainer.appendChild(durationContainer);
+
+ return controls;
+ };
+
+ self.detectLiveStream = () => {
+ const sourceElement = this.domRef.player.querySelector('source');
+ const sourceUrl = sourceElement?.src || '';
+ const isLiveAttribute = sourceElement?.getAttribute('data-live') === 'true';
+ const isHLSorDASH = sourceUrl.includes('.m3u8') || sourceUrl.includes('.mpd');
+ this.isLiveStream = isLiveAttribute || isHLSorDASH;
+ };
+
+ self.showLiveIndicator = () => {
+ const isLiveStream = this.isLiveStream || false;
+ if (isLiveStream) {
+ const liveIndicator = self.domRef.player.parentNode.getElementsByClassName('fluid_control_live_indicator');
+ const liveIndicatorButton = document.createElement('span');
+ liveIndicatorButton.className = 'fluid_button_live_indicator';
+ liveIndicatorButton.innerHTML = `LIVE `;
+
+ liveIndicatorButton.addEventListener('click', () => {
+ self.domRef.player.currentTime = self.currentVideoDuration;
+ });
+
+ for (let i = 0; i < liveIndicator.length; i++) {
+ liveIndicator[i].appendChild(liveIndicatorButton);
+ }
+
+ }
+ };
+
+ self.controlPlayPauseToggle = () => {
+ const playPauseButton = self.domRef.player.parentNode.getElementsByClassName('fluid_control_playpause');
+ const menuOptionPlay = self.domRef.wrapper.querySelector('.context_option_play');
+ const controlsDisplay = self.domRef.player.parentNode.getElementsByClassName('fluid_controls_container');
+ const fpLogo = self.domRef.wrapper.querySelector('.logo_holder');
+
+ const initialPlay = self.domRef.wrapper.querySelector('.fluid_initial_play');
+ if (initialPlay) {
+ self.domRef.wrapper.querySelector('.fluid_initial_play').style.display = "none";
+ self.domRef.wrapper.querySelector('.fluid_initial_play_button_container').style.opacity = "1";
+ }
+
+ if (!self.domRef.player.paused) {
+ for (let i = 0; i < playPauseButton.length; i++) {
+ playPauseButton[i].className = playPauseButton[i].className.replace(/\bfluid_button_play\b/g, 'fluid_button_pause');
+ }
+
+ for (let i = 0; i < controlsDisplay.length; i++) {
+ controlsDisplay[i].classList.remove('initial_controls_show');
+ }
+
+ if (fpLogo) {
+ fpLogo.classList.remove('initial_controls_show');
+ }
+
+ if (menuOptionPlay !== null) {
+ menuOptionPlay.innerHTML = self.displayOptions.captions.pause;
+ }
+
+ return;
+ }
+
+ for (let i = 0; i < playPauseButton.length; i++) {
+ playPauseButton[i].className = playPauseButton[i].className.replace(/\bfluid_button_pause\b/g, 'fluid_button_play');
+ }
+
+ for (let i = 0; i < controlsDisplay.length; i++) {
+ controlsDisplay[i].classList.add('initial_controls_show');
+ }
+
+ if (self.isCurrentlyPlayingAd && self.displayOptions.vastOptions.showPlayButton) {
+ self.domRef.wrapper.querySelector('.fluid_initial_play').style.display = "block";
+ self.domRef.wrapper.querySelector('.fluid_initial_play_button_container').style.opacity = "1";
+ }
+
+ if (fpLogo) {
+ fpLogo.classList.add('initial_controls_show');
+ }
+
+ if (menuOptionPlay !== null) {
+ menuOptionPlay.innerHTML = self.displayOptions.captions.play;
+ }
+ };
+
+ self.playPauseAnimationToggle = (play) => {
+ if (self.isCurrentlyPlayingAd || !self.displayOptions.layoutControls.playPauseAnimation || self.isSwitchingSource) {
+ return;
+ }
+
+ const playButtonElement = self.domRef.wrapper.querySelector('.fluid_initial_play_button, .fluid_initial_pause_button');
+
+ if (play) {
+ playButtonElement.classList.remove('fluid_initial_pause_button');
+ playButtonElement.classList.add('fluid_initial_play_button');
+ } else {
+ playButtonElement.classList.remove('fluid_initial_play_button');
+ playButtonElement.classList.add('fluid_initial_pause_button');
+ }
+
+ self.domRef.wrapper.querySelector('.fluid_initial_play').classList.add('transform-active');
+ setTimeout(
+ function () {
+ self.domRef.wrapper.querySelector('.fluid_initial_play').classList.remove('transform-active');
+ },
+ 800
+ );
+ };
+
+ self.contolProgressbarUpdate = () => {
+ const currentProgressTag = self.domRef.player.parentNode.getElementsByClassName('fluid_controls_currentprogress');
+
+ for (let i = 0; i < currentProgressTag.length; i++) {
+ currentProgressTag[i].style.width = (self.domRef.player.currentTime / self.currentVideoDuration * 100) + '%';
+ }
+ };
+
+ self.controlDurationUpdate = () => {
+ const currentPlayTime = self.formatTime(self.domRef.player.currentTime);
+
+ let isLiveHls = false;
+ if (self.hlsPlayer) {
+ isLiveHls = self.hlsPlayer.levels &&
+ self.hlsPlayer.levels[self.hlsPlayer.currentLevel] &&
+ self.hlsPlayer.levels[self.hlsPlayer.currentLevel].details.live;
+ }
+
+ let durationText;
+ if (isNaN(self.currentVideoDuration) || !isFinite(self.currentVideoDuration) || isLiveHls) {
+ durationText = currentPlayTime;
+ } else {
+ const totalTime = self.formatTime(self.currentVideoDuration);
+ durationText = currentPlayTime + ' / ' + totalTime;
+ }
+
+ const timePlaceholder = self.domRef.player.parentNode.getElementsByClassName('fluid_control_duration');
+
+ self.detectLiveStream();
+
+ for (let i = 0; i < timePlaceholder.length; i++) {
+ timePlaceholder[i].innerHTML = '';
+
+ if (this.isLiveStream) {
+ const liveIndicatorButton = document.createElement('span');
+ liveIndicatorButton.className = 'fluid_button_live_indicator';
+ liveIndicatorButton.innerHTML = `LIVE `;
+ liveIndicatorButton.addEventListener('pointerdown', () => {
+ self.domRef.player.currentTime = self.currentVideoDuration;
+ });
+ timePlaceholder[i].appendChild(liveIndicatorButton);
+ }
+
+ const durationTextElement = document.createElement('span');
+ durationTextElement.className = 'fluid_fluid_control_duration';
+ durationTextElement.innerText = durationText;
+ timePlaceholder[i].appendChild(durationTextElement);
+ }
+ };
+
+ self.contolVolumebarUpdate = () => {
+ const currentVolumeTag = self.domRef.wrapper.querySelector('.fluid_control_currentvolume');
+ const volumeposTag = self.domRef.wrapper.querySelector('.fluid_control_volume_currentpos');
+ const volumebarTotalWidth = self.domRef.wrapper.querySelector('.fluid_control_volume').clientWidth;
+ const volumeposTagWidth = volumeposTag.clientWidth;
+ const muteButtonTag = self.domRef.player.parentNode.getElementsByClassName('fluid_control_mute');
+ const menuOptionMute = self.domRef.wrapper.querySelector('.context_option_mute');
+
+ if (0 !== self.domRef.player.volume) {
+ self.latestVolume = self.domRef.player.volume;
+ self.fluidStorage.fluidMute = false;
+ } else {
+ self.fluidStorage.fluidMute = true;
+ }
+
+ if (self.domRef.player.volume && !self.domRef.player.muted) {
+ for (let i = 0; i < muteButtonTag.length; i++) {
+ muteButtonTag[i].className = muteButtonTag[i].className.replace(/\bfluid_button_mute\b/g, 'fluid_button_volume');
+ }
+
+ if (menuOptionMute !== null) {
+ menuOptionMute.innerHTML = self.displayOptions.captions.mute;
+ }
+
+ } else {
+ for (let i = 0; i < muteButtonTag.length; i++) {
+ muteButtonTag[i].className = muteButtonTag[i].className.replace(/\bfluid_button_volume\b/g, 'fluid_button_mute');
+ }
+
+ if (menuOptionMute !== null) {
+ menuOptionMute.innerHTML = self.displayOptions.captions.unmute;
+ }
+ }
+ currentVolumeTag.style.width = (self.domRef.player.volume * volumebarTotalWidth) + 'px';
+ volumeposTag.style.left = (self.domRef.player.volume * volumebarTotalWidth - (volumeposTagWidth / 2)) + 'px';
+ };
+
+ self.muteToggle = () => {
+ if (0 !== self.domRef.player.volume && !self.domRef.player.muted) {
+ self.domRef.player.volume = 0;
+ self.domRef.player.muted = true;
+ } else {
+ self.domRef.player.volume = self.latestVolume;
+ self.domRef.player.muted = false;
+ }
+
+ // Persistent settings
+ self.fluidStorage.fluidVolume = self.latestVolume;
+ self.fluidStorage.fluidMute = self.domRef.player.muted;
+ };
+
+ self.checkFullscreenSupport = () => {
+ const videoPlayerWrapper = self.domRef.wrapper;
+
+ if (videoPlayerWrapper.mozRequestFullScreen) {
+ return {
+ goFullscreen: 'mozRequestFullScreen',
+ exitFullscreen: 'mozCancelFullScreen',
+ isFullscreen: 'mozFullScreenElement'
+ };
+
+ } else if (videoPlayerWrapper.webkitRequestFullscreen) {
+ return {
+ goFullscreen: 'webkitRequestFullscreen',
+ exitFullscreen: 'webkitExitFullscreen',
+ isFullscreen: 'webkitFullscreenElement'
+ };
+
+ } else if (videoPlayerWrapper.msRequestFullscreen) {
+ return {
+ goFullscreen: 'msRequestFullscreen',
+ exitFullscreen: 'msExitFullscreen',
+ isFullscreen: 'msFullscreenElement'
+ };
+
+ } else if (videoPlayerWrapper.requestFullscreen) {
+ return {
+ goFullscreen: 'requestFullscreen',
+ exitFullscreen: 'exitFullscreen',
+ isFullscreen: 'fullscreenElement'
+ };
+
+ } else if (self.domRef.player.webkitSupportsFullscreen) {
+ return {
+ goFullscreen: 'webkitEnterFullscreen',
+ exitFullscreen: 'webkitExitFullscreen',
+ isFullscreen: 'webkitDisplayingFullscreen'
+ };
+ }
+
+ return false;
+ };
+
+ self.fullscreenOff = (fullscreenButton, menuOptionFullscreen) => {
+ for (let i = 0; i < fullscreenButton.length; i++) {
+ fullscreenButton[i].className = fullscreenButton[i].className.replace(/\bfluid_button_fullscreen_exit\b/g, 'fluid_button_fullscreen');
+ }
+ if (menuOptionFullscreen !== null) {
+ menuOptionFullscreen.innerHTML = 'Fullscreen';
+ }
+ self.fullscreenMode = false;
+ };
+
+ self.fullscreenOn = (fullscreenButton, menuOptionFullscreen) => {
+ for (let i = 0; i < fullscreenButton.length; i++) {
+ fullscreenButton[i].className = fullscreenButton[i].className.replace(/\bfluid_button_fullscreen\b/g, 'fluid_button_fullscreen_exit');
+ }
+
+ if (menuOptionFullscreen !== null) {
+ menuOptionFullscreen.innerHTML = self.displayOptions.captions.exitFullscreen;
+ }
+ self.fullscreenMode = true;
+ };
+
+ self.fullscreenToggle = () => {
+ self.debugMessage(`Toggling Full Screen`);
+ const videoPlayerTag = self.domRef.player;
+ const fullscreenTag = self.domRef.wrapper;
+ const requestFullscreenFunctionNames = self.checkFullscreenSupport();
+ const fullscreenButton = videoPlayerTag.parentNode.getElementsByClassName('fluid_control_fullscreen');
+ const menuOptionFullscreen = fullscreenTag.querySelector('.context_option_fullscreen');
+ self.resetDisplayMode('fullScreen');
+
+ let functionNameToExecute;
+
+ if (requestFullscreenFunctionNames) {
+ // iOS fullscreen elements are different and so need to be treated separately
+ if (requestFullscreenFunctionNames.goFullscreen === 'webkitEnterFullscreen') {
+ if (!videoPlayerTag[requestFullscreenFunctionNames.isFullscreen]) {
+ functionNameToExecute = 'videoPlayerTag.' + requestFullscreenFunctionNames.goFullscreen + '();';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ new Function('videoPlayerTag', functionNameToExecute)(videoPlayerTag);
+ }
+ } else {
+ if (document[requestFullscreenFunctionNames.isFullscreen] === null) {
+ //Go fullscreen
+ functionNameToExecute = 'videoPlayerTag.' + requestFullscreenFunctionNames.goFullscreen + '();';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ } else {
+ //Exit fullscreen
+ functionNameToExecute = 'document.' + requestFullscreenFunctionNames.exitFullscreen + '();';
+ self.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ }
+ new Function('videoPlayerTag', functionNameToExecute)(fullscreenTag);
+ }
+ } else {
+ //The browser does not support the Fullscreen API, so a pseudo-fullscreen implementation is used
+ if (fullscreenTag.className.search(/\bpseudo_fullscreen\b/g) !== -1) {
+ fullscreenTag.className = fullscreenTag.className.replace(/\bpseudo_fullscreen\b/g, '');
+ self.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ } else {
+ fullscreenTag.className += ' pseudo_fullscreen';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ }
+ }
+
+ self.resizeVpaidAuto();
+
+ // Listen for fullscreen exit event on safari, as the fullscreen mode uses the native UI in iOS
+ self.domRef.player.addEventListener('webkitendfullscreen', () => {
+ self.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ });
+ };
+
+ self.findClosestParent = (el, selector) => {
+ let matchesFn = null;
+
+ // find vendor prefix
+ ['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'].some(function (fn) {
+ if (typeof document.body[fn] == 'function') {
+ matchesFn = fn;
+ return true;
+ }
+ return false;
+ });
+
+ let parent;
+
+ // Check if the current element matches the selector
+ if (el[matchesFn](selector)) {
+ return el;
+ }
+
+ // traverse parents
+ while (el) {
+ parent = el.parentElement;
+ if (parent && parent[matchesFn](selector)) {
+ return parent;
+ }
+ el = parent;
+ }
+
+ return null;
+ };
+
+ self.getTranslateX = (el) => {
+ let coordinates = null;
+
+ try {
+ const results = el.style.transform.match(/translate3d\((-?\d+px,\s?){2}-?\d+px\)/);
+
+ if (results && results.length) {
+ coordinates = results[0]
+ .replace('translate3d(', '')
+ .replace(')', '')
+ .replace(/\s/g, '')
+ .replace(/px/g, '')
+ .split(',')
+ ;
+ }
+ } catch (e) {
+ coordinates = null;
+ }
+
+ return (coordinates && (coordinates.length === 3)) ? parseInt(coordinates[0]) : 0;
+ };
+
+ self.getEventOffsetX = (evt, el) => {
+ let x = 0;
+ let translateX = 0;
+
+ while (el && !isNaN(el.offsetLeft)) {
+ translateX = self.getTranslateX(el);
+
+ if (el.tagName === 'BODY') {
+ x += el.offsetLeft + el.clientLeft + translateX - (el.scrollLeft || document.documentElement.scrollLeft);
+ } else {
+ x += el.offsetLeft + el.clientLeft + translateX - el.scrollLeft;
+ }
+
+ el = el.offsetParent;
+ }
+
+ let eventX;
+ if (typeof evt.touches !== 'undefined' && typeof evt.touches[0] !== 'undefined') {
+ eventX = evt.touches[0].clientX;
+ } else {
+ eventX = evt.clientX
+ }
+
+ return eventX - x;
+ };
+
+ self.getEventOffsetY = (evt, el) => {
+ let fullscreenMultiplier = 1;
+
+ const requestFullscreenFunctionNames = self.checkFullscreenSupport();
+ if (requestFullscreenFunctionNames && document[requestFullscreenFunctionNames.isFullscreen]) {
+ fullscreenMultiplier = 0;
+ }
+
+ let y = 0;
+
+ while (el && !isNaN(el.offsetTop)) {
+ if (el.tagName === 'BODY') {
+ y += el.offsetTop - ((el.scrollTop || document.documentElement.scrollTop) * fullscreenMultiplier);
+
+ } else {
+ y += el.offsetTop - (el.scrollTop * fullscreenMultiplier);
+ }
+
+ el = el.offsetParent;
+ }
+
+ return evt.clientY - y;
+ };
+
+ self.onProgressbarMouseDown = (event) => {
+ self.displayOptions.layoutControls.playPauseAnimation = false;
+ // we need an initial position for touchstart events, as mouse up has no offset x for iOS
+ let initialPosition;
+
+ if (self.displayOptions.layoutControls.showCardBoardView) {
+ initialPosition = self.getEventOffsetX(event, event.target.parentNode);
+ } else {
+ initialPosition = self.getEventOffsetX(event, self.domRef.wrapper.querySelector('.fluid_controls_progress_container'));
+ }
+
+ if (self.isCurrentlyPlayingAd) {
+ return;
+ }
+
+ self.fluidPseudoPause = true;
+
+ const initiallyPaused = self.domRef.player.paused;
+ if (!initiallyPaused) {
+ self.domRef.player.pause();
+ }
+
+ const shiftTime = timeBarX => {
+ const totalWidth = self.domRef.wrapper.querySelector('.fluid_controls_progress_container').clientWidth;
+ if (totalWidth) {
+ self.domRef.player.currentTime = self.currentVideoDuration * timeBarX / totalWidth;
+ }
+
+ self.hideSuggestedVideos();
+ };
+
+ const onProgressbarMouseMove = event => {
+ const currentX = self.getEventOffsetX(event, event.target.parentNode);
+ initialPosition = NaN; // mouse up will fire after the move, we don't want to trigger the initial position in the event of iOS
+ shiftTime(currentX);
+ self.contolProgressbarUpdate();
+ self.controlDurationUpdate();
+ };
+
+ const onProgressbarMouseUp = event => {
+ document.removeEventListener('mousemove', onProgressbarMouseMove);
+ document.removeEventListener('touchmove', onProgressbarMouseMove);
+ document.removeEventListener('mouseup', onProgressbarMouseUp);
+ document.removeEventListener('touchend', onProgressbarMouseUp);
+
+ let clickedX = self.getEventOffsetX(event, event.target.parentNode);
+
+ if (isNaN(clickedX) && !isNaN(initialPosition)) {
+ clickedX = initialPosition;
+ }
+
+ if (!isNaN(clickedX)) {
+ shiftTime(clickedX);
+ }
+
+ if (!initiallyPaused) {
+ self.play();
+ }
+
+ // Wait till video played then re-enable the animations
+ if (self.initialAnimationSet) {
+ setTimeout(() => {
+ self.displayOptions.layoutControls.playPauseAnimation = self.initialAnimationSet;
+ }, 200);
+ }
+ self.fluidPseudoPause = false;
+ };
+
+ document.addEventListener('mouseup', onProgressbarMouseUp);
+ document.addEventListener('touchend', onProgressbarMouseUp, { passive: true });
+ document.addEventListener('mousemove', onProgressbarMouseMove);
+ document.addEventListener('touchmove', onProgressbarMouseMove, { passive: true });
+ };
+
+ self.onVolumeBarMouseDown = () => {
+ const shiftVolume = volumeBarX => {
+ const totalWidth = self.domRef.controls.volumeContainer.clientWidth;
+
+ if (totalWidth) {
+ let newVolume = volumeBarX / totalWidth;
+
+ if (newVolume < 0.05) {
+ newVolume = 0;
+ self.domRef.player.muted = true;
+ } else if (newVolume > 0.95) {
+ newVolume = 1;
+ }
+
+ if (self.domRef.player.muted && newVolume > 0) {
+ self.domRef.player.muted = false;
+ }
+
+ self.setVolume(newVolume);
+ }
+ }
+
+ const onVolumeBarMouseMove = event => {
+ const currentX = self.getEventOffsetX(event, self.domRef.controls.volumeContainer);
+ shiftVolume(currentX);
+ }
+
+ const onVolumeBarMouseUp = event => {
+ document.removeEventListener('mousemove', onVolumeBarMouseMove);
+ document.removeEventListener('touchmove', onVolumeBarMouseMove);
+ document.removeEventListener('mouseup', onVolumeBarMouseUp);
+ document.removeEventListener('touchend', onVolumeBarMouseUp);
+
+ const currentX = self.getEventOffsetX(event, self.domRef.controls.volumeContainer);
+
+ if (!isNaN(currentX)) {
+ shiftVolume(currentX);
+ }
+ }
+
+ document.addEventListener('mouseup', onVolumeBarMouseUp);
+ document.addEventListener('touchend', onVolumeBarMouseUp, { passive: true });
+ document.addEventListener('mousemove', onVolumeBarMouseMove);
+ document.addEventListener('touchmove', onVolumeBarMouseMove, { passive: true });
+ };
+
+ self.findRoll = (roll) => {
+ const ids = [];
+ ids.length = 0;
+
+ if (!roll || !self.hasOwnProperty('rollsById')) {
+ return;
+ }
+
+ for (let key in self.rollsById) {
+ if (!self.rollsById.hasOwnProperty(key)) {
+ continue;
+ }
+
+ if (self.rollsById[key].roll === roll) {
+ ids.push(key);
+ }
+ }
+
+ return ids;
+ };
+
+ self.onKeyboardVolumeChange = (direction) => {
+ let volume = self.domRef.player.volume;
+
+ if ('asc' === direction) {
+ volume += 0.05;
+ } else if ('desc' === direction) {
+ volume -= 0.05;
+ }
+
+ if (volume < 0.05) {
+ volume = 0;
+ } else if (volume > 0.95) {
+ volume = 1;
+ }
+
+ self.setVolume(volume);
+ };
+
+ self.onKeyboardSeekPosition = (keyCode) => {
+ if (self.isCurrentlyPlayingAd) {
+ return;
+ }
+
+ self.domRef.player.currentTime = self.getNewCurrentTimeValueByKeyCode(
+ keyCode,
+ self.domRef.player.currentTime,
+ self.domRef.player.duration
+ );
+ };
+
+ self.getNewCurrentTimeValueByKeyCode = (keyCode, currentTime, duration) => {
+ let newCurrentTime = currentTime;
+
+ switch (keyCode) {
+ case 35://End
+ newCurrentTime = duration;
+ break;
+ case 36://Home
+ newCurrentTime = 0;
+ break;
+ case 48://0
+ case 49://1
+ case 50://2
+ case 51://3
+ case 52://4
+ case 53://5
+ case 54://6
+ case 55://7
+ case 56://8
+ case 57://9
+ if (keyCode < 58 && keyCode > 47) {
+ const percent = (keyCode - 48) * 10;
+ newCurrentTime = duration * percent / 100;
+ }
+ break;
+ }
+
+ return newCurrentTime;
+ };
+
+ self.handleMouseleave = (event) => {
+ if (typeof event.clientX !== 'undefined'
+ && self.domRef.wrapper.contains(document.elementFromPoint(event.clientX, event.clientY))) {
+ //false positive; we didn't actually leave the player
+ return;
+ }
+
+ self.hideControlBar();
+ self.hideTitle();
+ };
+
+ self.handleMouseenterForKeyboard = () => {
+ if (self.captureKey) {
+ return;
+ }
+
+ self.captureKey = event => {
+ event.stopPropagation();
+ const keyCode = event.keyCode;
+
+ switch (keyCode) {
+ case 70://f
+ self.fullscreenToggle();
+ event.preventDefault();
+ break;
+ case 13://Enter
+ case 32://Space
+ self.playPauseToggle();
+ event.preventDefault();
+ break;
+ case 77://m
+ self.muteToggle();
+ event.preventDefault();
+ break;
+ case 38://up arrow
+ self.onKeyboardVolumeChange('asc');
+ event.preventDefault();
+ break;
+ case 40://down arrow
+ self.onKeyboardVolumeChange('desc');
+ event.preventDefault();
+ break;
+ case 37://left arrow
+ self.skipRelative(-self.timeSkipOffsetAmount);
+ break;
+ case 39://right arrow
+ self.skipRelative(self.timeSkipOffsetAmount);
+ break;
+ case 35://End
+ case 36://Home
+ case 48://0
+ case 49://1
+ case 50://2
+ case 51://3
+ case 52://4
+ case 53://5
+ case 54://6
+ case 55://7
+ case 56://8
+ case 57://9
+ self.onKeyboardSeekPosition(keyCode);
+ event.preventDefault();
+ break;
+ case 73: // i
+ self.toggleMiniPlayer(undefined, true);
+ break;
+ }
+
+ return false;
+
+ };
+
+ document.addEventListener('keydown', self.captureKey, true);
+ };
+
+ self.keyboardControl = () => {
+ self.domRef.wrapper.addEventListener('click', self.handleMouseenterForKeyboard, false);
+
+ // When we click outside player, we stop registering keyboard events
+ const clickHandler = self.handleWindowClick.bind(self);
+
+ self.destructors.push(() => {
+ window.removeEventListener('click', clickHandler);
+ });
+
+ window.addEventListener('click', clickHandler);
+ };
+
+ self.handleWindowClick = (e) => {
+ if (!self.domRef.wrapper) {
+ console.warn('Dangling click event listener should be collected for unknown wrapper.' +
+ 'Did you forget to call destroy on player instance?');
+ return;
+ }
+
+ const inScopeClick = self.domRef.wrapper.contains(e.target) || e.target.classList.contains('.js-skipHref');
+
+ if (inScopeClick) {
+ return;
+ }
+
+ document.removeEventListener('keydown', self.captureKey, true);
+ delete self['captureKey'];
+
+ if (self.theatreMode && !self.theatreModeAdvanced) {
+ self.theatreToggle();
+ }
+ };
+
+ self.initialPlay = () => {
+ self.domRef.player.addEventListener('playing', () => {
+ self.toggleLoader(false);
+ });
+
+ self.domRef.player.addEventListener('timeupdate', () => {
+ // some places we are manually displaying toggleLoader
+ // user experience toggleLoader being displayed even when content is playing in background
+ self.toggleLoader(false);
+ });
+
+ self.domRef.player.addEventListener('waiting', () => {
+ self.toggleLoader(true);
+ });
+
+ if (!self.displayOptions.layoutControls.playButtonShowing) {
+ // Controls always showing until the video is first played
+ const initialControlsDisplay = self.domRef.wrapper.querySelector('.fluid_controls_container');
+ initialControlsDisplay.classList.remove('initial_controls_show');
+ // The logo shows before playing but may need to be removed
+ const fpPlayer = self.domRef.wrapper.querySelector('.logo_holder');
+ if (fpPlayer) {
+ fpPlayer.classList.remove('initial_controls_show');
+ }
+ }
+
+ if (!self.firstPlayLaunched) {
+ self.playPauseToggle();
+ self.domRef.player.removeEventListener('play', self.initialPlay);
+ }
+ };
+
+ self.playPauseToggle = () => {
+ self.hideSuggestedVideos();
+ const isFirstStart = !self.firstPlayLaunched;
+ const preRolls = self.findRoll('preRoll');
+
+ if (!isFirstStart || preRolls.length === 0) {
+ if (isFirstStart && preRolls.length === 0) {
+ self.firstPlayLaunched = true;
+ self.displayOptions.vastOptions.vastAdvanced.noVastVideoCallback();
+ }
+
+ if (self.domRef.player.paused) {
+ if (self.isCurrentlyPlayingAd && self.vastOptions !== null && self.vastOptions.vpaid) {
+ // resume the vpaid linear ad
+ self.resumeVpaidAd();
+ } else {
+ // Check if video has ended. If so, replay
+ if (Math.floor(self.currentVideoDuration) === Math.floor(self.domRef.player.currentTime)) {
+ self.initialiseStreamers();
+ self.domRef.player.currentTime = 0;
+ }
+
+ // resume the regular linear vast or content video player
+ if (self.dashPlayer) {
+ self.dashPlayer.play();
+ } else {
+ self.domRef.player.play();
+ }
+ }
+
+ self.playPauseAnimationToggle(true);
+
+ } else if (!isFirstStart) {
+ if (self.isCurrentlyPlayingAd && self.vastOptions !== null && self.vastOptions.vpaid) {
+ // pause the vpaid linear ad
+ self.pauseVpaidAd();
+ } else {
+ // pause the regular linear vast or content video player
+ self.domRef.player.pause();
+ }
+
+ self.playPauseAnimationToggle(false);
+ }
+
+ self.toggleOnPauseAd();
+ } else {
+ self.isCurrentlyPlayingAd = true;
+
+ // Workaround for Safari or Mobile Chrome - otherwise it blocks the subsequent
+ // play() command, because it considers it not being triggered by the user.
+ // The URL is hardcoded here to cover widest possible use cases.
+ // If you know of an alternative workaround for this issue - let us know!
+ const browserVersion = self.getBrowserVersion();
+ const isChromeAndroid = self.mobileInfo.userOs !== false
+ && self.mobileInfo.userOs === 'Android'
+ && browserVersion.browserName === 'Google Chrome';
+
+ if ('Safari' === browserVersion.browserName || isChromeAndroid) {
+ self.domRef.player.src = 'https://cdn.fluidplayer.com/static/blank.mp4';
+ self.domRef.player.play();
+ self.playPauseAnimationToggle(true);
+ }
+
+ self.firstPlayLaunched = true;
+
+ //trigger the loading of the VAST Tag
+ self.prepareVast('preRoll');
+ self.preRollAdPodsLength = preRolls.length;
+ }
+
+ const prepareVastAdsThatKnowDuration = () => {
+ self.prepareVast('onPauseRoll');
+ self.scheduleOnDemandRolls();
+ };
+
+ if (isFirstStart) {
+ // Remove the div that was placed as a fix for poster image and DASH streaming, if it exists
+ const pseudoPoster = self.domRef.wrapper.querySelector('.fluid_pseudo_poster');
+ if (pseudoPoster) {
+ pseudoPoster.parentNode.removeChild(pseudoPoster);
+ }
+
+ if (self.mainVideoDuration > 0) {
+ prepareVastAdsThatKnowDuration();
+ } else {
+ self.domRef.player.addEventListener('mainVideoDurationSet', prepareVastAdsThatKnowDuration);
+ }
+ }
+
+ self.adTimer();
+
+ const blockOnPause = self.domRef.wrapper.querySelector('.fluid_html_on_pause_container');
+
+ if (blockOnPause && !self.isCurrentlyPlayingAd) {
+ if (self.domRef.player.paused) {
+ blockOnPause.style.display = 'flex';
+ } else {
+ blockOnPause.style.display = 'none';
+ }
+ }
+ };
+
+ self.setCustomControls = () => {
+ //Set the Play/Pause behaviour
+ self.trackEvent(self.domRef.player.parentNode, 'click', '.fluid_control_playpause', () => {
+ if (!self.firstPlayLaunched) {
+ self.domRef.player.removeEventListener('play', self.initialPlay);
+ }
+
+ self.playPauseToggle();
+ }, false);
+
+ self.domRef.player.addEventListener('play', () => {
+ self.controlPlayPauseToggle();
+ self.contolVolumebarUpdate();
+ }, false);
+
+ self.domRef.player.addEventListener('fluidplayerpause', () => {
+ self.controlPlayPauseToggle();
+ }, false);
+
+ //Set the progressbar
+ self.domRef.player.addEventListener('timeupdate', () => {
+ self.contolProgressbarUpdate();
+ self.controlDurationUpdate();
+ });
+
+ const isMobileChecks = self.getMobileOs();
+ const eventOn = (isMobileChecks.userOs) ? 'touchstart' : 'mousedown';
+
+ if (self.displayOptions.layoutControls.showCardBoardView) {
+ self.trackEvent(
+ self.domRef.player.parentNode,
+ eventOn,
+ '.fluid_controls_progress_container',
+ event => self.onProgressbarMouseDown(event),
+ false
+ );
+ } else {
+ self.domRef.wrapper.querySelector('.fluid_controls_progress_container')
+ .addEventListener(eventOn, event => self.onProgressbarMouseDown(event), { passive: true });
+ }
+
+ //Set the volume controls
+ self.domRef.wrapper.querySelector('.fluid_control_volume_container')
+ .addEventListener(eventOn, event => self.onVolumeBarMouseDown(), { passive: true });
+
+ self.domRef.player.addEventListener('volumechange', () => self.contolVolumebarUpdate());
+
+ self.trackEvent(self.domRef.player.parentNode, 'click', '.fluid_control_mute', () => self.muteToggle());
+
+ self.setBuffering();
+
+ //Set the fullscreen control
+ self.trackEvent(self.domRef.player.parentNode, 'click', '.fluid_control_fullscreen', () => self.fullscreenToggle());
+
+ // Theatre mode
+ if (self.displayOptions.layoutControls.allowTheatre && !self.isInIframe) {
+ self.domRef.wrapper.querySelector('.fluid_control_theatre').style.display = 'inline-block';
+ self.trackEvent(self.domRef.player.parentNode, 'click', '.fluid_control_theatre', () => self.theatreToggle());
+ } else {
+ self.domRef.wrapper.querySelector('.fluid_control_theatre').style.display = 'none';
+ }
+
+ // Mini Player
+ if (self.displayOptions.layoutControls.miniPlayer.enabled && !self.isInIframe) {
+ self.trackEvent(self.domRef.player.parentNode, 'click', '.fluid_control_mini_player', () => self.toggleMiniPlayer(undefined, true));
+ }
+
+ self.domRef.player.addEventListener('ratechange', () => {
+ if (self.isCurrentlyPlayingAd) {
+ self.playbackRate = 1;
+ }
+ });
+ };
+
+ // Create the time position preview only if the vtt previews aren't enabled
+ self.createTimePositionPreview = () => {
+ if (!self.showTimeOnHover) {
+ return;
+ }
+
+ const progressContainer = self.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+ const previewContainer = document.createElement('div');
+
+ previewContainer.className = 'fluid_timeline_preview';
+ previewContainer.style.display = 'none';
+ previewContainer.style.position = 'absolute';
+
+ progressContainer.appendChild(previewContainer);
+
+ // Set up hover for time position preview display
+ self.domRef.wrapper.querySelector('.fluid_controls_progress_container')
+ .addEventListener('mousemove', event => {
+ const progressContainer = self.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+ const totalWidth = progressContainer.clientWidth;
+ const hoverTimeItem = self.domRef.wrapper.querySelector('.fluid_timeline_preview');
+ const hoverQ = self.getEventOffsetX(event, progressContainer);
+
+ const hoverSecondQ = self.currentVideoDuration * hoverQ / totalWidth;
+ hoverTimeItem.innerText = self.formatTime(hoverSecondQ);
+
+ hoverTimeItem.style.display = 'block';
+ hoverTimeItem.style.left = (hoverSecondQ / self.domRef.player.duration * 100) + "%";
+ }, false);
+
+ // Hide timeline preview on mouseout
+ self.domRef.wrapper.querySelector('.fluid_controls_progress_container')
+ .addEventListener('mouseout', () => {
+ const hoverTimeItem = self.domRef.wrapper.querySelector('.fluid_timeline_preview');
+ hoverTimeItem.style.display = 'none';
+ }, false);
+ };
+
+ self.setCustomContextMenu = () => {
+ const playerWrapper = self.domRef.wrapper;
+
+ const showDefaultControls = self.displayOptions.layoutControls.contextMenu.controls;
+ const extraLinks = self.displayOptions.layoutControls.contextMenu.links;
+
+ //Create own context menu
+ const divContextMenu = document.createElement('div');
+ divContextMenu.className = 'fluid_context_menu';
+ divContextMenu.style.display = 'none';
+ divContextMenu.style.position = 'absolute';
+
+ const contextMenuList = document.createElement('ul');
+ divContextMenu.appendChild(contextMenuList);
+
+ if (Array.isArray(extraLinks)) {
+ extraLinks.forEach(function appendExtraLinks(link, index) {
+ const linkItem = document.createElement('li');
+ linkItem.innerHTML = link.label;
+ linkItem.addEventListener('click', () => window.open(link.href, '_blank'), false);
+ contextMenuList.appendChild(linkItem);
+ });
+ }
+
+ if (showDefaultControls) {
+ const menuItemPlay = document.createElement('li');
+ menuItemPlay.className = 'context_option_play';
+ menuItemPlay.innerHTML = self.displayOptions.captions.play;
+ menuItemPlay.addEventListener('click', () => self.playPauseToggle(), false);
+ contextMenuList.appendChild(menuItemPlay);
+
+ const menuItemMute = document.createElement('li');
+ menuItemMute.className = 'context_option_mute';
+ menuItemMute.innerHTML = self.displayOptions.captions.mute;
+ menuItemMute.addEventListener('click', () => self.muteToggle(), false);
+ contextMenuList.appendChild(menuItemMute);
+
+ const menuItemFullscreen = document.createElement('li');
+ menuItemFullscreen.className = 'context_option_fullscreen';
+ menuItemFullscreen.innerHTML = self.displayOptions.captions.fullscreen;
+ menuItemFullscreen.addEventListener('click', () => self.fullscreenToggle(), false);
+ contextMenuList.appendChild(menuItemFullscreen);
+ }
+
+ const menuItemVersion = document.createElement('li');
+ menuItemVersion.innerHTML = 'Fluid Player ' + self.version;
+ menuItemVersion.addEventListener('click', () => window.open(self.homepage, '_blank'), false)
+ contextMenuList.appendChild(menuItemVersion);
+
+ self.domRef.player.parentNode.insertBefore(divContextMenu, self.domRef.player.nextSibling);
+
+ //Disable the default context menu
+ playerWrapper.addEventListener('contextmenu', e => {
+ e.preventDefault();
+
+ divContextMenu.style.left = self.getEventOffsetX(e, self.domRef.player) + 'px';
+ divContextMenu.style.top = self.getEventOffsetY(e, self.domRef.player) + 'px';
+ divContextMenu.style.display = 'block';
+ }, false);
+
+ //Hide the context menu on clicking elsewhere
+ document.addEventListener('click', e => {
+ if ((e.target !== self.domRef.player) || e.button !== 2) {
+ divContextMenu.style.display = 'none';
+ }
+ }, false);
+ };
+
+ self.setDefaultLayout = () => {
+ self.domRef.wrapper.className += ' fluid_player_layout_' + self.displayOptions.layoutControls.layout;
+
+ self.setCustomContextMenu();
+
+ const controls = self.generateCustomControlTags({
+ displayVolumeBar: self.checkShouldDisplayVolumeBar(),
+ primaryColor: self.displayOptions.layoutControls.primaryColor
+ ? self.displayOptions.layoutControls.primaryColor
+ : 'red',
+ controlForwardBackward: !!self.displayOptions.layoutControls.controlForwardBackward.show,
+ miniPlayer: self.displayOptions.layoutControls.miniPlayer,
+ });
+
+ // Remove the default controls
+ self.domRef.player.removeAttribute('controls');
+
+ // Insert custom controls and append loader
+ self.domRef.player.parentNode.insertBefore(controls.root, self.domRef.player.nextSibling);
+ self.domRef.player.parentNode.insertBefore(controls.loader, self.domRef.player.nextSibling);
+
+ // Register controls locally
+ self.domRef.controls = controls;
+
+ /**
+ * Set the volumebar after its elements are properly rendered.
+ */
+ let remainingAttemptsToInitiateVolumeBar = 100;
+
+ const initiateVolumebar = function () {
+ if (!remainingAttemptsToInitiateVolumeBar) {
+ clearInterval(initiateVolumebarTimerId);
+ } else if (self.checkIfVolumebarIsRendered()) {
+ clearInterval(initiateVolumebarTimerId);
+ self.contolVolumebarUpdate();
+ } else {
+ remainingAttemptsToInitiateVolumeBar--;
+ }
+ };
+ let initiateVolumebarTimerId = setInterval(initiateVolumebar, 100);
+ self.destructors.push(() => clearInterval(initiateVolumebarTimerId));
+
+ if (self.displayOptions.layoutControls.doubleclickFullscreen && !(self.isTouchDevice() || !self.displayOptions.layoutControls.controlForwardBackward.doubleTapMobile)) {
+ self.domRef.player.addEventListener('dblclick', self.fullscreenToggle);
+ }
+
+ if (self.getMobileOs().userOs === 'iOS') {
+ let orientationListenerAdded = false;
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ self.domRef.player.inView = true;
+ if (self.displayOptions.layoutControls.autoRotateFullScreen && self.isTouchDevice() && !orientationListenerAdded) {
+ window.matchMedia("(orientation: landscape)").addEventListener('change', self.handleOrientationChange);
+ orientationListenerAdded = true;
+ }
+ } else {
+ self.domRef.player.inView = false;
+ }
+ });
+ });
+
+ observer.observe(self.domRef.player);
+ }
+
+ self.initHtmlOnPauseBlock();
+
+ self.setCustomControls();
+
+ self.setupThumbnailPreview();
+
+ self.createTimePositionPreview();
+
+ self.posterImage();
+
+ self.initPlayButton();
+
+ self.setVideoPreload();
+
+ self.createPlaybackList();
+
+ self.createDownload();
+
+ self.toggleMiniPlayerScreenDetection();
+
+ if (!!self.displayOptions.layoutControls.controlForwardBackward.show) {
+ self.initSkipControls();
+ }
+
+ if (!!self.displayOptions.layoutControls.controlForwardBackward.doubleTapMobile) {
+ self.initDoubleTapSkip();
+ }
+
+ self.initSkipAnimationElements();
+ };
+
+ self.initSkipControls = () => {
+ self.domRef.controls.skipBack.addEventListener('click', self.skipRelative.bind(this, -self.timeSkipOffsetAmount));
+ self.domRef.controls.skipForward.addEventListener('click', self.skipRelative.bind(this, self.timeSkipOffsetAmount));
+ };
+
+ // Function to handle fullscreen toggle based on orientation
+ self.handleOrientationChange = () => {
+ const isLandscape = window.matchMedia("(orientation: landscape)").matches;
+ const videoPlayerTag = self.domRef.player;
+ const fullscreenTag = self.domRef.wrapper;
+ const requestFullscreenFunctionNames = self.checkFullscreenSupport();
+ const fullscreenButton = videoPlayerTag.parentNode.getElementsByClassName('fluid_control_fullscreen');
+ const menuOptionFullscreen = fullscreenTag.querySelector('.context_option_fullscreen');
+ let functionNameToExecute;
+ if (isLandscape && self.domRef.player.inView) {
+ if (requestFullscreenFunctionNames) {
+ if (requestFullscreenFunctionNames.goFullscreen === 'webkitEnterFullscreen') {
+ functionNameToExecute = 'videoPlayerTag.' + requestFullscreenFunctionNames.goFullscreen + '();';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ new Function('videoPlayerTag', functionNameToExecute)(videoPlayerTag);
+ } else {
+ if (document[requestFullscreenFunctionNames.isFullscreen] === null) {
+ functionNameToExecute = 'videoPlayerTag.' + requestFullscreenFunctionNames.goFullscreen + '();';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ }
+ new Function('videoPlayerTag', functionNameToExecute)(fullscreenTag);
+ }
+ } else {
+ fullscreenTag.className += ' pseudo_fullscreen';
+ self.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ }
+ } else {
+ fullscreenTag.className = fullscreenTag.className.replace(/\bpseudo_fullscreen\b/g, '');
+ if (requestFullscreenFunctionNames) {
+ functionNameToExecute = 'document.' + requestFullscreenFunctionNames.exitFullscreen + '();';
+ self.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ new Function('videoPlayerTag', functionNameToExecute)(fullscreenTag);
+ } else {
+ if (fullscreenTag.className.search(/\bpseudo_fullscreen\b/g) !== -1) {
+ fullscreenTag.className = fullscreenTag.className.replace(/\bpseudo_fullscreen\b/g, '');
+ self.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ }
+ }
+ }
+ self.resizeVpaidAuto();
+ }
+
+ /**
+ * Creates the skip animation elements and appends them to the player
+ *
+ * @returns {void}
+ */
+ self.initSkipAnimationElements = function initSkipAnimationElements() {
+ const skipAnimationWrapper = document.createElement('div');
+ skipAnimationWrapper.classList.add('fluid_player_skip_offset');
+
+ const skipAnimationBackward = document.createElement('div');
+ skipAnimationBackward.classList.add('fluid_player_skip_offset__backward');
+ skipAnimationWrapper.appendChild(skipAnimationBackward);
+
+ const skipAnimationBackwardIcon = document.createElement('div');
+ skipAnimationBackwardIcon.classList.add('fluid_player_skip_offset__backward-icon');
+ skipAnimationBackwardIcon.ontransitionend = () => skipAnimationBackwardIcon.classList.remove('animate');
+ skipAnimationBackward.appendChild(skipAnimationBackwardIcon);
+
+ const skipAnimationForward = document.createElement('div');
+ skipAnimationForward.classList.add('fluid_player_skip_offset__forward');
+ skipAnimationWrapper.appendChild(skipAnimationForward);
+
+ const skipAnimationForwardIcon = document.createElement('div');
+ skipAnimationForwardIcon.classList.add('fluid_player_skip_offset__forward-icon');
+ skipAnimationForwardIcon.ontransitionend = () => skipAnimationForwardIcon.classList.remove('animate');
+ skipAnimationForward.appendChild(skipAnimationForwardIcon);
+
+ self.domRef.player.parentNode.insertBefore(skipAnimationWrapper, self.domRef.player.nextSibling);
+ }
+
+ /**
+ * Initialises the double tap skip functionality
+ */
+ self.initDoubleTapSkip = () => {
+ let hasDoubleClicked = false;
+ let timeouts = [];
+
+ function clearTimeouts() {
+ timeouts.forEach(timeout => clearTimeout(timeout));
+ timeouts = [];
+ }
+
+ self.domRef.player.addEventListener('pointerdown', (event) => {
+ // Check if it's mobile on the fly and prevent double click skip if it is
+ if (!self.isTouchDevice()) {
+ return;
+ }
+
+ if (!self.isControlBarVisible()) {
+ return;
+ }
+
+ const { offsetX } = event
+ const { clientWidth } = self.domRef.player;
+
+ // Simulates default behaviour if it's a single click
+ timeouts.push(setTimeout(() => {
+ hasDoubleClicked = false;
+ self.playPauseToggle();
+ }, 300));
+
+ // Skips video time if it's a double click
+ if (hasDoubleClicked) {
+ clearTimeouts();
+ hasDoubleClicked = false;
+ return self.skipRelative(offsetX < clientWidth / 2 ? -self.timeSkipOffsetAmount : self.timeSkipOffsetAmount);
+ }
+
+ hasDoubleClicked = true;
+ });
+ }
+
+ /**
+ * Skips the video time by timeOffset relative to the current video time
+ *
+ * @param {number} timeOffset
+ */
+ self.skipRelative = function skipRelative(timeOffset) {
+ self.debugMessage('skipping video time by ', timeOffset);
+ if (self.isCurrentlyPlayingAd) {
+ return;
+ }
+
+ let skipTo = self.domRef.player.currentTime + timeOffset;
+ if (skipTo < 0) {
+ skipTo = 0;
+ }
+ self.domRef.player.currentTime = skipTo;
+
+ // Trigger animation
+ if (timeOffset >= 0) {
+ const forwardElement = self.domRef.wrapper.querySelector(`.fluid_player_skip_offset__forward-icon`);
+ forwardElement.classList.add('animate');
+ } else {
+ const backwardElement = self.domRef.wrapper.querySelector(`.fluid_player_skip_offset__backward-icon`);
+ backwardElement.classList.add('animate');
+ }
+ }
+
+ /**
+ * Checks if the volumebar is rendered and the styling applied by comparing
+ * the width of 2 elements that should look different.
+ *
+ * @returns Boolean
+ */
+ self.checkIfVolumebarIsRendered = () => {
+ const volumeposTag = self.domRef.wrapper.querySelector('.fluid_control_volume_currentpos');
+ const volumebarTotalWidth = self.domRef.wrapper.querySelector('.fluid_control_volume').clientWidth;
+ const volumeposTagWidth = volumeposTag.clientWidth;
+
+ return volumeposTagWidth !== volumebarTotalWidth;
+ };
+
+ self.setLayout = () => {
+ //All other browsers
+ if (!self.isTouchDevice()) {
+ self.domRef.player.addEventListener('click', () => self.playPauseToggle(), false);
+ }
+ //Mobile Safari - because it does not emit a click event on initial click of the video
+ self.domRef.player.addEventListener('play', self.initialPlay, false);
+ self.setDefaultLayout();
+ };
+
+ self.handleFullscreen = () => {
+ if (typeof document.vastFullsreenChangeEventListenersAdded !== 'undefined') {
+ return;
+ }
+
+ ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange'].forEach(eventType => {
+ if (typeof (document['on' + eventType]) === 'object') {
+ document.addEventListener(eventType, function (ev) {
+ self.recalculateAdDimensions();
+ }, false);
+ }
+ });
+
+ document.vastFullsreenChangeEventListenersAdded = true;
+ };
+
+ self.setupPlayerWrapper = () => {
+ const wrapper = document.createElement('div');
+
+ wrapper.id = 'fluid_video_wrapper_' + self.videoPlayerId;
+ wrapper.className = self.isTouchDevice()
+ ? 'fluid_video_wrapper mobile'
+ : 'fluid_video_wrapper';
+
+ //Assign the height/width dimensions to the wrapper
+ if (self.displayOptions.layoutControls.fillToContainer) {
+ wrapper.style.width = '100%';
+ wrapper.style.height = '100%';
+ } else {
+ wrapper.style.height = self.domRef.player.clientHeight + 'px';
+ wrapper.style.width = self.domRef.player.clientWidth + 'px';
+ }
+
+ const parseBorderRadius = () => {
+ const roundedCorners = self.displayOptions.layoutControls.roundedCorners;
+ const parsedValue = Number(roundedCorners);
+
+ return !isNaN(parsedValue) && parsedValue !== 0
+ ? `${parsedValue}px`
+ : roundedCorners;
+ }
+
+ wrapper.style.borderRadius = self.domRef.player.style.borderRadius = parseBorderRadius();
+ wrapper.style.overflow = 'hidden';
+
+ self.domRef.player.style.height = '100%';
+ self.domRef.player.style.width = '100%';
+
+ self.domRef.player.parentNode.insertBefore(wrapper, self.domRef.player);
+ wrapper.appendChild(self.domRef.player);
+
+ return wrapper;
+ };
+
+ self.onErrorDetection = () => {
+ if (self.domRef.player.networkState === self.domRef.player.NETWORK_NO_SOURCE && self.isCurrentlyPlayingAd) {
+ //Probably the video ad file was not loaded successfully
+ self.playMainVideoWhenVastFails(401);
+ }
+ };
+
+ self.createVideoSourceSwitch = (initialLoad = true) => {
+ const sources = [];
+ const sourcesList = self.domRef.player.querySelectorAll('source');
+ [].forEach.call(sourcesList, source => {
+ if (source.title && source.src) {
+ sources.push({
+ 'title': source.title,
+ 'url': source.src,
+ 'isHD': (source.getAttribute('data-fluid-hd') != null)
+ });
+ }
+ });
+
+ const sourceChangeButton = self.domRef.wrapper.querySelector('.fluid_control_video_source');
+ self.videoSources = sources;
+
+ if (self.videoSources.length > 1) {
+ sourceChangeButton.style.display = 'inline-block';
+ } else {
+ sourceChangeButton.style.display = 'none';
+ }
+
+ if (self.videoSources.length <= 1) {
+ return;
+ }
+
+ let appendSourceChange = false;
+
+ const sourceChangeList = document.createElement('div');
+ sourceChangeList.className = 'fluid_video_sources_list';
+ sourceChangeList.style.display = 'none';
+
+ let firstSource = true;
+ for (const source of self.videoSources) {
+ // Fix for issues occurring on iOS with mkv files
+ const getTheType = source.url.split(".").pop();
+ if (self.mobileInfo.userOs === 'iOS' && getTheType === 'mkv') {
+ continue;
+ }
+
+ // On suggested videos, if the resolution doesn't exist in the new source list, use the first one in the list
+ // This gets overwritten if it's needed by setPersistentSettings()
+ if(firstSource && !initialLoad) {
+ self.domRef.player.src = source.url;
+ }
+
+ const sourceSelected = (firstSource) ? "source_selected" : "";
+ const hdElement = (source.isHD) ? ' ' : '';
+ firstSource = false;
+ const sourceChangeDiv = document.createElement('div');
+ sourceChangeDiv.className = 'fluid_video_source_list_item js-source_' + source.title;
+ sourceChangeDiv.innerHTML = ' ' + source.title + hdElement;
+
+ sourceChangeDiv.addEventListener('click', function (event) {
+ event.stopPropagation();
+ // While changing source the player size can flash, we want to set the pixel dimensions then back to 100% afterwards
+ self.domRef.player.style.width = self.domRef.player.clientWidth + 'px';
+ self.domRef.player.style.height = self.domRef.player.clientHeight + 'px';
+
+ const videoChangedTo = this;
+ const sourceIcons = self.domRef.wrapper.getElementsByClassName('source_button_icon');
+ for (let i = 0; i < sourceIcons.length; i++) {
+ sourceIcons[i].className = sourceIcons[i].className.replace('source_selected', '');
+ }
+ videoChangedTo.firstChild.className += ' source_selected';
+
+ self.videoSources.forEach(source => {
+ if (source.title === videoChangedTo.innerText.replace(/(\r\n\t|\n|\r\t)/gm, '')) {
+ self.setBuffering();
+ self.setVideoSource(source.url);
+ self.fluidStorage.fluidQuality = source.title;
+ }
+ });
+
+ self.openCloseVideoSourceSwitch();
+ });
+
+ sourceChangeList.appendChild(sourceChangeDiv);
+ appendSourceChange = true;
+ }
+
+ if (appendSourceChange) {
+ sourceChangeButton.appendChild(sourceChangeList);
+ // To reset player for suggested videos, in case the event listener already exists
+ sourceChangeButton.removeEventListener('click', self.openCloseVideoSourceSwitch);
+ sourceChangeButton.addEventListener('click', self.openCloseVideoSourceSwitch);
+ } else {
+ // Didn't give any source options
+ self.domRef.wrapper.querySelector('.fluid_control_video_source').style.display = 'none';
+ }
+ };
+
+ self.openCloseVideoSourceSwitch = () => {
+ const sourceChangeList = self.domRef.wrapper.querySelector('.fluid_video_sources_list');
+
+ if (self.isCurrentlyPlayingAd || self.isShowingSuggestedVideos()) {
+ sourceChangeList.style.display = 'none';
+ return;
+ }
+
+ if (sourceChangeList.style.display !== 'none') {
+ sourceChangeList.style.display = 'none';
+ return;
+ }
+
+ sourceChangeList.style.display = 'block';
+ const mouseOut = () => {
+ sourceChangeList.removeEventListener('mouseleave', mouseOut);
+ sourceChangeList.style.display = 'none';
+ };
+ sourceChangeList.addEventListener('mouseleave', mouseOut);
+ };
+
+ self.setVideoSource = (url) => {
+ if (self.mobileInfo.userOs === 'iOS' && url.indexOf('.mkv') > 0) {
+ console.log('[FP_ERROR] .mkv files not supported by iOS devices.');
+ return false;
+ }
+
+ if (self.isCurrentlyPlayingAd) {
+ self.originalSrc = url;
+ return;
+ }
+
+ self.isSwitchingSource = true;
+ let play = false;
+ if (!self.domRef.player.paused) {
+ self.domRef.player.pause();
+ play = true;
+ }
+
+ const currentTime = self.domRef.player.currentTime;
+ self.setCurrentTimeAndPlay(currentTime, play);
+
+ self.domRef.player.src = url;
+ self.originalSrc = url;
+ self.displayOptions.layoutControls.mediaType = self.getCurrentSrcType();
+ self.initialiseStreamers();
+ };
+
+ self.setCurrentTimeAndPlay = (newCurrentTime, shouldPlay) => {
+ const loadedMetadata = () => {
+ self.domRef.player.currentTime = newCurrentTime;
+ self.domRef.player.removeEventListener('loadedmetadata', loadedMetadata);
+ // Safari ios and mac fix to set currentTime
+ if (self.mobileInfo.userOs === 'iOS' || self.getBrowserVersion().browserName.toLowerCase() === 'safari') {
+ self.domRef.player.addEventListener('playing', videoPlayStart);
+ }
+
+ if (shouldPlay) {
+ self.domRef.player.play();
+ } else {
+ self.domRef.player.pause();
+ self.controlPlayPauseToggle();
+ }
+
+ self.isSwitchingSource = false;
+ self.domRef.player.style.width = '100%';
+ self.domRef.player.style.height = '100%';
+ };
+
+ let videoPlayStart = () => {
+ self.currentTime = newCurrentTime;
+ self.domRef.player.removeEventListener('playing', videoPlayStart);
+ };
+
+ self.domRef.player.addEventListener('loadedmetadata', loadedMetadata, false);
+ self.domRef.player.load();
+ };
+
+ self.initTitle = () => {
+ if (!self.displayOptions.layoutControls.title) {
+ return;
+ }
+
+ const titleHolder = document.createElement('div');
+ self.domRef.player.parentNode.insertBefore(titleHolder, null);
+ titleHolder.innerHTML += self.displayOptions.layoutControls.title;
+ titleHolder.classList.add('fp_title');
+ };
+
+ self.hasTitle = () => {
+ const title = self.domRef.wrapper.querySelector('.fp_title');
+ const titleOption = self.displayOptions.layoutControls.title;
+ return title && titleOption != null;
+ };
+
+ self.hideTitle = () => {
+ const titleHolder = self.domRef.wrapper.querySelector('.fp_title');
+
+ if (!self.hasTitle()) {
+ return;
+ }
+
+ titleHolder.classList.add('fade_out');
+ };
+
+ self.showTitle = () => {
+ const titleHolder = self.domRef.wrapper.querySelector('.fp_title');
+
+ if (!self.hasTitle()) {
+ return;
+ }
+
+ titleHolder.classList.remove('fade_out');
+ };
+
+ self.initLogo = () => {
+ if (!self.displayOptions.layoutControls.logo.imageUrl) {
+ return;
+ }
+
+ // Container div for the logo
+ // This is to allow for fade in and out logo_maintain_display
+ const logoHolder = document.createElement('div');
+ logoHolder.className = 'logo_holder';
+ if (self.displayOptions.layoutControls.logo.hideWithControls) {
+ logoHolder.classList.add('initial_controls_show', 'fp_logo');
+ } else {
+ logoHolder.classList.add('logo_maintain_display');
+ }
+ // The logo itself
+ const logoImage = document.createElement('img');
+ if (self.displayOptions.layoutControls.logo.imageUrl) {
+ logoImage.src = self.displayOptions.layoutControls.logo.imageUrl;
+ }
+
+ logoImage.style.position = 'absolute';
+ logoImage.style.margin = self.displayOptions.layoutControls.logo.imageMargin;
+ const logoPosition = self.displayOptions.layoutControls.logo.position.toLowerCase();
+
+ if (logoPosition.indexOf('bottom') !== -1) {
+ logoImage.style.bottom = 0;
+ } else {
+ logoImage.style.top = 0;
+ }
+ if (logoPosition.indexOf('right') !== -1) {
+ logoImage.style.right = 0;
+ } else {
+ logoImage.style.left = 0;
+ }
+ if (self.displayOptions.layoutControls.logo.opacity) {
+ logoImage.style.opacity = self.displayOptions.layoutControls.logo.opacity;
+ }
+
+ if (self.displayOptions.layoutControls.logo.clickUrl !== null) {
+ logoImage.style.cursor = 'pointer';
+ logoImage.addEventListener('click', function () {
+ const win = window.open(self.displayOptions.layoutControls.logo.clickUrl, '_blank');
+ win.focus();
+ });
+ }
+
+ // If a mouseOverImage is provided then we must set up the listeners for it
+ if (self.displayOptions.layoutControls.logo.mouseOverImageUrl) {
+ logoImage.addEventListener('mouseover', function () {
+ logoImage.src = self.displayOptions.layoutControls.logo.mouseOverImageUrl;
+ }, false);
+ logoImage.addEventListener('mouseout', function () {
+ logoImage.src = self.displayOptions.layoutControls.logo.imageUrl;
+ }, false);
+ }
+
+ self.domRef.player.parentNode.insertBefore(logoHolder, null);
+ logoHolder.appendChild(logoImage, null);
+ };
+
+ self.initHtmlOnPauseBlock = () => {
+ //If onPauseRoll is defined than HtmlOnPauseBlock won't be shown
+ if (self.hasValidOnPauseAd()) {
+ return;
+ }
+
+ if (!self.displayOptions.layoutControls.htmlOnPauseBlock.html) {
+ return;
+ }
+
+ const containerDiv = document.createElement('div');
+ containerDiv.className = 'fluid_html_on_pause_container';
+ containerDiv.style.display = 'none';
+ containerDiv.innerHTML = self.displayOptions.layoutControls.htmlOnPauseBlock.html;
+ containerDiv.onclick = function (event) {
+ self.playPauseToggle();
+ };
+
+ if (self.displayOptions.layoutControls.htmlOnPauseBlock.width) {
+ containerDiv.style.width = self.displayOptions.layoutControls.htmlOnPauseBlock.width + 'px';
+ }
+
+ if (self.displayOptions.layoutControls.htmlOnPauseBlock.height) {
+ containerDiv.style.height = self.displayOptions.layoutControls.htmlOnPauseBlock.height + 'px';
+ }
+
+ self.domRef.player.parentNode.insertBefore(containerDiv, null);
+ };
+
+ /**
+ * Play button in the middle when the video loads
+ */
+ self.initPlayButton = () => {
+ // Create the html for the play button
+ const containerDiv = document.createElement('div');
+ containerDiv.className = 'fluid_html_on_pause fluid_initial_play_button_container';
+ const backgroundColor = (self.displayOptions.layoutControls.primaryColor) ? self.displayOptions.layoutControls.primaryColor : "#333333";
+ containerDiv.innerHTML = '';
+ const initPlayEventTypes = ['click', 'touchend'];
+ const initPlayFunction = function () {
+ self.playPauseToggle();
+ initPlayEventTypes.forEach(eventType => containerDiv.removeEventListener(eventType, initPlayFunction))
+ };
+ initPlayEventTypes.forEach(eventType => containerDiv.addEventListener(eventType, initPlayFunction))
+
+ // If the user has chosen to not show the play button we'll make it invisible
+ // We don't hide altogether because animations might still be used
+ if (!self.displayOptions.layoutControls.playButtonShowing) {
+ const initialControlsDisplay = self.domRef.wrapper.querySelector('.fluid_controls_container');
+ initialControlsDisplay.classList.add('initial_controls_show');
+ containerDiv.style.opacity = '0';
+ }
+
+ self.domRef.player.parentNode.insertBefore(containerDiv, null);
+ };
+
+ /**
+ * Set the mainVideoDuration property one the video is loaded
+ */
+ self.mainVideoReady = () => {
+ if (!(self.mainVideoDuration === 0 && !self.isCurrentlyPlayingAd && self.mainVideoReadyState === false)) {
+ return;
+ }
+ const event = new CustomEvent('mainVideoDurationSet');
+
+ self.mainVideoDuration = self.domRef.player.duration;
+ self.mainVideoReadyState = true;
+ self.domRef.player.dispatchEvent(event);
+ self.domRef.player.removeEventListener('loadedmetadata', self.mainVideoReady);
+ };
+
+ self.userActivityChecker = () => {
+ const videoPlayer = self.domRef.wrapper;
+ self.newActivity = null;
+
+ let isMouseStillDown = false;
+
+ const activity = event => {
+ if (event.type === 'touchstart' || event.type === 'mousedown') {
+ isMouseStillDown = true;
+ }
+ if (event.type === 'touchend' || event.type === 'mouseup') {
+ isMouseStillDown = false;
+ }
+ self.newActivity = true;
+ };
+
+ const intervalId = setInterval(() => {
+ if (self.newActivity !== true) {
+ return;
+ }
+
+ if (!isMouseStillDown && !self.isLoading) {
+ self.newActivity = false;
+ }
+
+ if (self.isUserActive === false || !self.isControlBarVisible()) {
+ let event = new CustomEvent('userActive');
+ self.domRef.player.dispatchEvent(event);
+ self.isUserActive = true;
+ }
+
+ clearTimeout(self.inactivityTimeout);
+
+ self.inactivityTimeout = setTimeout(() => {
+ if (self.newActivity === true) {
+ clearTimeout(self.inactivityTimeout);
+ return;
+ }
+
+ self.isUserActive = false;
+
+ let event = new CustomEvent('userInactive');
+ self.domRef.player.dispatchEvent(event);
+ }, self.displayOptions.layoutControls.controlBar.autoHideTimeout * 1000);
+ }, 300);
+
+ self.destructors.push(() => clearInterval(intervalId));
+
+ const listenTo = (self.isTouchDevice())
+ ? ['touchstart', 'touchmove', 'touchend']
+ : ['mousemove', 'mousedown', 'mouseup'];
+
+ for (let i = 0; i < listenTo.length; i++) {
+ videoPlayer.addEventListener(listenTo[i], activity, { passive: true });
+ }
+ };
+
+ self.hasControlBar = () => {
+ return !!self.domRef.wrapper.querySelector('.fluid_controls_container');
+ };
+
+ self.isControlBarVisible = () => {
+ if (self.hasControlBar() === false) {
+ return false;
+ }
+
+ const controlBar = self.domRef.wrapper.querySelector('.fluid_controls_container');
+ const style = window.getComputedStyle(controlBar, null);
+ return !(style.opacity === 0 || style.visibility === 'hidden');
+ };
+
+ self.setVideoPreload = () => {
+ self.domRef.player.setAttribute('preload', self.displayOptions.layoutControls.preload);
+ };
+
+ self.hideControlBar = () => {
+ if (self.isCurrentlyPlayingAd && !self.domRef.player.paused) {
+ self.toggleAdCountdown(true);
+ }
+
+ self.domRef.player.style.cursor = 'none';
+
+ // handles both VR and Normal condition
+ if (!self.hasControlBar()) {
+ return;
+ }
+
+ const divVastControls = self.domRef.player.parentNode.getElementsByClassName('fluid_controls_container');
+ const fpLogo = self.domRef.player.parentNode.getElementsByClassName('fp_logo');
+
+ for (let i = 0; i < divVastControls.length; i++) {
+ if (self.displayOptions.layoutControls.controlBar.animated) {
+ divVastControls[i].classList.remove('fade_in');
+ divVastControls[i].classList.add('fade_out');
+ } else {
+ divVastControls[i].style.display = 'none';
+ }
+ }
+
+ if (self.displayOptions.layoutControls.logo.hideWithControls) {
+ for (let i = 0; i < fpLogo.length; i++) {
+ if (self.displayOptions.layoutControls.controlBar.animated) {
+ if (fpLogo[i]) {
+ fpLogo[i].classList.remove('fade_in');
+ fpLogo[i].classList.add('fade_out');
+ }
+ } else {
+ if (fpLogo[i]) {
+ fpLogo[i].style.display = 'none';
+ }
+ }
+ }
+ }
+ };
+
+ self.showControlBar = (event) => {
+ if (self.isCurrentlyPlayingAd && !self.domRef.player.paused) {
+ self.toggleAdCountdown(false);
+ }
+
+ if (event.type === 'mouseenter' || event.type === 'userActive') {
+ self.domRef.player.style.cursor = 'default';
+ }
+
+ if (!self.hasControlBar()) {
+ return;
+ }
+
+ const divVastControls = self.domRef.player.parentNode.getElementsByClassName('fluid_controls_container');
+ const fpLogo = self.domRef.player.parentNode.getElementsByClassName('fp_logo');
+ for (let i = 0; i < divVastControls.length; i++) {
+ if (self.displayOptions.layoutControls.controlBar.animated) {
+ divVastControls[i].classList.remove('fade_out');
+ divVastControls[i].classList.add('fade_in');
+ } else {
+ divVastControls[i].style.display = 'block';
+ }
+ }
+ if (self.displayOptions.layoutControls.logo.hideWithControls) {
+ for (let i = 0; i < fpLogo.length; i++) {
+ if (self.displayOptions.layoutControls.controlBar.animated) {
+ if (fpLogo[i]) {
+ fpLogo[i].classList.remove('fade_out');
+ fpLogo[i].classList.add('fade_in');
+ }
+ } else {
+ if (fpLogo[i]) {
+ fpLogo[i].style.display = 'block';
+ }
+ }
+ }
+ }
+ };
+
+ self.linkControlBarUserActivity = () => {
+ self.domRef.player.addEventListener('userInactive', self.hideControlBar);
+ self.domRef.player.addEventListener('userInactive', self.hideTitle);
+
+ self.domRef.player.addEventListener('userActive', self.showControlBar);
+ self.domRef.player.addEventListener('userActive', self.showTitle);
+ };
+
+ self.initMute = () => {
+ if (self.displayOptions.layoutControls.mute !== true) {
+ return;
+ }
+
+ self.domRef.player.volume = 0;
+ };
+
+ self.initLoop = () => {
+ self.domRef.player.loop = !!self.displayOptions.layoutControls.loop;
+ };
+
+ self.setBuffering = () => {
+ let progressInterval;
+ const bufferBar = self.domRef.player.parentNode.getElementsByClassName('fluid_controls_buffered');
+
+ for (let j = 0; j < bufferBar.length; j++) {
+ bufferBar[j].style.width = 0;
+ }
+
+ // Buffering
+ const logProgress = () => {
+ const duration = self.domRef.player.duration;
+ if (duration <= 0) {
+ return;
+ }
+
+ for (let i = 0; i < self.domRef.player.buffered.length; i++) {
+ if (self.domRef.player.buffered.start(self.domRef.player.buffered.length - 1 - i) >= self.domRef.player.currentTime) {
+ continue;
+ }
+
+ const newBufferLength = (self.domRef.player.buffered.end(self.domRef.player.buffered.length - 1 - i) / duration) * 100 + "%";
+
+ for (let j = 0; j < bufferBar.length; j++) {
+ bufferBar[j].style.width = newBufferLength;
+ }
+
+ // Stop checking for buffering if the video is fully buffered
+ if (!!progressInterval && 1 === (self.domRef.player.buffered.end(self.domRef.player.buffered.length - 1 - i) / duration)) {
+ clearInterval(progressInterval);
+ }
+
+ break;
+ }
+ };
+ progressInterval = setInterval(logProgress, 500);
+ self.destructors.push(() => clearInterval(progressInterval));
+ };
+
+ self.createPlaybackList = () => {
+ if (!self.displayOptions.layoutControls.playbackRateEnabled) {
+ return;
+ }
+
+ const sourceChangeButton = self.domRef.wrapper.querySelector('.fluid_control_playback_rate');
+ sourceChangeButton.style.display = 'inline-block';
+
+ const sourceChangeList = document.createElement('div');
+ sourceChangeList.className = 'fluid_video_playback_rates';
+ sourceChangeList.style.display = 'none';
+
+ if (
+ !Array.isArray(self.displayOptions.layoutControls.controlBar.playbackRates)
+ || self.displayOptions.layoutControls.controlBar.playbackRates.some(
+ rate => typeof rate !== 'string' || Number.isNaN(Number(rate.replace('x', '')))
+ )
+ ) {
+ self.displayOptions.layoutControls.controlBar.playbackRates = ['x2', 'x1.5', 'x1', 'x0.5'];
+ }
+
+ self.displayOptions.layoutControls.controlBar.playbackRates.forEach(function (rate) {
+ const sourceChangeDiv = document.createElement('div');
+ sourceChangeDiv.className = 'fluid_video_playback_rates_item';
+ sourceChangeDiv.innerText = rate;
+
+ sourceChangeDiv.addEventListener('click', function (event) {
+ event.stopPropagation();
+ let playbackRate = this.innerText.replace('x', '');
+ self.setPlaybackSpeed(playbackRate);
+ self.openCloseVideoPlaybackRate();
+
+ });
+ sourceChangeList.appendChild(sourceChangeDiv);
+ });
+
+ sourceChangeButton.appendChild(sourceChangeList);
+ sourceChangeButton.addEventListener('click', function () {
+ self.openCloseVideoPlaybackRate();
+ });
+ };
+
+ self.openCloseVideoPlaybackRate = () => {
+ const sourceChangeList = self.domRef.wrapper.querySelector('.fluid_video_playback_rates');
+
+ if (self.isCurrentlyPlayingAd || 'none' !== sourceChangeList.style.display) {
+ sourceChangeList.style.display = 'none';
+ return;
+ }
+
+ sourceChangeList.style.display = 'block';
+ const mouseOut = function () {
+ sourceChangeList.removeEventListener('mouseleave', mouseOut);
+ sourceChangeList.style.display = 'none';
+ };
+ sourceChangeList.addEventListener('mouseleave', mouseOut);
+ };
+
+ self.createDownload = () => {
+ const downloadOption = self.domRef.wrapper.querySelector('.fluid_control_download');
+ if (!self.displayOptions.layoutControls.allowDownload) {
+ return;
+ }
+ downloadOption.style.display = 'inline-block';
+
+ let downloadClick = document.createElement('a');
+ downloadClick.className = 'fp_download_click';
+ downloadClick.onclick = function (e) {
+ const linkItem = this;
+
+ if (typeof e.stopImmediatePropagation !== 'undefined') {
+ e.stopImmediatePropagation();
+ }
+
+ setTimeout(function () {
+ linkItem.download = '';
+ linkItem.href = '';
+ }, 100);
+ };
+
+ downloadOption.appendChild(downloadClick);
+
+ downloadOption.addEventListener('click', function () {
+ const downloadItem = self.domRef.wrapper.querySelector('.fp_download_click');
+ downloadItem.download = self.originalSrc;
+ downloadItem.href = self.originalSrc;
+ downloadClick.click();
+ });
+ };
+
+ self.theatreToggle = () => {
+ self.debugMessage(`Toggling Theater Mode`);
+ if (self.isInIframe) {
+ return;
+ }
+
+ // Theatre and fullscreen, it's only one or the other
+ this.resetDisplayMode('theaterMode');
+
+ // Advanced Theatre mode if specified
+ if (self.displayOptions.layoutControls.theatreAdvanced) {
+ const elementForTheatre = self.domRef.wrapper.querySelector(`#${self.displayOptions.layoutControls.theatreAdvanced.theatreElement}`);
+ const theatreClassToApply = self.displayOptions.layoutControls.theatreAdvanced.classToApply;
+ if (elementForTheatre != null && theatreClassToApply != null) {
+ if (!self.theatreMode) {
+ elementForTheatre.classList.add(theatreClassToApply);
+ } else {
+ elementForTheatre.classList.remove(theatreClassToApply);
+ }
+ self.theatreModeAdvanced = !self.theatreModeAdvanced;
+ } else {
+ console.log('[FP_ERROR] Theatre mode elements could not be found, defaulting behaviour.');
+ // Default overlay behaviour
+ self.defaultTheatre();
+ }
+ } else {
+ // Default overlay behaviour
+ self.defaultTheatre();
+ }
+
+ // Set correct variables
+ self.theatreMode = !self.theatreMode;
+ self.fluidStorage.fluidTheatre = self.theatreMode;
+
+ // Trigger theatre event
+ const theatreEvent = (self.theatreMode) ? 'theatreModeOn' : 'theatreModeOff';
+ const event = document.createEvent('CustomEvent');
+ event.initEvent(theatreEvent, false, true);
+ self.domRef.player.dispatchEvent(event);
+
+ self.resizeVpaidAuto();
+ };
+
+ self.defaultTheatre = () => {
+ const videoWrapper = self.domRef.wrapper;
+
+ if (self.theatreMode) {
+ videoWrapper.classList.remove('fluid_theatre_mode');
+ videoWrapper.style.maxHeight = '';
+ videoWrapper.style.marginTop = '';
+ videoWrapper.style.left = '';
+ videoWrapper.style.right = '';
+ videoWrapper.style.position = '';
+ if (!self.displayOptions.layoutControls.fillToContainer) {
+ videoWrapper.style.width = self.originalWidth + 'px';
+ videoWrapper.style.height = self.originalHeight + 'px';
+ } else {
+ videoWrapper.style.width = '100%';
+ videoWrapper.style.height = '100%';
+ }
+ return;
+ }
+
+ videoWrapper.classList.add('fluid_theatre_mode');
+ const workingWidth = self.displayOptions.layoutControls.theatreSettings.width;
+ let defaultHorizontalMargin = '10px';
+ videoWrapper.style.width = workingWidth;
+ videoWrapper.style.height = self.displayOptions.layoutControls.theatreSettings.height;
+ videoWrapper.style.maxHeight = screen.height + "px";
+ videoWrapper.style.marginTop = self.displayOptions.layoutControls.theatreSettings.marginTop + 'px';
+ switch (self.displayOptions.layoutControls.theatreSettings.horizontalAlign) {
+ case 'center':
+ // We must calculate the margin differently based on whether they passed % or px
+ if (typeof (workingWidth) == 'string' && workingWidth.substr(workingWidth.length - 1) === "%") {
+ // A margin of half the remaining space
+ defaultHorizontalMargin = ((100 - parseInt(workingWidth.substring(0, workingWidth.length - 1))) / 2) + "%";
+ } else if (typeof (workingWidth) == 'string' && workingWidth.substr(workingWidth.length - 2) === "px") {
+ // Half the (Remaining width / fullwidth)
+ defaultHorizontalMargin = (((screen.width - parseInt(workingWidth.substring(0, workingWidth.length - 2))) / screen.width) * 100 / 2) + "%";
+ } else {
+ console.log('[FP_ERROR] Theatre width specified invalid.');
+ }
+
+ videoWrapper.style.left = defaultHorizontalMargin;
+ break;
+ case 'right':
+ videoWrapper.style.right = defaultHorizontalMargin;
+ break;
+ case 'left':
+ default:
+ videoWrapper.style.left = defaultHorizontalMargin;
+ break;
+ }
+ };
+
+ // Set the poster for the video, taken from custom params
+ // Cannot use the standard video tag poster image as it can be removed by the persistent settings
+ self.posterImage = () => {
+ if (!self.displayOptions.layoutControls.posterImage) {
+ return;
+ }
+
+ const containerDiv = document.createElement('div');
+ containerDiv.className = 'fluid_pseudo_poster';
+ if (['auto', 'contain', 'cover'].indexOf(self.displayOptions.layoutControls.posterImageSize) === -1) {
+ console.log('[FP_ERROR] Not allowed value in posterImageSize');
+ return;
+ }
+ containerDiv.style.background = "url('" + self.displayOptions.layoutControls.posterImage + "') center center / "
+ + self.displayOptions.layoutControls.posterImageSize + " no-repeat black";
+ self.domRef.player.parentNode.insertBefore(containerDiv, null);
+ };
+
+ // This is called when a media type is unsupported. We'll find the current source and try set the next source if it exists
+ self.nextSource = () => {
+ const sources = self.domRef.player.getElementsByTagName('source');
+
+ if (!sources.length) {
+ return null;
+ }
+
+ for (let i = 0; i < sources.length - 1; i++) {
+ if (sources[i].getAttribute('src') === self.originalSrc && sources[i + 1].getAttribute('src')) {
+ self.setVideoSource(sources[i + 1].getAttribute('src'));
+ return;
+ }
+ }
+ };
+
+ self.inIframe = () => {
+ try {
+ return window.self !== window.top;
+ } catch (e) {
+ return true;
+ }
+ };
+
+ self.setPersistentSettings = (ignoreMute = false) => {
+ try {
+ if (!(typeof (Storage) !== 'undefined' && typeof (localStorage) !== 'undefined')) {
+ return;
+ }
+ } catch (e) {
+ return;
+ }
+
+ // See https://github.com/fluid-player/fluid-player/issues/271
+ const testKey = '_fp_storage_enabled', storage = localStorage;
+ try {
+ storage.setItem(testKey, '1');
+ storage.removeItem(testKey);
+ } catch (error) {
+ return false;
+ }
+
+ self.fluidStorage = localStorage;
+ if (typeof (self.fluidStorage.fluidVolume) !== 'undefined'
+ && self.displayOptions.layoutControls.persistentSettings.volume
+ && !ignoreMute) {
+ self.setVolume(self.fluidStorage.fluidVolume);
+
+ if (typeof (self.fluidStorage.fluidMute) !== 'undefined' && self.fluidStorage.fluidMute === 'true') {
+ self.muteToggle();
+ }
+ }
+
+ if (typeof (self.fluidStorage.fluidQuality) !== 'undefined'
+ && self.displayOptions.layoutControls.persistentSettings.quality) {
+ const sourceOption = self.domRef.wrapper.querySelector('.js-source_' + self.fluidStorage.fluidQuality);
+ const sourceChangeButton = self.domRef.wrapper.querySelector('.fluid_control_video_source');
+ if (sourceOption) {
+ sourceOption.click();
+ sourceChangeButton.click();
+ }
+ }
+
+ if (typeof (self.fluidStorage.fluidSpeed) !== 'undefined'
+ && self.displayOptions.layoutControls.persistentSettings.speed) {
+ self.setPlaybackSpeed(self.fluidStorage.fluidSpeed);
+ }
+
+ if (typeof (self.fluidStorage.fluidTheatre) !== 'undefined'
+ && self.fluidStorage.fluidTheatre === 'true'
+ && self.displayOptions.layoutControls.persistentSettings.theatre) {
+ self.theatreToggle();
+ }
+ };
+
+ // "API" Functions
+ self.play = () => {
+ if (!self.domRef.player.paused) {
+ return;
+ }
+ self.playPauseToggle();
+
+ return true;
+ };
+
+ self.pause = () => {
+ if (!self.domRef.player.paused) {
+ self.playPauseToggle();
+ }
+ return true;
+ };
+
+ self.skipTo = (time) => {
+ self.domRef.player.currentTime = time;
+ };
+
+ self.setPlaybackSpeed = (speed) => {
+ if (self.isCurrentlyPlayingAd) {
+ return;
+ }
+ self.domRef.player.playbackRate = speed;
+ self.fluidStorage.fluidSpeed = speed;
+ };
+
+ self.setVolume = (passedVolume) => {
+ self.domRef.player.volume = passedVolume;
+
+ // If user scrolls to volume 0, we should not store 0 as
+ // latest volume - there is a property called "muted" already
+ // and storing 0 will break the toggle.
+ // In case user scrolls to 0 we assume last volume to be 1
+ // for toggle.
+ const latestVolume = 0 === passedVolume ? 1 : passedVolume;
+
+ self.latestVolume = latestVolume;
+ self.fluidStorage.fluidVolume = latestVolume;
+ };
+
+ /**
+ * @param {HTMLVideoElement} instance
+ */
+ self.isCurrentlyPlayingVideo = (instance) => {
+ return instance && instance.currentTime > 0 && !instance.paused && !instance.ended && instance.readyState > 2;
+ };
+
+ self.setHtmlOnPauseBlock = (passedHtml) => {
+ if (typeof passedHtml != 'object' || typeof passedHtml.html == 'undefined') {
+ return false;
+ }
+
+ const htmlBlock = self.domRef.wrapper.querySelector('.fluid_html_on_pause_container');
+
+ // We create the HTML block from scratch if it doesn't already exist
+ if (!htmlBlock) {
+ const containerDiv = document.createElement('div');
+ containerDiv.className = 'fluid_html_on_pause';
+ containerDiv.style.display = 'none';
+ containerDiv.innerHTML = passedHtml.html;
+ containerDiv.onclick = function () {
+ self.playPauseToggle();
+ };
+
+ if (passedHtml.width) {
+ containerDiv.style.width = passedHtml.width + 'px';
+ }
+
+ if (passedHtml.height) {
+ containerDiv.style.height = passedHtml.height + 'px';
+ }
+
+ self.domRef.player.parentNode.insertBefore(containerDiv, null);
+ return;
+ }
+
+ htmlBlock.innerHTML = passedHtml.html;
+
+ if (passedHtml.width) {
+ htmlBlock.style.width = passedHtml.width + 'px';
+ }
+
+ if (passedHtml.height) {
+ htmlBlock.style.height = passedHtml.height + 'px';
+ }
+ };
+
+ self.toggleControlBar = (show) => {
+ const controlBar = self.domRef.wrapper.querySelector('.fluid_controls_container');
+
+ if (show) {
+ controlBar.className += ' initial_controls_show';
+ return;
+ }
+
+ controlBar.className = controlBar.className.replace(' initial_controls_show', '');
+ };
+
+ self.on = (eventCall, callback) => {
+ /**
+ * Improves events by adding player info to the callbacks
+ *
+ * source | preRoll | midRoll | postRoll
+ */
+ const getAdditionalInfo = () => ({
+ mediaSourceType: self.currentMediaSourceType
+ });
+
+ const functionCall = (event, additionalEventData = {}) => {
+ const additionalInfo = {...getAdditionalInfo(), ...additionalEventData}
+ return callback(event, additionalInfo);
+ }
+
+ const eventHandlers = {
+ play: () => self.domRef.player.addEventListener('play', functionCall),
+ seeked: () => self.domRef.player.addEventListener('seeked', functionCall),
+ ended: () => self.domRef.player.addEventListener('ended', functionCall),
+ pause: () => self.domRef.player.addEventListener('pause', (event) => {
+ if (!self.fluidPseudoPause) {
+ functionCall(event)
+ }
+ }),
+ playing: () => self.domRef.player.addEventListener('playing', functionCall),
+ waiting: () => self.domRef.player.addEventListener('waiting', functionCall),
+ theatreModeOn: () => self.domRef.player.addEventListener('theatreModeOn', functionCall),
+ theatreModeOff: () => self.domRef.player.addEventListener('theatreModeOff', functionCall),
+ timeupdate: () => self.domRef.player.addEventListener('timeupdate', (event) => {
+ functionCall(event, { currentTime: self.domRef.player.currentTime });
+ }),
+ miniPlayerToggle: () => self.domRef.player.addEventListener('miniPlayerToggle', functionCall)
+ };
+
+ if (!eventHandlers[eventCall]) {
+ console.error(`[FP_ERROR] Event "${eventCall}" is not recognized`);
+ return;
+ }
+
+ // Call event handler
+ eventHandlers[eventCall]();
+ };
+
+ self.toggleLogo = (logo) => {
+ if (typeof logo != 'object' || !logo.imageUrl) {
+ return false;
+ }
+
+ const logoBlock = self.domRef.wrapper.querySelector('.fp_logo');
+
+ // We create the logo from scratch if it doesn't already exist, they might not give everything correctly so we
+ self.displayOptions.layoutControls.logo.imageUrl = (logo.imageUrl) ? logo.imageUrl : null;
+ self.displayOptions.layoutControls.logo.position = (logo.position) ? logo.position : 'top left';
+ self.displayOptions.layoutControls.logo.clickUrl = (logo.clickUrl) ? logo.clickUrl : null;
+ self.displayOptions.layoutControls.logo.opacity = (logo.opacity) ? logo.opacity : 1;
+ self.displayOptions.layoutControls.logo.mouseOverImageUrl = (logo.mouseOverImageUrl) ? logo.mouseOverImageUrl : null;
+ self.displayOptions.layoutControls.logo.imageMargin = (logo.imageMargin) ? logo.imageMargin : '2px';
+ self.displayOptions.layoutControls.logo.hideWithControls = (logo.hideWithControls) ? logo.hideWithControls : false;
+ self.displayOptions.layoutControls.logo.showOverAds = (logo.showOverAds) ? logo.showOverAds : false;
+
+ if (logoBlock) {
+ logoBlock.remove();
+ }
+
+ self.initLogo();
+ };
+
+ // this functions helps in adding event listeners for future dynamic elements
+ // trackEvent(document, "click", ".some_elem", callBackFunction);
+ self.trackEvent = (el, evt, sel, handler) => {
+ if (typeof self.events[sel] === 'undefined') {
+ self.events[sel] = {};
+ }
+
+ if (typeof self.events[sel][evt] === 'undefined') {
+ self.events[sel][evt] = [];
+ }
+
+ self.events[sel][evt].push(handler);
+ self.registerListener(el, evt, sel, handler);
+ };
+
+ self.registerListener = (el, evt, sel, handler) => {
+ const currentElements = el.querySelectorAll(sel);
+ for (let i = 0; i < currentElements.length; i++) {
+ currentElements[i].addEventListener(evt, handler);
+ }
+ };
+
+ self.copyEvents = (topLevelEl) => {
+ for (let sel in self.events) {
+ if (!self.events.hasOwnProperty(sel)) {
+ continue;
+ }
+
+ for (let evt in self.events[sel]) {
+ if (!self.events[sel].hasOwnProperty(evt)) {
+ continue;
+ }
+
+ for (let i = 0; i < self.events[sel][evt].length; i++) {
+ self.registerListener(topLevelEl, evt, sel, self.events[sel][evt][i]);
+ }
+ }
+ }
+ };
+
+ /**
+ * Resets all display types that are not the target display mode
+ *
+ * @param {'fullScreen'|'theaterMode'|'miniPlayer'} displayTarget
+ */
+ self.resetDisplayMode = (displayTarget) => {
+ if (self.fullscreenMode && displayTarget !== 'fullScreen') {
+ self.fullscreenToggle();
+ }
+
+ if (self.theatreMode && displayTarget !== 'theaterMode') {
+ self.theatreToggle();
+ }
+
+ if (self.miniPlayerToggledOn && displayTarget !== 'miniPlayer') {
+ self.toggleMiniPlayer('off');
+ }
+ }
+
+ self.destroy = () => {
+ self.domRef.player.classList.remove('js-fluid-player');
+ const numDestructors = self.destructors.length;
+
+ if (0 === numDestructors) {
+ return;
+ }
+
+ self.destructors.forEach(destructor => destructor.call(self));
+
+ const container = self.domRef.wrapper;
+
+ if (!container) {
+ console.warn('Unable to remove wrapper element for Fluid Player instance - element not found');
+ return;
+ }
+
+ if ('function' === typeof container.remove) {
+ container.remove();
+ return;
+ }
+
+ if (container.parentNode) {
+ container.parentNode.removeChild(container);
+ return;
+ }
+
+ console.error('Unable to remove wrapper element for Fluid Player instance - no parent');
+ }
+};
+
+/**
+ * Public Fluid Player API interface
+ * @param {FluidPlayer} instance
+ */
+const fluidPlayerInterface = function (instance) {
+ this.play = () => {
+ return instance.play()
+ };
+
+ this.pause = () => {
+ return instance.pause()
+ };
+
+ this.skipTo = (position) => {
+ return instance.skipTo(position)
+ };
+
+ this.setPlaybackSpeed = (speed) => {
+ return instance.setPlaybackSpeed(speed)
+ };
+
+ this.setVolume = (volume) => {
+ return instance.setVolume(volume)
+ };
+
+ this.setHtmlOnPauseBlock = (options) => {
+ return instance.setHtmlOnPauseBlock(options)
+ };
+
+ this.toggleControlBar = (state) => {
+ return instance.toggleControlBar(state)
+ };
+
+ this.toggleFullScreen = (state) => {
+ return instance.fullscreenToggle(state)
+ };
+
+ this.toggleMiniPlayer = (state) => {
+ if (state === undefined) {
+ state = !instance.miniPlayerToggledOn;
+ }
+
+ return instance.toggleMiniPlayer(state ? 'on' : 'off', true);
+ };
+
+ this.destroy = () => {
+ instance.domRef.player
+ return instance.destroy()
+ };
+
+ this.dashInstance = () => {
+ return !!instance.dashPlayer ? instance.dashPlayer : null;
+ }
+
+ this.hlsInstance = () => {
+ return !!instance.hlsPlayer ? instance.hlsPlayer : null;
+ }
+
+ this.on = (event, callback) => {
+ return instance.on(event, callback)
+ };
+
+ this.setDebug = (value) => {
+ instance.displayOptions.debug = value;
+ }
+}
+
+/**
+ * Initialize and attach Fluid Player to instance of HTMLVideoElement
+ *
+ * @param target ID of HTMLVideoElement or reference to HTMLVideoElement
+ * @param options Fluid Player configuration options
+ * @returns {fluidPlayerInterface}
+ */
+const fluidPlayerInitializer = function (target, options) {
+ const instance = new fluidPlayerClass();
+
+ if (!options) {
+ options = {};
+ }
+
+ instance.init(target, options);
+
+ const publicInstance = new fluidPlayerInterface(instance);
+
+ if (window && FP_DEVELOPMENT_MODE) {
+ const debugApi = {
+ id: target,
+ options: options,
+ instance: publicInstance,
+ internals: instance
+ };
+
+ if (typeof window.fluidPlayerDebug === 'undefined') {
+ window.fluidPlayerDebug = [];
+ }
+
+ window.fluidPlayerDebug.push(debugApi);
+
+ console.log('Created instance of Fluid Player. ' +
+ 'Debug API available at window.fluidPlayerDebug[' + (window.fluidPlayerDebug.length - 1) + '].', debugApi);
+ }
+
+ return publicInstance;
+}
+
+
+if (FP_DEVELOPMENT_MODE) {
+ console.log('Fluid Player - Development Build' + (FP_RUNTIME_DEBUG ? ' (in debug mode)' : ''));
+}
+
+export default fluidPlayerInitializer;
diff --git a/client/fluid-player/src/index.d.ts b/client/fluid-player/src/index.d.ts
new file mode 100644
index 0000000..e9e232a
--- /dev/null
+++ b/client/fluid-player/src/index.d.ts
@@ -0,0 +1,222 @@
+declare module 'fluid-player' {
+ function fluidPlayer(
+ target: HTMLVideoElement | String | string,
+ options?: Partial
+ ): FluidPlayerInstance;
+
+ export default fluidPlayer;
+}
+
+declare type AdditionalEventInfo = { mediaSourceType: 'ad' | 'source' };
+declare type OnPlay = (event: 'play', callback: (additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnPlaying =
+ (event: 'playing', callback: (event: Event, additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnPause = (event: 'pause', callback: (additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnEnded = (event: 'ended', callback: (additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnSeeked = (event: 'seeked', callback: (additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnTheaterModeOn =
+ (event: 'theatreModeOn', callback: (event: Event, additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnTheaterModeOff =
+ (event: 'theatreModeOff', callback: (event: Event, additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnTimeUpdate =
+ (event: 'timeupdate', callback: (time: number, additionalInfo: AdditionalEventInfo) => void) => void;
+declare type OnMiniPlayerToggle =
+ (event: 'miniPlayerToggle', callback: (event: CustomEvent<{
+ isToggledOn: boolean
+ }>, additionalInfo: AdditionalEventInfo) => void) => void;
+
+declare interface FluidPlayerInstance {
+ play: () => void;
+ pause: () => void;
+ skipTo: (seconds: number) => void;
+ setPlaybackSpeed: (speed: number) => void;
+ setVolume: (volume: number) => void;
+ toggleControlBar: (shouldToggle: boolean) => void;
+ toggleFullScreen: (shouldToggle: boolean) => void;
+ toggleMiniPlayer: (shouldToggle: boolean) => void;
+ setHtmlOnPauseBlock: (pauseBlock: { html: string; width: number; height: number; }) => void;
+ destroy: () => void;
+ dashInstance: () => any | null;
+ hlsInstance: () => any | null;
+ on: OnPlay & OnPlaying & OnPause & OnEnded & OnSeeked & OnTheaterModeOn & OnTheaterModeOff & OnTimeUpdate &
+ OnMiniPlayerToggle;
+}
+
+declare interface LayoutControls {
+ primaryColor: false | string;
+ posterImage: false | string;
+ posterImageSize: 'auto' | 'cover' | 'contain';
+ playButtonShowing: boolean;
+ playPauseAnimation: boolean;
+ fillToContainer: boolean;
+ autoPlay: boolean;
+ preload: 'none' | 'metadata' | 'auto' | string;
+ mute: boolean;
+ doubleclickFullscreen: boolean;
+ subtitlesEnabled: boolean;
+ keyboardControl: boolean;
+ title: string;
+ loop: boolean;
+ logo: Partial<{
+ imageUrl: string | null;
+ position: 'top right' | 'top left' | 'bottom right' | 'bottom left';
+ clickUrl: string | null;
+ opacity: number;
+ mouseOverImageUrl: string | null;
+ imageMargin: string;
+ hideWithControls: boolean;
+ showOverAds: boolean;
+ }>;
+ controlBar: Partial<{
+ autoHide: boolean;
+ autoHideTimeout: number;
+ animated: boolean;
+ }>;
+ timelinePreview: VTTPreviewOptions | StaticPreviewOptions;
+ htmlOnPauseBlock: Partial<{
+ html: string | null;
+ height: number | null;
+ width: number | null;
+ }>;
+ layout: 'default' | string;
+ allowDownload: boolean;
+ playbackRateEnabled: boolean;
+ allowTheatre: boolean;
+ theatreAdvanced: Partial<{
+ theatreElement: string;
+ classToApply: string;
+ }>;
+ theatreSettings: Partial<{
+ width: string;
+ height: string;
+ marginTop: number;
+ horizontalAlign: 'center' | 'left' | 'right';
+ }>;
+ playerInitCallback: () => void;
+ persistentSettings: Partial<{
+ volume: boolean;
+ quality: boolean;
+ speed: boolean;
+ theatre: boolean;
+ }>;
+ controlForwardBackward: Partial<{
+ show: boolean;
+ doubleTapMobile: boolean;
+ }>;
+ contextMenu: Partial<{
+ controls: boolean;
+ links: Array<{
+ href: string;
+ label: string;
+ }>;
+ }>;
+ miniPlayer: Partial<{
+ enabled: boolean;
+ width: number;
+ height: number;
+ widthMobile: number;
+ placeholderText: string;
+ position: 'top right' | 'top left' | 'bottom right' | 'bottom left';
+ autoToggle: boolean;
+ }>;
+ showCardBoardView: boolean;
+ showCardBoardJoystick: boolean;
+}
+
+declare interface VTTPreviewOptions {
+ file: string;
+ type: 'VTT';
+ spriteRelativePath?: boolean;
+ sprite?: string;
+}
+
+declare interface StaticPreviewOptions {
+ type: 'static';
+ frames: Array<{
+ startTime: number;
+ endTime: number;
+ image: string;
+ x: number;
+ y: number;
+ w: number;
+ h: number;
+ }>
+}
+
+declare interface VastOptions {
+ adList: Array;
+ skipButtonCaption: string;
+ skipButtonClickCaption: string;
+ adText: string;
+ adTextPosition: 'top right' | 'top left' | 'bottom right' | 'bottom left';
+ adCTAText: string | boolean;
+ adCTATextPosition: 'top right' | 'top left' | 'bottom right' | 'bottom left';
+ adCTATextVast: boolean;
+ vastTimeout: number;
+ showPlayButton: boolean;
+ maxAllowedVastTagRedirects: number;
+ showProgressbarMarkers: boolean;
+ adClickable: boolean;
+ allowVPAID: boolean;
+ vastAdvanced: Partial<{
+ vastLoadedCallback: () => void;
+ noVastVideoCallback: () => void;
+ vastVideoSkippedCallback: () => void;
+ vastVideoEndedCallback: () => void;
+ }>;
+}
+
+declare interface AdOptions {
+ vastTag: string;
+ roll: string;
+ fallbackVastTags?: Array;
+ adText?: string;
+ adTextPosition?: 'top right' | 'top left' | 'bottom right' | 'bottom left';
+ adClickable?: boolean;
+ vAlign?: 'top' | 'middle' | 'bottom';
+ nonLinearDuration?: number;
+ size?: '468x60' | '300x250' | '728x90';
+}
+
+declare interface PreRollAdOptions extends AdOptions {
+ roll: 'preRoll';
+}
+
+declare interface MidRollAdOptions extends AdOptions {
+ roll: 'midRoll';
+ timer: number | string;
+}
+
+declare interface PostRollAdOptions extends AdOptions {
+ roll: 'postRoll';
+}
+
+declare interface OnPauseRollAdOptions extends AdOptions {
+ roll: 'onPauseRoll';
+}
+
+declare interface ModulesOptions {
+ configureHls: (options: any) => any;
+ onBeforeInitHls: (hls: any) => void;
+ onAfterInitHls: (hls: any) => void;
+ configureDash: (options: any) => any;
+ onBeforeInitDash: (dash: any) => void;
+ onAfterInitDash: (dash: any) => void;
+}
+
+declare interface FluidPlayerOptions {
+ layoutControls: Partial;
+ vastOptions: Partial;
+ modules: Partial;
+ onBeforeXMLHttpRequestOpen?: (request: XMLHttpRequest) => void;
+ onBeforeXMLHttpRequest?: (request: XMLHttpRequest) => void;
+ debug?: boolean;
+ captions: Partial<{
+ play: string;
+ pause: string;
+ mute: string;
+ unmute: string;
+ fullscreen: string;
+ exitFullscreen: string;
+ }>;
+}
diff --git a/client/fluid-player/src/index.js b/client/fluid-player/src/index.js
new file mode 100644
index 0000000..d26f47e
--- /dev/null
+++ b/client/fluid-player/src/index.js
@@ -0,0 +1,33 @@
+
+if ('undefined' === typeof FP_HOMEPAGE) {
+ globalThis.FP_HOMEPAGE = 'https://fluidplayer.com';
+}
+
+if ('undefined' === typeof FP_BUILD_VERSION) {
+ globalThis.FP_BUILD_VERSION = 'v3';
+}
+
+if ('undefined' === typeof FP_ENV) {
+ const isLocalhost = globalThis
+ && globalThis.location
+ && (globalThis.location.hostname === 'localhost'
+ || globalThis.location.hostname === '127.0.0.1'
+ || globalThis.location.hostname === '');
+
+ if ('undefined' !== typeof process && process && process.env && process.env.NODE_ENV) {
+ globalThis.FP_ENV = process.env.NODE_ENV;
+ } else if (globalThis && !isLocalhost) {
+ globalThis.FP_ENV = 'production';
+ } else {
+ globalThis.FP_ENV = 'development';
+ }
+}
+
+if ('undefined' === typeof FP_DEBUG) {
+ globalThis.FP_DEBUG = false;
+}
+
+import './polyfills';
+import fluidPlayerInitializer from './fluidplayer.js';
+
+export default fluidPlayerInitializer;
diff --git a/client/fluid-player/src/modules/adsupport.js b/client/fluid-player/src/modules/adsupport.js
new file mode 100644
index 0000000..4fb2d6a
--- /dev/null
+++ b/client/fluid-player/src/modules/adsupport.js
@@ -0,0 +1,1751 @@
+// @ts-check
+
+/**
+ * @param {import("../fluidplayer.js").FluidPlayer} playerInstance
+ * @param {unknown} options
+ */
+function adSupport(playerInstance, options) {
+ const VPAID_VERSION = '2.0';
+
+ playerInstance.renderLinearAd = (ad, backupTheVideoTime) => {
+ playerInstance.toggleLoader(false);
+
+ //get the proper ad
+ playerInstance.vastOptions = ad;
+
+ if (backupTheVideoTime) {
+ playerInstance.backupMainVideoContentTime(ad.rollListId);
+ }
+
+ const playVideoPlayer = ad => {
+ playerInstance.switchPlayerToVpaidMode = ad => {
+ playerInstance.debugMessage('starting function switchPlayerToVpaidMode');
+ const vpaidIframe = "fp_" + ad.id + "_fluid_vpaid_iframe";
+ const creativeData = {};
+ creativeData.AdParameters = ad.adParameters;
+ const slotElement = document.createElement('div');
+ slotElement.className = 'fluid_vpaid_slot';
+ slotElement.setAttribute('adListId', ad.id);
+
+ playerInstance.domRef.player.parentNode.insertBefore(slotElement, vpaidIframe.nextSibling);
+
+ const environmentVars = {
+ slot: slotElement,
+ videoSlot: playerInstance.domRef.player,
+ videoSlotCanAutoPlay: true
+ };
+
+ // calls this functions after ad unit is loaded in iframe
+ const ver = playerInstance.vpaidAdUnit.handshakeVersion(VPAID_VERSION);
+ const compare = playerInstance.compareVersion(VPAID_VERSION, ver);
+ if (compare === 1) {
+ //VPAID version of ad is lower than we need
+ ad.error = true;
+ playerInstance.playMainVideoWhenVpaidFails(403);
+ return false;
+ }
+
+ if (playerInstance.vastOptions.skipoffset !== false) {
+ playerInstance.addSkipButton();
+ }
+
+ playerInstance.domRef.player.loop = false;
+ playerInstance.domRef.player.removeAttribute('controls'); //Remove the default Controls
+
+ playerInstance.vpaidCallbackListenersAttach();
+ const mode = (playerInstance.fullscreenMode ? 'fullscreen' : 'normal');
+ const adWidth = playerInstance.domRef.player.offsetWidth;
+ const adHeight = playerInstance.domRef.player.offsetHeight;
+ playerInstance.vpaidAdUnit.initAd(adWidth, adHeight, mode, 3000, creativeData, environmentVars);
+
+ const progressbarContainer = playerInstance.domRef.player.parentNode.getElementsByClassName('fluid_controls_currentprogress');
+ for (let i = 0; i < progressbarContainer.length; i++) {
+ progressbarContainer[i].style.backgroundColor = playerInstance.displayOptions.layoutControls.adProgressColor;
+ }
+
+ playerInstance.toggleLoader(false);
+ ad.played = true;
+ playerInstance.adFinished = false;
+ };
+
+ playerInstance.switchPlayerToVastMode = () => {
+ // Get the actual duration from the video file if it is not present in the VAST XML
+ if (!playerInstance.vastOptions.duration) {
+ playerInstance.vastOptions.duration = selectedMediaFile.delivery === 'streaming' ?
+ Infinity : playerInstance.domRef.player.duration;
+ }
+
+ if (playerInstance.displayOptions.layoutControls.showCardBoardView) {
+
+ if (!ad.landingPage) {
+ playerInstance.addCTAButton(ad.clickthroughUrl);
+ } else {
+ playerInstance.addCTAButton(ad.landingPage);
+ }
+
+ } else {
+ let idAdClickable = [undefined, true]
+ .includes(playerInstance.displayOptions.vastOptions.adClickable);
+
+ if (playerInstance.rollsById[ad.rollListId].adClickable !== undefined) {
+ idAdClickable = playerInstance.rollsById[ad.rollListId].adClickable;
+ }
+
+ if (idAdClickable) {
+ playerInstance.addClickthroughLayer();
+ }
+
+ playerInstance.addCTAButton(ad.landingPage);
+ }
+
+ if (playerInstance.vastOptions.skipoffset !== false) {
+ playerInstance.addSkipButton();
+ }
+
+ playerInstance.domRef.player.loop = false;
+
+ playerInstance.addAdCountdown();
+
+ playerInstance.domRef.player.removeAttribute('controls'); //Remove the default Controls
+
+ playerInstance.vastLogoBehaviour(true);
+
+ const progressbarContainer = playerInstance.domRef.player.parentNode.getElementsByClassName('fluid_controls_currentprogress');
+ for (let i = 0; i < progressbarContainer.length; i++) {
+ progressbarContainer[i].style.backgroundColor = playerInstance.displayOptions.layoutControls.adProgressColor;
+ }
+
+ if (playerInstance.rollsById[ad.rollListId].adText || ad.adText) {
+ const adTextToShow = ad.adText ? ad.adText : playerInstance.rollsById[ad.rollListId].adText;
+ playerInstance.addAdPlayingText(adTextToShow);
+ }
+
+ playerInstance.positionTextElements(ad);
+
+ playerInstance.toggleLoader(false);
+ ad.played = true;
+ playerInstance.adFinished = false;
+ playerInstance.domRef.player.play();
+
+ //Announce the impressions
+ playerInstance.trackSingleEvent('impression');
+
+ playerInstance.domRef.player.removeEventListener('loadedmetadata', playerInstance.switchPlayerToVastMode);
+
+ // if in vr mode then do not show
+ if (playerInstance.vrMode) {
+ const adCountDownTimerText = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+ const ctaButton = playerInstance.domRef.wrapper.querySelector('.fluid_ad_cta');
+ const addAdPlayingTextOverlay = playerInstance.domRef.wrapper.querySelector('.fluid_ad_playing');
+ const skipBtn = playerInstance.domRef.wrapper.querySelector('.skip_button');
+
+ if (adCountDownTimerText) {
+ adCountDownTimerText.style.display = 'none';
+ }
+
+ if (ctaButton) {
+ ctaButton.style.display = 'none';
+ }
+
+ if (addAdPlayingTextOverlay) {
+ addAdPlayingTextOverlay.style.display = 'none';
+ }
+
+ if (skipBtn) {
+ skipBtn.style.display = 'none';
+ }
+ }
+ };
+
+ playerInstance.domRef.player.pause();
+
+ // Remove the streaming objects to prevent errors on the VAST content
+ playerInstance.detachStreamers();
+
+ // Try to load multiple
+ const selectedMediaFile = playerInstance.getSupportedMediaFileObject(playerInstance.vastOptions.mediaFileList);
+
+ // if player in cardboard mode then, linear ads media type should be a '360' video
+ if (playerInstance.displayOptions.layoutControls.showCardBoardView && ad.mediaType !== '360') {
+ ad.error = true;
+ playerInstance.playMainVideoWhenVastFails(403);
+ return false;
+ }
+
+ const isVpaid = playerInstance.vastOptions.vpaid;
+
+ if (!isVpaid && selectedMediaFile.isUnsuportedHls) {
+ import(/* webpackChunkName: "hlsjs" */ 'hls.js').then((it) => {
+ window.Hls = it.default;
+ const hls = new Hls({
+ debug: typeof FP_DEBUG !== 'undefined' && FP_DEBUG === true,
+ startPosition: 0,
+ p2pConfig: {
+ logLevel: false,
+ },
+ enableWebVTT: false,
+ enableCEA708Captions: false,
+ });
+
+ hls.attachMedia(playerInstance.domRef.player);
+ hls.loadSource(selectedMediaFile.src);
+ playerInstance.isCurrentlyPlayingAd = true;
+
+ playerInstance.hlsPlayer = hls;
+
+ playerInstance.domRef.player.addEventListener('loadedmetadata', playerInstance.switchPlayerToVastMode);
+ playerInstance.domRef.player.addEventListener('ended', () => {
+ hls.detachMedia();
+ hls.destroy();
+ playerInstance.hlsPlayer = false;
+ playerInstance.onVastAdEnded();
+ });
+
+ playerInstance.domRef.player.play();
+ });
+ } else if (!isVpaid) {
+ if (selectedMediaFile.src === false) {
+ // Couldn’t find MediaFile that is supported by this video player, based on the attributes of the MediaFile element.
+ ad.error = true;
+ playerInstance.playMainVideoWhenVastFails(403);
+ return false;
+ }
+
+ playerInstance.domRef.player.addEventListener('loadedmetadata', playerInstance.switchPlayerToVastMode);
+
+ playerInstance.domRef.player.src = selectedMediaFile.src;
+ playerInstance.isCurrentlyPlayingAd = true;
+
+ if (playerInstance.displayOptions.vastOptions.showProgressbarMarkers) {
+ playerInstance.hideAdMarkers();
+ }
+
+ playerInstance.domRef.player.load();
+
+ //Handle the ending of the Pre-Roll ad
+ playerInstance.domRef.player.addEventListener('ended', playerInstance.onVastAdEnded);
+
+ } else {
+ playerInstance.loadVpaid(ad, selectedMediaFile.src);
+
+ if (playerInstance.displayOptions.vastOptions.showProgressbarMarkers) {
+ playerInstance.hideAdMarkers();
+ }
+ }
+ };
+
+ /**
+ * Sends requests to the tracking URIs
+ */
+ const videoPlayerTimeUpdate = () => {
+ if (playerInstance.adFinished) {
+ playerInstance.domRef.player.removeEventListener('timeupdate', videoPlayerTimeUpdate);
+ return;
+ }
+
+ const currentTime = Math.floor(playerInstance.domRef.player.currentTime);
+ if (playerInstance.vastOptions.duration !== 0) {
+ playerInstance.scheduleTrackingEvent(currentTime, playerInstance.vastOptions.duration);
+ }
+
+ if (currentTime >= (playerInstance.vastOptions.duration - 1) && playerInstance.vastOptions.duration !== 0) {
+ playerInstance.domRef.player.removeEventListener('timeupdate', videoPlayerTimeUpdate);
+ playerInstance.adFinished = true;
+ }
+
+ };
+
+ playVideoPlayer(ad);
+
+ playerInstance.domRef.player.addEventListener('timeupdate', videoPlayerTimeUpdate);
+
+ };
+
+ playerInstance.playRoll = (adList) => {
+ // register all the ad pods
+ const newPods = [];
+ for (let i = 0; i < adList.length; i++) {
+ newPods.push(adList[i]);
+ }
+ playerInstance.temporaryAdPods = newPods;
+
+ if (playerInstance.vastOptions !== null && playerInstance.vastOptions.adType.toLowerCase() === 'linear') {
+ return;
+ }
+
+ const adToPlay = playerInstance.getNextAdPod();
+
+ if (adToPlay !== null) {
+ playerInstance.renderLinearAd(adToPlay, true);
+ }
+
+ const roll = playerInstance.rollsById[adToPlay.rollListId].roll;
+ playerInstance.currentMediaSourceType = roll;
+ };
+
+ playerInstance.backupMainVideoContentTime = (rollListId) => {
+ const roll = playerInstance.rollsById[rollListId].roll;
+
+ //spec configs by roll
+ switch (roll) {
+ case 'midRoll':
+ playerInstance.domRef.player.mainVideoCurrentTime = playerInstance.domRef.player.currentTime - 1;
+ break;
+
+ case 'postRoll':
+ playerInstance.domRef.player.mainVideoCurrentTime = playerInstance.mainVideoDuration;
+ playerInstance.autoplayAfterAd = false;
+ playerInstance.domRef.player.currentTime = playerInstance.mainVideoDuration;
+ break;
+
+ case 'preRoll':
+ if (playerInstance.domRef.player.currentTime > 0) {
+ playerInstance.domRef.player.mainVideoCurrentTime = playerInstance.domRef.player.currentTime - 1;
+ }
+ break;
+ }
+ };
+
+ playerInstance.getSupportedMediaFileObject = (mediaFiles) => {
+ let selectedMediaFile = null;
+ let adSupportedType = false;
+ if (mediaFiles.length) {
+ for (let i = 0; i < mediaFiles.length; i++) {
+
+ if (mediaFiles[i].apiFramework !== 'VPAID') {
+ const supportLevel = playerInstance.getMediaFileTypeSupportLevel(mediaFiles[i]['type']);
+
+ if (supportLevel === 'maybe' || supportLevel === 'probably') {
+ selectedMediaFile = mediaFiles[i];
+ adSupportedType = true;
+ }
+
+ //one of the best(s) option, no need to seek more
+ if (supportLevel === 'probably') {
+ break;
+ }
+
+ if (
+ supportLevel === 'no' && mediaFiles[i].delivery === 'streaming' &&
+ (mediaFiles[i].type === 'application/vnd.apple.mpegurl' || mediaFiles[i].type === 'application/x-mpegURL')
+ ) {
+ selectedMediaFile = mediaFiles[i];
+ selectedMediaFile.isUnsuportedHls = true;
+ adSupportedType = true;
+ }
+
+ } else {
+ selectedMediaFile = mediaFiles[i];
+ adSupportedType = true;
+ break;
+ }
+ }
+ }
+
+ if (adSupportedType === false) {
+ return false;
+ }
+
+ return selectedMediaFile;
+ };
+
+ /**
+ * Reports how likely it is that the current browser will be able to play media of a given MIME type.
+ * @return string|null "probably", "maybe", "no" or null
+ */
+ playerInstance.getMediaFileTypeSupportLevel = (mediaType) => {
+ if (null === mediaType) {
+ return null;
+ }
+
+ const tmpVideo = document.createElement('video');
+ let response = tmpVideo.canPlayType(mediaType);
+
+ return !response ? "no" : response;
+ };
+
+ playerInstance.scheduleTrackingEvent = (currentTime, duration) => {
+ if (currentTime === 0) {
+ playerInstance.trackSingleEvent('start');
+ playerInstance.observe();
+ playerInstance.domRef.player.timeInView = 0;
+ }
+
+ // View Impression is defined by IAB as: Watching at least 2 seconds of the video where at least 50% of the ad’s pixels are visible on the screen
+ if (playerInstance.domRef.player.inView) {
+ if (playerInstance.domRef.player.timeInView > 2) {
+ playerInstance.trackSingleEvent('viewImpression');
+ } else {
+ playerInstance.domRef.player.timeInView += currentTime;
+ }
+ }
+
+ if ((typeof playerInstance.vastOptions.tracking['progress'] !== 'undefined') &&
+ (playerInstance.vastOptions.tracking['progress'].length) &&
+ (typeof playerInstance.vastOptions.tracking['progress'][currentTime] !== 'undefined')) {
+
+ playerInstance.trackSingleEvent('progress', currentTime);
+ }
+
+ if (currentTime === (Math.floor(duration / 4))) {
+ playerInstance.trackSingleEvent('firstQuartile');
+ }
+
+ if (currentTime === (Math.floor(duration / 2))) {
+ playerInstance.trackSingleEvent('midpoint');
+ }
+
+ if (currentTime === (Math.floor(duration * 3 / 4))) {
+ playerInstance.trackSingleEvent('thirdQuartile');
+ }
+
+ if (currentTime >= (duration - 1)) {
+ playerInstance.trackSingleEvent('complete');
+ }
+ };
+
+
+ // ADS
+ playerInstance.trackSingleEvent = (eventType, eventSubType) => {
+ if (typeof playerInstance.vastOptions === 'undefined' || playerInstance.vastOptions === null) {
+ return;
+ }
+
+ let trackingUris = [];
+ trackingUris.length = 0;
+
+ switch (eventType) {
+ case 'start':
+ case 'firstQuartile':
+ case 'midpoint':
+ case 'thirdQuartile':
+ case 'complete':
+ if (playerInstance.vastOptions.stopTracking[eventType] === false) {
+ if (playerInstance.vastOptions.tracking[eventType] !== null) {
+ trackingUris = playerInstance.vastOptions.tracking[eventType];
+ }
+
+ playerInstance.vastOptions.stopTracking[eventType] = true;
+ }
+ break;
+
+ case 'progress':
+ playerInstance.vastOptions.tracking['progress'][eventSubType].elements.forEach(function (currentValue, index) {
+ if (
+ (playerInstance.vastOptions.tracking['progress'][eventSubType].stopTracking === false) &&
+ (playerInstance.vastOptions.tracking['progress'][eventSubType].elements.length)
+ ) {
+ trackingUris = playerInstance.vastOptions.tracking['progress'][eventSubType].elements;
+ }
+
+ playerInstance.vastOptions.tracking['progress'][eventSubType].stopTracking = true;
+ });
+ break;
+
+ case 'impression':
+ if (
+ (typeof playerInstance.vastOptions.impression !== 'undefined') &&
+ (playerInstance.vastOptions.impression !== null) &&
+ (typeof playerInstance.vastOptions.impression.length !== 'undefined')
+ ) {
+ trackingUris = playerInstance.vastOptions.impression;
+ }
+ break;
+
+ case 'viewImpression':
+ if (playerInstance.vastOptions.stopTracking['viewImpression'] === true) {
+ break;
+ }
+
+ if (
+ (typeof playerInstance.vastOptions.viewImpression !== 'undefined') &&
+ (playerInstance.vastOptions.viewImpression !== null) &&
+ (typeof playerInstance.vastOptions.viewImpression.length !== 'undefined')
+ ) {
+ trackingUris = playerInstance.vastOptions.viewImpression;
+ playerInstance.vastOptions.stopTracking['viewImpression'] = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ playerInstance.callUris(trackingUris);
+ };
+
+ // ADS
+ playerInstance.completeNonLinearStatic = (ad) => {
+ playerInstance.closeNonLinear(ad.id);
+ if (playerInstance.adFinished === false) {
+ playerInstance.adFinished = true;
+ playerInstance.trackSingleEvent('complete');
+ }
+ clearInterval(playerInstance.nonLinearTracking);
+ };
+
+ // ADS
+ /**
+ * Show up a nonLinear static creative
+ */
+ playerInstance.createNonLinearStatic = (ad) => {
+ //get the proper ad
+ playerInstance.vastOptions = ad;
+ playerInstance.createBoard(ad);
+ if (playerInstance.rollsById[ad.rollListId].error === true || ad.error === true) {
+ playerInstance.announceLocalError(101);
+ return;
+ }
+ playerInstance.adFinished = false;
+ let duration = (playerInstance.rollsById[ad.rollListId].nonLinearDuration) ? playerInstance.rollsById[ad.rollListId].nonLinearDuration : false;
+ if (!playerInstance.vastOptions.vpaid) {
+ playerInstance.trackSingleEvent('start');
+ duration = duration || playerInstance.vastOptions.duration;
+
+ playerInstance.nonLinearTracking = setInterval(function () {
+ if (playerInstance.adFinished === true) {
+ return;
+ }
+
+ const currentTime = Math.floor(playerInstance.domRef.player.currentTime);
+ playerInstance.scheduleTrackingEvent(currentTime, duration);
+ if (currentTime >= (duration - 1)) {
+ playerInstance.adFinished = true;
+ }
+ }, 400);
+ playerInstance.destructors.push(() => clearInterval(playerInstance.nonLinearTracking));
+ }
+
+ const time = parseInt(playerInstance.getCurrentTime()) + parseInt(duration);
+ playerInstance.scheduleTask({ time: time, closeStaticAd: ad, rollListId: ad.rollListId });
+ };
+
+ // ADS
+ playerInstance.createVpaidNonLinearBoard = (ad) => {
+ // create iframe
+ // pass the js
+
+ playerInstance.loadVpaidNonlinearAssets = function (ad) {
+ playerInstance.vastOptions = ad;
+ playerInstance.debugMessage('starting function switchPlayerToVpaidMode');
+
+ const vAlign = (ad.vAlign) ? ad.vAlign : playerInstance.nonLinearVerticalAlign;
+ const showCloseButton = (ad.vpaidNonLinearCloseButton) ? ad.vpaidNonLinearCloseButton : playerInstance.vpaidNonLinearCloseButton;
+ const vpaidIframe = "fp_" + ad.id + "_fluid_vpaid_iframe";
+ const creativeData = {};
+ creativeData.AdParameters = ad.adParameters;
+ const slotWrapper = document.createElement('div');
+ slotWrapper.id = 'fluid_vpaidNonLinear_' + ad.id;
+ slotWrapper.className = 'fluid_vpaidNonLinear_' + vAlign;
+ slotWrapper.className += ' fluid_vpaidNonLinear_ad';
+ slotWrapper.setAttribute('adListId', ad.id);
+
+ // Default values in case nothing defined in VAST data or ad settings
+ let adWidth = Math.min(468, playerInstance.domRef.player.offsetWidth);
+ let adHeight = Math.min(60, Math.floor(playerInstance.domRef.player.offsetHeight / 4));
+
+ if (typeof ad.size !== 'undefined') {
+ const dimensions = ad.size.split('x');
+ adWidth = dimensions[0];
+ adHeight = dimensions[1];
+ } else if (ad.dimension.width && ad.dimension.height) {
+ adWidth = ad.dimension.width;
+ adHeight = ad.dimension.height;
+ }
+
+ slotWrapper.style.width = '100%';
+ slotWrapper.style.height = adHeight + 'px';
+
+ let slotFrame;
+ if (showCloseButton) {
+ const slotFrame = document.createElement('div');
+ slotFrame.className = 'fluid_vpaidNonLinear_frame';
+ slotFrame.style.width = adWidth + 'px';
+ slotFrame.style.height = adHeight + 'px';
+ slotWrapper.appendChild(slotFrame);
+
+ const closeBtn = document.createElement('div');
+ closeBtn.className = 'close_button';
+ closeBtn.innerHTML = '';
+ closeBtn.title = playerInstance.displayOptions.layoutControls.closeButtonCaption;
+ const [tempadListId] = ad.id.split('_');
+ closeBtn.onclick = function (event) {
+
+ playerInstance.hardStopVpaidAd('');
+
+ if (typeof event.stopImmediatePropagation !== 'undefined') {
+ event.stopImmediatePropagation();
+ }
+ playerInstance.adFinished = true;
+
+ //if any other onPauseRoll then render it
+ if (playerInstance.rollsById[tempadListId].roll === 'onPauseRoll' && playerInstance.onPauseRollAdPods[0]) {
+ const getNextOnPauseRollAd = playerInstance.onPauseRollAdPods[0];
+ playerInstance.createBoard(getNextOnPauseRollAd);
+ playerInstance.currentOnPauseRollAd = playerInstance.onPauseRollAdPods[0];
+ delete playerInstance.onPauseRollAdPods[0];
+ }
+
+ return false;
+ };
+
+ slotFrame.appendChild(closeBtn);
+
+ }
+
+ const slotIframe = document.createElement('iframe');
+ slotIframe.id = playerInstance.videoPlayerId + 'non_linear_vapid_slot_iframe';
+ slotIframe.className = 'fluid_vpaid_nonlinear_slot_iframe';
+ slotIframe.setAttribute('width', adWidth + 'px');
+ slotIframe.setAttribute('height', adHeight + 'px');
+ slotIframe.setAttribute('sandbox', 'allow-forms allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts');
+ slotIframe.setAttribute('frameborder', '0');
+ slotIframe.setAttribute('scrolling', 'no');
+ slotIframe.setAttribute('marginwidth', '0');
+ slotIframe.setAttribute('marginheight', '0');
+ slotWrapper.appendChild(slotIframe);
+
+ playerInstance.domRef.player.parentNode.insertBefore(slotWrapper, vpaidIframe.nextSibling);
+
+ const slotElement = slotIframe.contentWindow.document.createElement('div');
+
+ slotIframe.contentWindow.document.body.appendChild(slotElement);
+
+ playerInstance.vastOptions.slotIframe = slotIframe;
+ playerInstance.vastOptions.slotFrame = slotFrame;
+
+ const environmentVars = {
+ slot: slotElement,
+ videoSlot: playerInstance.domRef.player,
+ videoSlotCanAutoPlay: true
+ };
+
+ playerInstance.debugMessage(ad);
+
+ // calls this functions after ad unit is loaded in iframe
+ const ver = playerInstance.vpaidAdUnit.handshakeVersion(VPAID_VERSION);
+ const compare = playerInstance.compareVersion(VPAID_VERSION, ver);
+ if (compare === 1) {
+ //VPAID version of ad is lower than we need
+ ad.error = true;
+ playerInstance.playMainVideoWhenVpaidFails(403);
+ return false;
+ }
+
+ playerInstance.domRef.player.loop = false;
+ playerInstance.domRef.player.removeAttribute('controls'); //Remove the default Controls
+
+ playerInstance.vpaidCallbackListenersAttach();
+ const mode = (playerInstance.fullscreenMode ? 'fullscreen' : 'normal');
+ playerInstance.vpaidAdUnit.initAd(adWidth, adHeight, mode, 3000, creativeData, environmentVars);
+
+ playerInstance.toggleLoader(false);
+ ad.played = true;
+ playerInstance.adFinished = false;
+ };
+
+ playerInstance.loadVpaid(ad, ad.staticResource);
+
+ playerInstance.debugMessage('create non linear vpaid');
+ };
+
+ // ADS
+ playerInstance.createNonLinearBoard = (ad) => {
+ ad.played = true;
+ const board = document.createElement('div');
+ const vAlign = (playerInstance.rollsById[ad.rollListId].vAlign) ? playerInstance.rollsById[ad.rollListId].vAlign : playerInstance.nonLinearVerticalAlign;
+
+ const creative = new Image();
+ creative.src = ad.staticResource;
+ creative.id = 'fluid_nonLinear_imgCreative_' + ad.id + '_' + playerInstance.videoPlayerId;
+
+ creative.onerror = function () {
+ playerInstance.rollsById[ad.rollListId].error = true;
+ playerInstance.announceError(500);
+ };
+
+ creative.onload = function () {
+ const playerWidth = playerInstance.domRef.player.clientWidth;
+ let origWidth;
+ let origHeight;
+ let newBannerWidth;
+ let newBannerHeight;
+
+ //Set banner size based on the below priority
+ // 1. adList -> roll -> size
+ // 2. VAST XML width/height attriubute (VAST 3.)
+ // 3. VAST XML static resource dimension
+ if (typeof playerInstance.rollsById[ad.rollListId].size !== 'undefined') {
+ origWidth = playerInstance.rollsById[ad.rollListId].size.split('x')[0];
+ origHeight = playerInstance.rollsById[ad.rollListId].size.split('x')[1];
+ } else if (ad.dimension.width && ad.dimension.height) {
+ origWidth = ad.dimension.width;
+ origHeight = ad.dimension.height;
+ } else {
+ origWidth = creative.width;
+ origHeight = creative.height;
+ }
+
+ if (origWidth > playerWidth) {
+ newBannerWidth = playerWidth - 5;
+ newBannerHeight = origHeight * newBannerWidth / origWidth;
+ } else {
+ newBannerWidth = origWidth;
+ newBannerHeight = origHeight;
+ }
+
+ if (playerInstance.rollsById[ad.rollListId].roll !== 'onPauseRoll') {
+ //Show the board only if media loaded
+ const nonLinear = playerInstance.domRef.wrapper.querySelector('#fluid_nonLinear_' + ad.id);
+
+ if (nonLinear) {
+ nonLinear.style.display = ''
+ }
+ }
+
+ const img = playerInstance.domRef.wrapper.querySelector('#' + creative.id);
+ img.width = newBannerWidth;
+ img.height = newBannerHeight;
+
+ playerInstance.trackSingleEvent('impression');
+ };
+
+ board.id = 'fluid_nonLinear_' + ad.id;
+ board.className = 'fluid_nonLinear_' + vAlign;
+ board.className += ' fluid_nonLinear_ad';
+ board.innerHTML = creative.outerHTML;
+ board.style.display = 'none';
+
+ //Bind the Onclick event
+ board.onclick = function () {
+ if (typeof ad.clickthroughUrl !== 'undefined') {
+ window.open(ad.clickthroughUrl);
+ }
+
+ //Tracking the NonLinearClickTracking events
+ if (typeof ad.clicktracking !== 'undefined') {
+ playerInstance.callUris([ad.clicktracking]);
+ }
+ };
+
+ if (typeof ad.clickthroughUrl !== 'undefined') {
+ board.style.cursor = 'pointer';
+ }
+
+ const closeBtn = document.createElement('div');
+ closeBtn.className = 'close_button';
+ closeBtn.innerHTML = '';
+ closeBtn.title = playerInstance.displayOptions.layoutControls.closeButtonCaption;
+ const tempRollListId = ad.rollListId;
+ closeBtn.onclick = function (event) {
+ this.parentElement.remove();
+ if (typeof event.stopImmediatePropagation !== 'undefined') {
+ event.stopImmediatePropagation();
+ }
+ playerInstance.adFinished = true;
+ clearInterval(playerInstance.nonLinearTracking);
+
+ //if any other onPauseRoll then render it
+ if (playerInstance.rollsById[tempRollListId].roll === 'onPauseRoll' && playerInstance.onPauseRollAdPods[0]) {
+ const getNextOnPauseRollAd = playerInstance.onPauseRollAdPods[0];
+ playerInstance.createBoard(getNextOnPauseRollAd);
+ playerInstance.currentOnPauseRollAd = playerInstance.onPauseRollAdPods[0];
+ delete playerInstance.onPauseRollAdPods[0];
+ }
+
+ return false;
+ };
+
+ board.appendChild(closeBtn);
+ playerInstance.domRef.player.parentNode.insertBefore(board, playerInstance.domRef.player.nextSibling);
+ };
+
+ // ADS
+ /**
+ * Adds a nonLinear static Image banner
+ *
+ * currently only image/gif, image/jpeg, image/png supported
+ */
+ playerInstance.createBoard = (ad) => {
+ // create nonLinear Vpaid
+ // create nonLinear regular
+ if (ad.vpaid) {
+ playerInstance.hardStopVpaidAd('');
+ playerInstance.createVpaidNonLinearBoard(ad);
+ } else {
+ if (
+ typeof ad.staticResource === 'undefined' ||
+ playerInstance.supportedStaticTypes.indexOf(ad.creativeType) === -1
+ ) {
+ // Couldn’t find NonLinear resource with supported type.
+ ad.error = true;
+
+ if (!playerInstance.vastOptions || typeof playerInstance.vastOptions.errorUrl === 'undefined') {
+ playerInstance.announceLocalError(503);
+ } else {
+ playerInstance.announceError(503);
+ }
+
+ return;
+ }
+ playerInstance.createNonLinearBoard(ad);
+ }
+ };
+
+ playerInstance.closeNonLinear = (adId) => {
+ const element = playerInstance.domRef.wrapper.querySelector('#fluid_nonLinear_' + adId + ', #fluid_vpaidNonLinear_' + adId);
+ if (element) {
+ element.remove();
+ }
+ };
+
+ playerInstance.rollGroupContainsLinear = (groupedRolls) => {
+ let found = false;
+ for (let i = 0; i < groupedRolls.length; i++) {
+ if (playerInstance.rollsById[groupedRolls[i].id].adType && playerInstance.rollsById[groupedRolls[i].id].adType === 'linear') {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ };
+ playerInstance.rollGroupContainsNonlinear = (groupedRolls) => {
+ let found = false;
+ for (let i = 0; i < groupedRolls.length; i++) {
+ if (playerInstance.rollsById[groupedRolls[i].id].adType.toLowerCase() === 'nonlinear') {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ };
+
+ playerInstance.preRollFail = () => {
+ const preRollsLength = playerInstance.preRollAdPodsLength;
+
+ playerInstance.preRollVastResolved++;
+
+ if (playerInstance.preRollVastResolved === preRollsLength) {
+ playerInstance.preRollAdsPlay();
+ }
+ };
+
+ playerInstance.preRollSuccess = () => {
+ const preRollsLength = playerInstance.preRollAdPodsLength;
+
+ playerInstance.preRollVastResolved++;
+
+ if (playerInstance.preRollVastResolved === preRollsLength) {
+ playerInstance.preRollAdsPlay();
+ }
+ };
+
+ playerInstance.preRollAdsPlay = () => {
+ const time = 0;
+ const rollListIds = playerInstance.preRollAdPods;
+ const adsByType = {
+ linear: [],
+ nonLinear: []
+ };
+
+ playerInstance.firstPlayLaunched = true;
+
+ for (let index = 0; index < rollListIds.length; index++) {
+ playerInstance.rollsById[rollListIds[index]].ads.forEach(ad => {
+ if (ad.played === true) {
+ return;
+ }
+
+ if (ad.adType === 'linear') {
+ adsByType.linear.push(ad);
+ }
+
+ if (ad.adType === 'nonLinear') {
+ adsByType.nonLinear.push(ad);
+ playerInstance.scheduleTask({time: time, playRoll: 'midRoll', rollListId: ad.rollListId });
+ }
+ });
+
+ }
+
+ if (adsByType.linear.length > 0) {
+ playerInstance.toggleLoader(false);
+ playerInstance.playRoll(adsByType.linear);
+ } else {
+ playerInstance.playMainVideoWhenVastFails(900);
+ }
+
+ };
+
+ playerInstance.preRoll = (event) => {
+ const vastObj = event.vastObj;
+ playerInstance.domRef.player.removeEventListener(event.type, playerInstance.preRoll);
+
+ const rollListIds = [];
+ rollListIds[0] = event.type.replace('adId_', '');
+ const time = 0;
+
+ if (playerInstance.rollsById[rollListIds[0]].played === true) {
+ return;
+ }
+
+ playerInstance.preRollAdPods.push(rollListIds[0]);
+
+ playerInstance.preRollSuccess(vastObj);
+ };
+
+ playerInstance.createAdMarker = (adListId, time) => {
+ const markersHolder = playerInstance.domRef.wrapper.querySelector('.fluid_controls_ad_markers_holder');
+ const adMarker = document.createElement('div');
+ adMarker.className = 'fluid_controls_ad_marker fluid_controls_ad_marker_' + adListId;
+ adMarker.dataset.adListId = adListId;
+ adMarker.style.left = (time / playerInstance.mainVideoDuration * 100) + '%';
+ if (playerInstance.isCurrentlyPlayingAd) {
+ adMarker.style.display = 'none';
+ }
+ markersHolder.appendChild(adMarker);
+ };
+
+ playerInstance.hideAdMarker = (adListId) => {
+ const element = playerInstance.domRef.wrapper.querySelector('fluid_controls_ad_marker_' + adListId);
+ if (element) {
+ element.style.display = 'none';
+ }
+ };
+
+ playerInstance.showAdMarkers = () => {
+ const markersHolder = playerInstance.domRef.wrapper.querySelector('.fluid_controls_ad_markers_holder');
+ const adMarkers = markersHolder.getElementsByClassName('fluid_controls_ad_marker');
+ for (let i = 0; i < adMarkers.length; ++i) {
+ const item = adMarkers[i];
+ const rollListId = item.dataset.adListId;
+ if (playerInstance.rollsById[rollListId].played === false) {
+ item.style.display = '';
+ }
+ }
+ };
+
+ playerInstance.hideAdMarkers = () => {
+ const markersHolder = playerInstance.domRef.wrapper.querySelector('.fluid_controls_ad_markers_holder');
+ const adMarkers = markersHolder.getElementsByClassName('fluid_controls_ad_marker');
+ for (let i = 0; i < adMarkers.length; ++i) {
+ const item = adMarkers[i];
+ item.style.display = 'none';
+ }
+ };
+
+ playerInstance.midRoll = (event) => {
+ playerInstance.domRef.player.removeEventListener(event.type, playerInstance.midRoll);
+
+ const rollListId = event.type.replace('adId_', '');
+ if (playerInstance.rollsById[rollListId].played === true) {
+ return;
+ }
+
+ let time = playerInstance.rollsById[rollListId].timer;
+
+ if (typeof time == 'string' && time.indexOf("%") !== -1) {
+ time = time.replace('%', '');
+ time = Math.floor(playerInstance.mainVideoDuration / 100 * time);
+ }
+
+ if (playerInstance.displayOptions.vastOptions.showProgressbarMarkers &&
+ playerInstance.rollsById[rollListId].adType === "nonLinear") {
+ playerInstance.createAdMarker(rollListId, time);
+ }
+
+ playerInstance.scheduleTask({
+ time: time,
+ playRoll: 'midRoll',
+ rollListId
+ });
+ };
+
+ playerInstance.postRoll = (event) => {
+ playerInstance.domRef.player.removeEventListener(event.type, playerInstance.postRoll);
+ const rollListId = event.type.replace('adId_', '');
+
+ playerInstance.scheduleTask({
+ time: Math.floor(playerInstance.mainVideoDuration),
+ playRoll: 'postRoll',
+ rollListId
+ });
+ };
+
+ playerInstance.onPauseRoll = (event) => {
+ playerInstance.domRef.player.removeEventListener(event.type, playerInstance.onPauseRoll);
+ const rollListId = event.type.replace('adId_', '');
+
+ playerInstance.rollsById[rollListId].ads.forEach(ad => {
+ if (ad.adType === 'nonLinear') {
+ if (playerInstance.rollsById[ad.rollListId].error === true || ad.error === true) {
+ playerInstance.announceLocalError(101);
+ return;
+ }
+
+ const nonLinearAdExists = playerInstance.domRef.wrapper.getElementsByClassName('fluid_nonLinear_ad')[0];
+ if (!nonLinearAdExists) {
+ playerInstance.createBoard(ad);
+ playerInstance.currentOnPauseRollAd = rollListId;
+ let onPauseAd = '';
+ for (const child of playerInstance.domRef.wrapper.children) {
+ if (child.id === 'fluid_nonLinear_' + rollListId) {
+ onPauseAd = child;
+ }
+ }
+ if (onPauseAd) {
+ onPauseAd.style.display = 'none';
+ }
+ } else {
+ playerInstance.onPauseRollAdPods.push(rollListId);
+ }
+
+ }
+ });
+ };
+
+ /**
+ * Check if player has a valid nonLinear onPause Ad
+ */
+ playerInstance.hasValidOnPauseAd = () => {
+ // TODO should be only one. Add validator to allow only one onPause roll
+ const onPauseAd = playerInstance.findRoll('onPauseRoll');
+
+ return (
+ onPauseAd.length !== 0 &&
+ playerInstance.rollsById[onPauseAd[0]] &&
+ playerInstance.rollsById[onPauseAd[0]].error === false &&
+ playerInstance.rollsById[onPauseAd[0]].ads.length &&
+ playerInstance.rollsById[onPauseAd[0]].ads[0].error !== true
+ );
+ };
+
+ /**
+ * Hide/show nonLinear onPause Ad
+ */
+ playerInstance.toggleOnPauseAd = () => {
+ playerInstance.toggleLoader(false);
+ if (playerInstance.hasValidOnPauseAd() && !playerInstance.isCurrentlyPlayingAd) {
+ const onPauseRoll = playerInstance.findRoll('onPauseRoll');
+ const ad = playerInstance.rollsById[onPauseRoll].ads[0];
+
+ playerInstance.vastOptions = ad;
+ let onPauseAd = '';
+ for (const child of playerInstance.domRef.wrapper.children) {
+ if (child.id === 'fluid_nonLinear_' + ad.id) {
+ onPauseAd = child;
+ }
+ }
+
+ if (onPauseAd && playerInstance.domRef.player.paused) {
+ setTimeout(function () {
+ onPauseAd.style.display = 'flex';
+ ad.played = false;
+ playerInstance.trackingOnPauseNonLinearAd(ad, 'start');
+ }, 500);
+ } else if (onPauseAd && !playerInstance.domRef.player.paused) {
+ onPauseAd.style.display = 'none';
+ playerInstance.adFinished = true;
+ playerInstance.trackingOnPauseNonLinearAd(ad, 'complete');
+ }
+ }
+ };
+
+ /**
+ * Helper function for tracking onPause Ads
+ */
+ playerInstance.trackingOnPauseNonLinearAd = (ad, status) => {
+ if (playerInstance.rollsById[ad.rollListId].error === true || ad.error === true) {
+ playerInstance.announceLocalError(101);
+ return;
+ }
+
+ playerInstance.vastOptions = ad;
+ playerInstance.trackSingleEvent(status);
+ };
+
+ playerInstance.getLinearAdsFromKeyTime = (keyTimeLinearObj) => {
+ const adListIds = [];
+
+ for (let i = 0; i < keyTimeLinearObj.length; i++) {
+ if (playerInstance.rollsById[keyTimeLinearObj[i].adListId].played === false) {
+ adListIds.push(keyTimeLinearObj[i].adListId);
+ }
+ }
+
+ return adListIds;
+ };
+
+ /**
+ * Handle scheduled tasks for a given key time
+ *
+ * @param keyTime key time in seconds
+ */
+ playerInstance.adKeytimePlay = (keyTime) => {
+ if (!playerInstance.timerPool[keyTime] || playerInstance.isCurrentlyPlayingAd) {
+ return;
+ }
+
+ const timerPoolKeytimeCloseStaticAdsLength = playerInstance.timerPool[keyTime]['closeStaticAd'].length;
+ const timerPoolKeytimeLinearAdsLength = playerInstance.timerPool[keyTime]['linear'].length;
+ const timerPoolKeytimeNonlinearAdsLength = playerInstance.timerPool[keyTime]['nonLinear'].length;
+ const timerPoolKeytimeLoadVastLength = playerInstance.timerPool[keyTime]['loadVast'].length;
+
+ // remove the item from keytime if no ads to play
+ if ([
+ timerPoolKeytimeCloseStaticAdsLength,
+ timerPoolKeytimeLinearAdsLength,
+ timerPoolKeytimeNonlinearAdsLength,
+ timerPoolKeytimeLoadVastLength
+ ].every(timerPoolLength => timerPoolLength === 0)) {
+ delete playerInstance.timerPool[keyTime];
+ return;
+ }
+
+ // Task: close nonLinear ads
+ if (timerPoolKeytimeCloseStaticAdsLength > 0) {
+ for (let index = 0; index < timerPoolKeytimeCloseStaticAdsLength; index++) {
+ const adToClose = playerInstance.timerPool[keyTime]['closeStaticAd'][index];
+ if (adToClose.played === true) {
+ playerInstance.completeNonLinearStatic(adToClose);
+ }
+ }
+
+ // empty closeStaticAd from the timerpool after closing
+ playerInstance.timerPool[keyTime]['closeStaticAd'] = [];
+ }
+
+ // Task: play linear ads
+ if (timerPoolKeytimeLinearAdsLength > 0) {
+ if (playerInstance.timerPool[keyTime]['linear'].length > 0) {
+ playerInstance.playRoll(playerInstance.timerPool[keyTime]['linear']);
+
+ // empty the linear ads from the timerpool after played
+ playerInstance.timerPool[keyTime]['linear'] = [];
+
+ // return after starting video ad, so non-linear will not overlap
+ return;
+ }
+ }
+
+ // Task: play nonLinear ads
+ if (timerPoolKeytimeNonlinearAdsLength > 0) {
+ for (let index = 0; index < timerPoolKeytimeNonlinearAdsLength; index++) {
+ const ad = playerInstance.timerPool[keyTime]['nonLinear'][index];
+ const rollListId = ad.rollListId;
+ const vastOptions = playerInstance.adPool[rollListId];
+
+ // we are not supporting nonLinear ads in cardBoard mode
+ if (ad.played === false && !playerInstance.displayOptions.layoutControls.showCardBoardView) {
+ playerInstance.createNonLinearStatic(ad);
+ if (playerInstance.displayOptions.vastOptions.showProgressbarMarkers) {
+ playerInstance.hideAdMarker(rollListId);
+ }
+
+ // delete nonLinear after playing
+ playerInstance.timerPool[keyTime]['nonLinear'].splice(index, 1);
+
+ // return after starting non-linear ad, so multiple non-linear will not overlap
+ // unplayed non-linear will appear if user seeks back to the time :)
+ return;
+ }
+ }
+ }
+
+ // Task: Load VAST on demand
+ if (timerPoolKeytimeLoadVastLength > 0) {
+ playerInstance.timerPool[keyTime]['loadVast'].forEach((roll) => {
+ if (roll.roll === `postRoll` && roll.voidPostRollTasks) {
+ // As postRoll schedules more than one task to cover the last few seconds of the video, we need to
+ // prevent any other loadVast task from running for that postRoll
+ return;
+ } else if (roll.roll === `postRoll`) {
+ roll.voidPostRollTasks = true;
+ }
+
+ playerInstance.debugMessage(`Handling on-demand VAST load for roll ${roll.id}`)
+ playerInstance.processVastWithRetries(roll);
+ });
+
+ playerInstance.timerPool[keyTime]['loadVast'] = [];
+ }
+ };
+
+ playerInstance.adTimer = () => {
+ if (!!playerInstance.isTimer) {
+ return;
+ }
+
+ playerInstance.isTimer = !playerInstance.isTimer;
+
+ playerInstance.timer = setInterval(
+ function () {
+ const keyTime = Math.floor(playerInstance.getCurrentTime());
+ playerInstance.adKeytimePlay(keyTime)
+ }, 800);
+ playerInstance.destructors.push(() => clearInterval(playerInstance.timer));
+ };
+
+ /**
+ * Schedule tasks that need to be run with the main video timer
+ *
+ * @param {{ time: number, rollListId: any, loadVast: any }} task
+ */
+ playerInstance.scheduleTask = (task) => {
+ if (task.time > playerInstance.mainVideoDuration || task.time < 0 || Number.isNaN(task.time)) {
+ console.warn(`Scheduled task has invalid time`, task.time, '. Check your configuration.');
+ return;
+ }
+
+ playerInstance.debugMessage(`Scheduling task`, task);
+
+ if (!playerInstance.timerPool.hasOwnProperty(task.time)) {
+ playerInstance.timerPool[task.time] = {linear: [], nonLinear: [], closeStaticAd: [], loadVast: []};
+ }
+
+ // Handle AD rendering
+ if (task.rollListId) {
+ const roll = playerInstance.rollsById[task.rollListId];
+
+ roll.ads
+ .filter(({ adType }) => {
+ if (task.time === 0) { // Only non-linear should be scheduled on "preRoll"
+ return adType !== 'linear';
+ }
+
+ return true;
+ })
+ .forEach(ad => {
+ if (task.hasOwnProperty('playRoll') && ad.adType === 'linear') {
+ playerInstance.timerPool[task.time]['linear'].push(ad);
+ } else if (task.hasOwnProperty('playRoll') && ad.adType === 'nonLinear') {
+ playerInstance.timerPool[task.time]['nonLinear'].push(ad);
+ } else if (task.hasOwnProperty('closeStaticAd')) {
+ playerInstance.timerPool[task.time]['closeStaticAd'].push(ad);
+ }
+ });
+ }
+
+ // Handle Loading VAST on demand
+ if (task.loadVast) {
+ playerInstance.timerPool[task.time]['loadVast'].push(task.roll)
+ }
+ };
+
+ /**
+ * Adds on demand rolls (midRoll, postRoll) to schedule
+ */
+ playerInstance.scheduleOnDemandRolls = () => {
+ const midRollListIds = playerInstance.findRoll(`midRoll`) || [];
+ const postRollListIds = playerInstance.findRoll(`postRoll`) || [];
+
+ [...midRollListIds, ...postRollListIds]
+ .map(rollListId => playerInstance.rollsById[rollListId])
+ .filter(rollAd => rollAd.vastLoaded !== true && rollAd.error !== true)
+ .forEach(rollAd => {
+ // Request will have the vastTimeout time to load
+ if (rollAd.roll === `midRoll`) {
+ if (typeof rollAd.timer === 'string') {
+ // This can result in NaN, in that case the midRoll will simply not happen (user configuration error)
+ rollAd.timer = Math.floor(playerInstance.mainVideoDuration / 100 * rollAd.timer.replace('%', ''));
+ playerInstance.debugMessage(`Replaced midRoll from percentage to timer value ${rollAd.timer} seconds`);
+ }
+
+ const time = rollAd.timer - (playerInstance.displayOptions.vastOptions.vastTimeout / 1000);
+
+ // Handles cases where the midRoll should be loaded now, skipping the task scheduler
+ if (time <= Number(playerInstance.getCurrentTime())) {
+ playerInstance.debugMessage(`Loading Mid Roll VAST immediately as it needs to be played soon`);
+ playerInstance.processVastWithRetries(rollAd);
+ } else {
+ playerInstance.scheduleTask({ loadVast: true, time, roll: rollAd })
+ }
+ } else {
+ const backwardScheduleTime = parseInt(playerInstance.mainVideoDuration);
+ const scheduleTimeAmount = (playerInstance.displayOptions.vastOptions.vastTimeout / 1000);
+
+ // Used to prevent loading more than one of the tasks bellow
+ rollAd.voidPostRollTasks = false;
+
+ for (let i = 1; i <= scheduleTimeAmount; i++) {
+ // Sets tasks for the last N seconds based on vastTimeout
+ playerInstance.scheduleTask({ loadVast: true, time: backwardScheduleTime - i, roll: rollAd });
+ }
+
+ }
+ });
+ }
+
+ // ADS
+ playerInstance.switchToMainVideo = () => {
+ playerInstance.debugMessage('starting main video');
+
+ playerInstance.domRef.player.src = playerInstance.originalSrc;
+
+ playerInstance.currentMediaSourceType = 'source';
+
+ playerInstance.initialiseStreamers();
+
+ const newCurrentTime = (typeof playerInstance.domRef.player.mainVideoCurrentTime !== 'undefined')
+ ? Math.floor(playerInstance.domRef.player.mainVideoCurrentTime) : 0;
+
+ if (playerInstance.domRef.player.hasOwnProperty('currentTime')) {
+ playerInstance.domRef.player.currentTime = newCurrentTime;
+ }
+
+ if (playerInstance.displayOptions.layoutControls.loop) {
+ playerInstance.domRef.player.loop = true;
+ }
+
+ playerInstance.setCurrentTimeAndPlay(newCurrentTime, playerInstance.autoplayAfterAd);
+
+ playerInstance.isCurrentlyPlayingAd = false;
+
+ playerInstance.deleteVastAdElements();
+
+ playerInstance.adFinished = true;
+ playerInstance.displayOptions.vastOptions.vastAdvanced.vastVideoEndedCallback();
+ playerInstance.vastOptions = null;
+
+ playerInstance.setBuffering();
+ const progressbarContainer = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+
+ if (progressbarContainer !== null) {
+ const backgroundColor = (playerInstance.displayOptions.layoutControls.primaryColor) ? playerInstance.displayOptions.layoutControls.primaryColor : "white";
+
+ const currentProgressBar = playerInstance.domRef.player.parentNode.getElementsByClassName('fluid_controls_currentprogress');
+
+ for (let i = 0; i < currentProgressBar.length; i++) {
+ currentProgressBar[i].style.backgroundColor = backgroundColor;
+ }
+ }
+
+ playerInstance.domRef.player.removeEventListener('ended', playerInstance.onVastAdEnded);
+
+ if (playerInstance.displayOptions.vastOptions.showProgressbarMarkers) {
+ playerInstance.showAdMarkers();
+ }
+
+ if (playerInstance.hasTitle()) {
+ const title = playerInstance.domRef.wrapper.querySelector('.fp_title');
+ title.style.display = 'inline';
+ }
+ };
+
+ // ADS
+ playerInstance.getNextAdPod = () => {
+ if (playerInstance.temporaryAdPods.length > 0) {
+ return playerInstance.temporaryAdPods.shift();
+ }
+
+ return null;
+ };
+
+ // ADS
+ playerInstance.checkForNextAd = () => {
+ const availableNextAdID = playerInstance.getNextAdPod();
+ if (availableNextAdID === null) {
+ playerInstance.switchToMainVideo();
+ playerInstance.vastOptions = null;
+ playerInstance.adFinished = true;
+ } else {
+ playerInstance.domRef.player.removeEventListener('ended', playerInstance.onVastAdEnded);
+ playerInstance.isCurrentlyPlayingAd = false;
+ playerInstance.vastOptions = null;
+ playerInstance.adFinished = true;
+ playerInstance.renderLinearAd(availableNextAdID, false); // passing false so it doesn't backup the Ad playbacktime as video playback time
+ }
+ };
+
+
+ /**
+ * Adds a Skip Button
+ */
+ playerInstance.addSkipButton = () => {
+ // TODO: ahh yes, the DIVbutton...
+ const divSkipButton = document.createElement('div');
+ divSkipButton.className = 'skip_button skip_button_disabled';
+ if (playerInstance.vastOptions.skipoffset > 0) {
+ divSkipButton.innerHTML = playerInstance.displayOptions.vastOptions.skipButtonCaption.replace('[seconds]', playerInstance.vastOptions.skipoffset);
+ }
+
+ playerInstance.domRef.wrapper.appendChild(divSkipButton);
+
+ if (playerInstance.vastOptions.skipoffset === 0) {
+ playerInstance.decreaseSkipOffset();
+ }
+
+ playerInstance.domRef.player.addEventListener('timeupdate', playerInstance.decreaseSkipOffset, false);
+ };
+
+ /**
+ * Ad Countdown
+ */
+ playerInstance.addAdCountdown = () => {
+ if ((playerInstance.isCurrentlyPlayingAd && playerInstance.hlsPlayer) || playerInstance.currentVideoDuration === Infinity) {
+ return; // Shouldn't show countdown if ad is a video live stream
+ }
+
+ const videoWrapper = playerInstance.domRef.wrapper;
+ const divAdCountdown = document.createElement('div');
+
+ // Create element
+ const adCountdown = playerInstance.pad(parseInt(playerInstance.currentVideoDuration / 60)) + ':' + playerInstance.pad(parseInt(playerInstance.currentVideoDuration % 60));
+ const durationText = parseInt(adCountdown);
+ divAdCountdown.className = 'ad_countdown';
+ divAdCountdown.innerHTML = "Ad - " + durationText;
+
+ videoWrapper.appendChild(divAdCountdown);
+
+ playerInstance.domRef.player.addEventListener('timeupdate', playerInstance.decreaseAdCountdown, false);
+ videoWrapper.addEventListener('mouseover', function () {
+ divAdCountdown.style.display = 'none';
+ }, false);
+ };
+
+ playerInstance.decreaseAdCountdown = function decreaseAdCountdown() {
+ const sec = parseInt(playerInstance.currentVideoDuration) - parseInt(playerInstance.domRef.player.currentTime);
+ const btn = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+
+ if (btn && isNaN(sec)) {
+ btn.parentNode.removeChild(btn);
+ return;
+ }
+
+ if (btn) {
+ btn.innerHTML = "Ad - " + playerInstance.pad(parseInt(sec / 60)) + ':' + playerInstance.pad(parseInt(sec % 60));
+ } else {
+ playerInstance.domRef.player.removeEventListener('timeupdate', playerInstance.decreaseAdCountdown);
+ }
+ };
+
+ playerInstance.removeAdCountdown = () => {
+ const btn = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+ if (btn) {
+ btn.parentElement.removeChild(btn);
+ }
+ };
+
+ playerInstance.toggleAdCountdown = (showing) => {
+ const btn = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+ if (btn) {
+ if (showing) {
+ btn.style.display = 'inline-block';
+ } else {
+ btn.style.display = 'none';
+ }
+ }
+ };
+
+ playerInstance.addAdPlayingText = (textToShow) => {
+ const adPlayingDiv = document.createElement('div');
+
+ if (playerInstance.displayOptions.layoutControls.primaryColor) {
+ adPlayingDiv.style.backgroundColor = playerInstance.displayOptions.layoutControls.primaryColor;
+ adPlayingDiv.style.opacity = 1;
+ }
+
+ adPlayingDiv.className = 'fluid_ad_playing';
+ adPlayingDiv.innerText = textToShow;
+
+ playerInstance.domRef.wrapper.appendChild(adPlayingDiv);
+ };
+
+ playerInstance.positionTextElements = (adListData) => {
+ const allowedPosition = ['top left', 'top right', 'bottom left', 'bottom right'];
+
+ const skipButton = playerInstance.domRef.wrapper.querySelector('.skip_button');
+ const adPlayingDiv = playerInstance.domRef.wrapper.querySelector('.fluid_ad_playing');
+ const ctaButton = playerInstance.domRef.wrapper.querySelector('.fluid_ad_cta');
+
+ let ctaButtonHeightWithSpacing = 0;
+ let adPlayingDivHeightWithSpacing = 0;
+ const pixelSpacing = 8;
+ let isBottom = false;
+ let skipButtonHeightWithSpacing = 0;
+ let positionsCTA = [];
+
+ const defaultPositions = {
+ top: {
+ left: { h: 34, v: 34 },
+ right: { h: 0, v: 34 },
+ },
+ bottom: {
+ left: { h: 34, v: 50 },
+ right: { h: 0, v: 50 },
+ }
+ };
+
+ if (skipButton !== null) {
+ skipButtonHeightWithSpacing = skipButton.offsetHeight + pixelSpacing;
+
+ const wrapperElement = playerInstance.domRef.wrapper;
+
+ if (wrapperElement.classList.contains('mobile')) {
+ defaultPositions.top = {
+ left: { h: 0, v: 8 },
+ right: { h: 0, v: 8 },
+ }
+ defaultPositions.bottom = {
+ left: { h: 0, v: 50 },
+ right: { h: 0, v: 50 },
+ }
+ }
+ }
+
+ let CTATextPosition;
+ if (ctaButton !== null) {
+ CTATextPosition = playerInstance.rollsById[adListData.rollListId].adCTATextPosition ?
+ playerInstance.rollsById[adListData.rollListId].adCTATextPosition.toLowerCase() :
+ playerInstance.displayOptions.vastOptions.adCTATextPosition;
+
+ if (allowedPosition.indexOf(CTATextPosition) === -1) {
+ console.log('[FP Error] Invalid position for CTAText. Reverting to "bottom right"');
+ CTATextPosition = 'bottom right';
+ }
+
+ ctaButton.classList.add.apply(ctaButton.classList, CTATextPosition.split(' '));
+
+ positionsCTA = CTATextPosition.split(' ');
+
+ isBottom = positionsCTA[0] === 'bottom';
+
+ ctaButton.style[positionsCTA[0]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].v + 'px';
+ ctaButton.style[positionsCTA[1]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].h + 'px';
+
+ if (isBottom && positionsCTA[1] === 'right') {
+ ctaButton.style[positionsCTA[0]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].v + skipButtonHeightWithSpacing + 'px';
+ }
+
+ ctaButtonHeightWithSpacing = ctaButton.offsetHeight + pixelSpacing + 'px';
+ }
+
+ let adPlayingDivPosition;
+ let positionsAdText;
+ if (adPlayingDiv !== null) {
+ adPlayingDivPosition = playerInstance.rollsById[adListData.rollListId].adTextPosition ?
+ playerInstance.rollsById[adListData.rollListId].adTextPosition.toLowerCase() :
+ playerInstance.displayOptions.vastOptions.adTextPosition;
+
+ if (allowedPosition.indexOf(adPlayingDivPosition) === -1) {
+ console.log('[FP Error] Invalid position for adText. Reverting to "top left"');
+ adPlayingDivPosition = 'top left';
+ }
+
+ positionsAdText = adPlayingDivPosition.split(' ');
+ adPlayingDiv.style[positionsAdText[0]] = defaultPositions[positionsAdText[0]][positionsAdText[1]].v + 'px';
+ adPlayingDiv.style[positionsAdText[1]] = defaultPositions[positionsAdText[0]][positionsAdText[1]].h + 'px';
+ adPlayingDivHeightWithSpacing = adPlayingDiv.offsetHeight + pixelSpacing + 'px';
+ }
+
+ if (ctaButtonHeightWithSpacing > 0 && adPlayingDivHeightWithSpacing > 0 && CTATextPosition === adPlayingDivPosition) {
+ if (isBottom) {
+ if (positionsCTA[1] === 'right') {
+ adPlayingDiv.style.bottom = defaultPositions[positionsAdText[0]][positionsAdText[1]].v + skipButtonHeightWithSpacing + ctaButtonHeightWithSpacing + 'px';
+ } else {
+ adPlayingDiv.style.bottom = defaultPositions[positionsAdText[0]][positionsAdText[1]].v + ctaButtonHeightWithSpacing + 'px';
+ }
+ } else {
+ ctaButton.style.top = defaultPositions[positionsCTA[0]][positionsCTA[1]].v + adPlayingDivHeightWithSpacing + 'px';
+ }
+ }
+ };
+
+ playerInstance.removeAdPlayingText = () => {
+ const div = playerInstance.domRef.wrapper.querySelector('.fluid_ad_playing');
+ if (!div) {
+ return;
+ }
+ div.parentElement.removeChild(div);
+ };
+
+ /**
+ * Adds CTA button from VAST, with fallback to IconClickTrough
+ *
+ * @param {string} landingPage
+ */
+ playerInstance.addCTAButton = (landingPage) => {
+ if (playerInstance.vastOptions.titleCTA) {
+ const { text, link, tracking } = playerInstance.vastOptions.titleCTA;
+ return playerInstance.createAndAppendCTAButton(text, link, tracking);
+ }
+
+ if (landingPage && typeof playerInstance.displayOptions.vastOptions.adCTAText === 'string') {
+ return playerInstance.createAndAppendCTAButton(
+ playerInstance.displayOptions.vastOptions.adCTAText,
+ landingPage,
+ playerInstance.vastOptions.clickthroughUrl
+ );
+ }
+ };
+
+ /**
+ * Creates and append CTA button given the input parameters
+ *
+ * @param {string} adCTAText
+ *
+ * @param {string} displayUrl
+ *
+ * @param {string} trackingUrl
+ */
+ playerInstance.createAndAppendCTAButton = (adCTAText, displayUrl, trackingUrl) => {
+ const ctaButton = document.createElement('div');
+ ctaButton.className = 'fluid_ad_cta';
+
+ const link = document.createElement('span');
+ let innerHTML = adCTAText;
+
+ if (displayUrl) {
+ innerHTML += "" + displayUrl + " "
+ }
+
+ link.innerHTML = innerHTML;
+
+ ctaButton.addEventListener('click', () => {
+ if (!playerInstance.domRef.player.paused) {
+ playerInstance.domRef.player.pause();
+ }
+
+ const win = window.open(trackingUrl, '_blank');
+ win.focus();
+ return true;
+ }, false);
+
+ ctaButton.appendChild(link);
+
+ playerInstance.domRef.wrapper.appendChild(ctaButton);
+ };
+
+ playerInstance.removeCTAButton = () => {
+ const btn = playerInstance.domRef.wrapper.querySelector('.fluid_ad_cta');
+ if (!btn) {
+ return;
+ }
+
+ btn.parentElement.removeChild(btn);
+ };
+
+ playerInstance.decreaseSkipOffset = () => {
+ if (typeof playerInstance.vastOptions === 'undefined' || playerInstance.vastOptions === null) {
+ return;
+ }
+ let sec = playerInstance.vastOptions.skipoffset - Math.floor(playerInstance.domRef.player.currentTime);
+ const btn = playerInstance.domRef.wrapper.querySelector('.skip_button');
+
+ if (!btn) {
+ playerInstance.domRef.player.removeEventListener('timeupdate', playerInstance.decreaseSkipOffset);
+ return;
+ }
+
+ if (sec >= 1) {
+ //set the button label with the remaining seconds
+ btn.innerHTML = playerInstance.displayOptions.vastOptions.skipButtonCaption.replace('[seconds]', sec);
+ return;
+ }
+
+ // TODO: refactored, but this is still terrible - remove all this and just make the button clickable...
+ const skipLink = document.createElement('a');
+ skipLink.href = '#';
+ skipLink.className = 'js-skipHref';
+ skipLink.innerHTML = playerInstance.displayOptions.vastOptions.skipButtonClickCaption;
+ skipLink.onclick = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ playerInstance.pressSkipButton();
+ };
+
+ btn.innerHTML = '';
+ btn.appendChild(skipLink);
+
+ //removes the CSS class for a disabled button
+ btn.className = btn.className.replace(/\bskip_button_disabled\b/, '');
+
+ playerInstance.domRef.player.removeEventListener('timeupdate', playerInstance.decreaseSkipOffset);
+ };
+
+ playerInstance.pressSkipButton = () => {
+ playerInstance.removeSkipButton();
+ playerInstance.removeAdPlayingText();
+ playerInstance.removeCTAButton();
+
+ if (playerInstance.vastOptions.vpaid) {
+ // skip the linear vpaid ad
+ playerInstance.skipVpaidAd();
+ return;
+ }
+
+ // skip the regular linear vast
+ playerInstance.displayOptions.vastOptions.vastAdvanced.vastVideoSkippedCallback();
+ const event = document.createEvent('Event');
+ event.initEvent('ended', false, true);
+ playerInstance.domRef.player.dispatchEvent(event);
+ };
+
+ playerInstance.removeSkipButton = () => {
+ const btn = playerInstance.domRef.wrapper.querySelector('.skip_button');
+ if (btn) {
+ btn.parentElement.removeChild(btn);
+ }
+ };
+
+ /**
+ * Makes the player open the ad URL on clicking
+ */
+ playerInstance.addClickthroughLayer = () => {
+ const divWrapper = playerInstance.domRef.wrapper;
+
+ const divClickThrough = document.createElement('div');
+ divClickThrough.className = 'vast_clickthrough_layer';
+ divClickThrough.setAttribute(
+ 'style',
+ 'position: absolute; cursor: pointer; top: 0; left: 0; width: ' +
+ playerInstance.domRef.player.offsetWidth + 'px; height: ' +
+ (playerInstance.domRef.player.offsetHeight) + 'px;'
+ );
+
+ divWrapper.appendChild(divClickThrough);
+
+ //Bind the Onclick event
+ const openClickthrough = function () {
+ window.open(playerInstance.vastOptions.clickthroughUrl);
+
+ //Tracking the Clickthorugh events
+ if (typeof playerInstance.vastOptions.clicktracking !== 'undefined') {
+ playerInstance.callUris(playerInstance.vastOptions.clicktracking);
+ }
+ };
+
+ const clickthroughLayer = playerInstance.domRef.wrapper.querySelector('.vast_clickthrough_layer');
+ const isIos9orLower = (playerInstance.mobileInfo.device === 'iPhone') && (playerInstance.mobileInfo.userOsMajor !== false) && (playerInstance.mobileInfo.userOsMajor <= 9);
+
+ clickthroughLayer.onclick = () => {
+ if (playerInstance.domRef.player.paused) {
+ //On Mobile Safari on iPhones with iOS 9 or lower open the clickthrough only once
+ if (isIos9orLower && !playerInstance.suppressClickthrough) {
+ openClickthrough();
+ playerInstance.suppressClickthrough = true;
+
+ } else {
+ playerInstance.domRef.player.play();
+ }
+
+ } else {
+ openClickthrough();
+ playerInstance.domRef.player.pause();
+ }
+ };
+ };
+
+ /**
+ * Remove the Clickthrough layer
+ */
+ playerInstance.removeClickthrough = () => {
+ const clickthroughLayer = playerInstance.domRef.wrapper.querySelector('.vast_clickthrough_layer');
+
+ if (clickthroughLayer) {
+ clickthroughLayer.parentNode.removeChild(clickthroughLayer);
+ }
+ };
+}
+
+export default adSupport
diff --git a/client/fluid-player/src/modules/cardboard.js b/client/fluid-player/src/modules/cardboard.js
new file mode 100644
index 0000000..a528c4e
--- /dev/null
+++ b/client/fluid-player/src/modules/cardboard.js
@@ -0,0 +1,343 @@
+export default function (playerInstance, options) {
+ playerInstance.createCardboardJoystickButton = (identity) => {
+ const vrJoystickPanel = playerInstance.domRef.wrapper.querySelector('.fluid_vr_joystick_panel');
+ const joystickButton = document.createElement('div');
+
+ joystickButton.className = 'fluid_vr_button fluid_vr_joystick_' + identity;
+ vrJoystickPanel.appendChild(joystickButton);
+
+ return joystickButton;
+ };
+
+ playerInstance.cardboardRotateLeftRight = (param /* 0 - right, 1 - left */) => {
+ const go = playerInstance.vrROTATION_POSITION;
+ const back = -playerInstance.vrROTATION_POSITION;
+ const pos = param < 1 ? go : back;
+ const easing = {val: pos};
+ const tween = new TWEEN.Tween(easing)
+ .to({val: 0}, playerInstance.vrROTATION_SPEED)
+ .easing(TWEEN.Easing.Quadratic.InOut)
+ .onUpdate(function () {
+ playerInstance.vrViewer.OrbitControls.rotateLeft(easing.val)
+ }).start();
+ };
+
+ playerInstance.cardboardRotateUpDown = (param /* 0 - down, 1- up */) => {
+ const go = playerInstance.vrROTATION_POSITION;
+ const back = -playerInstance.vrROTATION_POSITION;
+ const pos = param < 1 ? go : back;
+ const easing = {val: pos};
+ const tween = new TWEEN.Tween(easing)
+ .to({val: 0}, playerInstance.vrROTATION_SPEED)
+ .easing(TWEEN.Easing.Quadratic.InOut)
+ .onUpdate(function () {
+ playerInstance.vrViewer.OrbitControls.rotateUp(easing.val)
+ }).start();
+ };
+
+ playerInstance.createCardboardJoystick = () => {
+ const vrContainer = playerInstance.domRef.wrapper.querySelector('.fluid_vr_container');
+
+ // Create a JoyStick and append to VR container
+ const vrJoystickPanel = document.createElement('div');
+ vrJoystickPanel.className = 'fluid_vr_joystick_panel';
+ vrContainer.appendChild(vrJoystickPanel);
+
+ // Create Joystick buttons
+ const upButton = playerInstance.createCardboardJoystickButton('up');
+ const leftButton = playerInstance.createCardboardJoystickButton('left');
+ const rightButton = playerInstance.createCardboardJoystickButton('right');
+ const downButton = playerInstance.createCardboardJoystickButton('down');
+ const zoomDefaultButton = playerInstance.createCardboardJoystickButton('zoomdefault');
+ const zoomInButton = playerInstance.createCardboardJoystickButton('zoomin');
+ const zoomOutButton = playerInstance.createCardboardJoystickButton('zoomout');
+
+ // Camera movement buttons
+ upButton.addEventListener('click', function () {
+ //player.vrViewer.OrbitControls.rotateUp(-0.1);
+ playerInstance.cardboardRotateUpDown(1);
+ });
+
+ downButton.addEventListener('click', function () {
+ //player.vrViewer.OrbitControls.rotateUp(0.1);
+ playerInstance.cardboardRotateUpDown(0);
+ });
+
+ rightButton.addEventListener('click', function () {
+ //player.vrViewer.OrbitControls.rotateLeft(0.1);
+ playerInstance.cardboardRotateLeftRight(0);
+ });
+
+ leftButton.addEventListener('click', function () {
+ //player.vrViewer.OrbitControls.rotateLeft(-0.1);
+ playerInstance.cardboardRotateLeftRight(1);
+ });
+
+ zoomDefaultButton.addEventListener('click', function () {
+ playerInstance.vrViewer.camera.fov = 60;
+ playerInstance.vrViewer.camera.updateProjectionMatrix();
+ });
+
+ // Camera Zoom buttons
+ zoomOutButton.addEventListener('click', function () {
+ playerInstance.vrViewer.camera.fov *= 1.1;
+ playerInstance.vrViewer.camera.updateProjectionMatrix();
+ });
+
+ zoomInButton.addEventListener('click', function () {
+ playerInstance.vrViewer.camera.fov *= 0.9;
+ playerInstance.vrViewer.camera.updateProjectionMatrix();
+ });
+
+ };
+
+ playerInstance.cardBoardResize = () => {
+ playerInstance.domRef.player.removeEventListener('theatreModeOn', handleWindowResize);
+ playerInstance.domRef.player.addEventListener('theatreModeOn', handleWindowResize);
+
+ playerInstance.domRef.player.removeEventListener('theatreModeOff', handleWindowResize);
+ playerInstance.domRef.player.addEventListener('theatreModeOff', handleWindowResize);
+ };
+
+ function handleWindowResize() {
+ playerInstance.vrViewer.onWindowResize();
+ }
+
+ playerInstance.cardBoardSwitchToNormal = () => {
+ const vrJoystickPanel = playerInstance.domRef.wrapper.querySelector('.fluid_vr_joystick_panel');
+ const controlBar = playerInstance.domRef.wrapper.querySelector('.fluid_controls_container')
+ const videoPlayerTag = playerInstance.domRef.player;
+
+ playerInstance.vrViewer.enableEffect(PANOLENS.MODES.NORMAL);
+ playerInstance.vrViewer.onWindowResize();
+ playerInstance.vrMode = false;
+
+ // remove dual control bar
+ const newControlBar = videoPlayerTag.parentNode.getElementsByClassName('fluid_vr2_controls_container')[0];
+ videoPlayerTag.parentNode.removeChild(newControlBar);
+
+ if (playerInstance.displayOptions.layoutControls.showCardBoardJoystick && vrJoystickPanel) {
+ vrJoystickPanel.style.display = "block";
+ }
+ controlBar.classList.remove("fluid_vr_controls_container");
+
+ // show volume control bar
+ const volumeContainer = playerInstance.domRef.wrapper.getElementById('.fluid_control_volume_container');
+ volumeContainer.style.display = "block";
+
+ // show all ads overlays if any
+ const adCountDownTimerText = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+ const ctaButton = playerInstance.domRef.wrapper.querySelector('.fluid_ad_cta');
+ const addAdPlayingTextOverlay = playerInstance.domRef.wrapper.querySelector('.fluid_ad_playing');
+ const skipBtn = playerInstance.domRef.wrapper.querySelector('.skip_button');
+
+ if (adCountDownTimerText) {
+ adCountDownTimerText.style.display = 'block';
+ }
+
+ if (ctaButton) {
+ ctaButton.style.display = 'block';
+ }
+
+ if (addAdPlayingTextOverlay) {
+ addAdPlayingTextOverlay.style.display = 'block';
+ }
+
+ if (skipBtn) {
+ skipBtn.style.display = 'block';
+ }
+ };
+
+ playerInstance.cardBoardHideDefaultControls = () => {
+ const vrJoystickPanel = playerInstance.domRef.wrapper.querySelector('.fluid_vr_joystick_panel');
+ const initialPlay = playerInstance.domRef.wrapper.querySelector('.fluid_initial_play');
+ const volumeContainer = playerInstance.domRef.wrapper.querySelector('.fluid_control_volume_container');
+
+ // hide the joystick in VR mode
+ if (playerInstance.displayOptions.layoutControls.showCardBoardJoystick && vrJoystickPanel) {
+ vrJoystickPanel.style.display = "none";
+ }
+
+ // hide big play icon
+ if (initialPlay) {
+ playerInstance.domRef.wrapper.querySelector('.fluid_initial_play').style.display = "none";
+ playerInstance.domRef.wrapper.querySelector('.fluid_initial_play_button_container').style.opacity = "1";
+ }
+
+ // hide volume control bar
+ volumeContainer.style.display = "none";
+
+ };
+
+ playerInstance.cardBoardCreateVRControls = () => {
+ const controlBar = playerInstance.domRef.wrapper.querySelector('.fluid_controls_container')
+
+ // create and append dual control bar
+ const newControlBar = controlBar.cloneNode(true);
+ newControlBar.removeAttribute('id');
+ newControlBar.querySelectorAll('*').forEach(function (node) {
+ node.removeAttribute('id');
+ });
+
+ newControlBar.classList.add("fluid_vr2_controls_container");
+ playerInstance.domRef.player.parentNode.insertBefore(newControlBar, playerInstance.domRef.player.nextSibling);
+ playerInstance.copyEvents(newControlBar);
+ };
+
+ playerInstance.cardBoardSwitchToVR = () => {
+ const controlBar = playerInstance.domRef.wrapper.querySelector('.fluid_controls_container')
+
+ playerInstance.vrViewer.enableEffect(PANOLENS.MODES.CARDBOARD);
+
+ playerInstance.vrViewer.onWindowResize();
+ playerInstance.vrViewer.disableReticleControl();
+
+ playerInstance.vrMode = true;
+
+ controlBar.classList.add("fluid_vr_controls_container");
+
+ playerInstance.cardBoardHideDefaultControls();
+ playerInstance.cardBoardCreateVRControls();
+
+ // hide all ads overlays
+ const adCountDownTimerText = playerInstance.domRef.wrapper.querySelector('.ad_countdown');
+ const ctaButton = playerInstance.domRef.wrapper.querySelector('.fluid_ad_cta');
+ const addAdPlayingTextOverlay = playerInstance.domRef.wrapper.querySelector('.fluid_ad_playing');
+ const skipBtn = playerInstance.domRef.wrapper.querySelector('.skip_button');
+
+ if (adCountDownTimerText) {
+ adCountDownTimerText.style.display = 'none';
+ }
+
+ if (ctaButton) {
+ ctaButton.style.display = 'none';
+ }
+
+ if (addAdPlayingTextOverlay) {
+ addAdPlayingTextOverlay.style.display = 'none';
+ }
+
+ if (skipBtn) {
+ skipBtn.style.display = 'none';
+ }
+
+ };
+
+ playerInstance.cardBoardMoveTimeInfo = () => {
+ const timePlaceholder = playerInstance.domRef.wrapper.querySelector('.fluid_control_duration');
+ const controlBar = playerInstance.domRef.wrapper.querySelector('.fluid_controls_container')
+
+ timePlaceholder.classList.add("cardboard_time");
+ controlBar.appendChild(timePlaceholder);
+
+ // override the time display function for this instance
+ playerInstance.controlDurationUpdate = function () {
+
+ const currentPlayTime = playerInstance.formatTime(playerInstance.domRef.player.currentTime);
+ const totalTime = playerInstance.formatTime(playerInstance.currentVideoDuration);
+ const timePlaceholder = playerInstance.domRef.player.parentNode.getElementsByClassName('fluid_control_duration');
+
+ let durationText = '';
+
+ if (playerInstance.isCurrentlyPlayingAd) {
+ durationText = "AD : " + currentPlayTime + ' / ' + totalTime;
+
+ for (let i = 0; i < timePlaceholder.length; i++) {
+ timePlaceholder[i].classList.add("ad_timer_prefix");
+ }
+
+ } else {
+ durationText = currentPlayTime + ' / ' + totalTime;
+
+ for (let i = 0; i < timePlaceholder.length; i++) {
+ timePlaceholder[i].classList.remove("ad_timer_prefix");
+ }
+ }
+
+ for (let i = 0; i < timePlaceholder.length; i++) {
+ timePlaceholder[i].innerHTML = durationText;
+ }
+ }
+ };
+
+ playerInstance.cardBoardAlterDefaultControls = () => {
+ playerInstance.cardBoardMoveTimeInfo();
+ };
+
+ playerInstance.createCardboardView = () => {
+ // Create a container for 360degree
+ const vrContainer = document.createElement('div');
+ vrContainer.className = 'fluid_vr_container';
+ playerInstance.domRef.player.parentNode.insertBefore(vrContainer, playerInstance.domRef.player.nextSibling);
+
+ // OverRide some conflicting functions from panolens
+ PANOLENS.VideoPanorama.prototype.pauseVideo = function () {
+ };
+ PANOLENS.VideoPanorama.prototype.playVideo = function () {
+ };
+
+ playerInstance.vrPanorama = new PANOLENS.VideoPanorama('', {
+ videoElement: playerInstance.domRef.player,
+ autoplay: playerInstance.displayOptions.layoutControls.autoPlay,
+ loop: !!playerInstance.displayOptions.layoutControls.loop
+ });
+
+ playerInstance.vrViewer = new PANOLENS.Viewer({
+ container: vrContainer,
+ controlBar: true,
+ controlButtons: [],
+ enableReticle: false
+ });
+ playerInstance.vrViewer.add(playerInstance.vrPanorama);
+
+ playerInstance.vrViewer.enableEffect(PANOLENS.MODES.NORMAL);
+ playerInstance.vrViewer.onWindowResize();
+
+ // if Mobile device then enable controls using gyroscope
+ if (playerInstance.getMobileOs().userOs === 'Android' || playerInstance.getMobileOs().userOs === 'iOS') {
+ playerInstance.vrViewer.enableControl(1);
+ }
+
+ // Make Changes for default skin
+ playerInstance.cardBoardAlterDefaultControls();
+
+ // resize on toggle theater mode
+ playerInstance.cardBoardResize();
+
+ // Store initial camera position
+ playerInstance.vrViewer.initialCameraPosition = JSON.parse(JSON.stringify(playerInstance.vrViewer.camera.position));
+
+ if (playerInstance.displayOptions.layoutControls.showCardBoardJoystick) {
+ if (!(playerInstance.getMobileOs().userOs === 'Android' || playerInstance.getMobileOs().userOs === 'iOS')) {
+ playerInstance.createCardboardJoystick();
+ }
+ // Disable zoom if showing joystick
+ playerInstance.vrViewer.OrbitControls.noZoom = true;
+ }
+
+ playerInstance.trackEvent(playerInstance.domRef.player.parentNode, 'click', '.fluid_control_cardboard', function () {
+ if (playerInstance.vrMode) {
+ playerInstance.cardBoardSwitchToNormal();
+ } else {
+ playerInstance.cardBoardSwitchToVR();
+ }
+ });
+ };
+
+ playerInstance.createCardboard = () => {
+ if (!playerInstance.displayOptions.layoutControls.showCardBoardView) {
+ return;
+ }
+
+ playerInstance.domRef.wrapper.querySelector('.fluid_control_cardboard').style.display = 'inline-block';
+
+ if (!window.PANOLENS) {
+ import(/* webpackChunkName: "panolens" */ 'panolens').then((it) => {
+ window.PANOLENS = it;
+ playerInstance.createCardboardView();
+ });
+ } else {
+ playerInstance.createCardboardView();
+ }
+ };
+}
diff --git a/client/fluid-player/src/modules/miniplayer.js b/client/fluid-player/src/modules/miniplayer.js
new file mode 100644
index 0000000..8c99c6f
--- /dev/null
+++ b/client/fluid-player/src/modules/miniplayer.js
@@ -0,0 +1,385 @@
+export default function (playerInstance) {
+ // Module constants
+ const MINIMUM_WIDTH = 400; // Pixels
+ const MINIMUM_HEIGHT = 225; // Pixels
+ const MINIMUM_WIDTH_MOBILE = 40; // Percentage
+ const TOGGLE_BY_VISIBILITY_DETECTION_RATE = 1000 / 60; // ms
+
+ const DISABLE_MINI_PLAYER_MOBILE_ANIMATION_CLAMP = 50;
+ const DISABLE_MINI_PLAYER_MOBILE_ANIMATION_DEADZONE = 5;
+
+ const DESKTOP_ONLY_MEDIA_QUERY = '(max-width: 768px)';
+
+ const FLUID_PLAYER_WRAPPER_CLASS = 'fluid_mini_player_mode';
+ const CLOSE_BUTTON_WRAPPER_CLASS = 'mini-player-close-button-wrapper';
+ const CLOSE_BUTTON_CLASS = 'mini-player-close-button';
+ const PLACEHOLDER_CLASS = 'fluidplayer-miniplayer-player-placeholder'
+ const DISABLE_MINI_PLAYER_MOBILE_CLASS = 'disable-mini-player-mobile';
+
+ const LINEAR_CLICKTHROUGH_SELECTOR = '.vast_clickthrough_layer';
+ const NON_LINEAR_SELECTOR = '.fluid_nonLinear_ad img, .fluid_vpaid_nonlinear_slot_iframe';
+ const VPAID_FRAME_SELECTOR = '.fluid_vpaidNonLinear_frame';
+
+ const MINI_PLAYER_TOGGLE_EVENT = 'miniPlayerToggle';
+
+ // Module variables
+ let originalWidth = null;
+ let originalHeight = null;
+ let originalNonLinearWidth = null
+ let originalNonLinearHeight = null;
+ let isSetup = false;
+ /** @type null | Element */
+ let placeholderElement = null;
+ let isMobile = false;
+ /** @type boolean */
+ let toggleByVisibilityControl = false;
+
+ /**
+ * Toggles the MiniPlayer given that it's enabled. Resets all other display modes.
+ *
+ * @param {'on'|'off'} [forceToggle]
+ * @param {boolean} manualToggle
+ */
+ function toggleMiniPlayer(forceToggle, manualToggle = false) {
+ playerInstance.debugMessage(`[MiniPlayer] Toggling MiniPlayer, forceToggle: ${forceToggle}`);
+
+ const miniPlayerOptions = playerInstance.displayOptions.layoutControls.miniPlayer;
+
+ if (!miniPlayerOptions.enabled) {
+ playerInstance.debugMessage(`[MiniPlayer] Prevent toggle MiniPlayer, it's currently disabled`);
+ return;
+ }
+
+ if ((forceToggle === 'on' && playerInstance.miniPlayerToggledOn) || (forceToggle === 'off' && !playerInstance.miniPlayerToggledOn)) {
+ playerInstance.debugMessage(`[MiniPlayer] Can't force toggle Mini Player to it's same state`);
+ return;
+ }
+
+ if (manualToggle) {
+ toggleScreenDetection();
+ }
+
+ if (window.matchMedia(DESKTOP_ONLY_MEDIA_QUERY).matches) {
+ isMobile = true;
+ }
+
+ // Important as the player can be in full screen or theater mode
+ playerInstance.resetDisplayMode('miniPlayer');
+
+ if (!isSetup) {
+ // Setups JIT to avoid extra processing
+ setupMiniPlayer();
+ }
+
+ if (forceToggle === 'off' || playerInstance.miniPlayerToggledOn) {
+ toggleMiniPlayerOff();
+ } else if (forceToggle === 'on' || !playerInstance.miniPlayerToggledOn) {
+ toggleMiniPlayerOn(miniPlayerOptions.width, miniPlayerOptions.height, miniPlayerOptions.widthMobile, miniPlayerOptions.position);
+ }
+ }
+
+ /**
+ * Setups custom Mini Player DOM
+ */
+ function setupMiniPlayer() {
+ const hasCloseButton = Boolean(playerInstance.domRef.player.parentNode.querySelector(`.${CLOSE_BUTTON_CLASS}`));
+
+ if (!hasCloseButton) {
+ const closeButtonWrapper = document.createElement('div');
+ closeButtonWrapper.classList.add(CLOSE_BUTTON_WRAPPER_CLASS);
+
+ const closeButton = document.createElement('span');
+ closeButton.classList.add(CLOSE_BUTTON_CLASS);
+ closeButton.addEventListener('click', () => {
+ toggleMiniPlayer('off', true);
+
+ if (!playerInstance.domRef.player.paused) {
+ playerInstance.playPauseToggle();
+ }
+ });
+
+ closeButtonWrapper.appendChild(closeButton);
+ playerInstance.domRef.player.parentNode.append(closeButtonWrapper);
+ }
+
+ if (isMobile) {
+ setupMobile();
+ }
+
+ isSetup = true;
+ }
+
+ /**
+ * Toggles the MiniPlayer off and restores previous functionality to player
+ */
+ function toggleMiniPlayerOff() {
+ const videoWrapper = playerInstance.domRef.wrapper;
+
+ removePlayerPlaceholder();
+
+ videoWrapper.classList.remove(FLUID_PLAYER_WRAPPER_CLASS);
+ videoWrapper.style.width = `${originalWidth}px`;
+ videoWrapper.style.height = `${originalHeight}px`;
+
+ originalWidth = null;
+ originalHeight = null;
+
+ adaptNonLinearSize();
+ adaptLinearSize();
+ playerInstance.miniPlayerToggledOn = false;
+ emitToggleEvent();
+ }
+
+ /**
+ * Toggles the MiniPlayer on, stores the original size of the player.
+ *
+ * @param {number} width
+ * @param {number} height
+ * @param {number} mobileWidth
+ * @param {'top left'|'top right'|'bottom left'|'bottom right'} position
+ */
+ function toggleMiniPlayerOn(width, height, mobileWidth, position) {
+ const videoWrapper = playerInstance.domRef.wrapper;
+ const targetWidth = width > MINIMUM_WIDTH ? width : MINIMUM_WIDTH;
+ const targetHeight = height > MINIMUM_HEIGHT ? height : MINIMUM_HEIGHT;
+ const targetMobileWidth = mobileWidth > MINIMUM_WIDTH_MOBILE ? mobileWidth : MINIMUM_WIDTH_MOBILE;
+
+ originalWidth = extractSizeFromElement(videoWrapper, 'width', 'clientWidth');
+ originalHeight = extractSizeFromElement(videoWrapper, 'height', 'clientHeight');
+
+ videoWrapper.classList.add(
+ FLUID_PLAYER_WRAPPER_CLASS,
+ `${FLUID_PLAYER_WRAPPER_CLASS}--${position.trim().replace(/\s/, '-')}`
+ );
+
+ if (!isMobile) {
+ videoWrapper.style.width = `${targetWidth}px`;
+ videoWrapper.style.height = `${targetHeight}px`;
+ } else {
+ videoWrapper.style.width = `${targetMobileWidth}vw`;
+ videoWrapper.style.height = `auto`;
+ videoWrapper.style.aspectRatio = `16 / 9`;
+ }
+
+ createPlayerPlaceholder(originalWidth, originalHeight);
+ adaptNonLinearSize(targetWidth, targetHeight, targetMobileWidth);
+ adaptLinearSize();
+ playerInstance.miniPlayerToggledOn = true;
+ emitToggleEvent();
+ }
+
+ /**
+ * Emits event to Fluid Player Event API
+ */
+ function emitToggleEvent() {
+ playerInstance.domRef.player.dispatchEvent(
+ new CustomEvent(MINI_PLAYER_TOGGLE_EVENT, { detail: { isToggledOn: playerInstance.miniPlayerToggledOn } })
+ );
+ }
+
+ /**
+ * Extracts size from an element checking multiple element properties
+ *
+ * @param {HTMLElement} element
+ * @param {'width'|'height'|null} styleProperty
+ * @param {'clientWidth'|'clientHeight'|'width'|'height'} htmlProperty
+ * @returns {number}
+ */
+ function extractSizeFromElement(element, styleProperty, htmlProperty) {
+ if (styleProperty && element.style[styleProperty] && element.style[styleProperty].match('px')) {
+ return parseInt(element.style[styleProperty]);
+ } else {
+ return String(element[htmlProperty]).match('px') ? parseInt(element[htmlProperty]) : element[htmlProperty];
+ }
+ }
+
+ /**
+ * Adapts NonLinear size (if present) to fit MiniPlayer view
+ *
+ * @param {number} [width]
+ * @param {number} [height]
+ * @param {number} [mobileWidth]
+ */
+ function adaptNonLinearSize(width, height, mobileWidth) {
+ /** @type HTMLImageElement|HTMLIFrameElement */
+ const nonLinear = playerInstance.domRef.wrapper.querySelector(NON_LINEAR_SELECTOR);
+ /** @type HTMLElement */
+ const vpaidFrame = playerInstance.domRef.wrapper.querySelector(VPAID_FRAME_SELECTOR);
+
+ if (!nonLinear) return;
+
+ if (isMobile) {
+ width = window.innerWidth * mobileWidth / 100; // Transforms vw to px
+ }
+
+ const nonLinearWidth = extractSizeFromElement(nonLinear, null, 'width');
+ const nonLinearHeight = extractSizeFromElement(nonLinear, null, 'height');
+
+ if (originalNonLinearWidth && originalNonLinearHeight) {
+ nonLinear.width = originalNonLinearWidth;
+ nonLinear.height = originalNonLinearHeight;
+
+ if (vpaidFrame) {
+ vpaidFrame.style.width = `${originalNonLinearWidth}px`;
+ vpaidFrame.style.height = `${originalNonLinearHeight}px`;
+ }
+
+ originalNonLinearWidth = originalNonLinearHeight = null;
+ } else if (nonLinearWidth > width || nonLinearHeight > height) {
+ const targetRatio = (width - (isMobile ? 4 : 32)) / nonLinearWidth;
+
+ originalNonLinearWidth = nonLinearWidth;
+ originalNonLinearHeight = nonLinearHeight;
+
+ nonLinear.width = Math.round(nonLinearWidth * targetRatio);
+ nonLinear.height = Math.round(nonLinearHeight * targetRatio);
+
+ if (vpaidFrame) {
+ vpaidFrame.style.width = `${Math.round(nonLinearWidth * targetRatio)}px`;
+ vpaidFrame.style.height = `${Math.round(nonLinearHeight * targetRatio)}px`;
+ }
+ }
+ }
+
+ /**
+ * Adapts Linear size (if present) to fit MiniPlayer view
+ */
+ function adaptLinearSize() {
+ const clickTroughLayer = playerInstance.domRef.wrapper.querySelector(LINEAR_CLICKTHROUGH_SELECTOR);
+
+ if (clickTroughLayer) {
+ clickTroughLayer.style.width = `${playerInstance.domRef.player.offsetWidth}px`;
+ clickTroughLayer.style.height = `${playerInstance.domRef.player.offsetHeight}px`;
+ }
+ }
+
+ /**
+ * Setups mobile disable element
+ */
+ function setupMobile() {
+ const disableMiniPlayerMobile = document.createElement('div');
+ let animationAmount = 0;
+ let startTimestamp = 0;
+ let startScreenX = 0;
+ let hasTriggeredAnimation;
+ disableMiniPlayerMobile.classList.add(DISABLE_MINI_PLAYER_MOBILE_CLASS);
+ const closeButton = document.createElement('span');
+ closeButton.classList.add(CLOSE_BUTTON_CLASS);
+ disableMiniPlayerMobile.appendChild(closeButton);
+
+ disableMiniPlayerMobile.ontouchstart = event => {
+ hasTriggeredAnimation = false;
+ startTimestamp = event.timeStamp;
+ startScreenX = event.changedTouches[0].screenX;
+ event.preventDefault();
+ }
+
+ disableMiniPlayerMobile.ontouchmove = event => {
+ animationAmount = Math.min(
+ Math.max(
+ startScreenX - event.changedTouches[0].screenX,
+ DISABLE_MINI_PLAYER_MOBILE_ANIMATION_CLAMP * -1),
+ DISABLE_MINI_PLAYER_MOBILE_ANIMATION_CLAMP
+ );
+
+ if (Math.abs(animationAmount) > DISABLE_MINI_PLAYER_MOBILE_ANIMATION_DEADZONE) {
+ // Moves the element the same amount as the touch event moved
+ playerInstance.domRef.wrapper.style.transform = `translateX(${animationAmount * -1}px)`;
+ hasTriggeredAnimation = true;
+ } else {
+ playerInstance.domRef.wrapper.style.transform = `translateX(0px)`
+ }
+ }
+
+ disableMiniPlayerMobile.ontouchend = event => {
+ if (Math.abs(animationAmount) > DISABLE_MINI_PLAYER_MOBILE_ANIMATION_DEADZONE) {
+ // Scroll X behaviour - Disable mini player and pauses video
+ toggleMiniPlayer('off', true);
+
+ if (!playerInstance.domRef.player.paused) {
+ playerInstance.playPauseToggle();
+ }
+ event.preventDefault();
+ } else if (!hasTriggeredAnimation) {
+ // Tap behaviour - Disable mini player and moves screen to video
+ toggleMiniPlayer('off', true);
+ setTimeout(() => {
+ playerInstance.domRef.wrapper.scrollIntoView({
+ behavior: 'smooth',
+ block: 'center',
+ });
+ })
+ }
+
+ animationAmount = 0;
+ playerInstance.domRef.wrapper.style.transform = ``;
+ }
+
+ // Fallback for when there is no touch event
+ disableMiniPlayerMobile.onmouseup = () => toggleMiniPlayer('off', true)
+
+ playerInstance.domRef.wrapper.insertBefore(disableMiniPlayerMobile, playerInstance.domRef.player.nextSibling);
+ }
+
+ /**
+ * Creates a placeholder element in place where the video player was
+ *
+ * @param {number} placeholderWidth
+ * @param {number} placeholderHeight
+ */
+ function createPlayerPlaceholder(placeholderWidth, placeholderHeight) {
+ placeholderElement = document.createElement('div');
+ placeholderElement.classList.add(PLACEHOLDER_CLASS);
+ placeholderElement.style.height = `${placeholderHeight}px`;
+ placeholderElement.style.width = `${placeholderWidth}px`;
+ placeholderElement.innerText = playerInstance.displayOptions.layoutControls.miniPlayer.placeholderText || '';
+ placeholderElement.onclick = () => toggleMiniPlayer('off', true);
+
+ playerInstance.domRef.wrapper.parentElement.insertBefore(placeholderElement, playerInstance.domRef.wrapper);
+ }
+
+ /**
+ * Removes the placeholder that was in place where video player was
+ */
+ function removePlayerPlaceholder() {
+ playerInstance.domRef.wrapper.parentElement.removeChild(placeholderElement);
+ placeholderElement = null;
+ }
+
+ /**
+ * Toggles auto toggle for mini player
+ */
+ function toggleScreenDetection() {
+ const autoToggle = playerInstance.displayOptions.layoutControls.miniPlayer.autoToggle;
+
+ if (toggleByVisibilityControl || !autoToggle) {
+ document.removeEventListener('scroll', toggleMiniPlayerByVisibility);
+ return;
+ }
+
+ toggleByVisibilityControl = true;
+ document.addEventListener('scroll', toggleMiniPlayerByVisibility, { passive: true });
+ }
+
+ /**
+ * Checks for player visibility and toggles mini player based on it
+ */
+ const toggleMiniPlayerByVisibility = playerInstance.throttle(function toggleMiniPlayerByVisibility() {
+ if (playerInstance.domRef.player.paused) {
+ return;
+ }
+
+ const isPlayerVisible = playerInstance.isElementVisible(playerInstance.domRef.player);
+ const isPlaceholderVisible = playerInstance.isElementVisible(playerInstance.domRef.wrapper.querySelector(`.${PLACEHOLDER_CLASS}`));
+
+ if (!isPlayerVisible && !playerInstance.miniPlayerToggledOn) {
+ toggleMiniPlayer('on');
+ } else if (isPlaceholderVisible && playerInstance.miniPlayerToggledOn) {
+ toggleMiniPlayer('off');
+ }
+ }, TOGGLE_BY_VISIBILITY_DETECTION_RATE);
+
+ // Exposes public module functions
+ playerInstance.toggleMiniPlayer = toggleMiniPlayer;
+ playerInstance.toggleMiniPlayerScreenDetection = toggleScreenDetection;
+}
diff --git a/client/fluid-player/src/modules/streaming.js b/client/fluid-player/src/modules/streaming.js
new file mode 100644
index 0000000..cdaa1cf
--- /dev/null
+++ b/client/fluid-player/src/modules/streaming.js
@@ -0,0 +1,299 @@
+
+// Prevent DASH.js from automatically attaching to video sources by default.
+// Whoever thought this is a good idea?!
+if (typeof window !== 'undefined' && !window.dashjs) {
+ window.dashjs = {
+ skipAutoCreate: true,
+ isDefaultSubject: true
+ };
+}
+
+export default function (playerInstance, options) {
+ playerInstance.initialiseStreamers = () => {
+ playerInstance.detachStreamers();
+ switch (playerInstance.displayOptions.layoutControls.mediaType) {
+ case 'application/dash+xml': // MPEG-DASH
+ if (!playerInstance.dashScriptLoaded && (!window.dashjs || window.dashjs.isDefaultSubject)) {
+ playerInstance.dashScriptLoaded = true;
+ import(/* webpackChunkName: "dashjs" */ 'dashjs').then((it) => {
+ window.dashjs = it.default;
+ playerInstance.initialiseDash();
+ });
+ } else {
+ playerInstance.initialiseDash();
+ }
+ break;
+ case 'application/x-mpegurl': // HLS
+ const { displayOptions, domRef } = playerInstance;
+ const { player } = domRef;
+ const { hls } = displayOptions;
+
+ // Doesn't load hls.js if player can play it natively
+ if (player.canPlayType('application/x-mpegurl') && !hls.overrideNative) {
+ playerInstance.debugMessage('Native HLS support found, skipping hls.js');
+ break;
+ }
+
+ if (!playerInstance.hlsScriptLoaded && !window.Hls) {
+ playerInstance.hlsScriptLoaded = true;
+ import(/* webpackChunkName: "hlsjs" */ 'hls.js').then((it) => {
+ window.Hls = it.default;
+ playerInstance.initialiseHls();
+ });
+ } else {
+ playerInstance.initialiseHls();
+ }
+ break;
+ }
+ };
+
+ playerInstance.initialiseDash = () => {
+ if (typeof (window.MediaSource || window.WebKitMediaSource) === 'function') {
+ // If false we want to override the autoPlay, as it comes from postRoll
+ const playVideo = !playerInstance.autoplayAfterAd
+ ? playerInstance.autoplayAfterAd
+ : playerInstance.displayOptions.layoutControls.autoPlay;
+
+ const defaultOptions = {
+ 'debug': {
+ 'logLevel': typeof FP_DEBUG !== 'undefined' && FP_DEBUG === true
+ ? dashjs.Debug.LOG_LEVEL_DEBUG
+ : dashjs.Debug.LOG_LEVEL_FATAL
+ }
+ };
+
+ const dashPlayer = dashjs.MediaPlayer().create();
+ const options = playerInstance.displayOptions.modules.configureDash(defaultOptions);
+
+ dashPlayer.updateSettings(options);
+
+ playerInstance.displayOptions.modules.onBeforeInitDash(dashPlayer);
+
+ dashPlayer.initialize(playerInstance.domRef.player, playerInstance.originalSrc, playVideo);
+
+ dashPlayer.on('streamInitializing', () => {
+ playerInstance.toggleLoader(true);
+ });
+
+ dashPlayer.on('canPlay', () => {
+ playerInstance.toggleLoader(false);
+ });
+
+ dashPlayer.on('playbackPlaying', () => {
+ playerInstance.toggleLoader(false);
+ });
+
+ playerInstance.displayOptions.modules.onAfterInitDash(dashPlayer);
+
+ playerInstance.dashPlayer = dashPlayer;
+ } else {
+ playerInstance.nextSource();
+ console.log('[FP_WARNING] Media type not supported by this browser using DASH.js. (application/dash+xml)');
+ }
+ };
+
+ playerInstance.initialiseHls = () => {
+ if (typeof Hls !== 'undefined' && Hls.isSupported()) {
+ playerInstance.debugMessage('Initializing hls.js');
+
+ const defaultOptions = {
+ debug: typeof FP_DEBUG !== 'undefined' && FP_DEBUG === true,
+ startPosition: 0,
+ p2pConfig: {
+ logLevel: false,
+ },
+ enableWebVTT: false,
+ enableCEA708Captions: false,
+ };
+
+ const options = playerInstance.displayOptions.modules.configureHls(defaultOptions);
+ const hls = new Hls(options);
+ playerInstance.displayOptions.modules.onBeforeInitHls(hls);
+
+ hls.attachMedia(playerInstance.domRef.player);
+ hls.loadSource(playerInstance.originalSrc);
+
+ playerInstance.displayOptions.modules.onAfterInitHls(hls);
+
+ playerInstance.hlsPlayer = hls;
+
+ if (!playerInstance.firstPlayLaunched && playerInstance.displayOptions.layoutControls.autoPlay) {
+ playerInstance.domRef.player.play();
+ }
+
+ playerInstance.createHLSVideoSourceSwitch();
+ } else {
+ playerInstance.nextSource();
+ console.log('[FP_WARNING] Media type not supported by this browser using HLS.js. (application/x-mpegURL)');
+ }
+ };
+
+ playerInstance.createHLSVideoSourceSwitch = () => {
+ playerInstance.hlsPlayer.on(Hls.Events.MANIFEST_PARSED, function () {
+ try {
+ const levels = createHLSLevels();
+ const sortedLevels = sortLevels(levels);
+ playerInstance.videoSources = sortedLevels;
+
+ // <=2 because of the added auto function
+ if (sortedLevels.length <= 2) return;
+
+ const sourceChangeButton = playerInstance.domRef.wrapper.querySelector('.fluid_control_video_source');
+
+ toggleSourceChangeButtonVisibility(sortedLevels, sourceChangeButton);
+
+ const sourceChangeList = createSourceChangeList(sortedLevels);
+ attachSourceChangeList(sourceChangeButton, sourceChangeList);
+
+ // Set initial level based on persisted quality or default to auto
+ setInitialLevel(sortedLevels);
+ } catch (err) {
+ console.error(err);
+ }
+ });
+ };
+
+ function createHLSLevels() {
+ const HLSLevels = playerInstance.hlsPlayer.levels
+ .map((level, index) => ({
+ id: index,
+ title: String(level.width),
+ isHD: level.videoRange === 'HDR',
+ bitrate: level.bitrate
+ }));
+
+ const autoLevel = {
+ id: -1,
+ title: 'auto',
+ isHD: false,
+ bitrate: 0
+ };
+
+ return [...HLSLevels, autoLevel];
+ }
+
+ function toggleSourceChangeButtonVisibility(levels, sourceChangeButton) {
+ if (levels.length > 1) {
+ sourceChangeButton.style.display = 'inline-block';
+ } else {
+ sourceChangeButton.style.display = 'none';
+ }
+ }
+
+ function createSourceChangeList(levels) {
+ const sourceChangeList = document.createElement('div');
+ sourceChangeList.className = 'fluid_video_sources_list';
+ sourceChangeList.style.display = 'none';
+
+ levels.forEach(level => {
+ const sourceChangeDiv = createSourceChangeItem(level);
+ sourceChangeList.appendChild(sourceChangeDiv);
+ });
+
+ return sourceChangeList;
+ }
+
+ function createSourceChangeItem(level) {
+ const sourceSelectedClass = getSourceSelectedClass(level);
+ const hdIndicator = level.isHD ? ` ` : '';
+
+ const sourceChangeDiv = document.createElement('div');
+ sourceChangeDiv.className = `fluid_video_source_list_item js-source_${level.title}`;
+ sourceChangeDiv.innerHTML = ` ${level.title}${hdIndicator}`;
+
+ sourceChangeDiv.addEventListener('click', event => onSourceChangeClick(event, level));
+
+ return sourceChangeDiv;
+ }
+
+ function getSourceSelectedClass(level) {
+ const matchingLevels = playerInstance.videoSources.filter(source => source.title === playerInstance.fluidStorage.fluidQuality);
+
+ // If there are multiple matching levels, use the first one
+ if (matchingLevels.length > 1) {
+ if (matchingLevels[0].id === level.id) {
+ return "source_selected";
+ }
+ } else if (matchingLevels.length === 1) {
+ return matchingLevels[0].id === level.id ? "source_selected" : "";
+ }
+
+ // Fallback to auto selection if no persistent level exists
+ if (!matchingLevels.length && level.title === 'auto') {
+ return "source_selected";
+ }
+
+ return "";
+ }
+
+ function onSourceChangeClick(event, selectedLevel) {
+ event.stopPropagation();
+
+ setPlayerDimensions();
+
+ const videoChangedTo = event.currentTarget;
+ clearSourceSelectedIcons();
+
+ videoChangedTo.firstChild.classList.add('source_selected');
+
+ playerInstance.videoSources.forEach(source => {
+ if (source.title === videoChangedTo.innerText.replace(/(\r\n\t|\n|\r\t)/gm, '')) {
+ playerInstance.hlsPlayer.currentLevel = selectedLevel.id;
+ playerInstance.fluidStorage.fluidQuality = selectedLevel.title;
+ }
+ });
+
+ playerInstance.openCloseVideoSourceSwitch();
+ }
+
+ // While changing source the player size can flash, we want to set the pixel dimensions then back to 100% afterwards
+ function setPlayerDimensions() {
+ playerInstance.domRef.player.style.width = `${playerInstance.domRef.player.clientWidth}px`;
+ playerInstance.domRef.player.style.height = `${playerInstance.domRef.player.clientHeight}px`;
+ }
+
+ function clearSourceSelectedIcons() {
+ const sourceIcons = playerInstance.domRef.wrapper.getElementsByClassName('source_button_icon');
+ Array.from(sourceIcons).forEach(icon => icon.classList.remove('source_selected'));
+ }
+
+ function attachSourceChangeList(sourceChangeButton, sourceChangeList) {
+ sourceChangeButton.appendChild(sourceChangeList);
+ sourceChangeButton.removeEventListener('click', playerInstance.openCloseVideoSourceSwitch);
+ sourceChangeButton.addEventListener('click', playerInstance.openCloseVideoSourceSwitch);
+ }
+
+ function setInitialLevel(levels) {
+ // Check if a persistency level exists and set the current level accordingly
+ const persistedLevel = levels.find(level => level.title === playerInstance.fluidStorage.fluidQuality);
+
+ if (persistedLevel) {
+ playerInstance.hlsPlayer.currentLevel = persistedLevel.id;
+ } else {
+ // Default to 'auto' if no persisted level is found
+ const autoLevel = levels.find(level => level.title === 'auto');
+ playerInstance.hlsPlayer.currentLevel = autoLevel.id;
+ }
+ }
+
+ function sortLevels(levels) {
+ return [...levels].sort((a, b) => {
+ // First sort by width in descending order
+ if (b.width !== a.width) {
+ return b.width - a.width;
+ }
+ // If width is the same, sort by bitrate in descending order
+ return b.bitrate - a.bitrate;
+ });
+ }
+
+ playerInstance.detachStreamers = () => {
+ if (playerInstance.dashPlayer) {
+ playerInstance.dashPlayer.reset();
+ playerInstance.dashPlayer = false;
+ } else if (playerInstance.hlsPlayer) {
+ playerInstance.hlsPlayer.detachMedia();
+ playerInstance.hlsPlayer = false;
+ }
+ };
+}
diff --git a/client/fluid-player/src/modules/subtitles.js b/client/fluid-player/src/modules/subtitles.js
new file mode 100644
index 0000000..5232aeb
--- /dev/null
+++ b/client/fluid-player/src/modules/subtitles.js
@@ -0,0 +1,225 @@
+export default function (playerInstance, options) {
+ playerInstance.subtitleFetchParse = (subtitleItem) => {
+ playerInstance.sendRequest(
+ subtitleItem.url,
+ true,
+ playerInstance.displayOptions.vastOptions.vastTimeout,
+ function () {
+ const convertVttRawData = function (vttRawData) {
+ if (!(
+ (typeof vttRawData.cues !== 'undefined') &&
+ (vttRawData.cues.length)
+ )) {
+ return [];
+ }
+
+ const result = [];
+
+ for (let i = 0; i < vttRawData.cues.length; i++) {
+ let tempThumbnailData = vttRawData.cues[i].text.split('#');
+
+ result.push({
+ startTime: vttRawData.cues[i].startTime,
+ endTime: vttRawData.cues[i].endTime,
+ text: vttRawData.cues[i].text,
+ cue: vttRawData.cues[i]
+ })
+ }
+
+ return result;
+ };
+
+ const xmlHttpReq = this;
+
+ if ((xmlHttpReq.readyState === 4) && (xmlHttpReq.status !== 200)) {
+ //The response returned an error.
+ return;
+ }
+
+ if (!((xmlHttpReq.readyState === 4) && (xmlHttpReq.status === 200))) {
+ return;
+ }
+
+ const textResponse = xmlHttpReq.responseText;
+
+ const parser = new WebVTT.Parser(window, WebVTT.StringDecoder());
+ const cues = [];
+ const regions = []; // TODO: unused?
+ parser.oncue = function (cue) {
+ cues.push(cue);
+ };
+ parser.onregion = function (region) {
+ regions.push(region);
+ };
+ parser.parse(textResponse);
+ parser.flush();
+ playerInstance.subtitlesData = cues;
+
+ }
+ );
+ };
+
+ playerInstance.createSubtitlesSwitch = () => {
+ const subtitlesOff = 'OFF';
+ playerInstance.subtitlesData = [];
+
+ if (!playerInstance.displayOptions.layoutControls.subtitlesEnabled) {
+ // No other video subtitles
+ playerInstance.domRef.wrapper.querySelector('.fluid_control_subtitles').style.display = 'none';
+ return;
+ }
+
+ const tracks = [];
+ tracks.push({'label': subtitlesOff, 'url': 'na', 'lang': subtitlesOff});
+
+ const tracksList = playerInstance.domRef.player.querySelectorAll('track');
+
+ [].forEach.call(tracksList, function (track) {
+ if (track.kind === 'metadata' && track.src) {
+ tracks.push({'label': track.label, 'url': track.src, 'lang': track.srclang, 'default': track.default});
+ }
+ });
+
+ playerInstance.subtitlesTracks = tracks;
+ const subtitlesChangeButton = playerInstance.domRef.wrapper.querySelector('.fluid_control_subtitles');
+ subtitlesChangeButton.style.display = 'inline-block';
+ let appendSubtitleChange = false;
+
+ const subtitlesChangeList = document.createElement('div');
+ subtitlesChangeList.className = 'fluid_subtitles_list';
+ subtitlesChangeList.style.display = 'none';
+
+ let hasSelectedSubtitle = false;
+ const hasDefault = !!playerInstance.subtitlesTracks.find(track => track.default);
+ playerInstance.subtitlesTracks.forEach(function (subtitle) {
+ let subtitleSelected = ''
+
+ const subtitlesOnByDefault = playerInstance.displayOptions.layoutControls.subtitlesOnByDefault;
+
+ if (!hasSelectedSubtitle && (subtitlesOnByDefault && subtitle.default ||
+ (!hasDefault && subtitle.label !== subtitlesOff) ||
+ playerInstance.subtitlesTracks.length === 1) ||
+ !subtitlesOnByDefault && subtitle.label === subtitlesOff
+ ) {
+ subtitleSelected = 'subtitle_selected';
+ playerInstance.subtitleFetchParse(subtitle);
+ hasSelectedSubtitle = true;
+ }
+
+ const subtitlesChangeDiv = document.createElement('div');
+ subtitlesChangeDiv.className = 'fluid_subtitle_list_item';
+ subtitlesChangeDiv.innerHTML = ' ' + subtitle.label;
+
+ subtitlesChangeDiv.addEventListener('click', function (event) {
+ event.stopPropagation();
+ const subtitleChangedTo = this;
+ const subtitleIcons = playerInstance.domRef.wrapper.getElementsByClassName('subtitle_button_icon');
+
+ for (let i = 0; i < subtitleIcons.length; i++) {
+ subtitleIcons[i].className = subtitleIcons[i].className.replace("subtitle_selected", "");
+ }
+
+ subtitleChangedTo.firstChild.className += ' subtitle_selected';
+
+ playerInstance.subtitlesTracks.forEach(function (subtitle) {
+ if (subtitle.label === subtitleChangedTo.innerText.replace(/(\r\n\t|\n|\r\t)/gm, "")) {
+ if (subtitle.label === subtitlesOff) {
+ playerInstance.subtitlesData = [];
+ } else {
+ playerInstance.subtitleFetchParse(subtitle);
+ }
+ }
+ });
+ playerInstance.openCloseSubtitlesSwitch();
+
+ });
+
+ subtitlesChangeList.appendChild(subtitlesChangeDiv);
+ appendSubtitleChange = true;
+
+ });
+
+ if (appendSubtitleChange) {
+ subtitlesChangeButton.appendChild(subtitlesChangeList);
+ subtitlesChangeButton.removeEventListener('click', handleSubtitlesChange);
+ subtitlesChangeButton.addEventListener('click', handleSubtitlesChange);
+ } else {
+ // Didn't give any subtitle options
+ playerInstance.domRef.wrapper.querySelector('.fluid_control_subtitles').style.display = 'none';
+ }
+
+ playerInstance.domRef.player.removeEventListener('timeupdate', videoPlayerSubtitlesUpdate);
+ playerInstance.domRef.player.addEventListener('timeupdate', videoPlayerSubtitlesUpdate);
+ };
+
+ function handleSubtitlesChange() {
+ playerInstance.openCloseSubtitlesSwitch();
+ }
+
+ //attach subtitles to show based on time
+ //this function is for rendering of subtitles when content is playing
+ function videoPlayerSubtitlesUpdate() {
+ playerInstance.renderSubtitles();
+ }
+
+ playerInstance.renderSubtitles = () => {
+ const videoPlayer = playerInstance.domRef.player;
+
+ //if content is playing then no subtitles
+ let currentTime = Math.floor(videoPlayer.currentTime);
+ let subtitlesAvailable = false;
+ let subtitlesContainer = playerInstance.domRef.wrapper.querySelector('.fluid_subtitles_container');
+
+ if (playerInstance.isCurrentlyPlayingAd) {
+ subtitlesContainer.innerHTML = '';
+ return;
+ }
+
+ for (let i = 0; i < playerInstance.subtitlesData.length; i++) {
+ if (currentTime >= (playerInstance.subtitlesData[i].startTime) && currentTime <= (playerInstance.subtitlesData[i].endTime)) {
+ subtitlesContainer.innerHTML = '';
+ subtitlesContainer.appendChild(WebVTT.convertCueToDOMTree(window, playerInstance.subtitlesData[i].text));
+ subtitlesAvailable = true;
+ }
+ }
+
+ if (!subtitlesAvailable) {
+ subtitlesContainer.innerHTML = '';
+ }
+ };
+
+ playerInstance.openCloseSubtitlesSwitch = () => {
+ const subtitleChangeList = playerInstance.domRef.wrapper.querySelector('.fluid_subtitles_list');
+
+ if (playerInstance.isCurrentlyPlayingAd) {
+ subtitleChangeList.style.display = 'none';
+ return;
+ }
+
+ if (subtitleChangeList.style.display === 'none') {
+ subtitleChangeList.style.display = 'block';
+ const mouseOut = function (event) {
+ subtitleChangeList.removeEventListener('mouseleave', mouseOut);
+ subtitleChangeList.style.display = 'none';
+ };
+ subtitleChangeList.addEventListener('mouseleave', mouseOut);
+ } else {
+ subtitleChangeList.style.display = 'none';
+ }
+ };
+
+ playerInstance.createSubtitles = () => {
+ const divSubtitlesContainer = document.createElement('div');
+ divSubtitlesContainer.className = 'fluid_subtitles_container';
+ playerInstance.domRef.player.parentNode.insertBefore(divSubtitlesContainer, playerInstance.domRef.player.nextSibling);
+
+ if (!playerInstance.displayOptions.layoutControls.subtitlesEnabled) {
+ return;
+ }
+
+ import(/* webpackChunkName: "vttjs" */ 'videojs-vtt.js').then((it) => {
+ window.WebVTT = it.WebVTT || it.default.WebVTT;
+ playerInstance.createSubtitlesSwitch();
+ });
+ };
+}
diff --git a/client/fluid-player/src/modules/suggestedVideos.js b/client/fluid-player/src/modules/suggestedVideos.js
new file mode 100644
index 0000000..7f3ab8a
--- /dev/null
+++ b/client/fluid-player/src/modules/suggestedVideos.js
@@ -0,0 +1,197 @@
+export default function (playerInstance, options) {
+ playerInstance.suggestedVideosGrid = null;
+
+ playerInstance.generateSuggestedVideoList = () => {
+ const configUrl = playerInstance.displayOptions.suggestedVideos.configUrl;
+
+ if (!configUrl) {
+ return;
+ }
+
+ playerInstance.sendRequestAsync(configUrl, false, 5000).then(({response}) => {
+ const config = JSON.parse(response);
+ const suggestedVideosGrid = playerInstance.generateSuggestedVideoGrid(config);
+
+ playerInstance.suggestedVideosGrid = suggestedVideosGrid;
+
+ }).catch(err => {
+ console.error('[FP_ERROR] given suggested videos config url is invalid or not found.', err);
+ })
+ };
+
+ playerInstance.generateSuggestedVideoGrid = (config) => {
+ const suggestedVideosGrid = document.createElement('div');
+ suggestedVideosGrid.className = 'suggested_tile_grid';
+
+ for (let i = 0; i < 12; i++) {
+ const videoTile = playerInstance.createVideoTile(config[i]);
+ suggestedVideosGrid.appendChild(videoTile);
+ }
+
+ return suggestedVideosGrid;
+ };
+
+ playerInstance.displaySuggestedVideos = () => {
+ const PlayerDOM = playerInstance.domRef.wrapper;
+ PlayerDOM.appendChild(playerInstance.suggestedVideosGrid);
+ };
+
+ playerInstance.clickSuggestedVideo = (sources, subtitles, configUrl) => {
+ playerInstance.toggleLoader(true);
+ playerInstance.hideSuggestedVideos();
+ playerInstance.resetPlayer(sources, subtitles, configUrl);
+
+ playerInstance.generateSuggestedVideoList();
+ };
+
+ playerInstance.resetPlayer = (sources, subtitles, configUrl) => {
+ const videoDOM = playerInstance.domRef.wrapper.querySelector(`#${playerInstance.videoPlayerId}`);
+ videoDOM.innerHTML = '';
+
+ let sourcesHTML = '';
+ if (sources) {
+ sources.forEach(source => {
+ sourcesHTML += ` `;
+ });
+ }
+ if (subtitles) {
+ subtitles.forEach(subtitle => {
+ sourcesHTML += ``;
+ });
+ }
+
+ videoDOM.innerHTML = sourcesHTML;
+
+ playerInstance.removeVideoSourcesListFromDOM();
+
+ const videoSourceList = playerInstance.domRef.wrapper.getElementsByClassName('fluid_control_video_source')[0];
+ videoSourceList.innerHTML = '';
+ playerInstance.domRef.player.src = '';
+ playerInstance.domRef.player.removeAttribute('src');
+ playerInstance.setVideoSource(sources[0].url);
+ playerInstance.createVideoSourceSwitch(false);
+ playerInstance.resetSubtitles();
+ playerInstance.setPersistentSettings(true);
+ playerInstance.loadInNewVideo();
+ playerInstance.resetAds();
+
+ // set new API config url
+ if (configUrl) {
+ playerInstance.displayOptions.suggestedVideos.configUrl = configUrl;
+ playerInstance.generateSuggestedVideoList();
+ }
+ }
+
+ playerInstance.createVideoTile = (config) => {
+ const videoTile = document.createElement('div');
+ videoTile.addEventListener('click', function () {
+ playerInstance.clickSuggestedVideo(config.sources, config.subtitles, config.configUrl);
+ }, false);
+ videoTile.className = 'suggested_tile';
+ videoTile.id = 'suggested_tile_' + config.id;
+
+ playerInstance.getImageTwoMostProminentColours(config.thumbnailUrl).then(mostProminentColors => {
+ if (mostProminentColors && mostProminentColors.length) {
+ videoTile.style = `background: ${mostProminentColors[0]};`;
+ }
+ });
+
+ const videoImage = document.createElement('img');
+ videoImage.src = config.thumbnailUrl;
+ videoImage.className = 'suggested_tile_image';
+
+ const videoTileOverlay = document.createElement('div');
+ videoTileOverlay.className='suggested_tile_overlay';
+ const title = document.createElement('p');
+ title.className = 'suggested_tile_title';
+ title.innerText = config.title;
+ videoTileOverlay.appendChild(title);
+
+ videoTile.appendChild(videoImage);
+ videoTile.appendChild(videoTileOverlay);
+
+ return videoTile;
+ }
+
+ playerInstance.resetSubtitles = () => {
+ playerInstance.removeSubtitlesListFromDOM();
+ const videoSubtitlesList = playerInstance.domRef.wrapper.getElementsByClassName('fluid_control_subtitles')[0];
+ videoSubtitlesList.innerHTML = '';
+ playerInstance.domRef.player.load();
+ playerInstance.createSubtitles(false);
+ }
+
+ playerInstance.loadInNewVideo = () => {
+ playerInstance.displayOptions.layoutControls.mediaType = playerInstance.getCurrentSrcType();
+ playerInstance.initialiseStreamers();
+ playerInstance.domRef.player.currentTime = 0;
+ playerInstance.domRef.player.mainVideoCurrentTime = 0;
+ playerInstance.setBuffering();
+ }
+
+ playerInstance.resetAds = () => {
+ // Clear midroll and postroll ads
+ playerInstance.timerPool = {};
+ playerInstance.rollsById = {};
+ playerInstance.adPool = {};
+ playerInstance.adGroupedByRolls = {};
+ playerInstance.onPauseRollAdPods = [];
+ playerInstance.currentOnPauseRollAd = '';
+
+ // Reset variables and flags, needed for assigning the different rolls correctly
+ playerInstance.isTimer = false;
+ playerInstance.timer = null;
+ playerInstance.firstPlayLaunched = false;
+
+ // Clear preroll ads
+ playerInstance.preRollAdsResolved = false;
+ playerInstance.preRollAdPods = [];
+ playerInstance.preRollAdPodsLength = 0;
+ playerInstance.preRollVastResolved = 0;
+ playerInstance.autoplayAfterAd = true;
+
+ // Wait until new selected video is buffered so we can get the video length
+ // This is needed for mid and post rolls to assign the correct time key to their respective triggers
+ const checkMainVideoDuration = () => {
+ if (!isNaN(playerInstance.domRef.player.duration) && playerInstance.domRef.player.duration > 0) {
+ playerInstance.toggleLoader(true);
+ playerInstance.mainVideoDuration = playerInstance.domRef.player.duration;
+
+ clearInterval(intervalId);
+
+ // Set up ads
+ playerInstance.setVastList();
+ playerInstance.checkForNextAd();
+ playerInstance.playPauseToggle();
+ }
+ };
+
+ const intervalId = setInterval(checkMainVideoDuration, 100);
+ }
+
+ playerInstance.removeVideoSourcesListFromDOM = () => {
+ const sourcesDOM = playerInstance.domRef.wrapper.getElementsByClassName('fluid_video_source_list_item');
+ for (let i = 0; i < sourcesDOM.length; i++) {
+ sourcesDOM[i].remove();
+ }
+ };
+
+ playerInstance.removeSubtitlesListFromDOM = () => {
+ const tracksDOM = playerInstance.domRef.wrapper.getElementsByClassName('fluid_subtitle_list_item');
+ for (let i = 0; i < tracksDOM.length; i++) {
+ tracksDOM[i].remove();
+ }
+ };
+
+ playerInstance.hideSuggestedVideos = () => {
+ const suggestedVideosDOM = playerInstance.domRef.wrapper.getElementsByClassName('suggested_tile_grid')[0];
+ if (suggestedVideosDOM) {
+ suggestedVideosDOM.remove();
+ }
+ };
+
+ playerInstance.isShowingSuggestedVideos = () => {
+ return !!playerInstance.domRef.wrapper.getElementsByClassName('suggested_tile_grid')[0];
+ }
+
+}
diff --git a/client/fluid-player/src/modules/timeline.js b/client/fluid-player/src/modules/timeline.js
new file mode 100644
index 0000000..24ce806
--- /dev/null
+++ b/client/fluid-player/src/modules/timeline.js
@@ -0,0 +1,202 @@
+export default function (playerInstance, options) {
+ playerInstance.setupThumbnailPreviewVtt = () => {
+ playerInstance.sendRequest(
+ playerInstance.displayOptions.layoutControls.timelinePreview.file,
+ true,
+ playerInstance.displayOptions.vastOptions.vastTimeout,
+ function () {
+ const convertVttRawData = function (vttRawData) {
+ if (!(
+ (typeof vttRawData.cues !== 'undefined') &&
+ (vttRawData.cues.length)
+ )) {
+ return [];
+ }
+
+ const result = [];
+ let tempThumbnailData = null;
+ let tempThumbnailCoordinates = null;
+
+ for (let i = 0; i < vttRawData.cues.length; i++) {
+ tempThumbnailData = vttRawData.cues[i].text.split('#');
+ let xCoords = 0, yCoords = 0, wCoords = 122.5, hCoords = 69;
+
+ // .vtt file contains sprite corrdinates
+ if (
+ (tempThumbnailData.length === 2) &&
+ (tempThumbnailData[1].indexOf('xywh=') === 0)
+ ) {
+ tempThumbnailCoordinates = tempThumbnailData[1].substring(5);
+ tempThumbnailCoordinates = tempThumbnailCoordinates.split(',');
+
+ if (tempThumbnailCoordinates.length === 4) {
+ playerInstance.displayOptions.layoutControls.timelinePreview.spriteImage = true;
+ xCoords = parseInt(tempThumbnailCoordinates[0]);
+ yCoords = parseInt(tempThumbnailCoordinates[1]);
+ wCoords = parseInt(tempThumbnailCoordinates[2]);
+ hCoords = parseInt(tempThumbnailCoordinates[3]);
+ }
+ }
+
+ let imageUrl;
+ if (playerInstance.displayOptions.layoutControls.timelinePreview.spriteRelativePath
+ && playerInstance.displayOptions.layoutControls.timelinePreview.file.indexOf('/') !== -1
+ && (typeof playerInstance.displayOptions.layoutControls.timelinePreview.sprite === 'undefined' || playerInstance.displayOptions.layoutControls.timelinePreview.sprite === '')
+ ) {
+ imageUrl = playerInstance.displayOptions.layoutControls.timelinePreview.file.substring(0, playerInstance.displayOptions.layoutControls.timelinePreview.file.lastIndexOf('/'));
+ imageUrl += '/' + tempThumbnailData[0];
+ } else {
+ imageUrl = (playerInstance.displayOptions.layoutControls.timelinePreview.sprite ? playerInstance.displayOptions.layoutControls.timelinePreview.sprite : tempThumbnailData[0]);
+ }
+
+ result.push({
+ startTime: vttRawData.cues[i].startTime,
+ endTime: vttRawData.cues[i].endTime,
+ image: imageUrl,
+ x: xCoords,
+ y: yCoords,
+ w: wCoords,
+ h: hCoords
+ });
+ }
+
+ return result;
+ };
+
+ const xmlHttpReq = this;
+
+ if ((xmlHttpReq.readyState === 4) && (xmlHttpReq.status !== 200)) {
+ //The response returned an error.
+ return;
+ }
+
+ if (!((xmlHttpReq.readyState === 4) && (xmlHttpReq.status === 200))) {
+ return;
+ }
+
+ const textResponse = xmlHttpReq.responseText;
+
+ const webVttParser = new window.WebVTTParser();
+ const vttRawData = webVttParser.parse(textResponse);
+
+ playerInstance.timelinePreviewData = convertVttRawData(vttRawData);
+ }
+ );
+ };
+
+ playerInstance.generateTimelinePreviewTags = () => {
+ const progressContainer = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+ const previewContainer = document.createElement('div');
+
+ previewContainer.className = 'fluid_timeline_preview_container';
+ previewContainer.style.display = 'none';
+ previewContainer.style.position = 'absolute';
+
+ progressContainer.appendChild(previewContainer);
+
+ //Shadow is needed to not trigger mouseleave event, that stops showing thumbnails, in case one scrubs a bit too fast and leaves current thumb before new one drawn.
+ const previewContainerShadow = document.createElement('div');
+ previewContainerShadow.className = 'fluid_timeline_preview_container_shadow';
+ previewContainerShadow.style.position = 'absolute';
+ previewContainerShadow.style.display = 'none';
+ previewContainerShadow.style.opacity = 1;
+ progressContainer.appendChild(previewContainerShadow);
+ };
+
+ playerInstance.getThumbnailCoordinates = (second) => {
+ if (playerInstance.timelinePreviewData.length) {
+ for (let i = 0; i < playerInstance.timelinePreviewData.length; i++) {
+ if ((second >= playerInstance.timelinePreviewData[i].startTime) && (second <= playerInstance.timelinePreviewData[i].endTime)) {
+ return playerInstance.timelinePreviewData[i];
+ }
+ }
+ }
+
+ return false;
+ };
+
+ playerInstance.drawTimelinePreview = (event) => {
+ const timelinePreviewTag = playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container');
+ const timelinePreviewShadow = playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container_shadow');
+ const progressContainer = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+ const totalWidth = progressContainer.clientWidth;
+
+ if (playerInstance.isCurrentlyPlayingAd) {
+ if (timelinePreviewTag.style.display !== 'none') {
+ timelinePreviewTag.style.display = 'none';
+ }
+
+ return;
+ }
+
+ //get the hover position
+ const hoverX = playerInstance.getEventOffsetX(event, progressContainer);
+ let hoverSecond = null;
+
+ if (totalWidth) {
+ hoverSecond = playerInstance.currentVideoDuration * hoverX / totalWidth;
+
+ //get the corresponding thumbnail coordinates
+ const thumbnailCoordinates = playerInstance.getThumbnailCoordinates(hoverSecond);
+ timelinePreviewShadow.style.width = totalWidth + 'px';
+ timelinePreviewShadow.style.display = 'block';
+
+ if (thumbnailCoordinates !== false) {
+ timelinePreviewTag.style.width = thumbnailCoordinates.w + 'px';
+ timelinePreviewTag.style.height = thumbnailCoordinates.h + 'px';
+ timelinePreviewShadow.style.height = thumbnailCoordinates.h + 'px';
+ timelinePreviewTag.style.background =
+ 'url(' + thumbnailCoordinates.image + ') no-repeat scroll -' + thumbnailCoordinates.x + 'px -' + thumbnailCoordinates.y + 'px';
+ timelinePreviewTag.style.left = hoverX - (thumbnailCoordinates.w / 2) + 'px';
+ timelinePreviewTag.style.display = 'block';
+ if (!playerInstance.displayOptions.layoutControls.timelinePreview.spriteImage) {
+ timelinePreviewTag.style.backgroundSize = 'contain';
+ }
+
+ } else {
+ timelinePreviewTag.style.display = 'none';
+ }
+ }
+ };
+
+ playerInstance.setupThumbnailPreview = () => {
+ let timelinePreview = playerInstance.displayOptions.layoutControls.timelinePreview;
+ if (!timelinePreview || !timelinePreview.type) {
+ return;
+ }
+
+ let eventOn = 'mousemove';
+ let eventOff = 'mouseleave';
+ if (playerInstance.mobileInfo.userOs) {
+ eventOn = 'touchmove';
+ eventOff = 'touchend';
+ }
+ playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container')
+ .addEventListener(eventOn, playerInstance.drawTimelinePreview.bind(playerInstance), false);
+ playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container')
+ .addEventListener(eventOff, function (event) {
+ const progress = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
+ if (typeof event.clientX !== 'undefined' && progress.contains(document.elementFromPoint(event.clientX, event.clientY))) {
+ //False positive (Chrome bug when fast click causes leave event)
+ return;
+ }
+ playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container').style.display = 'none';
+ playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container_shadow').style.display = 'none';
+ }, false);
+ playerInstance.generateTimelinePreviewTags();
+
+ if ('VTT' === timelinePreview.type && typeof timelinePreview.file === 'string') {
+ import(/* webpackChunkName: "webvtt" */ '../../vendor/webvtt').then((it) => {
+ window.WebVTTParser = it.default;
+ playerInstance.setupThumbnailPreviewVtt();
+ });
+ } else if ('static' === timelinePreview.type && typeof timelinePreview.frames === 'object') {
+ timelinePreview.spriteImage = true;
+ playerInstance.timelinePreviewData = timelinePreview.frames;
+ } else {
+ throw 'Invalid thumbnail-preview - type must be VTT or static';
+ }
+
+ playerInstance.showTimeOnHover = false;
+ };
+}
diff --git a/client/fluid-player/src/modules/utils.js b/client/fluid-player/src/modules/utils.js
new file mode 100644
index 0000000..5b63bb3
--- /dev/null
+++ b/client/fluid-player/src/modules/utils.js
@@ -0,0 +1,326 @@
+export default function (playerInstance, options) {
+ playerInstance.isTouchDevice = () => {
+ return !!('ontouchstart' in window // works on most browsers
+ || navigator.maxTouchPoints); // works on IE10/11 and Surface
+ };
+
+ /**
+ * Distinguishes iOS from Android devices and the OS version.
+ *
+ * This should be avoided in favor of capability detection.
+ *
+ * @deprecated deprecated as of v3.0
+ * @returns object
+ */
+ playerInstance.getMobileOs = () => {
+ const ua = navigator.userAgent || '';
+ const result = {device: false, userOs: false, userOsVer: false, userOsMajor: false};
+
+ let versionIndex;
+ // determine OS
+ if (ua.match(/Android/i)) {
+ result.userOs = 'Android';
+ versionIndex = ua.indexOf('Android ');
+ } else if (ua.match(/iPhone/i)) {
+ result.device = 'iPhone';
+ result.userOs = 'iOS';
+ versionIndex = ua.indexOf('OS ');
+ } else if (ua.match(/iPad/i)) {
+ result.device = 'iPad';
+ result.userOs = 'iOS';
+ versionIndex = ua.indexOf('OS ');
+ } else {
+ result.userOs = false;
+ }
+
+ // determine version
+ if ('iOS' === result.userOs && versionIndex > -1) {
+ const userOsTemp = ua.substr(versionIndex + 3);
+ const indexOfEndOfVersion = userOsTemp.indexOf(' ');
+
+ if (indexOfEndOfVersion !== -1) {
+ result.userOsVer = userOsTemp.substring(0, userOsTemp.indexOf(' ')).replace(/_/g, '.');
+ result.userOsMajor = parseInt(result.userOsVer);
+ }
+ } else if ('Android' === result.userOs && versionIndex > -1) {
+ result.userOsVer = ua.substr(versionIndex + 8, 3);
+ } else {
+ result.userOsVer = false;
+ }
+
+ return result;
+ };
+
+ /**
+ * Browser detection.
+ * This should be avoided in favor of capability detection.
+ *
+ * @deprecated deprecated as of v3.0
+ *
+ * @returns object
+ */
+ playerInstance.getBrowserVersion = () => {
+ const ua = navigator.userAgent || '';
+ const result = {browserName: false, fullVersion: false, majorVersion: false, userOsMajor: false};
+
+ let idx, uaindex;
+
+ try {
+ result.browserName = navigator.appName;
+
+ if ((idx = ua.indexOf('OPR/')) !== -1) {
+ result.browserName = 'Opera';
+ result.fullVersion = ua.substring(idx + 4);
+ } else if ((idx = ua.indexOf('Opera')) !== -1) {
+ result.browserName = 'Opera';
+ result.fullVersion = ua.substring(idx + 6);
+ if ((idx = ua.indexOf('Version')) !== -1)
+ result.fullVersion = ua.substring(idx + 8);
+ } else if ((idx = ua.indexOf('MSIE')) !== -1) {
+ result.browserName = 'Microsoft Internet Explorer';
+ result.fullVersion = ua.substring(idx + 5);
+ } else if ((idx = ua.indexOf('Chrome')) !== -1) {
+ result.browserName = 'Google Chrome';
+ result.fullVersion = ua.substring(idx + 7);
+ } else if ((idx = ua.indexOf('Safari')) !== -1) {
+ result.browserName = 'Safari';
+ result.fullVersion = ua.substring(idx + 7);
+ if ((idx = ua.indexOf('Version')) !== -1)
+ result.fullVersion = ua.substring(idx + 8);
+ } else if ((idx = ua.indexOf('Firefox')) !== -1) {
+ result.browserName = 'Mozilla Firefox';
+ result.fullVersion = ua.substring(idx + 8);
+ }
+
+ // Others "name/version" is at the end of userAgent
+ else if ((uaindex = ua.lastIndexOf(' ') + 1) < (idx = ua.lastIndexOf('/'))) {
+ result.browserName = ua.substring(uaindex, idx);
+ result.fullVersion = ua.substring(idx + 1);
+ if (result.browserName.toLowerCase() === result.browserName.toUpperCase()) {
+ result.browserName = navigator.appName;
+ }
+ }
+
+ // trim the fullVersion string at semicolon/space if present
+ if ((uaindex = result.fullVersion.indexOf(';')) !== -1) {
+ result.fullVersion = result.fullVersion.substring(0, uaindex);
+ }
+ if ((uaindex = result.fullVersion.indexOf(' ')) !== -1) {
+ result.fullVersion = result.fullVersion.substring(0, uaindex);
+ }
+
+ result.majorVersion = parseInt('' + result.fullVersion, 10);
+
+ if (isNaN(result.majorVersion)) {
+ result.fullVersion = '' + parseFloat(navigator.appVersion);
+ result.majorVersion = parseInt(navigator.appVersion, 10);
+ }
+ } catch (e) {
+ //Return default obj.
+ }
+
+ return result;
+ };
+
+ playerInstance.compareVersion = (v1, v2) => {
+ if (typeof v1 !== 'string') return false;
+ if (typeof v2 !== 'string') return false;
+ v1 = v1.split('.');
+ v2 = v2.split('.');
+ const k = Math.min(v1.length, v2.length);
+ for (let i = 0; i < k; ++i) {
+ v1[i] = parseInt(v1[i], 10);
+ v2[i] = parseInt(v2[i], 10);
+ if (v1[i] > v2[i]) return 1;
+ if (v1[i] < v2[i]) return -1;
+ }
+ return v1.length === v2.length ? 0 : (v1.length < v2.length ? -1 : 1);
+ };
+
+ playerInstance.convertTimeStringToSeconds = (str) => {
+ if (!(str && str.match(/^(\d){2}(:[0-5][0-9]){2}(.(\d){1,3})?$/))) {
+ return false;
+ }
+
+ const timeParts = str.split(':');
+ return ((parseInt(timeParts[0], 10)) * 3600) + ((parseInt(timeParts[1], 10)) * 60) + (parseInt(timeParts[2], 10));
+ };
+
+ // Format time to hh:mm:ss
+ playerInstance.formatTime = (duration) => {
+ const formatDateObj = new Date(duration * 1000);
+ const formatHours = playerInstance.pad(formatDateObj.getUTCHours());
+ const formatMinutes = playerInstance.pad(formatDateObj.getUTCMinutes());
+ const formatSeconds = playerInstance.pad(formatDateObj.getSeconds());
+
+ return formatHours >= 1
+ ? formatHours + ':' + formatMinutes + ':' + formatSeconds
+ : formatMinutes + ':' + formatSeconds;
+ };
+
+ playerInstance.pad = (value) => {
+ if (value < 10) {
+ return '0' + value;
+ }
+ return value;
+ };
+
+ /**
+ * Checks if element is fully visible in the viewport
+ *
+ * @param {Element} element
+ * @returns {boolean|null}
+ */
+ playerInstance.isElementVisible = (element) => {
+ if (!element) { return null; }
+
+ const rect = element.getBoundingClientRect();
+ return (
+ rect.top >= 0 &&
+ rect.left >= 0 &&
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+ );
+ }
+
+ playerInstance.observe = () => {
+ var observer = new IntersectionObserver(
+ function (entries) {
+ entries.forEach(function (entry) {
+ if (entry.intersectionRatio >= 0.5) {
+ playerInstance.domRef.player.inView = true;
+ }
+
+ if (entry.intersectionRatio == 0 && entry.target.glast) {
+ playerInstance.domRef.player.inView = false;
+ }
+ });
+ },
+ {
+ threshold: [0.0, 0.5],
+ },
+ );
+
+ observer.observe(playerInstance.domRef.wrapper);
+ }
+
+ /**
+ * Throttles callback by time
+ *
+ * @param callback
+ * @param time
+ * @returns {function(): void}
+ */
+ playerInstance.throttle = function throttle(callback, time) {
+ let throttleControl = false;
+
+ return function () {
+ if (!throttleControl) {
+ callback.apply(this, arguments);
+ throttleControl = true;
+ setTimeout(function () {
+ throttleControl = false;
+ }, time);
+ }
+ }
+ }
+
+ playerInstance.getImageTwoMostProminentColours = (imageUrl) => {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+ img.crossOrigin = 'Anonymous';
+ img.src = imageUrl;
+
+ img.onload = () => {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0, img.width, img.height);
+ const imageData = ctx.getImageData(0, 0, img.width, img.height).data;
+
+ const colorCount = {};
+ for (let i = 0; i < imageData.length; i += 4) {
+ const r = imageData[i];
+ const g = imageData[i + 1];
+ const b = imageData[i + 2];
+ const color = `rgb(${r},${g},${b})`;
+
+ if (colorCount[color]) {
+ colorCount[color]++;
+ } else {
+ colorCount[color] = 1;
+ }
+ }
+
+ const rgbToHsl = (r, g, b) => {
+ r /= 255, g /= 255, b /= 255;
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
+ let h, s, l = (max + min) / 2;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ const d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+
+ return [h, s, l];
+ };
+
+ const sortedColors = Object.keys(colorCount).map(color => {
+ const [r, g, b] = color.match(/\d+/g).map(Number);
+ const [h, s, l] = rgbToHsl(r, g, b);
+ return { color, h, s, l, score: s + (1 - Math.abs(2 * l - 1)) };
+ }).sort((a, b) => b.score - a.score);
+
+ const isCloseToBlack = (color) => {
+ const rgb = color.match(/\d+/g).map(Number);
+ const blackThreshold = 40;
+ return rgb[0] < blackThreshold && rgb[1] < blackThreshold && rgb[2] < blackThreshold;
+ };
+
+ const minHueDifference = 0.1;
+ const minSaturationDifference = 0.1;
+ const minLightnessDifference = 0.1;
+
+ let mostVibrantColors = [];
+
+ for (const colorObj of sortedColors) {
+ if (mostVibrantColors.length === 2) break;
+ if (!isCloseToBlack(colorObj.color)) {
+ const enoughDifference = mostVibrantColors.every(existingColor => {
+ const hueDifference = Math.abs(colorObj.h - existingColor.h);
+ const saturationDifference = Math.abs(colorObj.s - existingColor.s);
+ const lightnessDifference = Math.abs(colorObj.l - existingColor.l);
+ return (
+ hueDifference >= minHueDifference &&
+ saturationDifference >= minSaturationDifference &&
+ lightnessDifference >= minLightnessDifference
+ );
+ });
+ if (enoughDifference) {
+ mostVibrantColors.push(colorObj);
+ }
+ }
+ }
+
+ if (mostVibrantColors.length < 2) {
+ mostVibrantColors = sortedColors.slice(0, 2);
+ }
+
+ resolve(mostVibrantColors.map(colorObj => colorObj.color));
+ };
+
+ img.onerror = () => {
+ reject(new Error('Failed to load image'));
+ };
+ });
+ }
+}
diff --git a/client/fluid-player/src/modules/vast.js b/client/fluid-player/src/modules/vast.js
new file mode 100644
index 0000000..b69735c
--- /dev/null
+++ b/client/fluid-player/src/modules/vast.js
@@ -0,0 +1,1122 @@
+// @ts-check
+
+// VAST support module
+
+/* Type declarations */
+
+/**
+ * @typedef {Object} RawAdTree
+ * @property {Array} children
+ * @property {XMLDocument} data
+ * @property {'inLine'|'wrapper'} tagType
+ * @property {boolean|undefined} fallbackOnNoAd
+ * @property {Array | undefined} wrappers
+*/
+
+/**
+ * @typedef {Object} RawAd
+ * @property {XMLDocument} data
+ * @property {Array} wrappers
+ * @property {'inLine' | 'wrapper'} tagType
+ */
+
+/**
+ * @typedef {Object & RawAd} Ad
+ * @property {Array} clicktracking
+ * @property {string} errorUrl
+ * @property {Array} impressions
+ * @property {Array} viewImpression
+ * @property {Array} stopTracking
+ * @property {Array} tracking
+ * @property {number|null} sequence
+ * @property {number} duration
+ * @property {boolean} played
+ */
+
+/**
+ *
+ * @param {import("../fluidplayer.js").FluidPlayer} playerInstance
+ * @param {unknown} options
+ */
+function vast(playerInstance, options) {
+ /**
+ * Gets CTA parameters from VAST and sets them on tempOptions
+ *
+ * Fallbacks to any value that is filled on the TitleCTA extension, but needs at least an url and a text
+ *
+ * @param {HTMLElement} titleCtaElement
+ *
+ * @param {any} tmpOptions
+ */
+ playerInstance.setCTAFromVast = (titleCtaElement, tmpOptions) => {
+ if (playerInstance.displayOptions.vastOptions.adCTATextVast && titleCtaElement) {
+ const mobileText = playerInstance.extractNodeDataByTagName(titleCtaElement, 'MobileText');
+ const desktopText = playerInstance.extractNodeDataByTagName(titleCtaElement, 'PCText');
+ const link =
+ playerInstance.extractNodeDataByTagName(titleCtaElement, 'DisplayUrl') ||
+ playerInstance.extractNodeDataByTagName(titleCtaElement, 'Link');
+ const tracking = playerInstance.extractNodeDataByTagName(titleCtaElement, 'Tracking');
+ const isMobile = window.matchMedia('(max-width: 768px)').matches;
+
+ if ((desktopText || mobileText) && tracking) {
+ tmpOptions.titleCTA = {
+ text: isMobile ?
+ mobileText || desktopText :
+ desktopText || mobileText,
+ link: link || null,
+ tracking,
+ }
+ }
+ }
+ };
+
+ playerInstance.getClickThroughUrlFromLinear = (linear) => {
+ const videoClicks = linear.getElementsByTagName('VideoClicks');
+
+ if (videoClicks.length) { //There should be exactly 1 node
+ const clickThroughs = videoClicks[0].getElementsByTagName('ClickThrough');
+
+ if (clickThroughs.length) {
+ return playerInstance.extractNodeData(clickThroughs[0]);
+ }
+ }
+
+ return false;
+ };
+
+ playerInstance.getVastAdTagUriFromWrapper = (xmlResponse) => {
+ const wrapper = xmlResponse.getElementsByTagName('Wrapper');
+
+ if (typeof wrapper !== 'undefined' && wrapper.length) {
+ const vastAdTagURI = wrapper[0].getElementsByTagName('VASTAdTagURI');
+
+ if (vastAdTagURI.length) {
+ return playerInstance.extractNodeData(vastAdTagURI[0]);
+ }
+ }
+
+ return false;
+ };
+
+ playerInstance.hasInLine = (xmlResponse) => {
+ const inLine = xmlResponse.getElementsByTagName('InLine');
+ return ((typeof inLine !== 'undefined') && inLine.length);
+ };
+
+ playerInstance.hasVastAdTagUri = (xmlResponse) => {
+ const vastAdTagURI = xmlResponse.getElementsByTagName('VASTAdTagURI');
+ return ((typeof vastAdTagURI !== 'undefined') && vastAdTagURI.length);
+ };
+
+ playerInstance.getClickThroughUrlFromNonLinear = (nonLinear) => {
+ let result = '';
+ const nonLinears = nonLinear.getElementsByTagName('NonLinear');
+
+ if (nonLinears.length) {//There should be exactly 1 node
+ const nonLinearClickThrough = nonLinear.getElementsByTagName('NonLinearClickThrough');
+ if (nonLinearClickThrough.length) {
+ result = playerInstance.extractNodeData(nonLinearClickThrough[0]);
+ }
+ }
+
+ return result;
+ };
+
+ playerInstance.getTrackingFromLinear = (linear) => {
+ const trackingEvents = linear.getElementsByTagName('TrackingEvents');
+
+ if (trackingEvents.length) {//There should be no more than one node
+ return trackingEvents[0].getElementsByTagName('Tracking');
+ }
+
+ return [];
+ };
+
+ playerInstance.getDurationFromLinear = (linear) => {
+ const duration = linear.getElementsByTagName('Duration');
+
+ if (duration.length && (typeof duration[0].childNodes[0] !== 'undefined')) {
+ const nodeDuration = playerInstance.extractNodeData(duration[0]);
+ return playerInstance.convertTimeStringToSeconds(nodeDuration);
+ }
+
+ return false;
+ };
+
+ playerInstance.getDurationFromNonLinear = (tag) => {
+ let result = 0;
+ const nonLinear = tag.getElementsByTagName('NonLinear');
+ if (nonLinear.length && (typeof nonLinear[0].getAttribute('minSuggestedDuration') !== 'undefined')) {
+ result = playerInstance.convertTimeStringToSeconds(nonLinear[0].getAttribute('minSuggestedDuration'));
+ }
+ return result;
+ };
+
+ playerInstance.getDimensionFromNonLinear = (tag) => {
+ const result = { 'width': null, 'height': null };
+ const nonLinear = tag.getElementsByTagName('NonLinear');
+
+ if (nonLinear.length) {
+ if (typeof nonLinear[0].getAttribute('width') !== 'undefined') {
+ result.width = nonLinear[0].getAttribute('width');
+ }
+ if (typeof nonLinear[0].getAttribute('height') !== 'undefined') {
+ result.height = nonLinear[0].getAttribute('height');
+ }
+ }
+
+ return result;
+ };
+
+ playerInstance.getCreativeTypeFromStaticResources = (tag) => {
+ let result = '';
+ const nonLinears = tag.getElementsByTagName('NonLinear');
+
+ if (nonLinears.length && (typeof nonLinears[0].childNodes[0] !== 'undefined')) {//There should be exactly 1 StaticResource node
+ result = nonLinears[0].getElementsByTagName('StaticResource')[0].getAttribute('creativeType');
+ }
+
+ return result.toLowerCase();
+ };
+
+ playerInstance.getMediaFilesFromLinear = (linear) => {
+ const mediaFiles = linear.getElementsByTagName('MediaFiles');
+
+ if (mediaFiles.length) {//There should be exactly 1 MediaFiles node
+ return mediaFiles[0].getElementsByTagName('MediaFile');
+ }
+
+ return [];
+ };
+
+ playerInstance.getStaticResourcesFromNonLinear = (linear) => {
+ let result = [];
+ const nonLinears = linear.getElementsByTagName('NonLinear');
+
+ if (nonLinears.length) {//There should be exactly 1 StaticResource node
+ result = nonLinears[0].getElementsByTagName('StaticResource');
+ }
+
+ return result;
+ };
+
+ /**
+ * Gets the first element found by tag name, and returns the element data
+ *
+ * @param {HTMLElement} parentNode
+ *
+ * @param {string} tagName
+ *
+ * @returns {string|null}
+ */
+ playerInstance.extractNodeDataByTagName = (parentNode, tagName) => {
+ const element = parentNode.getElementsByTagName(tagName);
+
+ if (element && element.length) {
+ return playerInstance.extractNodeData(element[0]);
+ } else {
+ return null;
+ }
+ };
+
+ playerInstance.extractNodeData = (parentNode) => {
+ let contentAsString = "";
+ for (let n = 0; n < parentNode.childNodes.length; n++) {
+ const child = parentNode.childNodes[n];
+ if (child.nodeType === 8 || (child.nodeType === 3 && /^\s*$/.test(child.nodeValue))) {
+ // Comments or text with no content
+ } else {
+ contentAsString += child.nodeValue;
+ }
+ }
+ return contentAsString.replace(/(^\s+|\s+$)/g, '');
+ };
+
+ playerInstance.getAdParametersFromLinear = (linear) => {
+ const adParameters = linear.getElementsByTagName('AdParameters');
+ let adParametersData = null;
+
+ if (adParameters.length) {
+ adParametersData = playerInstance.extractNodeData(adParameters[0]);
+ }
+
+ return adParametersData;
+ };
+
+ playerInstance.getMediaFileListFromLinear = (linear) => {
+ const mediaFileList = [];
+ const mediaFiles = playerInstance.getMediaFilesFromLinear(linear);
+
+ if (!mediaFiles.length) {
+ return mediaFileList;
+ }
+
+ for (let n = 0; n < mediaFiles.length; n++) {
+ let mediaType = mediaFiles[n].getAttribute('mediaType');
+
+ if (!mediaType) {
+ // if there is no mediaType attribute then the video is 2D
+ mediaType = '2D';
+ }
+
+ // get all the attributes of media file
+ mediaFileList.push({
+ 'src': playerInstance.extractNodeData(mediaFiles[n]),
+ 'type': mediaFiles[n].getAttribute('type'),
+ 'apiFramework': mediaFiles[n].getAttribute('apiFramework'),
+ 'codec': mediaFiles[n].getAttribute('codec'),
+ 'id': mediaFiles[n].getAttribute('codec'),
+ 'fileSize': mediaFiles[n].getAttribute('fileSize'),
+ 'delivery': mediaFiles[n].getAttribute('delivery'),
+ 'width': mediaFiles[n].getAttribute('width'),
+ 'height': mediaFiles[n].getAttribute('height'),
+ 'mediaType': mediaType.toLowerCase()
+ });
+
+ }
+
+ return mediaFileList;
+ };
+
+ playerInstance.getIconClickThroughFromLinear = (linear) => {
+ const iconClickThrough = linear.getElementsByTagName('IconClickThrough');
+
+ if (iconClickThrough.length) {
+ return playerInstance.extractNodeData(iconClickThrough[0]);
+ }
+
+ return '';
+ };
+
+ playerInstance.getStaticResourceFromNonLinear = (linear) => {
+ let fallbackStaticResource;
+ const staticResources = playerInstance.getStaticResourcesFromNonLinear(linear);
+
+ for (let i = 0; i < staticResources.length; i++) {
+ if (!staticResources[i].getAttribute('type')) {
+ fallbackStaticResource = playerInstance.extractNodeData(staticResources[i]);
+ }
+
+ if (staticResources[i].getAttribute('type') === playerInstance.displayOptions.staticResource) {
+ return playerInstance.extractNodeData(staticResources[i]);
+ }
+ }
+
+ return fallbackStaticResource;
+ };
+
+ playerInstance.registerTrackingEvents = (creativeLinear, tmpOptions) => {
+ const trackingEvents = playerInstance.getTrackingFromLinear(creativeLinear);
+ let eventType = '';
+ let oneEventOffset = 0;
+
+ for (let i = 0; i < trackingEvents.length; i++) {
+ eventType = trackingEvents[i].getAttribute('event');
+
+ switch (eventType) {
+ case 'start':
+ case 'firstQuartile':
+ case 'midpoint':
+ case 'thirdQuartile':
+ case 'complete':
+ if (typeof tmpOptions.tracking[eventType] === 'undefined') {
+ tmpOptions.tracking[eventType] = [];
+ }
+
+ if (typeof tmpOptions.stopTracking[eventType] === 'undefined') {
+ tmpOptions.stopTracking[eventType] = [];
+ }
+ tmpOptions.tracking[eventType].push(trackingEvents[i].textContent.trim());
+ tmpOptions.stopTracking[eventType] = false;
+
+ break;
+
+ case 'progress':
+ if (typeof tmpOptions.tracking[eventType] === 'undefined') {
+ tmpOptions.tracking[eventType] = [];
+ }
+
+ oneEventOffset = playerInstance.convertTimeStringToSeconds(trackingEvents[i].getAttribute('offset'));
+
+ if (typeof tmpOptions.tracking[eventType][oneEventOffset] === 'undefined') {
+ tmpOptions.tracking[eventType][oneEventOffset] = {
+ elements: [],
+ stopTracking: false
+ };
+ }
+
+ tmpOptions.tracking[eventType][oneEventOffset].elements.push(trackingEvents[i].textContent.trim());
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ };
+
+ playerInstance.registerClickTracking = (clickTrackingTag, tmpOptions) => {
+ if (!clickTrackingTag || !clickTrackingTag.length) {
+ return;
+ }
+
+ for (let i = 0; i < clickTrackingTag.length; i++) {
+ if (clickTrackingTag[i] === '') {
+ continue;
+ }
+
+ tmpOptions.clicktracking.push(clickTrackingTag[i]);
+ }
+
+ };
+
+ playerInstance.registerViewableImpressionEvents = (viewableImpressionTags, tmpOptions) => {
+ if (!viewableImpressionTags.length) {
+ return;
+ }
+
+ for (let i = 0; i < viewableImpressionTags.length; i++) {
+ const viewableImpressionEvent = playerInstance.extractNodeData(viewableImpressionTags[i]);
+ tmpOptions.viewImpression.push(viewableImpressionEvent);
+ }
+ };
+
+ playerInstance.registerImpressionEvents = (impressionTags, tmpOptions) => {
+ if (!impressionTags.length) {
+ return;
+ }
+
+ for (let i = 0; i < impressionTags.length; i++) {
+ const impressionEvent = playerInstance.extractNodeData(impressionTags[i]);
+ tmpOptions.impression.push(impressionEvent);
+ }
+ };
+
+ playerInstance.registerErrorEvents = (errorTags, tmpOptions) => {
+ if ((typeof errorTags !== 'undefined') &&
+ (errorTags !== null) &&
+ (errorTags.length === 1) && //Only 1 Error tag is expected
+ (errorTags[0].childNodes.length === 1)) {
+ tmpOptions.errorUrl = errorTags[0].childNodes[0].nodeValue;
+ }
+ };
+
+ playerInstance.announceError = (code) => {
+ if (typeof playerInstance.vastOptions.errorUrl === 'undefined' || !playerInstance.vastOptions.errorUrl) {
+ return;
+ }
+
+ const parsedCode = typeof code !== 'undefined' ? parseInt(code) : 900;
+ const errorUrl = playerInstance.vastOptions.errorUrl.replace('[ERRORCODE]', parsedCode);
+
+ //Send the error request
+ playerInstance.callUris([errorUrl]);
+ };
+
+ playerInstance.getClickTrackingEvents = (linear) => {
+ const result = [];
+
+ const videoClicks = linear.getElementsByTagName('VideoClicks');
+
+ //There should be exactly 1 node
+ if (!videoClicks.length) {
+ return;
+ }
+
+ const clickTracking = videoClicks[0].getElementsByTagName('ClickTracking');
+
+ if (!clickTracking.length) {
+ return;
+ }
+
+ for (let i = 0; i < clickTracking.length; i++) {
+ const clickTrackingEvent = playerInstance.extractNodeData(clickTracking[i]);
+ result.push(clickTrackingEvent);
+ }
+
+ return result;
+ };
+
+ playerInstance.getNonLinearClickTrackingEvents = (nonLinear) => {
+ const result = [];
+ const nonLinears = nonLinear.getElementsByTagName('NonLinear');
+
+ if (!nonLinears.length) {
+ return;
+ }
+
+ const clickTracking = nonLinear.getElementsByTagName('NonLinearClickTracking');
+
+ if (!clickTracking.length) {
+ return;
+ }
+
+ for (let i = 0; i < clickTracking.length; i++) {
+ const NonLinearClickTracking = playerInstance.extractNodeData(clickTracking[i]);
+ result.push(NonLinearClickTracking);
+ }
+
+ return result;
+ };
+
+ // TODO: ???
+ playerInstance.callUris = (uris) => {
+ for (let i = 0; i < uris.length; i++) {
+ new Image().src = uris[i];
+ }
+ };
+
+ playerInstance.recalculateAdDimensions = () => {
+ const videoPlayer = playerInstance.domRef.player;
+ const divClickThrough = playerInstance.domRef.wrapper.querySelector('.vast_clickthrough_layer');
+
+ if (divClickThrough) {
+ divClickThrough.style.width = videoPlayer.offsetWidth + 'px';
+ divClickThrough.style.height = videoPlayer.offsetHeight + 'px';
+ }
+
+ const requestFullscreenFunctionNames = playerInstance.checkFullscreenSupport();
+ const fullscreenButton = playerInstance.domRef.wrapper.querySelector('.fluid_control_fullscreen');
+ const menuOptionFullscreen = playerInstance.domRef.wrapper.querySelector('.context_option_fullscreen');
+
+ if (requestFullscreenFunctionNames) {
+ // this will go other way around because we already exited full screen
+ if (document[requestFullscreenFunctionNames.isFullscreen] === null) {
+ // Exit fullscreen
+ playerInstance.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ } else {
+ // Go fullscreen
+ playerInstance.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ }
+ } else {
+ // TODO: I am fairly certain this fallback does not work...
+ //The browser does not support the Fullscreen API, so a pseudo-fullscreen implementation is used
+ const fullscreenTag = playerInstance.domRef.wrapper;
+
+ if (fullscreenTag.className.search(/\bpseudo_fullscreen\b/g) !== -1) {
+ fullscreenTag.className += ' pseudo_fullscreen';
+ playerInstance.fullscreenOn(fullscreenButton, menuOptionFullscreen);
+ } else {
+ fullscreenTag.className = fullscreenTag.className.replace(/\bpseudo_fullscreen\b/g, '');
+ playerInstance.fullscreenOff(fullscreenButton, menuOptionFullscreen);
+ }
+ }
+ };
+
+ /**
+ * Prepares VAST for instant ads
+ *
+ * @param roll
+ */
+ playerInstance.prepareVast = (roll) => {
+ let list = playerInstance.findRoll(roll);
+
+ for (let i = 0; i < list.length; i++) {
+ const rollListId = list[i];
+
+ if (!(playerInstance.rollsById[rollListId].vastLoaded !== true && playerInstance.rollsById[rollListId].error !== true)) {
+ continue;
+ }
+
+ playerInstance.processVastWithRetries(playerInstance.rollsById[rollListId]);
+ }
+ };
+
+ playerInstance.playMainVideoWhenVastFails = (errorCode) => {
+ playerInstance.debugMessage('playMainVideoWhenVastFails called');
+ playerInstance.domRef.player.removeEventListener('loadedmetadata', playerInstance.switchPlayerToVastMode);
+ playerInstance.domRef.player.pause();
+ playerInstance.toggleLoader(false);
+ playerInstance.displayOptions.vastOptions.vastAdvanced.noVastVideoCallback();
+
+ if (!playerInstance.vastOptions || typeof playerInstance.vastOptions.errorUrl === 'undefined') {
+ playerInstance.announceLocalError(errorCode);
+ } else {
+ playerInstance.announceError(errorCode);
+ }
+
+ playerInstance.switchToMainVideo();
+ };
+
+ // TODO: ???
+ playerInstance.switchPlayerToVastMode = () => {
+ };
+
+ /**
+ * Process the XML response
+ *
+ * @param ad
+ */
+ function processAdCreatives(ad) {
+ const adElement = ad.data;
+
+ if (!adElement) {
+ return;
+ }
+
+ const creativeElements = Array.from(adElement.getElementsByTagName('Creative'));
+
+ if (creativeElements.length) {
+ for (let i = 0; i < creativeElements.length; i++) {
+ const creativeElement = creativeElements[i];
+
+ try {
+ if (ad.adType === 'linear') {
+ const linearCreatives = creativeElement.getElementsByTagName('Linear');
+ const creativeLinear = linearCreatives[0];
+
+ //Extract the Ad data if it is actually the Ad (!wrapper)
+ if (!playerInstance.hasVastAdTagUri(adElement) && playerInstance.hasInLine(adElement)) {
+ //Set initial values
+ ad.adFinished = false;
+ ad.vpaid = false;
+
+ //Extract the necessary data from the Linear node
+ ad.skipoffset = playerInstance.convertTimeStringToSeconds(creativeLinear.getAttribute('skipoffset'));
+ ad.clickthroughUrl = playerInstance.getClickThroughUrlFromLinear(creativeLinear);
+ ad.duration = playerInstance.getDurationFromLinear(creativeLinear);
+ ad.mediaFileList = playerInstance.getMediaFileListFromLinear(creativeLinear);
+ ad.adParameters = playerInstance.getAdParametersFromLinear(creativeLinear);
+ ad.iconClick = ad.iconClick || playerInstance.getIconClickThroughFromLinear(creativeLinear);
+
+ if (ad.adParameters) {
+ ad.vpaid = true;
+ }
+ }
+ }
+
+ if (ad.adType === 'nonLinear') {
+ const nonLinearCreatives = creativeElement.getElementsByTagName('NonLinearAds');
+ const creativeNonLinear = nonLinearCreatives[0];
+
+ //Extract the Ad data if it is actually the Ad (!wrapper)
+ if (!playerInstance.hasVastAdTagUri(adElement) && playerInstance.hasInLine(adElement)) {
+ //Set initial values
+ ad.vpaid = false;
+
+ //Extract the necessary data from the NonLinear node
+ ad.clickthroughUrl = playerInstance.getClickThroughUrlFromNonLinear(creativeNonLinear);
+ ad.duration = playerInstance.getDurationFromNonLinear(creativeNonLinear); // VAST version < 4.0
+ ad.dimension = playerInstance.getDimensionFromNonLinear(creativeNonLinear); // VAST version < 4.0
+ ad.staticResource = playerInstance.getStaticResourceFromNonLinear(creativeNonLinear);
+ ad.creativeType = playerInstance.getCreativeTypeFromStaticResources(creativeNonLinear);
+ ad.adParameters = playerInstance.getAdParametersFromLinear(creativeNonLinear);
+
+ if (ad.adParameters) {
+ ad.vpaid = true;
+ }
+ }
+ }
+
+ // Current support is for only one creative element
+ // break the loop if creative was successful
+ break;
+ } catch (err) {
+ if (creativeElement.firstElementChild &&
+ !(creativeElement.firstElementChild.tagName === 'Linear' ||
+ creativeElement.firstElementChild.tagName === 'NonLinearAds')) {
+ console.warn('Skipping ' + creativeElement.firstElementChild.tagName + ', this might not be supported yet.')
+ }
+ console.error(err);
+ }
+ };
+ }
+
+ return ad;
+ }
+
+ /**
+ * Parse the VAST Tag
+ *
+ * @param vastObj
+ */
+ playerInstance.processVastWithRetries = (vastObj) => {
+ let vastTag = vastObj.vastTag;
+ const rollListId = vastObj.id;
+
+ playerInstance.domRef.player.addEventListener('adId_' + rollListId, playerInstance[vastObj.roll]);
+
+ const handleVastResult = function (pass, adOptionsList) {
+ if (pass && Array.isArray(adOptionsList) && !playerInstance.displayOptions.vastOptions.allowVPAID && adOptionsList.some(adOptions => adOptions.vpaid)) {
+ adOptionsList = adOptionsList.filter(adOptions => adOptions.vpaid !== true);
+ playerInstance.announceLocalError('103', 'VPAID not allowed, so skipping this VAST tag.')
+ }
+
+ if (pass && Array.isArray(adOptionsList) && adOptionsList.length) {
+
+ playerInstance.adPool[rollListId] = [];
+
+ adOptionsList.forEach((tmpOptions, index) => {
+ tmpOptions.id = rollListId + '_AD' + index;
+ tmpOptions.rollListId = rollListId;
+
+ if (tmpOptions.adType === 'linear') {
+
+ if ((typeof tmpOptions.iconClick !== 'undefined') && (tmpOptions.iconClick !== null) && tmpOptions.iconClick.length) {
+ tmpOptions.landingPage = tmpOptions.iconClick;
+ }
+
+ const selectedMediaFile = playerInstance.getSupportedMediaFileObject(tmpOptions.mediaFileList);
+ if (selectedMediaFile) {
+ tmpOptions.mediaType = selectedMediaFile.mediaType;
+ }
+
+ }
+
+ tmpOptions.adType = tmpOptions.adType ? tmpOptions.adType : 'unknown';
+ playerInstance.adPool[rollListId].push(Object.assign({}, tmpOptions));
+
+ if (playerInstance.hasTitle()) {
+ const title = playerInstance.domRef.wrapper.querySelector('.fp_title');
+ title.style.display = 'none';
+ }
+
+ playerInstance.rollsById[rollListId].ads.push(tmpOptions);
+ });
+
+ playerInstance.rollsById[rollListId].vastLoaded = true;
+
+ const event = document.createEvent('Event');
+
+ event.initEvent('adId_' + rollListId, false, true);
+ playerInstance.domRef.player.dispatchEvent(event);
+ playerInstance.displayOptions.vastOptions.vastAdvanced.vastLoadedCallback();
+ } else {
+ // when vast failed
+ playerInstance.announceLocalError('101');
+
+ if (vastObj.hasOwnProperty('fallbackVastTags') && vastObj.fallbackVastTags.length > 0) {
+ vastTag = vastObj.fallbackVastTags.shift();
+ playerInstance.processUrl(vastTag, handleVastResult, rollListId);
+ } else {
+ if (vastObj.roll === 'preRoll') {
+ playerInstance.preRollFail(vastObj);
+ }
+ playerInstance.rollsById[rollListId].error = true;
+ }
+ }
+ };
+
+ playerInstance.processUrl(vastTag, handleVastResult, rollListId);
+ };
+
+ playerInstance.processUrl = (vastTag, callBack, rollListId) => {
+ const numberOfRedirects = 0;
+
+ const tmpOptions = {
+ tracking: [],
+ stopTracking: [],
+ impression: [],
+ viewImpression: [],
+ clicktracking: [],
+ vastLoaded: false
+ };
+
+ playerInstance.resolveVastTag(
+ vastTag,
+ numberOfRedirects,
+ tmpOptions,
+ callBack,
+ rollListId
+ );
+ };
+
+ /**
+ * Gets first stand-alone ad
+ *
+ * @param {Array} ads
+ * @returns {Array}
+ */
+ function getFirstStandAloneAd(ads) {
+ for (const ad of ads) {
+ const isAdPod = ad.data.attributes.sequence !== undefined;
+
+ if (!isAdPod) {
+ return [ad];
+ }
+ }
+
+ return [];
+ }
+
+ /**
+ * Resolves ad requests recursively and returns a tree of "Ad" and "Wrapper" elements
+ *
+ * @param {string} url vast resource url
+ * @param {number} maxDepth depth of recursive calls (wrapper depth)
+ * @param {Partial} baseNode used for recursive calls as base node
+ * @param {number} currentDepth used internally to track depth
+ * @param {boolean} followAdditionalWrappers used internally to track nested wrapper calls
+ * @returns {Promise}
+ */
+ async function resolveAdTreeRequests(url, maxDepth, baseNode = {}, currentDepth = 0, followAdditionalWrappers = true) {
+ const adTree = { ...baseNode, children: [] };
+ const { responseXML } = await playerInstance.sendRequestAsync(url, true, playerInstance.displayOptions.vastOptions.vastTimeout);
+ const adElements = Array.from(responseXML.getElementsByTagName('Ad'));
+
+ for (const adElement of adElements) {
+ const vastAdTagUri = playerInstance.getVastAdTagUriFromWrapper(adElement);
+ const isAdPod = adElement.attributes.sequence !== undefined;
+ const adNode = { data: adElement };
+
+ if (vastAdTagUri && currentDepth <= maxDepth && followAdditionalWrappers) {
+ const [wrapperElement] = adElement.getElementsByTagName('Wrapper');
+ const disableAdditionalWrappers = wrapperElement.attributes.followAdditionalWrappers && ["false", "0"].includes(wrapperElement.attributes.followAdditionalWrappers.value); // See VAST Wrapper spec
+ const allowMultipleAds = wrapperElement.attributes.allowMultipleAds && ["true", "1"].includes(wrapperElement.attributes.allowMultipleAds.value); // See VAST Wrapper spec
+ const fallbackOnNoAd = wrapperElement.attributes.fallbackOnNoAd && ["true", "1"].includes(wrapperElement.attributes.fallbackOnNoAd.value);
+
+ try {
+ const wrapperResponse = await resolveAdTreeRequests(vastAdTagUri, maxDepth, { tagType: 'wrapper', ...adNode, fallbackOnNoAd }, currentDepth+1, !disableAdditionalWrappers);
+ wrapperResponse.fallbackOnNoAd = fallbackOnNoAd;
+
+ if (!allowMultipleAds || isAdPod) {
+ wrapperResponse.children = getFirstStandAloneAd(wrapperResponse.children);
+ }
+
+ adTree.children.push(wrapperResponse);
+ } catch (e) {
+ adTree.children.push({ tagType: `wrapper`, fallbackOnNoAd, httpError: true })
+ playerInstance.debugMessage(`Error when loading Wrapper, will trigger fallback if available`, e);
+ }
+ } else if (!vastAdTagUri) {
+ let mediaFileIsValid = true;
+ let mediaFileUrl = '';
+ if (Array.from(adElement.getElementsByTagName('AdParameters')).length) {
+ const mediaFiles = Array.from(adElement.getElementsByTagName('AdParameters'));
+ mediaFileIsValid = false;
+ for (const mediaFile of mediaFiles) {
+ mediaFileUrl = mediaFile.textContent.trim();
+ try {
+ const mediaFileObj = JSON.parse(mediaFileUrl);
+ mediaFileUrl = mediaFileObj.videos[0].url;
+ } catch (error) {
+ console.error("Error parsing media file URL:", error);
+ }
+ }
+ } else if (Array.from(adElement.getElementsByTagName('MediaFiles')).length) {
+ const mediaFiles = Array.from(adElement.getElementsByTagName('MediaFiles'));
+ const mediaFile = mediaFiles[0].getElementsByTagName('MediaFile');
+ mediaFileIsValid = false;
+ for (const mediaFileTemp of mediaFile) {
+ mediaFileUrl = mediaFileTemp.textContent.trim();
+ }
+ };
+ mediaFileIsValid = await validateMediaFile(mediaFileUrl);
+ if (mediaFileIsValid) {
+ adTree.children.push({ tagType: 'inLine', mediaFileUrl, ...adNode });
+ break;
+ } else {
+ adTree.children.push({ tagType: 'inLine', mediaError: true, ...adNode });
+ playerInstance.debugMessage(`No valid media file found in Inline ad.`);
+ }
+ }
+ }
+
+ return adTree;
+ }
+
+
+ /**
+ * Validate Media File to check if videos play
+ *
+ * @param {mediaFileUrl}
+ */
+ async function validateMediaFile(mediaFileUrl) {
+ try {
+ const response = await fetch(mediaFileUrl);
+ if (!response.ok || response.headers.get('content-type').indexOf('video') === -1) {
+ return false;
+ }
+ const videoElement = document.createElement('video');
+ videoElement.src = mediaFileUrl;
+ const canPlay = await videoElement.canPlayType(response.headers.get('content-type'));
+ return canPlay !== "";
+ } catch (error) {
+ console.error('Failed to load media file:', error);
+ return false;
+ }
+ }
+
+ /**
+ * Transforms an Ad Tree to a 1-dimensional array of Ads with wrapper data attached to each ad
+ *
+ * @param {RawAdTree} root
+ * @param {Array} ads
+ * @param {Array} wrappers
+ * @returns {Array}
+ */
+ function flattenAdTree(root, ads = [], wrappers = []) {
+ const currentWrappers = [...wrappers, root.data];
+
+ if (Array.isArray(root.children) && root.children.length) {
+ root.children.forEach(child => flattenAdTree(child, ads, currentWrappers));
+ }
+
+ if (root.tagType === 'inLine') {
+ ads.push({ ...root, wrappers: currentWrappers.filter(Boolean) });
+ }
+
+ return ads;
+ }
+
+ /**
+ * Register Ad element properties to an Ad based on its data and its wrapper data if available
+ *
+ * @param {RawAd} rawAd
+ * @param {{ tracking: Array, stopTracking: Array, impression: Array, viewImpression: Array, clicktracking: Array }} options
+ * @returns {Ad}
+ */
+ function registerAdProperties(rawAd, options) {
+ const ad = { ...rawAd, ...JSON.parse(JSON.stringify(options)) };
+
+ ad.adType = (ad.data.getElementsByTagName('Linear').length && 'linear') ||
+ (ad.data.getElementsByTagName('NonLinearAds').length && 'nonLinear') || 'unknown';
+
+ [...(ad.wrappers || []), ad.data].filter(Boolean).forEach(dataSource => {
+ // Register impressions
+ const impression = dataSource.getElementsByTagName('Impression');
+ if (impression !== null) {
+ playerInstance.registerImpressionEvents(impression, ad);
+ }
+
+ // Register viewable impressions
+ const viewableImpression = dataSource.getElementsByTagName('Viewable');
+ if (viewableImpression !== null) {
+ playerInstance.registerViewableImpressionEvents(viewableImpression, ad);
+ }
+
+ // Get the error tag, if any
+ const errorTags = dataSource.getElementsByTagName('Error');
+ if (errorTags !== null) {
+ playerInstance.registerErrorEvents(errorTags, ad);
+ }
+
+ // Sets CTA from vast
+ const [titleCta] = dataSource.getElementsByTagName('TitleCTA');
+ if (titleCta) {
+ playerInstance.setCTAFromVast(titleCta, ad);
+ }
+
+ // Register tracking events
+ playerInstance.registerTrackingEvents(dataSource, ad);
+ const clickTracks = ad.adType === 'linear' ?
+ playerInstance.getClickTrackingEvents(dataSource) :
+ playerInstance.getNonLinearClickTrackingEvents(dataSource);
+ playerInstance.registerClickTracking(clickTracks, ad);
+ });
+
+ ad.sequence = ad.data.attributes.sequence ? Number(ad.data.attributes.sequence.value) : null;
+ ad.played = false;
+
+ return ad;
+ }
+
+ /**
+ * Handles selection of ad pod or standalone ad to be played
+ *
+ * @param {Array} ads
+ * @param {number} maxDuration
+ * @param {number} maxQuantity
+ * @param {boolean} forceStandAloneAd
+ */
+ function getPlayableAds(ads, maxDuration, maxQuantity, forceStandAloneAd) {
+ const { adPod } = ads
+ .filter(ad => Boolean(ad.sequence))
+ .sort((adX, adY) => adX.sequence - adY.sequence)
+ .reduce((playableAds, ad) => {
+ if (playableAds.adPod.length < maxQuantity && (playableAds.totalDuration + ad.duration) <= maxDuration) {
+ playableAds.adPod.push(ad);
+ }
+
+ return playableAds;
+ }, { adPod: [], totalDuration: 0 });
+ const adBuffet = ads.filter(ad => !Boolean(ad.sequence) && ad.duration < maxDuration);
+
+ const isValidAdPodFormats = adPod.map(ad => ad.adType).slice(0, -1).every(adType => adType === 'linear');
+
+ if (adPod.length > 0 && !forceStandAloneAd && isValidAdPodFormats) {
+ playerInstance.debugMessage('Playing valid adPod', adPod);
+ return adPod;
+ } else {
+ playerInstance.debugMessage('Trying to play single ad, adBuffet:', adBuffet);
+ return adBuffet.length > 0 ? [adBuffet[0]] : [];
+ }
+ }
+
+ /**
+ * @param vastTag
+ * @param numberOfRedirects
+ * @param tmpOptions
+ * @param callback
+ * @param rollListId
+ */
+ playerInstance.resolveVastTag = (vastTag, numberOfRedirects, tmpOptions, callback, rollListId) => {
+ if (!vastTag || vastTag === '') {
+ return callback(false);
+ }
+
+ resolveAdTreeRequests(vastTag, playerInstance.displayOptions.vastOptions.maxAllowedVastTagRedirects)
+ .then(result => {
+ try {
+ /** @see VAST 4.0 Wrapper.fallbackOnNoAd */
+ const triggerFallbackOnNoAd = result.children.some(ad =>
+ ad.tagType === 'wrapper' && ad.fallbackOnNoAd && (!/"tagType":"ad"/.test(JSON.stringify(ad)) || ad.httpError)
+ );
+
+ if (triggerFallbackOnNoAd) {
+ playerInstance.debugMessage('Error on VAST Wrapper, triggering fallbackOnNoAd. Ad tree:', result);
+ }
+
+ result = flattenAdTree(result).map(ad => processAdCreatives(registerAdProperties(ad, tmpOptions)));
+
+ const playableAds = getPlayableAds(
+ result,
+ playerInstance.rollsById[rollListId].maxTotalDuration || Number.MAX_SAFE_INTEGER,
+ playerInstance.rollsById[rollListId].maxTotalQuantity || Number.MAX_SAFE_INTEGER,
+ triggerFallbackOnNoAd,
+ );
+
+ (playableAds && playableAds.length) ? callback(true, playableAds) : callback(false);
+ } catch (error) {
+ callback(false);
+ }
+ })
+ .catch(() => {
+ return callback(false);
+ });
+ };
+
+ playerInstance.setVastList = () => {
+ const rolls = {};
+ const rollsGroupedByType = { preRoll: [], postRoll: [], midRoll: [], onPauseRoll: [] };
+ const def = {
+ id: null,
+ roll: null,
+ vastLoaded: false,
+ error: false,
+ adText: null,
+ adTextPosition: null,
+ };
+ let idPart = 0;
+
+ const validateVastList = function (item) {
+ let hasError = false;
+
+ if (item.roll === 'midRoll') {
+ if (typeof item.timer === 'undefined') {
+ hasError = true;
+ }
+ }
+
+ return hasError;
+ };
+
+ const validateRequiredParams = function (item) {
+ let hasError = false;
+
+ if (!item.vastTag) {
+ playerInstance.announceLocalError(102, '"vastTag" property is missing from adList.');
+ hasError = true;
+ }
+
+ if (!item.roll) {
+ playerInstance.announceLocalError(102, '"roll" is missing from adList.');
+ hasError = true;
+ }
+
+ if (playerInstance.availableRolls.indexOf(item.roll) === -1) {
+ playerInstance.announceLocalError(102, 'Only ' + playerInstance.availableRolls.join(',') + ' rolls are supported.');
+ hasError = true;
+ }
+
+ if (item.size && playerInstance.supportedNonLinearAd.indexOf(item.size) === -1) {
+ playerInstance.announceLocalError(102, 'Only ' + playerInstance.supportedNonLinearAd.join(',') + ' size are supported.');
+ hasError = true;
+ }
+
+ return hasError;
+ };
+
+ if (playerInstance.displayOptions.vastOptions.hasOwnProperty('adList')) {
+
+ for (let key in playerInstance.displayOptions.vastOptions.adList) {
+
+ let rollItem = playerInstance.displayOptions.vastOptions.adList[key];
+
+ if (validateRequiredParams(rollItem)) {
+ playerInstance.announceLocalError(102, 'Wrong adList parameters.');
+ continue;
+ }
+ const id = 'ID' + idPart;
+
+ rolls[id] = Object.assign({}, def);
+ rolls[id] = Object.assign(rolls[id], playerInstance.displayOptions.vastOptions.adList[key]);
+ if (rollItem.roll === 'midRoll') {
+ rolls[id].error = validateVastList('midRoll', rollItem);
+ }
+ rolls[id].id = id;
+ rolls[id].ads = [];
+ idPart++;
+
+ }
+ }
+
+ // group the ads by roll
+ // pushing object references and forming json
+ Object.keys(rolls).map(function (e) {
+ switch (rolls[e].roll.toLowerCase()) {
+ case 'preRoll'.toLowerCase():
+ rollsGroupedByType.preRoll.push(rolls[e]);
+ break;
+ case 'midRoll'.toLowerCase():
+ rollsGroupedByType.midRoll.push(rolls[e]);
+ break;
+ case 'postRoll'.toLowerCase():
+ rollsGroupedByType.postRoll.push(rolls[e]);
+ break;
+ case 'onPauseRoll'.toLowerCase():
+ rollsGroupedByType.onPauseRoll.push(rolls[e]);
+ break;
+ default:
+ console.error(`${rolls[e].roll.toLowerCase()} is not a recognized roll`);
+ break;
+ }
+ });
+
+ playerInstance.adGroupedByRolls = rollsGroupedByType;
+ playerInstance.rollsById = rolls;
+ };
+
+ playerInstance.onVastAdEnded = (event) => {
+ if (event) {
+ event.stopImmediatePropagation();
+ }
+ playerInstance.vastOptions.adFinished = true;
+ //"this" is the HTML5 video tag, because it dispatches the "ended" event
+ playerInstance.deleteVastAdElements();
+ playerInstance.checkForNextAd();
+ };
+
+ playerInstance.vastLogoBehaviour = (vastPlaying) => {
+ if (!playerInstance.displayOptions.layoutControls.logo.showOverAds) {
+ const logoHolder = playerInstance.domRef.wrapper.querySelector('.logo_holder');
+
+ if (!logoHolder) {
+ return;
+ }
+
+ logoHolder.style.display = vastPlaying ? 'none' : 'inline';
+ }
+ };
+
+ playerInstance.deleteVastAdElements = () => {
+ playerInstance.removeClickthrough();
+ playerInstance.removeSkipButton();
+ playerInstance.removeAdCountdown();
+ playerInstance.removeAdPlayingText();
+ playerInstance.removeCTAButton();
+ playerInstance.vastLogoBehaviour(false);
+ };
+}
+
+export default vast
diff --git a/client/fluid-player/src/modules/vpaid.js b/client/fluid-player/src/modules/vpaid.js
new file mode 100644
index 0000000..6bb3f82
--- /dev/null
+++ b/client/fluid-player/src/modules/vpaid.js
@@ -0,0 +1,543 @@
+// VPAID support module
+export default function (playerInstance, options) {
+ const callbacks = {
+ AdStarted: () => playerInstance.onStartVpaidAd,
+ AdStopped: () => playerInstance.onStopVpaidAd,
+ AdSkipped: () => playerInstance.onSkipVpaidAd,
+ AdLoaded: () => playerInstance.onVpaidAdLoaded,
+ AdLinearChange: () => playerInstance.onVpaidAdLinearChange,
+ AdSizeChange: () => playerInstance.onVpaidAdSizeChange,
+ AdExpandedChange: () => playerInstance.onVpaidAdExpandedChange,
+ AdSkippableStateChange: () => playerInstance.onVpaidAdSkippableStateChange,
+ AdDurationChange: () => playerInstance.onVpaidAdDurationChange,
+ AdRemainingTimeChange: () => playerInstance.onVpaidAdRemainingTimeChange,
+ AdVolumeChange: () => playerInstance.onVpaidAdVolumeChange,
+ AdImpression: () => playerInstance.onVpaidAdImpression,
+ AdClickThru: () => playerInstance.onVpaidAdClickThru,
+ AdInteraction: () => playerInstance.onVpaidAdInteraction,
+ AdVideoStart: () => playerInstance.onVpaidAdVideoStart,
+ AdVideoFirstQuartile: () => playerInstance.onVpaidAdVideoFirstQuartile,
+ AdVideoMidpoint: () => playerInstance.onVpaidAdVideoMidpoint,
+ AdVideoThirdQuartile: () => playerInstance.onVpaidAdVideoThirdQuartile,
+ AdVideoComplete: () => playerInstance.onVpaidAdVideoComplete,
+ AdUserAcceptInvitation: () => playerInstance.onVpaidAdUserAcceptInvitation,
+ AdUserMinimize: () => playerInstance.onVpaidAdUserMinimize,
+ AdUserClose: () => playerInstance.onVpaidAdUserClose,
+ AdPaused: () => playerInstance.onVpaidAdPaused,
+ AdPlaying: () => playerInstance.onVpaidAdPlaying,
+ AdError: () => playerInstance.onVpaidAdError,
+ AdLog: () => playerInstance.onVpaidAdLog
+ };
+
+ playerInstance.checkVPAIDInterface = (vpaidAdUnit) => {
+ const VPAIDCreative = vpaidAdUnit;
+ // checks if all the mandatory params present
+ return !!(VPAIDCreative.handshakeVersion && typeof VPAIDCreative.handshakeVersion == "function"
+ && VPAIDCreative.initAd && typeof VPAIDCreative.initAd == "function"
+ && VPAIDCreative.startAd && typeof VPAIDCreative.startAd == "function"
+ && VPAIDCreative.stopAd && typeof VPAIDCreative.stopAd == "function"
+ && VPAIDCreative.skipAd && typeof VPAIDCreative.skipAd == "function"
+ && VPAIDCreative.resizeAd && typeof VPAIDCreative.resizeAd == "function"
+ && VPAIDCreative.pauseAd && typeof VPAIDCreative.pauseAd == "function"
+ && VPAIDCreative.resumeAd && typeof VPAIDCreative.resumeAd == "function"
+ && VPAIDCreative.expandAd && typeof VPAIDCreative.expandAd == "function"
+ && VPAIDCreative.collapseAd && typeof VPAIDCreative.collapseAd == "function"
+ && VPAIDCreative.subscribe && typeof VPAIDCreative.subscribe == "function"
+ && VPAIDCreative.unsubscribe && typeof VPAIDCreative.unsubscribe == "function");
+ };
+
+ // Callback for AdPaused
+ playerInstance.onVpaidAdPaused = () => {
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.debugMessage("onAdPaused");
+ };
+
+ // Callback for AdPlaying
+ playerInstance.onVpaidAdPlaying = () => {
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.debugMessage("onAdPlaying");
+ };
+
+ // Callback for AdError
+ playerInstance.onVpaidAdError = (message) => {
+ playerInstance.debugMessage("onAdError: " + message);
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.onVpaidEnded();
+ };
+
+ // Callback for AdLog
+ playerInstance.onVpaidAdLog = (message) => {
+ playerInstance.debugMessage("onAdLog: " + message);
+ };
+
+ // Callback for AdUserAcceptInvitation
+ playerInstance.onVpaidAdUserAcceptInvitation = () => {
+ playerInstance.debugMessage("onAdUserAcceptInvitation");
+ };
+
+ // Callback for AdUserMinimize
+ playerInstance.onVpaidAdUserMinimize = () => {
+ playerInstance.debugMessage("onAdUserMinimize");
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdUserClose = () => {
+ playerInstance.debugMessage("onAdUserClose");
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdSkippableStateChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad Skippable State Changed to: " + playerInstance.vpaidAdUnit.getAdSkippableState());
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdExpandedChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad Expanded Changed to: " + playerInstance.vpaidAdUnit.getAdExpanded());
+ };
+
+ // Pass through for getAdExpanded
+ playerInstance.getVpaidAdExpanded = () => {
+ playerInstance.debugMessage("getAdExpanded");
+
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+
+ return playerInstance.vpaidAdUnit.getAdExpanded();
+ };
+
+ // Pass through for getAdSkippableState
+ playerInstance.getVpaidAdSkippableState = () => {
+ playerInstance.debugMessage("getAdSkippableState");
+
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ return playerInstance.vpaidAdUnit.getAdSkippableState();
+ };
+
+ // Callback for AdSizeChange
+ playerInstance.onVpaidAdSizeChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad size changed to: w=" + playerInstance.vpaidAdUnit.getAdWidth() + " h=" + playerInstance.vpaidAdUnit.getAdHeight());
+ };
+
+ // Callback for AdDurationChange
+ playerInstance.onVpaidAdDurationChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad Duration Changed to: " + playerInstance.vpaidAdUnit.getAdDuration());
+ };
+
+ // Callback for AdRemainingTimeChange
+ playerInstance.onVpaidAdRemainingTimeChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad Remaining Time Changed to: " + playerInstance.vpaidAdUnit.getAdRemainingTime());
+ };
+
+ // Pass through for getAdRemainingTime
+ playerInstance.getVpaidAdRemainingTime = () => {
+ playerInstance.debugMessage("getAdRemainingTime");
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ return playerInstance.vpaidAdUnit.getAdRemainingTime();
+ };
+
+ // Callback for AdImpression
+ playerInstance.onVpaidAdImpression = () => {
+ playerInstance.debugMessage("Ad Impression");
+
+ //Announce the impressions
+ playerInstance.trackSingleEvent('impression');
+ };
+
+ // Callback for AdClickThru
+ playerInstance.onVpaidAdClickThru = (url, id, playerHandles) => {
+ playerInstance.debugMessage("Clickthrough portion of the ad was clicked");
+
+ // if playerHandles flag is set to true
+ // then player need to open click thorough url in new window
+ if (playerHandles) {
+ window.open(playerInstance.vastOptions.clickthroughUrl);
+ }
+
+ playerInstance.pauseVpaidAd();
+ // fire click tracking
+ playerInstance.callUris(playerInstance.vastOptions.clicktracking);
+ };
+
+ // Callback for AdInteraction
+ playerInstance.onVpaidAdInteraction = (id) => {
+ playerInstance.debugMessage("A non-clickthrough event has occured");
+ };
+
+ // Callback for AdVideoStart
+ playerInstance.onVpaidAdVideoStart = () => {
+ playerInstance.debugMessage("Video 0% completed");
+ playerInstance.trackSingleEvent('start');
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdVideoFirstQuartile = () => {
+ playerInstance.debugMessage("Video 25% completed");
+ playerInstance.trackSingleEvent('firstQuartile');
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdVideoMidpoint = () => {
+ playerInstance.debugMessage("Video 50% completed");
+ playerInstance.trackSingleEvent('midpoint');
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onVpaidAdVideoThirdQuartile = () => {
+ playerInstance.debugMessage("Video 75% completed");
+ playerInstance.trackSingleEvent('thirdQuartile');
+ };
+
+ // Callback for AdVideoComplete
+ playerInstance.onVpaidAdVideoComplete = () => {
+ playerInstance.debugMessage("Video 100% completed");
+ playerInstance.trackSingleEvent('complete');
+ };
+
+ // Callback for AdLinearChange
+ playerInstance.onVpaidAdLinearChange = () => {
+ const vpaidNonLinearSlot = playerInstance.domRef.wrapper.getElementsByClassName("fluid_vpaidNonLinear_ad")[0];
+ const closeBtn = playerInstance.domRef.wrapper.querySelector('.close_button');
+ const adListId = vpaidNonLinearSlot.getAttribute('adlistid');
+ playerInstance.debugMessage("Ad linear has changed: " + playerInstance.vpaidAdUnit.getAdLinear());
+
+ if (!playerInstance.vpaidAdUnit.getAdLinear()) {
+ return;
+ }
+
+ playerInstance.backupMainVideoContentTime(adListId.split('_')[0]);
+ playerInstance.isCurrentlyPlayingAd = true;
+
+ if (closeBtn) {
+ closeBtn.remove();
+ }
+
+ vpaidNonLinearSlot.className = 'fluid_vpaid_slot';
+ playerInstance.domRef.player.loop = false;
+ playerInstance.domRef.player.removeAttribute('controls');
+
+ const progressbarContainer = playerInstance.domRef.player.parentNode.getElementsByClassName('fluid_controls_currentprogress');
+
+ for (let i = 0; i < progressbarContainer.length; i++) {
+ progressbarContainer[i].style.backgroundColor = playerInstance.displayOptions.layoutControls.adProgressColor;
+ }
+
+ playerInstance.toggleLoader(false);
+ };
+
+ // Pass through for getAdLinear
+ playerInstance.getVpaidAdLinear = () => {
+ playerInstance.debugMessage("getAdLinear");
+ return playerInstance.vpaidAdUnit.getAdLinear();
+ };
+
+ // Pass through for startAd()
+ playerInstance.startVpaidAd = () => {
+ playerInstance.debugMessage("startAd");
+ playerInstance.vpaidTimeoutTimerStart();
+ playerInstance.vpaidAdUnit.startAd();
+ };
+
+ // Callback for AdLoaded
+ playerInstance.onVpaidAdLoaded = () => {
+ playerInstance.debugMessage("ad has been loaded");
+ // start the video play as vpaid is loaded successfully
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.startVpaidAd();
+ };
+
+ // Callback for StartAd()
+ playerInstance.onStartVpaidAd = () => {
+ playerInstance.debugMessage("Ad has started");
+ playerInstance.vpaidTimeoutTimerClear();
+ };
+
+ // Pass through for stopAd()
+ playerInstance.stopVpaidAd = () => {
+ playerInstance.vpaidTimeoutTimerStart();
+ playerInstance.vpaidAdUnit.stopAd();
+ };
+
+ // Hard Pass through for stopAd() excluding deleteOtherVpaidAdsApart
+ playerInstance.hardStopVpaidAd = (ad) => {
+ // this is hard stop of vpaid ads
+ // we delete all the vpaid assets so the new one can be loaded
+ // delete all assets apart from the ad from deleteOtherVpaidAdsApart
+ if (playerInstance.vpaidAdUnit) {
+ playerInstance.vpaidAdUnit.stopAd();
+ playerInstance.vpaidAdUnit = null;
+ }
+
+ const vpaidIframes = playerInstance.domRef.wrapper.getElementsByClassName("fluid_vpaid_iframe");
+ const vpaidSlots = playerInstance.domRef.wrapper.getElementsByClassName("fluid_vpaid_slot");
+ const vpaidNonLinearSlots = playerInstance.domRef.wrapper.getElementsByClassName("fluid_vpaidNonLinear_ad");
+
+ for (let i = 0; i < vpaidIframes.length; i++) {
+ if (vpaidIframes[i].getAttribute('adListId') !== ad.id) {
+ vpaidIframes[i].remove();
+ }
+ }
+
+ for (let j = 0; j < vpaidSlots.length; j++) {
+ if (vpaidSlots[j].getAttribute('adListId') !== ad.id) {
+ vpaidSlots[j].remove();
+ }
+ }
+
+ for (let k = 0; k < vpaidNonLinearSlots.length; k++) {
+ if (vpaidNonLinearSlots[k].getAttribute('adListId') !== ad.id) {
+ vpaidNonLinearSlots[k].remove();
+ }
+ }
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onStopVpaidAd = () => {
+ playerInstance.debugMessage("Ad has stopped");
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.onVpaidEnded();
+ };
+
+ // Callback for AdUserClose
+ playerInstance.onSkipVpaidAd = () => {
+ playerInstance.debugMessage("Ad was skipped");
+
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.onVpaidEnded();
+ };
+
+ // Passthrough for skipAd
+ playerInstance.skipVpaidAd = () => {
+ playerInstance.vpaidTimeoutTimerStart();
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.skipAd()
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.onVpaidEnded();
+ };
+
+ // Passthrough for setAdVolume
+ playerInstance.setVpaidAdVolume = (val) => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.setAdVolume(val);
+ };
+
+ // Passthrough for getAdVolume
+ playerInstance.getVpaidAdVolume = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ return playerInstance.vpaidAdUnit.getAdVolume();
+ };
+
+ // Callback for AdVolumeChange
+ playerInstance.onVpaidAdVolumeChange = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.debugMessage("Ad Volume has changed to - " + playerInstance.vpaidAdUnit.getAdVolume());
+ };
+
+ playerInstance.resizeVpaidAuto = () => {
+ if (playerInstance.vastOptions !== null && playerInstance.vastOptions.vpaid && playerInstance.vastOptions.linear) {
+ const adWidth = playerInstance.domRef.player.offsetWidth;
+ const adHeight = playerInstance.domRef.player.offsetHeight;
+ const mode = (playerInstance.fullscreenMode ? 'fullscreen' : 'normal');
+ playerInstance.resizeVpaidAd(adWidth, adHeight, mode);
+ }
+ };
+
+ // Passthrough for resizeAd
+ playerInstance.resizeVpaidAd = (width, height, viewMode) => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.resizeAd(width, height, viewMode);
+ };
+
+ // Passthrough for pauseAd()
+ playerInstance.pauseVpaidAd = () => {
+ playerInstance.vpaidTimeoutTimerStart();
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.pauseAd();
+ };
+
+ // Passthrough for resumeAd()
+ playerInstance.resumeVpaidAd = () => {
+ playerInstance.vpaidTimeoutTimerStart();
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.resumeAd();
+ };
+
+ // Passthrough for expandAd()
+ playerInstance.expandVpaidAd = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.expandAd();
+ };
+
+ // Passthrough for collapseAd()
+ playerInstance.collapseVpaidAd = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ playerInstance.vpaidAdUnit.collapseAd();
+ };
+
+ playerInstance.vpaidTimeoutTimerClear = () => {
+ if (playerInstance.vpaidTimer) {
+ clearTimeout(playerInstance.vpaidTimer);
+ }
+ };
+
+ // placeholder for timer function
+ playerInstance.vpaidTimeoutTimerStart = () => {
+ // clear previous timer if any
+ playerInstance.vpaidTimeoutTimerClear();
+ playerInstance.vpaidTimer = setTimeout(function () {
+ playerInstance.announceLocalError('901');
+ playerInstance.onVpaidEnded();
+ }, playerInstance.displayOptions.vastOptions.vpaidTimeout);
+ };
+
+ playerInstance.vpaidCallbackListenersAttach = () => {
+ // The key of the object is the event name and the value is a reference to the callback function that is registered with the creative
+ // Looping through the object and registering each of the callbacks with the creative
+ for (let eventName in callbacks) {
+ playerInstance.vpaidAdUnit.subscribe(callbacks[eventName](), eventName, playerInstance);
+ }
+ };
+
+ playerInstance.vpaidCallbackListenersDetach = () => {
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+ for (let eventName in callbacks) {
+ playerInstance.vpaidAdUnit.unsubscribe(callbacks[eventName](), eventName, playerInstance);
+ }
+ };
+
+ playerInstance.loadVpaid = (ad, vpaidJsUrl) => {
+ const vpaidIframe = document.createElement('iframe');
+ vpaidIframe.id = "fp_" + ad.id + "_fluid_vpaid_iframe";
+ vpaidIframe.className = 'fluid_vpaid_iframe';
+ vpaidIframe.setAttribute('adListId', ad.id);
+ vpaidIframe.setAttribute('frameborder', '0');
+
+ playerInstance.domRef.player.parentNode.insertBefore(vpaidIframe, playerInstance.domRef.player.nextSibling);
+
+ const vpaidJsScriptElement = document.createElement('script');
+ vpaidJsScriptElement.src = vpaidJsUrl;
+
+ vpaidIframe.contentWindow.document.head.append(vpaidJsScriptElement);
+
+ // set interval with timeout
+ playerInstance.tempVpaidCounter = 0;
+ playerInstance.getVPAIDAdInterval = setInterval(function () {
+ if (vpaidIframe && vpaidIframe.contentWindow) {
+ const fn = vpaidIframe.contentWindow['getVPAIDAd'];
+
+ // check if JS is loaded fully in iframe
+ if (fn && typeof fn == 'function') {
+
+ if (playerInstance.vpaidAdUnit) {
+ playerInstance.hardStopVpaidAd(ad);
+ }
+
+ playerInstance.vpaidAdUnit = fn();
+ clearInterval(playerInstance.getVPAIDAdInterval);
+ if (playerInstance.checkVPAIDInterface(playerInstance.vpaidAdUnit)) {
+
+ if (playerInstance.getVpaidAdLinear()) {
+ playerInstance.isCurrentlyPlayingAd = true;
+ playerInstance.switchPlayerToVpaidMode(ad);
+ } else {
+ playerInstance.debugMessage('non linear vpaid ad is loaded');
+ playerInstance.loadVpaidNonlinearAssets(ad);
+ }
+
+ }
+
+ } else {
+
+ // video player will wait for 2seconds if vpaid is not loaded, then it will declare vast error and move ahead
+ playerInstance.tempVpaidCounter++;
+ if (playerInstance.tempVpaidCounter >= 20) {
+ clearInterval(playerInstance.getVPAIDAdInterval);
+ playerInstance.rollsById[ad.rollListId].error = true;
+ playerInstance.playMainVideoWhenVpaidFails(403);
+ return false;
+ } else {
+ playerInstance.debugMessage(playerInstance.tempVpaidCounter);
+ }
+
+ }
+ }
+
+ }, 100);
+
+ playerInstance.destructors.push(() => clearInterval(playerInstance.getVPAIDAdInterval));
+
+ };
+
+ playerInstance.onVpaidEnded = (event) => {
+ if (event) {
+ event.stopImmediatePropagation();
+ }
+
+ if (!playerInstance.vpaidAdUnit) {
+ return;
+ }
+
+ const vpaidSlot = playerInstance.domRef.wrapper.querySelector('.fluid_vpaid_slot');
+
+ playerInstance.vpaidCallbackListenersDetach();
+
+ playerInstance.vpaidAdUnit = null;
+ clearInterval(playerInstance.getVPAIDAdInterval);
+
+ if (!!vpaidSlot) {
+ vpaidSlot.remove();
+ }
+
+ playerInstance.checkForNextAd();
+ };
+
+ playerInstance.playMainVideoWhenVpaidFails = (errorCode) => {
+ const vpaidSlot = playerInstance.domRef.wrapper.querySelector('.fluid_vpaid_slot');
+
+ if (vpaidSlot) {
+ vpaidSlot.remove();
+ }
+
+ clearInterval(playerInstance.getVPAIDAdInterval);
+ playerInstance.playMainVideoWhenVastFails(errorCode);
+ };
+}
diff --git a/client/fluid-player/src/polyfills.js b/client/fluid-player/src/polyfills.js
new file mode 100644
index 0000000..b30b8eb
--- /dev/null
+++ b/client/fluid-player/src/polyfills.js
@@ -0,0 +1,77 @@
+
+import promisePolyfill from 'es6-promise';
+
+// Object.assign polyfill
+if (typeof Object.assign != 'function') {
+ // Must be writable: true, enumerable: false, configurable: true
+ Object.defineProperty(Object, 'assign', {
+ value: function assign(target, varArgs) { // .length of function is 2
+ 'use strict';
+ if (target == null) { // TypeError if undefined or null
+ throw new TypeError('Cannot convert undefined or null to object');
+ }
+
+ const to = Object(target);
+
+ for (let index = 1; index < arguments.length; index++) {
+ const nextSource = arguments[index];
+
+ if (nextSource != null) { // Skip over if undefined or null
+ for (let nextKey in nextSource) {
+ // Avoid bugs when hasOwnProperty is shadowed
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+ to[nextKey] = nextSource[nextKey];
+ }
+ }
+ }
+ }
+ return to;
+ },
+ writable: true,
+ configurable: true
+ });
+}
+
+// CustomEvent polyfill
+(function () {
+ if (typeof globalThis.CustomEvent === 'function') return false;
+
+ function CustomEvent(event, params) {
+ params = params || {bubbles: false, cancelable: false, detail: undefined};
+ const evt = document.createEvent('CustomEvent');
+ evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
+ return evt;
+ }
+
+ CustomEvent.prototype = globalThis.Event.prototype;
+
+ globalThis.CustomEvent = CustomEvent;
+})();
+
+// .remove() polyfill
+if (
+ typeof globalThis.Element !== 'undefined' &&
+ typeof globalThis.CharacterData !== 'undefined' &&
+ typeof globalThis.DocumentType !== 'undefined'
+) {
+ (function (arr) {
+ arr.forEach(function (item) {
+ if (item.hasOwnProperty('remove')) {
+ return;
+ }
+ Object.defineProperty(item, 'remove', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: function remove() {
+ if (this.parentNode === null) {
+ return;
+ }
+ this.parentNode.removeChild(this);
+ }
+ });
+ });
+ })([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
+}
+
+promisePolyfill.polyfill();
diff --git a/client/fluid-player/src/static/close-icon.svg b/client/fluid-player/src/static/close-icon.svg
new file mode 100644
index 0000000..71276e9
--- /dev/null
+++ b/client/fluid-player/src/static/close-icon.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/client/fluid-player/src/static/fluid-icons.svg b/client/fluid-player/src/static/fluid-icons.svg
new file mode 100644
index 0000000..c009d6f
--- /dev/null
+++ b/client/fluid-player/src/static/fluid-icons.svg
@@ -0,0 +1,353 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/src/static/fluid-spinner.svg b/client/fluid-player/src/static/fluid-spinner.svg
new file mode 100644
index 0000000..a63511f
--- /dev/null
+++ b/client/fluid-player/src/static/fluid-spinner.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/client/fluid-player/src/static/miniplayer-toggle-off.svg b/client/fluid-player/src/static/miniplayer-toggle-off.svg
new file mode 100644
index 0000000..cf84132
--- /dev/null
+++ b/client/fluid-player/src/static/miniplayer-toggle-off.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/client/fluid-player/src/static/miniplayer-toggle-on.svg b/client/fluid-player/src/static/miniplayer-toggle-on.svg
new file mode 100644
index 0000000..75855fc
--- /dev/null
+++ b/client/fluid-player/src/static/miniplayer-toggle-on.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/client/fluid-player/src/static/skip-backward.svg b/client/fluid-player/src/static/skip-backward.svg
new file mode 100644
index 0000000..ab4a557
--- /dev/null
+++ b/client/fluid-player/src/static/skip-backward.svg
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/client/fluid-player/src/static/skip-forward.svg b/client/fluid-player/src/static/skip-forward.svg
new file mode 100644
index 0000000..503c3fc
--- /dev/null
+++ b/client/fluid-player/src/static/skip-forward.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/src/types.ts b/client/fluid-player/src/types.ts
new file mode 100644
index 0000000..1dd3435
--- /dev/null
+++ b/client/fluid-player/src/types.ts
@@ -0,0 +1,546 @@
+export interface IFluidPlayer {
+ domRef: DomRef;
+ version: string;
+ homepage: string;
+ destructors: ((this: IFluidPlayer) => void)[];
+ init: (this: IFluidPlayer, playerTarget: HTMLVideoElement | string, options: unknown) => void;
+ getCurrentVideoDuration: () => number;
+ getCurrentTime: () => number;
+ toggleLoader: (showLoader?: boolean) => void;
+ sendRequest: (
+ url: unknown,
+ withCredentials: unknown,
+ timeout: unknown,
+ functionReadyStateChange: unknown
+ ) => void;
+ displayOptions: DisplayOptions;
+ sendRequestAsync: (
+ url: unknown,
+ withCredentials: unknown,
+ timeout: unknown
+ ) => Promise;
+ announceLocalError: (code: unknown, msg: unknown) => void;
+ debugMessage: (...msg: unknown[]) => void;
+ onMainVideoEnded: (event: unknown) => void;
+ isCurrentlyPlayingAd: unknown;
+ autoplayAfterAd: boolean;
+ mainVideoDuration: unknown;
+ adKeytimePlay: (keyTime: unknown) => void;
+ timer: number | null;
+ switchToMainVideo: () => void;
+ playPauseToggle: () => void;
+ displaySuggestedVideos: () => void;
+ mainVideoCurrentTime: unknown;
+ getCurrentSrc: () => null | string;
+ getCurrentSrcType: () => null | string;
+ onRecentWaiting: () => void;
+ recentWaiting: boolean;
+ onFluidPlayerPause: () => void;
+ checkShouldDisplayVolumeBar: () => boolean;
+ getMobileOs: () => { userOS: string };
+ generateCustomControlTags: (options: unknown) => CustomControls;
+ detectLiveStream: () => void;
+ isLiveStream: () => boolean;
+ showLiveIndicator: () => void;
+ currentVideoDuration: number;
+ controlPlayPauseToggle: () => void;
+ playPauseAnimationToggle: (play: any) => void;
+ isSwitchingSource: boolean;
+ contolProgressbarUpdate: () => void;
+ controlDurationUpdate: () => void;
+ formatTime: (time: number) => void;
+ hlsPlayer: false | HLSPlayer;
+ contolVolumebarUpdate: () => void;
+ latestVolume: number;
+ fluidStorage: { fluidMute?: boolean; fluidVolume?: unknown };
+ muteToggle: () => void;
+ checkFullscreenSupport: () =>
+ | false
+ | {
+ goFullscreen: string;
+ exitFullscreen: string;
+ isFullscreen: string;
+ };
+ fullscreenOff: (
+ fullscreenButton: unknown[],
+ menuOptionFullscreen: null
+ ) => void;
+ fullscreenMode: boolean;
+ fullscreenOn: (
+ fullscreenButton: unknown,
+ menuOptionFullscreen: unknown
+ ) => void;
+ fullscreenToggle: () => void;
+ findClosestParent: (el: unknown, selector: unknown) => null;
+ getTranslateX: (el: unknown) => number;
+ getEventOffsetX: (evt: unknown, el: unknown) => number;
+ getEventOffsetY: (evt: unknown, el: unknown) => number;
+ onProgressbarMouseDown: (event: unknown) => void;
+ onVolumeBarMouseDown: () => void;
+ findRoll: (roll: unknown) => string[] | undefined;
+ onKeyboardVolumeChange: (direction: unknown) => void;
+ onKeyboardSeekPosition: (keyCode: unknown) => void;
+ getNewCurrentTimeValueByKeyCode: (
+ keyCode: unknown,
+ currentTime: unknown,
+ duration: unknown
+ ) => unknown;
+ handleMouseleave: (event: unknown) => void;
+ handleMouseenterForKeyboard: () => void;
+ keyboardControl: () => void;
+ handleWindowClick: (event: unknown) => void;
+ initialPlay: () => void;
+ setCustomControls: () => void;
+ createTimePositionPreview: () => void;
+ setCustomContextMenu: () => void;
+ setDefaultLayout: () => void;
+ initSkipControls: () => void;
+ handleOrientationChange: () => void;
+ initSkipAnimationElements: () => void;
+ initDoubleTapSkip: () => void;
+ skipRelative: (timeOffset: number) => void;
+ checkIfVolumebarIsRendered: () => boolean;
+ setLayout: () => void;
+ handleFullscreen: () => void;
+ setupPlayerWrapper: () => HTMLDivElement;
+ onErrorDetection: () => void;
+ createVideoSourceSwitch: (initialLoad?: boolean) => void;
+ openCloseVideoSourceSwitch: () => void;
+ setVideoSource: (url: unknown) => false | undefined;
+ setCurrentTimeAndPlay: (
+ newCurrentTime: unknown,
+ shouldPlay: unknown
+ ) => void;
+ initTitle: () => void;
+ hasTitle: () => unknown;
+ hideTitle: () => void;
+ showTitle: () => void;
+ initLogo: () => void;
+ initHtmlOnPauseBlock: () => void;
+ initPlayButton: () => void;
+ mainVideoReady: () => void;
+ userActivityChecker: () => void;
+ hasControlBar: () => boolean;
+ isControlBarVisible: () => boolean;
+ setVideoPreload: () => void;
+ hideControlBar: () => void;
+ showControlBar: (event: unknown) => void;
+ linkControlBarUserActivity: () => void;
+ initMute: () => void;
+ initLoop: () => void;
+ setBuffering: () => void;
+ createPlaybackList: () => void;
+ openCloseVideoPlaybackRate: () => void;
+ createDownload: () => void;
+ theatreToggle: () => void;
+ defaultTheatre: () => void;
+ posterImage: () => void;
+ nextSource: () => null | undefined;
+ inIframe: () => boolean;
+ setPersistentSettings: (ignoreMute?: boolean) => false | undefined;
+ play: () => true | undefined;
+ pause: () => boolean;
+ skipTo: (time: unknown) => void;
+ setPlaybackSpeed: (speed: unknown) => void;
+ setVolume: (passedVolume: unknown) => void;
+ isCurrentlyPlayingVideo: (instance: HTMLVideoElement) => boolean;
+ setHtmlOnPauseBlock: (passedHtml: unknown) => false | undefined;
+ toggleControlBar: (show: unknown) => void;
+ on: (eventCall: unknown, callback: unknown) => void;
+ toggleLogo: (logo: unknown) => false | undefined;
+ trackEvent: (
+ el: unknown,
+ evt: unknown,
+ sel: unknown,
+ handler: unknown
+ ) => void;
+ registerListener: (
+ el: unknown,
+ evt: unknown,
+ sel: unknown,
+ handler: unknown
+ ) => void;
+ copyEvents: (topLevelEl: unknown) => void;
+ resetDisplayMode: (
+ displayTarget: "fullScreen" | "theaterMode" | "miniPlayer"
+ ) => void;
+ destroy: () => void;
+ setCTAFromVast: (titleCtaElement: HTMLElement, tmpOptions: unknown) => void;
+ getClickThroughUrlFromLinear: (linear: HTMLElement) => unknown;
+ getVastAdTagUriFromWrapper: (xmlResponse: HTMLElement) => unknown;
+ hasInLine: (xmlResponse: HTMLElement) => number | false;
+ hasVastAdTagUri: (xmlResponse: HTMLElement) => number | false;
+ getClickThroughUrlFromNonLinear: (nonLinear: HTMLElement) => string;
+ getTrackingFromLinear: (
+ linear: HTMLElement
+ ) => never[] | HTMLCollectionOf;
+ getDurationFromLinear: (linear: HTMLElement) => unknown;
+ getDurationFromNonLinear: (tag: HTMLElement) => number;
+ getDimensionFromNonLinear: (tag: HTMLElement) => {
+ width: null;
+ height: null;
+ };
+ getCreativeTypeFromStaticResources: (tag: HTMLElement) => string;
+ getMediaFilesFromLinear: (
+ linear: HTMLElement
+ ) => HTMLCollectionOf | never[];
+ getStaticResourcesFromNonLinear: (linear: HTMLElement) => unknown[];
+ extractNodeDataByTagName: (
+ parentNode: HTMLElement,
+ tagName: string
+ ) => string | null;
+ extractNodeData: (parentNode: HTMLElement) => string;
+ getAdParametersFromLinear: (linear: HTMLElement) => string | null;
+ getMediaFileListFromLinear: (linear: HTMLElement) => unknown[];
+ getIconClickThroughFromLinear: (linear: HTMLElement) => string;
+ getStaticResourceFromNonLinear: (linear: HTMLElement) => string | undefined;
+ registerTrackingEvents: (
+ creativeLinear: unknown,
+ tmpOptions: unknown
+ ) => void;
+ registerClickTracking: (
+ clickTrackingTag: unknown,
+ tmpOptions: unknown
+ ) => void;
+ registerViewableImpressionEvents: (
+ viewableImpressionTags: unknown,
+ tmpOptions: unknown
+ ) => void;
+ registerImpressionEvents: (
+ impressionTags: unknown,
+ tmpOptions: unknown
+ ) => void;
+ registerErrorEvents: (errorTags: unknown, tmpOptions: unknown) => void;
+ announceError: (code: unknown) => void;
+ getClickTrackingEvents: (linear: unknown) => string[] | undefined;
+ getNonLinearClickTrackingEvents: (
+ nonLinear: unknown
+ ) => string[] | undefined;
+ callUris: (uris: unknown) => void;
+ recalculateAdDimensions: () => void;
+ prepareVast: (roll: unknown) => void;
+ playMainVideoWhenVastFails: (errorCode: unknown) => void;
+ switchPlayerToVastMode: () => void;
+ processVastWithRetries: (vastObj: unknown) => void;
+ processUrl: (
+ vastTag: unknown,
+ callBack: unknown,
+ rollListId: unknown
+ ) => void;
+ resolveVastTag: (
+ vastTag: unknown,
+ numberOfRedirects: unknown,
+ tmpOptions: unknown,
+ callback: unknown,
+ rollListId: unknown
+ ) => any;
+ setVastList: () => void;
+ onVastAdEnded: (event: unknown) => void;
+ vastLogoBehaviour: (vastPlaying: unknown) => void;
+ deleteVastAdElements: () => void;
+ renderLinearAd: (ad: unknown, backupTheVideoTime: unknown) => void;
+ playRoll: (adList: unknown) => void;
+ backupMainVideoContentTime: (rollListId: unknown) => void;
+ getSupportedMediaFileObject: (mediaFiles: unknown) => unknown;
+ getMediaFileTypeSupportLevel: (
+ mediaType: unknown
+ ) => "maybe" | "probably" | "no" | null;
+ scheduleTrackingEvent: (currentTime: unknown, duration: unknown) => void;
+ trackSingleEvent: (eventType: unknown, eventSubType: unknown) => void;
+ completeNonLinearStatic: (ad: unknown) => void;
+ createNonLinearStatic: (ad: unknown) => void;
+ createVpaidNonLinearBoard: (ad: unknown) => void;
+ createNonLinearBoard: (ad: unknown) => void;
+ createBoard: (ad: unknown) => void;
+ closeNonLinear: (adId: unknown) => void;
+ rollGroupContainsLinear: (groupedRolls: unknown) => boolean;
+ rollGroupContainsNonlinear: (groupedRolls: unknown) => boolean;
+ preRollFail: () => void;
+ preRollSuccess: () => void;
+ preRollAdsPlay: () => void;
+ preRoll: (event: unknown) => void;
+ createAdMarker: (adListId: unknown, time: unknown) => void;
+ hideAdMarker: (adListId: unknown) => void;
+ showAdMarkers: () => void;
+ hideAdMarkers: () => void;
+ midRoll: (event: unknown) => void;
+ postRoll: (event: unknown) => void;
+ onPauseRoll: (event: unknown) => void;
+ hasValidOnPauseAd: () => unknown;
+ toggleOnPauseAd: () => void;
+ trackingOnPauseNonLinearAd: (ad: unknown, status: unknown) => void;
+ getLinearAdsFromKeyTime: (keyTimeLinearObj: unknown) => unknown[];
+ adTimer: () => void;
+ scheduleTask: (task: {
+ time: number;
+ rollListId: unknown;
+ loadVast: unknown;
+ }) => void;
+ scheduleOnDemandRolls: () => void;
+ getNextAdPod: () => unknown;
+ checkForNextAd: () => void;
+ addSkipButton: () => void;
+ addAdCountdown: () => void;
+ decreaseAdCountdown: () => void;
+ removeAdCountdown: () => void;
+ toggleAdCountdown: (showing: unknown) => void;
+ addAdPlayingText: (textToShow: unknown) => void;
+ positionTextElements: (adListData: unknown) => void;
+ removeAdPlayingText: () => void;
+ addCTAButton: (landingPage: string) => unknown;
+ createAndAppendCTAButton: (
+ adCTAText: string,
+ displayUrl: string,
+ trackingUrl: string
+ ) => void;
+ removeCTAButton: () => void;
+ decreaseSkipOffset: () => void;
+ pressSkipButton: () => void;
+ removeSkipButton: () => void;
+ addClickthroughLayer: () => void;
+ removeClickthrough: () => void;
+ isTimer: unknown;
+ vrROTATION_POSITION: number;
+ vrROTATION_SPEED: number;
+ vrMode: boolean;
+ vrPanorama: null;
+ vrViewer: null;
+ vpaidTimer: null;
+ vpaidAdUnit: null;
+ vastOptions: null;
+ videoPlayerId: string;
+ originalSrc: string | null;
+ firstPlayLaunched: boolean;
+ suppressClickthrough: boolean;
+ timelinePreviewData: unknown[];
+ timerPool: Record;
+ rollsById: Record;
+ adPool: Record;
+ adGroupedByRolls: Record;
+ onPauseRollAdPods: unknown[];
+ currentOnPauseRollAd: string;
+ preRollAdsResolved: boolean;
+ preRollAdPods: unknown[];
+ preRollAdPodsLength: number;
+ preRollVastResolved: number;
+ temporaryAdPods: unknown[];
+ availableRolls: ["preRoll", "midRoll", "postRoll", "onPauseRoll"];
+ supportedNonLinearAd: ["300x250", "468x60", "728x90"];
+ nonLinearDuration: number;
+ supportedStaticTypes: ["image/gif", "image/jpeg", "image/png"];
+ inactivityTimeout: null;
+ isUserActive: null;
+ nonLinearVerticalAlign: "bottom";
+ vpaidNonLinearCloseButton: boolean;
+ showTimeOnHover: boolean;
+ initialAnimationSet: boolean;
+ theatreMode: boolean;
+ theatreModeAdvanced: boolean;
+ originalWidth: number;
+ originalHeight: number;
+ dashPlayer: boolean;
+ dashScriptLoaded: boolean;
+ hlsScriptLoaded: boolean;
+ isPlayingMedia: boolean;
+ isLoading: boolean;
+ isInIframe: boolean;
+ mainVideoReadyState: boolean;
+ xmlCollection: unknown[];
+ inLineFound: null;
+ fluidPseudoPause: boolean;
+ mobileInfo: { userOS: string };
+ events: Record;
+ timeSkipOffsetAmount: number;
+ currentMediaSourceType: "source";
+}
+
+export interface DomRef {
+ player: null | HTMLVideoElement;
+ wrapper?: null | HTMLDivElement;
+}
+
+export interface DisplayOptions {
+ onBeforeXMLHttpRequestOpen: (request: XMLHttpRequest) => void;
+ onBeforeXMLHttpRequest: (request: XMLHttpRequest) => void;
+ debug: boolean;
+ layoutControls: ILayoutControls;
+ suggestedVideos: { configUrl: null };
+ vastOptions: IVastOptions;
+ captions: ICaptions;
+ hls: IHLSOptions;
+ modules: {
+ configureHls: (options: unknown) => typeof options;
+ onBeforeInitHls: (hls: unknown) => unknown;
+ onAfterInitHls: (hls: unknown) => unknown;
+ configureDash: (options: unknown) => typeof options;
+ onBeforeInitDash: (dash: unknown) => void;
+ onAfterInitDash: (dash: unknown) => void;
+ };
+}
+
+interface ILayoutControls {
+ mediaType: string | null;
+ primaryColor: boolean;
+ posterImage: boolean;
+ posterImageSize: "contain";
+ adProgressColor: string;
+ playButtonShowing: boolean;
+ playPauseAnimation: boolean;
+ closeButtonCaption: "Close"; // Remove?
+ fillToContainer: boolean;
+ autoPlay: boolean;
+ preload: "auto";
+ mute: boolean;
+ loop: null;
+ keyboardControl: boolean;
+ allowDownload: boolean;
+ playbackRateEnabled: boolean;
+ subtitlesEnabled: boolean;
+ subtitlesOnByDefault: boolean;
+ showCardBoardView: boolean;
+ showCardBoardJoystick: boolean;
+ allowTheatre: boolean;
+ doubleclickFullscreen: boolean;
+ autoRotateFullScreen: boolean;
+ theatreSettings: ITheatreOptions;
+ theatreAdvanced: {
+ theatreElement: null;
+ };
+ title: null;
+ logo: ILogoOptions;
+ controlBar: {
+ autoHide: false;
+ autoHideTimeout: 3;
+ animated: true;
+ playbackRates: ["x2", "x1.5", "x1", "x0.5"];
+ };
+ timelinePreview: {
+ spriteImage: false;
+ spriteRelativePath: false;
+ };
+ htmlOnPauseBlock: {
+ html: null;
+ height: null;
+ width: null;
+ };
+ layout: "default"; //options: 'default', ''
+ playerInitCallback: () => void;
+ persistentSettings: {
+ volume: true;
+ quality: true;
+ speed: true;
+ theatre: true;
+ };
+ controlForwardBackward: {
+ show: false;
+ doubleTapMobile: true;
+ };
+ contextMenu: {
+ controls: true;
+ links: [];
+ };
+ miniPlayer: {
+ enabled: true;
+ width: 400;
+ height: 225;
+ widthMobile: 50;
+ placeholderText: "Playing in Miniplayer";
+ position: "bottom right";
+ autoToggle: false;
+ };
+ roundedCorners: 0;
+}
+
+interface ITheatreOptions {
+ width: "100%";
+ height: "60%";
+ marginTop: number;
+ horizontalAlign: "center";
+ keepPosition: boolean;
+}
+
+interface ILogoOptions {
+ imageUrl: null;
+ position: "top left";
+ clickUrl: null;
+ opacity: 1;
+ mouseOverImageUrl: null;
+ imageMargin: "2px";
+ hideWithControls: false;
+ showOverAds: false;
+}
+
+interface ICaptions {
+ play: "Play";
+ pause: "Pause";
+ mute: "Mute";
+ unmute: "Unmute";
+ fullscreen: "Fullscreen";
+ subtitles: "Subtitles";
+ exitFullscreen: "Exit Fullscreen";
+}
+
+interface IVastOptions {
+ adList: Record;
+ skipButtonCaption: "Skip ad in [seconds]";
+ skipButtonClickCaption: 'Skip Ad ';
+ adText: null;
+ adTextPosition: "top left";
+ adCTAText: "Visit now!";
+ adCTATextPosition: "bottom right";
+ adCTATextVast: boolean;
+ adClickable: boolean;
+ vastTimeout: number;
+ showProgressbarMarkers: boolean;
+ allowVPAID: boolean;
+ showPlayButton: boolean;
+ maxAllowedVastTagRedirects: number;
+ vpaidTimeout: number;
+
+ vastAdvanced: {
+ vastLoadedCallback: () => void;
+ noVastVideoCallback: () => void;
+ vastVideoSkippedCallback: () => void;
+ vastVideoEndedCallback: () => void;
+ };
+}
+
+interface CustomControls {
+ loader: HTMLDivElement;
+ root: HTMLDivElement;
+ leftContainer: HTMLDivElement;
+ playPause: HTMLDivElement;
+ skipBack: HTMLDivElement;
+ skipForward: HTMLDivElement;
+ progressContainer: HTMLDivElement;
+ progressWrapper: HTMLDivElement;
+ progressCurrent: HTMLDivElement;
+ progress_current_marker: HTMLDivElement;
+ bufferedIndicator: HTMLDivElement;
+ adMarkers: HTMLDivElement;
+ rightContainer: HTMLDivElement;
+ fullscreen: HTMLDivElement;
+ miniPlayer: HTMLDivElement;
+ theatre: HTMLDivElement;
+ cardboard: HTMLDivElement;
+ subtitles: HTMLDivElement;
+ videoSource: HTMLDivElement;
+ playbackRate: HTMLDivElement;
+ download: HTMLDivElement;
+ volumeContainer: HTMLDivElement;
+ volume: HTMLDivElement;
+ volumeCurrent: HTMLDivElement;
+ volumeCurrentPos: HTMLDivElement;
+ mute: HTMLDivElement;
+ durationContainer: HTMLDivElement;
+ duration: HTMLDivElement;
+ live_indicator: HTMLDivElement;
+}
+
+interface IHLSOptions {
+ overrideNative: boolean;
+}
+
+interface HLSPlayer {
+ levels: { details: { live: unknown } }[];
+}
diff --git a/client/fluid-player/test/html/custom_context.tpl.html b/client/fluid-player/test/html/custom_context.tpl.html
new file mode 100644
index 0000000..7fe3938
--- /dev/null
+++ b/client/fluid-player/test/html/custom_context.tpl.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ Custom context menu
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/dash_live.tpl.html b/client/fluid-player/test/html/dash_live.tpl.html
new file mode 100644
index 0000000..eafaa76
--- /dev/null
+++ b/client/fluid-player/test/html/dash_live.tpl.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ DASH Live Stream
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/dash_live_vast.tpl.html b/client/fluid-player/test/html/dash_live_vast.tpl.html
new file mode 100644
index 0000000..d602183
--- /dev/null
+++ b/client/fluid-player/test/html/dash_live_vast.tpl.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ DASH Live Stream with VAST
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/dash_vod.tpl.html b/client/fluid-player/test/html/dash_vod.tpl.html
new file mode 100644
index 0000000..aa07ccc
--- /dev/null
+++ b/client/fluid-player/test/html/dash_vod.tpl.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ DASH VOD
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/dash_vod_vast.tpl.html b/client/fluid-player/test/html/dash_vod_vast.tpl.html
new file mode 100644
index 0000000..897a590
--- /dev/null
+++ b/client/fluid-player/test/html/dash_vod_vast.tpl.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ DASH VOD with VAST
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/e2e/ads_linear.html b/client/fluid-player/test/html/e2e/ads_linear.html
new file mode 100644
index 0000000..67d6fe0
--- /dev/null
+++ b/client/fluid-player/test/html/e2e/ads_linear.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ E2E with VAST Linear
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/e2e/controls.html b/client/fluid-player/test/html/e2e/controls.html
new file mode 100644
index 0000000..661c5c4
--- /dev/null
+++ b/client/fluid-player/test/html/e2e/controls.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ Controls
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/e2e/suggested_videos_e2e.tpl.html b/client/fluid-player/test/html/e2e/suggested_videos_e2e.tpl.html
new file mode 100644
index 0000000..45d0e1d
--- /dev/null
+++ b/client/fluid-player/test/html/e2e/suggested_videos_e2e.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ Suggested videos with subtitles
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/hls_live.tpl.html b/client/fluid-player/test/html/hls_live.tpl.html
new file mode 100644
index 0000000..abdf42e
--- /dev/null
+++ b/client/fluid-player/test/html/hls_live.tpl.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ HLS Live Stream
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/hls_live_vast.tpl.html b/client/fluid-player/test/html/hls_live_vast.tpl.html
new file mode 100644
index 0000000..f3f120f
--- /dev/null
+++ b/client/fluid-player/test/html/hls_live_vast.tpl.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ HLS Live Stream with VAST
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/hls_vod.tpl.html b/client/fluid-player/test/html/hls_vod.tpl.html
new file mode 100644
index 0000000..50c3902
--- /dev/null
+++ b/client/fluid-player/test/html/hls_vod.tpl.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ HLS VOD
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/hls_vod_suggested_videos.html b/client/fluid-player/test/html/hls_vod_suggested_videos.html
new file mode 100644
index 0000000..3eff57e
--- /dev/null
+++ b/client/fluid-player/test/html/hls_vod_suggested_videos.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+ Hls VOD suggested videos
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+Hls with suggested videos
+NOTE : Only Hls supports auto quality, for now
+
+ Initial video is an mp4
+
+ All suggested videos in the initial video are Hls
+ Suggested videos at the end of the second video are mp4's
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/hls_vod_vast.tpl.html b/client/fluid-player/test/html/hls_vod_vast.tpl.html
new file mode 100644
index 0000000..9639690
--- /dev/null
+++ b/client/fluid-player/test/html/hls_vod_vast.tpl.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ HLS VOD with VAST
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/player-reinitialization.tpl.html b/client/fluid-player/test/html/player-reinitialization.tpl.html
new file mode 100644
index 0000000..9e0fecb
--- /dev/null
+++ b/client/fluid-player/test/html/player-reinitialization.tpl.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ Player Reinitialization
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+Destroy
+Create New Instance
+Create and Destroy
+
+
+
+This test is meant to check if the Fluid Player instance is properly clean up after destroying it
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/skip_return.tpl.html b/client/fluid-player/test/html/skip_return.tpl.html
new file mode 100644
index 0000000..4fcf410
--- /dev/null
+++ b/client/fluid-player/test/html/skip_return.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ Skip & Return
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/special-cases/_README.md b/client/fluid-player/test/html/special-cases/_README.md
new file mode 100644
index 0000000..21d95fc
--- /dev/null
+++ b/client/fluid-player/test/html/special-cases/_README.md
@@ -0,0 +1,18 @@
+# Special cases
+
+Templates put here will not appear in the e2e file list, but will be accessible directly by URL in the root of the test server.
+These templates should be used to share a link of an issue to an issue when creating a PR.
+
+To avoid conflicts with any naming, always use identifiers that point to the cause, for example:
+
+* Internal issues: `internal-vast-click-tracking-issue.tpl.html`
+* Github issues: `issue-215.tpl.html`
+
+These files would be accessible in the following URLs when running the dev server:
+
+* http://localhost:8080/internal-vast-click-tracking-issue.html
+* http://localhost:8080/issues-215.html
+
+To use specific static files, please create them in `test/static/special-cases`, no special naming is required.
+
+For more information about how these files are being loaded, check `webpack.config.js`
diff --git a/client/fluid-player/test/html/special-cases/internal-vast-click-tracking-issue.html b/client/fluid-player/test/html/special-cases/internal-vast-click-tracking-issue.html
new file mode 100644
index 0000000..3bc64cd
--- /dev/null
+++ b/client/fluid-player/test/html/special-cases/internal-vast-click-tracking-issue.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ Fluid player doesn't track clicks on some sites
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/special-cases/issue-702.tpl.html b/client/fluid-player/test/html/special-cases/issue-702.tpl.html
new file mode 100644
index 0000000..ad76428
--- /dev/null
+++ b/client/fluid-player/test/html/special-cases/issue-702.tpl.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ Issue 702 - CurrentTime reset after switch HLS source on IOS
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/suggested_videos_ads.tpl.html b/client/fluid-player/test/html/suggested_videos_ads.tpl.html
new file mode 100644
index 0000000..6104711
--- /dev/null
+++ b/client/fluid-player/test/html/suggested_videos_ads.tpl.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ Suggested videos with ads
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/suggested_videos_subtitles.tpl.html b/client/fluid-player/test/html/suggested_videos_subtitles.tpl.html
new file mode 100644
index 0000000..cc2d5d3
--- /dev/null
+++ b/client/fluid-player/test/html/suggested_videos_subtitles.tpl.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ Suggested videos with subtitles
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+Video with no subtitles initially, two video sources
+
+
+
+
+
+
+Video with no subtitles initially, only 1 video source
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic.tpl.html b/client/fluid-player/test/html/vod_basic.tpl.html
new file mode 100644
index 0000000..b342e5e
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic.tpl.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ VOD
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_autohide.tpl.html b/client/fluid-player/test/html/vod_basic_autohide.tpl.html
new file mode 100644
index 0000000..de144a1
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_autohide.tpl.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ VOD auto-hide toolbar
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_by_ref.tpl.html b/client/fluid-player/test/html/vod_basic_by_ref.tpl.html
new file mode 100644
index 0000000..bea153b
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_by_ref.tpl.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+ VOD using reference
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_cta_from_config.tpl.html b/client/fluid-player/test/html/vod_basic_cta_from_config.tpl.html
new file mode 100644
index 0000000..083c937
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_cta_from_config.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ VOD with CTA set from Player Configurations
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_cta_from_vast.tpl.html b/client/fluid-player/test/html/vod_basic_cta_from_vast.tpl.html
new file mode 100644
index 0000000..1a2b4be
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_cta_from_vast.tpl.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+ VOD with CTA set from VAST
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_cta_from_vast_no_friendly_url.tpl.html b/client/fluid-player/test/html/vod_basic_cta_from_vast_no_friendly_url.tpl.html
new file mode 100644
index 0000000..05b4ecb
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_cta_from_vast_no_friendly_url.tpl.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ VOD with CTA set from VAST with no friendly url
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_multiple.tpl.html b/client/fluid-player/test/html/vod_basic_multiple.tpl.html
new file mode 100644
index 0000000..d8d1c05
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_multiple.tpl.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ VOD two players
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_subtitles.tpl.html b/client/fluid-player/test/html/vod_basic_subtitles.tpl.html
new file mode 100644
index 0000000..b61a236
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_subtitles.tpl.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ VOD with subtitles
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_vr.tpl.html b/client/fluid-player/test/html/vod_basic_vr.tpl.html
new file mode 100644
index 0000000..cd28953
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_vr.tpl.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ VOD VR
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_vr_autoplay.tpl.html b/client/fluid-player/test/html/vod_basic_vr_autoplay.tpl.html
new file mode 100644
index 0000000..f3aa9ea
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_vr_autoplay.tpl.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ VOD VR with Auto Play
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_vtt.tpl.html b/client/fluid-player/test/html/vod_basic_vtt.tpl.html
new file mode 100644
index 0000000..5278bf6
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_vtt.tpl.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ VOD with timeline thumbnails
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_basic_vtt_static.tpl.html b/client/fluid-player/test/html/vod_basic_vtt_static.tpl.html
new file mode 100644
index 0000000..013db4b
--- /dev/null
+++ b/client/fluid-player/test/html/vod_basic_vtt_static.tpl.html
@@ -0,0 +1,1857 @@
+
+
+
+
+
+
+ VOD with timeline static-thumbnails
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_event_api.html b/client/fluid-player/test/html/vod_event_api.html
new file mode 100644
index 0000000..f041938
--- /dev/null
+++ b/client/fluid-player/test/html/vod_event_api.html
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+ VOD with Event API callbacks
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+Check your console for the messages beginning with type Callback
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_extended.tpl.html b/client/fluid-player/test/html/vod_extended.tpl.html
new file mode 100644
index 0000000..acc8cef
--- /dev/null
+++ b/client/fluid-player/test/html/vod_extended.tpl.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ VOD extended
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_live_ad.tpl.html b/client/fluid-player/test/html/vod_live_ad.tpl.html
new file mode 100644
index 0000000..63cb986
--- /dev/null
+++ b/client/fluid-player/test/html/vod_live_ad.tpl.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ VOD with VAST Live Ad Creative
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_miniplayer.tpl.html b/client/fluid-player/test/html/vod_miniplayer.tpl.html
new file mode 100644
index 0000000..bdf569d
--- /dev/null
+++ b/client/fluid-player/test/html/vod_miniplayer.tpl.html
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+ VOD with Mini Player
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_responsive.tpl.html b/client/fluid-player/test/html/vod_responsive.tpl.html
new file mode 100644
index 0000000..1115a3b
--- /dev/null
+++ b/client/fluid-player/test/html/vod_responsive.tpl.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ VOD responsive
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast__linear.html b/client/fluid-player/test/html/vod_vast__linear.html
new file mode 100644
index 0000000..565c22f
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast__linear.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ VOD with VAST Linear
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast__non_linear.html b/client/fluid-player/test/html/vod_vast__non_linear.html
new file mode 100644
index 0000000..f771031
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast__non_linear.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ VOD with VAST Non Linear
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_ad_buffet.tpl.html b/client/fluid-player/test/html/vod_vast_ad_buffet.tpl.html
new file mode 100644
index 0000000..4340c3a
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_ad_buffet.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ VOD with VAST Ad Buffet
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_ad_buffet_with_error.tpl.html b/client/fluid-player/test/html/vod_vast_ad_buffet_with_error.tpl.html
new file mode 100644
index 0000000..c379f19
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_ad_buffet_with_error.tpl.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ VOD with VAST Ad Buffet With Error
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+First AD doesn't have a Creative, fallbacks to second ad.
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_ad_pod.tpl.html b/client/fluid-player/test/html/vod_vast_ad_pod.tpl.html
new file mode 100644
index 0000000..92045d5
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_ad_pod.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ VOD with VAST Ad Pod
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_ad_pod_from_wrapper.tpl.html b/client/fluid-player/test/html/vod_vast_ad_pod_from_wrapper.tpl.html
new file mode 100644
index 0000000..534941d
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_ad_pod_from_wrapper.tpl.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ VOD with VAST Ad Pod - Loaded from a VAST Wrapper
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_ad_pod_truncated.tpl.html b/client/fluid-player/test/html/vod_vast_ad_pod_truncated.tpl.html
new file mode 100644
index 0000000..e59b1b8
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_ad_pod_truncated.tpl.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ VOD with VAST Ad Pod - Truncated by maxTotalQuantity
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+In this scenario VAST returns an Ad Pod with 3 Ads, but we limit the Ad Pods to play only 2 Ads
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_false.tpl.html b/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_false.tpl.html
new file mode 100644
index 0000000..1dec9b0
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_false.tpl.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - followAdditionalWrappers: false
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+Expected: No AD should play, as it won't follow the nested VAST Wrappers
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_true.tpl.html b/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_true.tpl.html
new file mode 100644
index 0000000..63a3aeb
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_followAdditionalWrappers_true.tpl.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - followAdditionalWrappers: true
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_on-demand.html b/client/fluid-player/test/html/vod_vast_on-demand.html
new file mode 100644
index 0000000..bbffafc
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_on-demand.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+ VOD with VAST loaded on demand
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+
+ midRoll 1 (Linear) - Will be loaded on video start, since its timer is set to 3
+ midRoll 2 (Linear) - Will be loaded at 10 seconds, since its timer is set to 15
+ midRoll 3 (Non-Linear) - Will be loaded at 25 seconds, since its timer is set to 30
+ postRoll (Linear) - Will be loaded in any of the 5 last seconds of the video
+
+
+Check DevTools to see the VAST requests being loaded on demand
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_waterfall_false.tpl.html b/client/fluid-player/test/html/vod_vast_waterfall_false.tpl.html
new file mode 100644
index 0000000..6bc8a28
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_waterfall_false.tpl.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - VAST Waterfall Off (fallbackOnNoAd=false)
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+VOD with VAST Wrapper - VAST Waterfall Off (fallbackOnNoAd=false)
+This scenario represents the following statement from the fallbackOnNoAd description: "(...) instruction for using an available Ad when the requested VAST response returns no ads. (...) If false and the Wrapper represents an Ad in a Pod, the video player should move on to the next Ad in a Pod;".
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_waterfall_false_http_error.tpl.html b/client/fluid-player/test/html/vod_vast_waterfall_false_http_error.tpl.html
new file mode 100644
index 0000000..bc87dff
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_waterfall_false_http_error.tpl.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - VAST Waterfall Off (fallbackOnNoAd=false) - Http Error
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+VOD with VAST Wrapper - VAST Waterfall Off (fallbackOnNoAd=false)
+This scenario represents the following statement from the fallbackOnNoAd description: "(...) instruction for using an available Ad when the requested VAST response returns no ads. (...) If false and the Wrapper represents an Ad in a Pod, the video player should move on to the next Ad in a Pod;".
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_waterfall_true.tpl.html b/client/fluid-player/test/html/vod_vast_waterfall_true.tpl.html
new file mode 100644
index 0000000..a3ea703
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_waterfall_true.tpl.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - VAST Waterfall On (fallbackOnNoAd=true)
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+VOD with VAST Wrapper - VAST Waterfall On (fallbackOnNoAd=true)
+This scenario represents the following statement from the fallbackOnNoAd description: "(...) instruction for using an available Ad when the requested VAST response returns no ads. If true, the video player should select from any stand-alone ads available.".
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_waterfall_true_http_error.tpl.html b/client/fluid-player/test/html/vod_vast_waterfall_true_http_error.tpl.html
new file mode 100644
index 0000000..98aeb93
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_waterfall_true_http_error.tpl.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - VAST Waterfall On (fallbackOnNoAd=true) - Http Error
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+VOD with VAST Wrapper - VAST Waterfall On (fallbackOnNoAd=true)
+This scenario represents the following statement from the fallbackOnNoAd description: "(...) instruction for using an available Ad when the requested VAST response returns no ads. If true, the video player should select from any stand-alone ads available.".
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_wrapper.tpl.html b/client/fluid-player/test/html/vod_vast_wrapper.tpl.html
new file mode 100644
index 0000000..f34fa05
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_wrapper.tpl.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vast_wrapper_cyclical.tpl.html b/client/fluid-player/test/html/vod_vast_wrapper_cyclical.tpl.html
new file mode 100644
index 0000000..0cd34b7
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vast_wrapper_cyclical.tpl.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ VOD with VAST Wrapper - Cyclical reference
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+Expected: No AD should play, as it will stop following the cyclical wrapper references
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vpaid_linear.html b/client/fluid-player/test/html/vod_vpaid_linear.html
new file mode 100644
index 0000000..deae0b8
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vpaid_linear.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ VOD with VPAID Linear
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vpaid_linear_viewableImpresson.html b/client/fluid-player/test/html/vod_vpaid_linear_viewableImpresson.html
new file mode 100644
index 0000000..09ea309
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vpaid_linear_viewableImpresson.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+ VOD with VPAID Linear Viewable Impression
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+Viewable impression tests
+
+Regular scenario: Here you should see the viewable impression being called in the network tab
+
+
+
+
+
+
+
+Player off screen, so no viewable impression is going to be called
+Order of what's happening
+
+ Player starts -> 2 seconds later it will go off screen
+ Player starts playing ad after 5 seconds, there should be no viewable impression
+ The moment you scroll down to the player, the viewable impression should be called in the network tab (if the ad is still rolling)
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/html/vod_vpaid_non_linear.html b/client/fluid-player/test/html/vod_vpaid_non_linear.html
new file mode 100644
index 0000000..1cf6dfd
--- /dev/null
+++ b/client/fluid-player/test/html/vod_vpaid_non_linear.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ VOD with VPAID Non Linear
+ <%= htmlWebpackPlugin.tags.headTags %>
+
+
+
+
+
+
+
+
+
+
+<%= htmlWebpackPlugin.tags.bodyTags %>
+
+
+
+
+
diff --git a/client/fluid-player/test/index.html b/client/fluid-player/test/index.html
new file mode 100644
index 0000000..984a07b
--- /dev/null
+++ b/client/fluid-player/test/index.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ Fluid Player E2E test case index listing
+
+
+
+
+
+
+ Fluid Player E2E cases
+
+
+ Note: you need to restart the dev-server for new cases to be listed here.
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/logo.png b/client/fluid-player/test/static/logo.png
new file mode 100644
index 0000000..e001c5a
Binary files /dev/null and b/client/fluid-player/test/static/logo.png differ
diff --git a/client/fluid-player/test/static/special-cases/fp-215-2.xml b/client/fluid-player/test/static/special-cases/fp-215-2.xml
new file mode 100644
index 0000000..757e314
--- /dev/null
+++ b/client/fluid-player/test/static/special-cases/fp-215-2.xml
@@ -0,0 +1,108 @@
+
+
+
+ Fluid Player
+ Exclusive Offer - Join Now
+
+
+
+
+
+
+
+
+ 00:00:30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/special-cases/fp-215.xml b/client/fluid-player/test/static/special-cases/fp-215.xml
new file mode 100644
index 0000000..11a8e73
--- /dev/null
+++ b/client/fluid-player/test/static/special-cases/fp-215.xml
@@ -0,0 +1,37 @@
+
+
+
+ Fluid Player
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/subtitles/deutsch.vtt b/client/fluid-player/test/static/subtitles/deutsch.vtt
new file mode 100644
index 0000000..f7d8e40
--- /dev/null
+++ b/client/fluid-player/test/static/subtitles/deutsch.vtt
@@ -0,0 +1,309 @@
+WEBVTT
+
+1
+00:00:15.042 --> 00:00:18.042 align:start
+Auf der linken Seite sehen wir...
+
+2
+00:00:18.750 --> 00:00:20.333 align:middle
+Auf der rechten Seite sehen wir die...
+
+3
+00:00:20.417 --> 00:00:21.917
+...die Enthaupter.
+
+4
+00:00:22.000 --> 00:00:24.625 align:end
+Alles ist sicher. Vollkommen sicher.
+
+5
+00:00:26.333 --> 00:00:27.333
+Emo?
+
+6
+00:00:28.875 --> 00:00:30.250 line:6% size:110%
+Pass auf!
+
+7
+00:00:47.125 --> 00:00:48.250
+Bist du verletzt?
+
+8
+00:00:51.917 --> 00:00:53.917
+Ich glaube nicht. Und du?
+
+9
+00:00:55.625 --> 00:00:57.125
+Mir fehlt nichts.
+
+10
+00:00:57.583 --> 00:01:01.667
+Steh auf! Emo, es ist gefährlich hier.
+
+11
+00:01:02.208 --> 00:01:03.667
+Weiter!
+
+12
+00:01:03.750 --> 00:01:05.750
+Was jetzt?
+
+13
+00:01:05.875 --> 00:01:07.875
+Du wirst es sehen.
+
+14
+00:01:16.167 --> 00:01:18.375
+Emo, hier lang.
+
+15
+00:01:34.958 --> 00:01:35.792
+Mir nach!
+
+16
+00:02:11.583 --> 00:02:12.792
+Schneller, Emo!
+
+17
+00:02:48.375 --> 00:02:50.083
+Du bist unaufmerksam!
+
+18
+00:02:50.750 --> 00:02:54.500
+Ich wollte doch nur an... ...ans Telefon gehen.
+
+19
+00:02:55.000 --> 00:02:58.208
+Emo, schau, ich meine, hör zu.
+
+20
+00:02:59.750 --> 00:03:02.292
+Du musst lernen zuzuhören.
+
+21
+00:03:03.625 --> 00:03:05.125
+Das hier ist kein Spiel.
+
+22
+00:03:06.167 --> 00:03:08.750
+u, wir, könnten hier draußen leicht sterben.
+
+23
+00:03:10.208 --> 00:03:14.125
+Hör zu... Hör dem Klang der Maschine zu.
+
+24
+00:03:18.333 --> 00:03:20.417
+Hör auf deinen Atem.
+
+25
+00:04:27.208 --> 00:04:29.250
+Hast du nie genug davon?
+
+26
+00:04:29.583 --> 00:04:31.083
+Genug?!?
+
+27
+00:04:31.750 --> 00:04:34.667
+Die Maschine ist wie ein Uhrwerk.
+
+28
+00:04:35.500 --> 00:04:37.708
+Ein falscher Schritt...
+
+29
+00:04:37.833 --> 00:04:39.792
+...und du wirst zerquetscht.
+
+30
+00:04:41.042 --> 00:04:42.375
+Aber ist es nicht...
+
+31
+00:04:42.417 --> 00:04:46.542
+Zerquetscht, Emo! Willst du das? Zerquetscht werden?
+
+32
+00:04:48.083 --> 00:04:50.000
+Dein Lebensziel?
+
+33
+00:04:50.583 --> 00:04:52.250
+Zerquetscht!
+
+34
+00:05:41.833 --> 00:05:43.458
+Emo, schließ die Augen.
+
+35
+00:05:44.917 --> 00:05:46.583
+Warum? - Sofort!
+
+36
+00:05:53.750 --> 00:05:56.042
+Gut.
+
+37
+00:05:59.542 --> 00:06:02.792
+Was siehst du zu deiner Linken, Emo?
+
+38
+00:06:04.417 --> 00:06:06.000
+Nichts. - Wirklich?
+
+39
+00:06:06.333 --> 00:06:07.917
+Überhaupt nichts.
+
+40
+00:06:08.042 --> 00:06:12.417
+Und zu deiner Rechten, was siehst du zu deiner Rechten, Emo?
+
+41
+00:06:13.875 --> 00:06:16.917
+Dasselbe, Proog, genau dasselbe...
+
+42
+00:06:17.083 --> 00:06:18.583
+Nichts!
+
+43
+00:06:40.625 --> 00:06:42.958
+Hör mal, Proog! Hörst du das?
+
+44
+00:06:43.625 --> 00:06:45.042
+Können wir hier hingehen?
+
+45
+00:06:45.208 --> 00:06:48.042
+Dorthin? Das ist gefährlich.
+
+46
+00:06:49.917 --> 00:06:52.500
+Aber... - Vertrau mir, es ist gefährlich.
+
+47
+00:06:53.292 --> 00:06:54.792
+Vielleicht könnte ich...
+
+48
+00:06:54.833 --> 00:06:56.333
+Nein.
+
+49
+00:06:57.667 --> 00:07:00.167
+NEIN!
+
+50
+00:07:00.875 --> 00:07:03.750
+Sonst noch Fragen, Emo?
+
+51
+00:07:04.250 --> 00:07:05.917
+Nein.
+
+52
+00:07:09.458 --> 00:07:10.833
+Emo.
+
+53
+00:07:11.875 --> 00:07:13.542
+Emo, warum...
+
+54
+00:07:13.583 --> 00:07:14.458
+Emo...
+
+55
+00:07:14.500 --> 00:07:18.500
+...warum erkennst du nicht die Schönheit dieses Ortes?
+
+56
+00:07:18.833 --> 00:07:20.750
+ie alles funktioniert.
+
+57
+00:07:20.875 --> 00:07:24.000
+Wie vollkommen es ist.
+
+58
+00:07:24.083 --> 00:07:27.417
+Nein, Proog, ich erkenne nichts.
+
+59
+00:07:27.542 --> 00:07:30.333
+Ich erkenne nichts, weil da nichts ist.
+
+60
+00:07:31.500 --> 00:07:35.333
+Und warum sollte ich mein Leben etwas anvertrauen, das gar nicht da ist?
+
+61
+00:07:35.583 --> 00:07:37.042
+Kannst du mir das sagen? - Emo...
+
+62
+00:07:37.500 --> 00:07:39.167
+Antworte mir!
+
+63
+00:07:43.208 --> 00:07:44.583
+Proog...
+
+64
+00:07:45.500 --> 00:07:47.333
+Du bist krank, Mann!
+
+65
+00:07:47.375 --> 00:07:49.208
+Bleib weg von mir!
+
+66
+00:07:52.583 --> 00:07:55.083
+Nein! Emo! Das ist eine Falle!
+
+67
+00:07:55.833 --> 00:07:57.167
+Haha, eine Falle.
+
+68
+00:07:57.208 --> 00:08:01.750
+Auf der linken Seite sieht man die Hängenden Gärten von Babylon.
+
+69
+00:08:02.250 --> 00:08:04.292
+Wie wär das als Falle?
+
+70
+00:08:05.458 --> 00:08:07.125
+Nein, Emo.
+
+71
+00:08:09.417 --> 00:08:12.792
+Auf der rechten Seite sieht man... ...rate mal...
+
+72
+00:08:13.000 --> 00:08:14.750
+...den Koloss von Rhodos!
+
+73
+00:08:15.833 --> 00:08:16.708
+Nein!
+
+74
+00:08:16.750 --> 00:08:22.167
+Den Koloss von Rhodos und er ist nur für dich hier, Proog.
+
+75
+00:08:51.333 --> 00:08:53.167
+Es ist da...
+
+76
+00:08:53.208 --> 00:08:55.500
+Wenn ich es dir doch sage, Emo...
+
+77
+00:08:57.333 --> 00:09:00.000
+...es ist da.
\ No newline at end of file
diff --git a/client/fluid-player/test/static/subtitles/english.vtt b/client/fluid-player/test/static/subtitles/english.vtt
new file mode 100644
index 0000000..7d3e2cc
--- /dev/null
+++ b/client/fluid-player/test/static/subtitles/english.vtt
@@ -0,0 +1,357 @@
+WEBVTT
+
+1
+00:00:15.000 --> 00:00:18.000 align:start
+At the left we can see...
+
+2
+00:00:18.167 --> 00:00:20.083 align:middle
+At the right we can see the...
+
+3
+00:00:20.083 --> 00:00:22.000
+...the head-snarlers
+
+4
+00:00:22.000 --> 00:00:24.417 align:end
+Everything is safe. Perfectly safe.
+
+5
+00:00:24.583 --> 00:00:27.083
+Emo?
+
+6
+00:00:28.208 --> 00:00:30.042 line:6% size:110%
+Watch out!
+
+7
+00:00:47.042 --> 00:00:48.542
+Are you hurt?
+
+8
+00:00:52.000 --> 00:00:54.000
+I don't think so. You?
+
+9
+00:00:55.167 --> 00:00:57.042
+I'm Ok.
+
+10
+00:00:57.125 --> 00:01:01.167
+Get up. Emo, it's not safe here.
+
+11
+00:01:02.042 --> 00:01:03.167
+Let's go.
+
+12
+00:01:03.167 --> 00:01:05.167
+What's next?
+
+13
+00:01:05.208 --> 00:01:09.208
+You'll see!
+
+14
+00:01:12.000 --> 00:01:14.000
+(howling wind)
+
+15
+00:01:16.042 --> 00:01:18.083
+Emo. This way.
+
+16
+00:01:34.250 --> 00:01:35.542
+Follow me!
+
+17
+00:01:39.000 --> 00:01:42.000
+(buzzing wires and chattery conversations)
+
+18
+00:02:11.125 --> 00:02:12.542
+Hurry Emo!
+
+19
+00:02:20.292 --> 00:02:22.792
+(louder telephone voices)
+
+20
+00:02:32.000 --> 00:02:34.500
+(phone ringing)
+
+21
+00:02:48.083 --> 00:02:50.000
+You're not paying attention!
+
+22
+00:02:50.167 --> 00:02:54.125
+I just want to answer the... ...phone.
+
+23
+00:02:55.000 --> 00:02:58.042
+Emo, look, I mean listen.
+
+24
+00:02:59.167 --> 00:03:02.083
+You have to learn to listen.
+
+25
+00:03:03.167 --> 00:03:05.042
+This is not some game.
+
+26
+00:03:05.083 --> 00:03:09.417
+You, I mean we, we could easily die out here.
+
+27
+00:03:10.042 --> 00:03:14.042
+Listen, listen to the sounds of the machine.
+
+28
+00:03:18.083 --> 00:03:20.083
+Listen to your breathing.
+
+29
+00:03:27.000 --> 00:03:29.000
+(Buzzing wires)
+
+30
+00:03:34.500 --> 00:03:36.500
+(laughing)
+
+31
+00:04:13.417 --> 00:04:15.417
+(oriental dance music)
+
+32
+00:04:27.042 --> 00:04:29.042
+Well, don't you ever get tired of this?
+
+33
+00:04:29.125 --> 00:04:31.000
+Tired?!?
+
+34
+00:04:31.167 --> 00:04:34.583
+Emo, the machine is like clockwork.
+
+35
+00:04:35.125 --> 00:04:37.167
+One move out of place...
+
+36
+00:04:37.208 --> 00:04:39.208
+...and you're ground to a pulp.
+
+37
+00:04:41.000 --> 00:04:42.083
+But isn't it -
+
+38
+00:04:42.083 --> 00:04:46.125
+Pulp, Emo! Is that what you want, pulp?
+
+39
+00:04:47.083 --> 00:04:49.083
+Emo, your goal in life...
+
+40
+00:04:50.125 --> 00:04:52.042
+...pulp?
+
+41
+00:05:08.000 --> 00:05:10.500
+(loud metal sounds)
+
+42
+00:05:41.208 --> 00:05:43.125
+Emo, close your eyes.
+
+43
+00:05:44.208 --> 00:05:46.125
+Why? - Now!
+
+44
+00:05:51.208 --> 00:05:52.208
+Ok.
+
+45
+00:05:53.167 --> 00:05:54.792
+Good.
+
+46
+00:05:59.125 --> 00:06:02.208
+What do you see at your left side, Emo?
+
+47
+00:06:04.083 --> 00:06:06.000
+Nothing. - Really?
+
+48
+00:06:06.083 --> 00:06:07.208
+No, nothing at all.
+
+49
+00:06:08.000 --> 00:06:12.083
+And at your right, what do you see at your right side, Emo?
+
+50
+00:06:13.208 --> 00:06:16.208
+The same Proog, exactly the same...
+
+51
+00:06:17.000 --> 00:06:19.208
+...nothing! - Great.
+
+52
+00:06:25.208 --> 00:06:27.208
+(sound of camera flash)
+
+53
+00:06:29.792 --> 00:06:31.792
+(engine drone)
+
+54
+00:06:40.167 --> 00:06:42.833
+Listen Proog! Do you hear that! (amusement park music)
+
+55
+00:06:43.167 --> 00:06:45.000
+Can we go here?
+
+56
+00:06:45.042 --> 00:06:48.000
+There? It isn't safe, Emo.
+
+57
+00:06:49.208 --> 00:06:52.125
+But... - Trust me, it's not.
+
+58
+00:06:53.083 --> 00:06:54.208
+Maybe I could...
+
+59
+00:06:54.208 --> 00:06:56.083
+No.
+
+60
+00:06:57.167 --> 00:07:00.042
+NO!
+
+61
+00:07:00.208 --> 00:07:03.167
+Any further questions, Emo?
+
+62
+00:07:04.042 --> 00:07:05.208
+No.
+
+63
+00:07:09.125 --> 00:07:10.208
+Emo?
+
+64
+00:07:11.208 --> 00:07:13.125
+Emo, why...
+
+65
+00:07:13.125 --> 00:07:14.125
+Emo...
+
+66
+00:07:14.125 --> 00:07:18.125
+...why can't you see the beauty of this place?
+
+67
+00:07:18.208 --> 00:07:20.167
+The way it works.
+
+68
+00:07:20.208 --> 00:07:24.000
+How perfect it is.
+
+69
+00:07:24.000 --> 00:07:27.083
+No, Proog, I don't see.
+
+70
+00:07:27.125 --> 00:07:30.083
+I don't see because there's nothing there.
+
+71
+00:07:31.125 --> 00:07:35.083
+And why should I trust my life to something that isn't there?
+
+72
+00:07:35.125 --> 00:07:37.042
+Well can you tell me that? - Emo...
+
+73
+00:07:37.125 --> 00:07:39.042
+Answer me!
+
+74
+00:07:43.042 --> 00:07:44.125
+Proog...
+
+75
+00:07:45.125 --> 00:07:47.083
+...you're a sick man!
+
+76
+00:07:47.083 --> 00:07:49.042
+Stay away from me!
+
+77
+00:07:52.125 --> 00:07:55.000
+No! Emo! It's a trap!
+
+78
+00:07:55.208 --> 00:07:57.042
+Hah, it's a trap.
+
+79
+00:07:57.042 --> 00:08:01.167
+At the left side you can see the hanging gardens of Babylon!
+
+80
+00:08:02.042 --> 00:08:04.083
+How's that for a trap?
+
+81
+00:08:05.125 --> 00:08:07.042
+No, Emo.
+
+82
+00:08:09.083 --> 00:08:12.208
+At the right side you can see... ...well guess what...
+
+83
+00:08:13.000 --> 00:08:14.792
+...the colossus of Rhodes!
+
+84
+00:08:15.208 --> 00:08:16.167
+No!
+
+85
+00:08:16.167 --> 00:08:22.042
+The colossus of Rhodes and it is here just for you Proog.
+
+86
+00:08:51.083 --> 00:08:53.042
+It is there...
+
+87
+00:08:53.042 --> 00:08:56.167
+I'm telling you, Emo...
+
+88
+00:08:57.083 --> 00:09:00.000
+...it is, it is.
+
+89
+00:09:05.000 --> 00:09:07.500
+(howling wind)
\ No newline at end of file
diff --git a/client/fluid-player/test/static/suggested_videos_example_v1.json b/client/fluid-player/test/static/suggested_videos_example_v1.json
new file mode 100644
index 0000000..5e6950a
--- /dev/null
+++ b/client/fluid-player/test/static/suggested_videos_example_v1.json
@@ -0,0 +1,396 @@
+[
+ {
+ "id": 0,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ },
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "480p"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "Big Buck Bunny",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 1,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ },
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "1080p",
+ "hd": "true"
+ }
+ ],
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg",
+ "title": "Elephant Dream",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 2,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerBlazes.jpg",
+ "title": "For Bigger Blazes",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 3,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerEscapes.jpg",
+ "title": "For Bigger Escape",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en",
+ "default": true
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de"
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 4,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerFun.jpg",
+ "title": "For Bigger Fun",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 5,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerJoyrides.jpg",
+ "title": "For Bigger Joyrides",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 6,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerMeltdowns.jpg",
+ "title": "For Bigger Meltdowns",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 7,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/Sintel.jpg",
+ "title": "Sintel",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 8,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/SubaruOutbackOnStreetAndDirt.jpg",
+ "title": "Subaru Outback On Street And Dirt",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 9,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/TearsOfSteel.jpg",
+ "title": "Tears of Steel",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 10,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/VolkswagenGTIReview.jpg",
+ "title": "Volkswagen GTI Review",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 11,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/WeAreGoingOnBullrun.jpg",
+ "title": "We Are Going On Bullrun",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 12,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WhatCarCanYouGetForAGrand.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/WhatCarCanYouGetForAGrand.jpg",
+ "title": "What care can you get for a grand?",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ }
+]
\ No newline at end of file
diff --git a/client/fluid-player/test/static/suggested_videos_example_v2.json b/client/fluid-player/test/static/suggested_videos_example_v2.json
new file mode 100644
index 0000000..706f9e0
--- /dev/null
+++ b/client/fluid-player/test/static/suggested_videos_example_v2.json
@@ -0,0 +1,383 @@
+[
+ {
+ "id": 3,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerEscapes.jpg",
+ "title": "For Bigger Escape",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en",
+ "default": true
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de"
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 10,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/VolkswagenGTIReview.jpg",
+ "title": "Volkswagen GTI Review",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 2,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerBlazes.jpg",
+ "title": "For Bigger Blazes",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 4,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerFun.jpg",
+ "title": "For Bigger Fun",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 11,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/WeAreGoingOnBullrun.jpg",
+ "title": "We Are Going On Bullrun",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 6,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerMeltdowns.jpg",
+ "title": "For Bigger Meltdowns",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 7,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/Sintel.jpg",
+ "title": "Sintel",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 0,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ },
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "480p"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "Big Buck Bunny",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 8,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/SubaruOutbackOnStreetAndDirt.jpg",
+ "title": "Subaru Outback On Street And Dirt",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 9,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/TearsOfSteel.jpg",
+ "title": "Tears of Steel",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 12,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WhatCarCanYouGetForAGrand.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/WhatCarCanYouGetForAGrand.jpg",
+ "title": "What care can you get for a grand?",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl"
+ },
+ {
+ "label": "Deutsch",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "de",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 1,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ },
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "1080p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg",
+ "title": "Elephant Dream",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 5,
+ "sources": [
+ {
+ "url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4",
+ "mimeType": "video/mp4",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerJoyrides.jpg",
+ "title": "For Bigger Joyrides",
+ "subtitles": [
+ {
+ "label": "English",
+ "url": "/static/subtitles/english.vtt",
+ "lang": "en"
+ },
+ {
+ "label": "Nederlands",
+ "url": "/static/subtitles/deutsch.vtt",
+ "lang": "nl",
+ "default": true
+ }
+ ],
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ }
+]
\ No newline at end of file
diff --git a/client/fluid-player/test/static/suggested_videos_example_v3.json b/client/fluid-player/test/static/suggested_videos_example_v3.json
new file mode 100644
index 0000000..8c74832
--- /dev/null
+++ b/client/fluid-player/test/static/suggested_videos_example_v3.json
@@ -0,0 +1,170 @@
+[
+ {
+ "id": 0,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 1,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 2,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 3,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 4,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 5,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 6,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 7,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 8,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 9,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 10,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ },
+ {
+ "id": 11,
+ "sources": [
+ {
+ "url": "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
+ "mimeType": "application/x-mpegurl",
+ "resolution": "720p",
+ "hd": "true"
+ }
+ ],
+ "thumbnailUrl": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg",
+ "title": "HLS VOD",
+ "configUrl" : "/static/suggested_videos_example_v2.json"
+ }
+]
\ No newline at end of file
diff --git a/client/fluid-player/test/static/thumbnails.jpg b/client/fluid-player/test/static/thumbnails.jpg
new file mode 100644
index 0000000..32269b1
Binary files /dev/null and b/client/fluid-player/test/static/thumbnails.jpg differ
diff --git a/client/fluid-player/test/static/thumbnails.vtt b/client/fluid-player/test/static/thumbnails.vtt
new file mode 100644
index 0000000..8b95e4c
--- /dev/null
+++ b/client/fluid-player/test/static/thumbnails.vtt
@@ -0,0 +1,607 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:00.500
+/static/thumbnails.jpg#xywh=0,0,200,84
+
+00:00:00.500 --> 00:00:01.000
+/static/thumbnails.jpg#xywh=200,0,200,84
+
+00:00:01.000 --> 00:00:01.500
+/static/thumbnails.jpg#xywh=400,0,200,84
+
+00:00:01.500 --> 00:00:02.000
+/static/thumbnails.jpg#xywh=600,0,200,84
+
+00:00:02.000 --> 00:00:02.500
+/static/thumbnails.jpg#xywh=800,0,200,84
+
+00:00:02.500 --> 00:00:03.000
+/static/thumbnails.jpg#xywh=1000,0,200,84
+
+00:00:03.000 --> 00:00:03.500
+/static/thumbnails.jpg#xywh=1200,0,200,84
+
+00:00:03.500 --> 00:00:04.000
+/static/thumbnails.jpg#xywh=1400,0,200,84
+
+00:00:04.000 --> 00:00:04.500
+/static/thumbnails.jpg#xywh=1600,0,200,84
+
+00:00:04.500 --> 00:00:05.000
+/static/thumbnails.jpg#xywh=1800,0,200,84
+
+00:00:05.000 --> 00:00:05.500
+/static/thumbnails.jpg#xywh=2000,0,200,84
+
+00:00:05.500 --> 00:00:06.000
+/static/thumbnails.jpg#xywh=2200,0,200,84
+
+00:00:06.000 --> 00:00:06.500
+/static/thumbnails.jpg#xywh=2400,0,200,84
+
+00:00:06.500 --> 00:00:07.000
+/static/thumbnails.jpg#xywh=2600,0,200,84
+
+00:00:07.000 --> 00:00:07.500
+/static/thumbnails.jpg#xywh=2800,0,200,84
+
+00:00:07.500 --> 00:00:08.000
+/static/thumbnails.jpg#xywh=3000,0,200,84
+
+00:00:08.000 --> 00:00:08.500
+/static/thumbnails.jpg#xywh=3200,0,200,84
+
+00:00:08.500 --> 00:00:09.000
+/static/thumbnails.jpg#xywh=3400,0,200,84
+
+00:00:09.000 --> 00:00:09.500
+/static/thumbnails.jpg#xywh=3600,0,200,84
+
+00:00:09.500 --> 00:00:10.000
+/static/thumbnails.jpg#xywh=3800,0,200,84
+
+00:00:10.000 --> 00:00:10.500
+/static/thumbnails.jpg#xywh=4000,0,200,84
+
+00:00:10.500 --> 00:00:11.000
+/static/thumbnails.jpg#xywh=4200,0,200,84
+
+00:00:11.000 --> 00:00:11.500
+/static/thumbnails.jpg#xywh=4400,0,200,84
+
+00:00:11.500 --> 00:00:12.000
+/static/thumbnails.jpg#xywh=4600,0,200,84
+
+00:00:12.000 --> 00:00:12.500
+/static/thumbnails.jpg#xywh=4800,0,200,84
+
+00:00:12.500 --> 00:00:13.000
+/static/thumbnails.jpg#xywh=5000,0,200,84
+
+00:00:13.000 --> 00:00:13.500
+/static/thumbnails.jpg#xywh=5200,0,200,84
+
+00:00:13.500 --> 00:00:14.000
+/static/thumbnails.jpg#xywh=5400,0,200,84
+
+00:00:14.000 --> 00:00:14.500
+/static/thumbnails.jpg#xywh=5600,0,200,84
+
+00:00:14.500 --> 00:00:15.000
+/static/thumbnails.jpg#xywh=5800,0,200,84
+
+00:00:15.000 --> 00:00:15.500
+/static/thumbnails.jpg#xywh=6000,0,200,84
+
+00:00:15.500 --> 00:00:16.000
+/static/thumbnails.jpg#xywh=6200,0,200,84
+
+00:00:16.000 --> 00:00:16.500
+/static/thumbnails.jpg#xywh=6400,0,200,84
+
+00:00:16.500 --> 00:00:17.000
+/static/thumbnails.jpg#xywh=6600,0,200,84
+
+00:00:17.000 --> 00:00:17.500
+/static/thumbnails.jpg#xywh=6800,0,200,84
+
+00:00:17.500 --> 00:00:18.000
+/static/thumbnails.jpg#xywh=7000,0,200,84
+
+00:00:18.000 --> 00:00:18.500
+/static/thumbnails.jpg#xywh=7200,0,200,84
+
+00:00:18.500 --> 00:00:19.000
+/static/thumbnails.jpg#xywh=7400,0,200,84
+
+00:00:19.000 --> 00:00:19.500
+/static/thumbnails.jpg#xywh=7600,0,200,84
+
+00:00:19.500 --> 00:00:20.000
+/static/thumbnails.jpg#xywh=7800,0,200,84
+
+00:00:20.000 --> 00:00:20.500
+/static/thumbnails.jpg#xywh=8000,0,200,84
+
+00:00:20.500 --> 00:00:21.000
+/static/thumbnails.jpg#xywh=8200,0,200,84
+
+00:00:21.000 --> 00:00:21.500
+/static/thumbnails.jpg#xywh=8400,0,200,84
+
+00:00:21.500 --> 00:00:22.000
+/static/thumbnails.jpg#xywh=8600,0,200,84
+
+00:00:22.000 --> 00:00:22.500
+/static/thumbnails.jpg#xywh=8800,0,200,84
+
+00:00:22.500 --> 00:00:23.000
+/static/thumbnails.jpg#xywh=9000,0,200,84
+
+00:00:23.000 --> 00:00:23.500
+/static/thumbnails.jpg#xywh=9200,0,200,84
+
+00:00:23.500 --> 00:00:24.000
+/static/thumbnails.jpg#xywh=9400,0,200,84
+
+00:00:24.000 --> 00:00:24.500
+/static/thumbnails.jpg#xywh=9600,0,200,84
+
+00:00:24.500 --> 00:00:25.000
+/static/thumbnails.jpg#xywh=9800,0,200,84
+
+00:00:25.000 --> 00:00:25.500
+/static/thumbnails.jpg#xywh=10000,0,200,84
+
+00:00:25.500 --> 00:00:26.000
+/static/thumbnails.jpg#xywh=10200,0,200,84
+
+00:00:26.000 --> 00:00:26.500
+/static/thumbnails.jpg#xywh=10400,0,200,84
+
+00:00:26.500 --> 00:00:27.000
+/static/thumbnails.jpg#xywh=10600,0,200,84
+
+00:00:27.000 --> 00:00:27.500
+/static/thumbnails.jpg#xywh=10800,0,200,84
+
+00:00:27.500 --> 00:00:28.000
+/static/thumbnails.jpg#xywh=11000,0,200,84
+
+00:00:28.000 --> 00:00:28.500
+/static/thumbnails.jpg#xywh=11200,0,200,84
+
+00:00:28.500 --> 00:00:29.000
+/static/thumbnails.jpg#xywh=11400,0,200,84
+
+00:00:29.000 --> 00:00:29.500
+/static/thumbnails.jpg#xywh=11600,0,200,84
+
+00:00:29.500 --> 00:00:30.000
+/static/thumbnails.jpg#xywh=11800,0,200,84
+
+00:00:30.000 --> 00:00:30.500
+/static/thumbnails.jpg#xywh=12000,0,200,84
+
+00:00:30.500 --> 00:00:31.000
+/static/thumbnails.jpg#xywh=12200,0,200,84
+
+00:00:31.000 --> 00:00:31.500
+/static/thumbnails.jpg#xywh=12400,0,200,84
+
+00:00:31.500 --> 00:00:32.000
+/static/thumbnails.jpg#xywh=12600,0,200,84
+
+00:00:32.000 --> 00:00:32.500
+/static/thumbnails.jpg#xywh=12800,0,200,84
+
+00:00:32.500 --> 00:00:33.000
+/static/thumbnails.jpg#xywh=13000,0,200,84
+
+00:00:33.000 --> 00:00:33.500
+/static/thumbnails.jpg#xywh=13200,0,200,84
+
+00:00:33.500 --> 00:00:34.000
+/static/thumbnails.jpg#xywh=13400,0,200,84
+
+00:00:34.000 --> 00:00:34.500
+/static/thumbnails.jpg#xywh=13600,0,200,84
+
+00:00:34.500 --> 00:00:35.000
+/static/thumbnails.jpg#xywh=13800,0,200,84
+
+00:00:35.000 --> 00:00:35.500
+/static/thumbnails.jpg#xywh=14000,0,200,84
+
+00:00:35.500 --> 00:00:36.000
+/static/thumbnails.jpg#xywh=14200,0,200,84
+
+00:00:36.000 --> 00:00:36.500
+/static/thumbnails.jpg#xywh=14400,0,200,84
+
+00:00:36.500 --> 00:00:37.000
+/static/thumbnails.jpg#xywh=14600,0,200,84
+
+00:00:37.000 --> 00:00:37.500
+/static/thumbnails.jpg#xywh=14800,0,200,84
+
+00:00:37.500 --> 00:00:38.000
+/static/thumbnails.jpg#xywh=15000,0,200,84
+
+00:00:38.000 --> 00:00:38.500
+/static/thumbnails.jpg#xywh=15200,0,200,84
+
+00:00:38.500 --> 00:00:39.000
+/static/thumbnails.jpg#xywh=15400,0,200,84
+
+00:00:39.000 --> 00:00:39.500
+/static/thumbnails.jpg#xywh=15600,0,200,84
+
+00:00:39.500 --> 00:00:40.000
+/static/thumbnails.jpg#xywh=15800,0,200,84
+
+00:00:40.000 --> 00:00:40.500
+/static/thumbnails.jpg#xywh=16000,0,200,84
+
+00:00:40.500 --> 00:00:41.000
+/static/thumbnails.jpg#xywh=16200,0,200,84
+
+00:00:41.000 --> 00:00:41.500
+/static/thumbnails.jpg#xywh=16400,0,200,84
+
+00:00:41.500 --> 00:00:42.000
+/static/thumbnails.jpg#xywh=16600,0,200,84
+
+00:00:42.000 --> 00:00:42.500
+/static/thumbnails.jpg#xywh=16800,0,200,84
+
+00:00:42.500 --> 00:00:43.000
+/static/thumbnails.jpg#xywh=17000,0,200,84
+
+00:00:43.000 --> 00:00:43.500
+/static/thumbnails.jpg#xywh=17200,0,200,84
+
+00:00:43.500 --> 00:00:44.000
+/static/thumbnails.jpg#xywh=17400,0,200,84
+
+00:00:44.000 --> 00:00:44.500
+/static/thumbnails.jpg#xywh=17600,0,200,84
+
+00:00:44.500 --> 00:00:45.000
+/static/thumbnails.jpg#xywh=17800,0,200,84
+
+00:00:45.000 --> 00:00:45.500
+/static/thumbnails.jpg#xywh=18000,0,200,84
+
+00:00:45.500 --> 00:00:46.000
+/static/thumbnails.jpg#xywh=18200,0,200,84
+
+00:00:46.000 --> 00:00:46.500
+/static/thumbnails.jpg#xywh=18400,0,200,84
+
+00:00:46.500 --> 00:00:47.000
+/static/thumbnails.jpg#xywh=18600,0,200,84
+
+00:00:47.000 --> 00:00:47.500
+/static/thumbnails.jpg#xywh=18800,0,200,84
+
+00:00:47.500 --> 00:00:48.000
+/static/thumbnails.jpg#xywh=19000,0,200,84
+
+00:00:48.000 --> 00:00:48.500
+/static/thumbnails.jpg#xywh=19200,0,200,84
+
+00:00:48.500 --> 00:00:49.000
+/static/thumbnails.jpg#xywh=19400,0,200,84
+
+00:00:49.000 --> 00:00:49.500
+/static/thumbnails.jpg#xywh=19600,0,200,84
+
+00:00:49.500 --> 00:00:50.000
+/static/thumbnails.jpg#xywh=19800,0,200,84
+
+00:00:50.000 --> 00:00:50.500
+/static/thumbnails.jpg#xywh=20000,0,200,84
+
+00:00:50.500 --> 00:00:51.000
+/static/thumbnails.jpg#xywh=20200,0,200,84
+
+00:00:51.000 --> 00:00:51.500
+/static/thumbnails.jpg#xywh=20400,0,200,84
+
+00:00:51.500 --> 00:00:52.000
+/static/thumbnails.jpg#xywh=20600,0,200,84
+
+00:00:52.000 --> 00:00:52.500
+/static/thumbnails.jpg#xywh=20800,0,200,84
+
+00:00:52.500 --> 00:00:53.000
+/static/thumbnails.jpg#xywh=21000,0,200,84
+
+00:00:53.000 --> 00:00:53.500
+/static/thumbnails.jpg#xywh=21200,0,200,84
+
+00:00:53.500 --> 00:00:54.000
+/static/thumbnails.jpg#xywh=21400,0,200,84
+
+00:00:54.000 --> 00:00:54.500
+/static/thumbnails.jpg#xywh=21600,0,200,84
+
+00:00:54.500 --> 00:00:55.000
+/static/thumbnails.jpg#xywh=21800,0,200,84
+
+00:00:55.000 --> 00:00:55.500
+/static/thumbnails.jpg#xywh=22000,0,200,84
+
+00:00:55.500 --> 00:00:56.000
+/static/thumbnails.jpg#xywh=22200,0,200,84
+
+00:00:56.000 --> 00:00:56.500
+/static/thumbnails.jpg#xywh=22400,0,200,84
+
+00:00:56.500 --> 00:00:57.000
+/static/thumbnails.jpg#xywh=22600,0,200,84
+
+00:00:57.000 --> 00:00:57.500
+/static/thumbnails.jpg#xywh=22800,0,200,84
+
+00:00:57.500 --> 00:00:58.000
+/static/thumbnails.jpg#xywh=23000,0,200,84
+
+00:00:58.000 --> 00:00:58.500
+/static/thumbnails.jpg#xywh=23200,0,200,84
+
+00:00:58.500 --> 00:00:59.000
+/static/thumbnails.jpg#xywh=23400,0,200,84
+
+00:00:59.000 --> 00:00:59.500
+/static/thumbnails.jpg#xywh=23600,0,200,84
+
+00:00:59.500 --> 00:01:00.000
+/static/thumbnails.jpg#xywh=23800,0,200,84
+
+00:01:00.000 --> 00:01:00.500
+/static/thumbnails.jpg#xywh=24000,0,200,84
+
+00:01:00.500 --> 00:01:01.000
+/static/thumbnails.jpg#xywh=24200,0,200,84
+
+00:01:01.000 --> 00:01:01.500
+/static/thumbnails.jpg#xywh=24400,0,200,84
+
+00:01:01.500 --> 00:01:02.000
+/static/thumbnails.jpg#xywh=24600,0,200,84
+
+00:01:02.000 --> 00:01:02.500
+/static/thumbnails.jpg#xywh=24800,0,200,84
+
+00:01:02.500 --> 00:01:03.000
+/static/thumbnails.jpg#xywh=25000,0,200,84
+
+00:01:03.000 --> 00:01:03.500
+/static/thumbnails.jpg#xywh=25200,0,200,84
+
+00:01:03.500 --> 00:01:04.000
+/static/thumbnails.jpg#xywh=25400,0,200,84
+
+00:01:04.000 --> 00:01:04.500
+/static/thumbnails.jpg#xywh=25600,0,200,84
+
+00:01:04.500 --> 00:01:05.000
+/static/thumbnails.jpg#xywh=25800,0,200,84
+
+00:01:05.000 --> 00:01:05.500
+/static/thumbnails.jpg#xywh=26000,0,200,84
+
+00:01:05.500 --> 00:01:06.000
+/static/thumbnails.jpg#xywh=26200,0,200,84
+
+00:01:06.000 --> 00:01:06.500
+/static/thumbnails.jpg#xywh=26400,0,200,84
+
+00:01:06.500 --> 00:01:07.000
+/static/thumbnails.jpg#xywh=26600,0,200,84
+
+00:01:07.000 --> 00:01:07.500
+/static/thumbnails.jpg#xywh=26800,0,200,84
+
+00:01:07.500 --> 00:01:08.000
+/static/thumbnails.jpg#xywh=27000,0,200,84
+
+00:01:08.000 --> 00:01:08.500
+/static/thumbnails.jpg#xywh=27200,0,200,84
+
+00:01:08.500 --> 00:01:09.000
+/static/thumbnails.jpg#xywh=27400,0,200,84
+
+00:01:09.000 --> 00:01:09.500
+/static/thumbnails.jpg#xywh=27600,0,200,84
+
+00:01:09.500 --> 00:01:10.000
+/static/thumbnails.jpg#xywh=27800,0,200,84
+
+00:01:10.000 --> 00:01:10.500
+/static/thumbnails.jpg#xywh=28000,0,200,84
+
+00:01:10.500 --> 00:01:10.000
+/static/thumbnails.jpg#xywh=28200,0,200,84
+
+00:01:11.000 --> 00:01:11.500
+/static/thumbnails.jpg#xywh=28400,0,200,84
+
+00:01:11.500 --> 00:01:12.000
+/static/thumbnails.jpg#xywh=28600,0,200,84
+
+00:01:12.000 --> 00:01:12.500
+/static/thumbnails.jpg#xywh=28800,0,200,84
+
+00:01:12.500 --> 00:01:13.000
+/static/thumbnails.jpg#xywh=29000,0,200,84
+
+00:01:13.000 --> 00:01:13.500
+/static/thumbnails.jpg#xywh=29200,0,200,84
+
+00:01:13.500 --> 00:01:14.000
+/static/thumbnails.jpg#xywh=29400,0,200,84
+
+00:01:14.000 --> 00:01:14.500
+/static/thumbnails.jpg#xywh=29600,0,200,84
+
+00:01:14.500 --> 00:01:15.000
+/static/thumbnails.jpg#xywh=29800,0,200,84
+
+00:01:15.000 --> 00:01:15.500
+/static/thumbnails.jpg#xywh=30000,0,200,84
+
+00:01:15.500 --> 00:01:16.000
+/static/thumbnails.jpg#xywh=30200,0,200,84
+
+00:01:16.000 --> 00:01:16.500
+/static/thumbnails.jpg#xywh=30400,0,200,84
+
+00:01:16.500 --> 00:01:17.000
+/static/thumbnails.jpg#xywh=30600,0,200,84
+
+00:01:17.000 --> 00:01:17.500
+/static/thumbnails.jpg#xywh=30800,0,200,84
+
+00:01:17.500 --> 00:01:18.000
+/static/thumbnails.jpg#xywh=31000,0,200,84
+
+00:01:18.000 --> 00:01:18.500
+/static/thumbnails.jpg#xywh=31200,0,200,84
+
+00:01:18.500 --> 00:01:19.000
+/static/thumbnails.jpg#xywh=31400,0,200,84
+
+00:01:19.000 --> 00:01:19.500
+/static/thumbnails.jpg#xywh=31600,0,200,84
+
+00:01:19.500 --> 00:01:20.000
+/static/thumbnails.jpg#xywh=31800,0,200,84
+
+00:01:20.000 --> 00:01:20.500
+/static/thumbnails.jpg#xywh=32000,0,200,84
+
+00:01:20.500 --> 00:01:21.000
+/static/thumbnails.jpg#xywh=32200,0,200,84
+
+00:01:21.000 --> 00:01:21.500
+/static/thumbnails.jpg#xywh=32400,0,200,84
+
+00:01:21.500 --> 00:01:22.000
+/static/thumbnails.jpg#xywh=32600,0,200,84
+
+00:01:22.000 --> 00:01:22.500
+/static/thumbnails.jpg#xywh=32800,0,200,84
+
+00:01:22.500 --> 00:01:23.000
+/static/thumbnails.jpg#xywh=33000,0,200,84
+
+00:01:23.000 --> 00:01:23.500
+/static/thumbnails.jpg#xywh=33200,0,200,84
+
+00:01:23.500 --> 00:01:24.000
+/static/thumbnails.jpg#xywh=33400,0,200,84
+
+00:01:24.000 --> 00:01:24.500
+/static/thumbnails.jpg#xywh=33600,0,200,84
+
+00:01:24.500 --> 00:01:25.000
+/static/thumbnails.jpg#xywh=33800,0,200,84
+
+00:01:25.000 --> 00:01:25.500
+/static/thumbnails.jpg#xywh=34000,0,200,84
+
+00:01:25.500 --> 00:01:26.000
+/static/thumbnails.jpg#xywh=34200,0,200,84
+
+00:01:26.000 --> 00:01:26.500
+/static/thumbnails.jpg#xywh=34400,0,200,84
+
+00:01:26.500 --> 00:01:27.000
+/static/thumbnails.jpg#xywh=34600,0,200,84
+
+00:01:27.000 --> 00:01:27.500
+/static/thumbnails.jpg#xywh=34800,0,200,84
+
+00:01:27.500 --> 00:01:28.000
+/static/thumbnails.jpg#xywh=35000,0,200,84
+
+00:01:28.000 --> 00:01:28.500
+/static/thumbnails.jpg#xywh=35200,0,200,84
+
+00:01:28.500 --> 00:01:29.000
+/static/thumbnails.jpg#xywh=35400,0,200,84
+
+00:01:29.000 --> 00:01:29.500
+/static/thumbnails.jpg#xywh=35600,0,200,84
+
+00:01:29.500 --> 00:01:30.000
+/static/thumbnails.jpg#xywh=35800,0,200,84
+
+00:01:30.000 --> 00:01:30.500
+/static/thumbnails.jpg#xywh=36000,0,200,84
+
+00:01:30.500 --> 00:01:31.000
+/static/thumbnails.jpg#xywh=36200,0,200,84
+
+00:01:31.000 --> 00:01:31.500
+/static/thumbnails.jpg#xywh=36400,0,200,84
+
+00:01:31.500 --> 00:01:32.000
+/static/thumbnails.jpg#xywh=36600,0,200,84
+
+00:01:32.000 --> 00:01:32.500
+/static/thumbnails.jpg#xywh=36800,0,200,84
+
+00:01:32.500 --> 00:01:33.000
+/static/thumbnails.jpg#xywh=37000,0,200,84
+
+00:01:33.000 --> 00:01:33.500
+/static/thumbnails.jpg#xywh=37200,0,200,84
+
+00:01:33.500 --> 00:01:34.000
+/static/thumbnails.jpg#xywh=37400,0,200,84
+
+00:01:34.000 --> 00:01:34.500
+/static/thumbnails.jpg#xywh=37600,0,200,84
+
+00:01:34.500 --> 00:01:35.000
+/static/thumbnails.jpg#xywh=37800,0,200,84
+
+00:01:35.000 --> 00:01:35.500
+/static/thumbnails.jpg#xywh=38000,0,200,84
+
+00:01:35.500 --> 00:01:36.000
+/static/thumbnails.jpg#xywh=38200,0,200,84
+
+00:01:36.000 --> 00:01:36.500
+/static/thumbnails.jpg#xywh=38400,0,200,84
+
+00:01:36.500 --> 00:01:37.000
+/static/thumbnails.jpg#xywh=38600,0,200,84
+
+00:01:37.000 --> 00:01:37.500
+/static/thumbnails.jpg#xywh=38800,0,200,84
+
+00:01:37.500 --> 00:01:38.000
+/static/thumbnails.jpg#xywh=39000,0,200,84
+
+00:01:38.000 --> 00:01:38.500
+/static/thumbnails.jpg#xywh=39200,0,200,84
+
+00:01:38.500 --> 00:01:39.000
+/static/thumbnails.jpg#xywh=39400,0,200,84
+
+00:01:39.000 --> 00:01:39.500
+/static/thumbnails.jpg#xywh=39600,0,200,84
+
+00:01:39.500 --> 00:01:40.000
+/static/thumbnails.jpg#xywh=39800,0,200,84
+
+00:01:40.000 --> 00:01:40.500
+/static/thumbnails.jpg#xywh=40000,0,200,84
+
+00:01:40.500 --> 00:01:41.000
+/static/thumbnails.jpg#xywh=40200,0,200,84
diff --git a/client/fluid-player/test/static/vast4.xsd b/client/fluid-player/test/static/vast4.xsd
new file mode 100644
index 0000000..64203c7
--- /dev/null
+++ b/client/fluid-player/test/static/vast4.xsd
@@ -0,0 +1,1284 @@
+
+
+
+
+
+ IAB VAST (Video Ad Serving Template), Version 4.2
+
+
+
+
+
+ Top-level element, wraps each ad in the response or ad unit in an ad pod. This MUST be present unless an Error element is present.
+
+
+
+
+
+ Second-level element surrounding complete ad data for a single ad
+
+
+
+
+ Second-level element surrounding wrapper ad pointing to Secondary ad server.
+
+
+
+
+
+
+ Identifies the sequence of multiple Ads that are part of an Ad Pod.
+
+
+
+
+ [@Deprecated in VAST 4.1 with apiFramework] A Boolean value that identifies a conditional ad.
+
+
+
+
+ An optional string that identifies the type of ad. This allows VAST to support audio ad scenarios. The default value is video.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Used when there is no ad response. When the ad server does not or cannot return an Ad. If included the video player must send a request to the URI provided (Sec 3.2.1).
+
+
+
+
+
+ Current version is 4.1
+
+
+
+
+
+
+
+
+ URLs to ping when icon action occurs.
+
+
+
+
+
+
+
+
+
+
+
+ Each <Tracking> element is used to define a single event to be tracked by the verification vendor. Multiple tracking elements may be used to define multiple events to be tracked, but may also be used to track events of the same type for multiple parties.
+
+
+
+
+
+
+ A string that defines the event being tracked. One event type is currently supported: verificationNotExecuted: the player did not or was not able to execute the provided verification code
+
+
+
+
+
+
+
+
+
+
+
+
+ The name of the event to track for the element. The creativeView should always be requested when present.
+
+
+
+
+
+
+ The name of the event to track. For nonlinear ads these events should be recorded on the video within the ad.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The time during the video at which this url should be pinged. Must be present for progress event.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ URL to request for tracking purposes when user clicks on the video.
+
+
+
+
+
+
+
+
+
+
+
+ URL to open as destination page when user clicks on the video. This can occur zero to many times. The XSD syntax can't represent that.
+
+
+
+
+
+
+
+
+
+
+
+ URLs to request on custom events such as hotspotted video.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ad server ID for the impression
+
+
+
+
+
+
+
+ A base creative resource type (sec 3.13) for non-video creative content. This specifies static, IFrame, or HTML content, or a combination thereof
+
+
+
+
+ HTML to display the companion element. This can occur zero to many times, but order should not be important.
+
+
+
+
+ URI source for an IFrame to display the companion element. This can occur zero to many times, but order should not be important.
+
+
+
+
+ URI to a static file, such as an image. This can occur zero to many times, but order should not be important.
+
+
+
+
+
+
+ MIME type of static resource
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Element used to display information when an icon click occurs.
+
+
+
+
+
+
+
+ URI to a static file, such as an image.
+
+
+
+
+
+ Pixel height of the image asset
+
+
+
+
+ Pixel width of the image asset
+
+
+
+
+
+
+
+
+
+ URL to open as destination page when user clicks on the icon.
+
+
+
+
+ URLs to ping when user clicks on the the icon.
+
+
+
+
+
+
+
+ A URI for the tracking resource file to be called when the icon creative is displayed.
+
+
+
+
+
+ Program represented in the Icon.
+
+
+
+
+ Pixel dimensions of icon.
+
+
+
+
+ Pixel dimensions of icon.
+
+
+
+
+ The x-cooridinate of the top, left corner of the icon asset relative to the ad display area
+
+
+
+
+
+
+
+
+
+ The y-cooridinate of the top left corner of the icon asset relative to the ad display area.
+
+
+
+
+
+
+
+
+
+ The duration for which the player must display the icon. Expressed in standard time format hh:mm:ss.
+
+
+
+
+ Start time at which the player should display the icon. Expressed in standard time format hh:mm:ss.
+
+
+
+
+ The apiFramework defines the method to use for communication with the icon element
+
+
+
+
+ The pixel ratio for which the icon creative is intended. The pixel ratio is the ratio of physical pixels on the device to the device-independent pixels. An ad intended for display on a device with a pixel ratio that is twice that of a standard 1:1 pixel ratio would use the value "2" Default value is "1"
+
+
+
+
+
+
+
+
+
+ Any valid XML may be included in the Extensions node. This can occur zero to many times.
+
+
+
+
+
+
+
+ The MIME type of any code that might be included in the extension.
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies whether the parameters are XML-encoded
+
+
+
+
+
+
+
+ The URI to a static creative file to be used for the ad component identified in the parent element, which is either: <NonLinear>, <Companion>, or <Icon>.
+
+
+
+
+
+
+
+
+ Video formatted ad that plays linearly
+
+
+
+
+
+
+
+ Any number of icons representing advertising industry initiatives.
+
+
+
+
+
+
+
+
+
+ The time at which the ad becomes skippable, if absent, the ad is not skippable.
+
+
+
+
+
+
+
+
+
+
+ Video formatted ad that plays linearly
+
+
+
+
+
+
+
+
+
+
+
+ Video formatted ad that plays linearly
+
+
+
+
+
+
+ [Note: SIMID is set to replace VPAID] [Note: VPAID has been deprecated in VAST 4.1 ] Data to be passed into the video ad. Used to pass VAST info to VPAID object. When a VAST response is used to serve a VPAID ad unit, the <AdParameters> element is currently the only way to pass information from the VAST response into the VPAID object; no other mechanism is provided.
+
+
+
+
+ Duration in standard time format, hh:mm:ss
+
+
+
+
+
+
+
+
+
+
+ A CDATA-wrapped URI to a file providing Closed Caption info for the media file.
+
+
+
+
+
+
+ Identifies the MIME type of the file provided.
+
+
+
+
+ Language of the Closed Caption File using ISO 631-1 codes. An optional locale suffix can also be provided.
+
+
+
+
+
+
+
+
+
+
+
+ URI location of linear file. Content must be wrapped in CDATA tag.
+
+
+
+
+
+
+ Optional identifier
+
+
+
+
+ Either "progressive" for progressive download protocols (such as HTTP) or "streaming" for streaming protocols.
+
+
+
+
+
+
+
+
+
+
+ MIME type. Popular MIME types include, but are not limited to "video/x-ms-wmv" for Windows Media, and "video/x-flv" for Flash Video. Image ads or interactive ads can be included in the MediaFiles section with appropriate Mime types. Flash support was deprecated in January 2017 and is now being removed.
+
+
+
+
+ Pixel dimensions of video, or 0 for audio ads
+
+
+
+
+ Pixel dimensions of video, or 0 for audio ads
+
+
+
+
+ The codec used to produce the media file as specified in RFC 4281.
+
+
+
+
+ Bitrate of encoded video in Kbps. If bitrate is supplied, minBitrate and maxBitrate should not be supplied.
+
+
+
+
+ Minimum bitrate of an adaptive stream in Kbps. If minBitrate is supplied, maxBitrate must be supplied and bitrate should not be supplied.
+
+
+
+
+ Maximum bitrate of an adaptive stream in Kbps. If maxBitrate is supplied, minBitrate must be supplied and bitrate should not be supplied.
+
+
+
+
+ Whether it is acceptable to scale the image.
+
+
+
+
+ Whether the ad must have its aspect ratio maintained when scales
+
+
+
+
+ Optional field that helps eliminate the need to calculate the size based on bitrate and duration. Units - Bytes
+
+
+
+
+ Type of media file (2D / 3D / 360 / etc). Default value = 2D
+
+
+
+
+ [@Deprecated in 4.1 in preparation for VPAID being phased out]. identifies the API needed to execute an interactive media file, but current support is for backward compatibility. Please use the <InteractiveCreativeFile> element to include files that require an API for execution.
+
+
+
+
+
+
+
+
+ URI location to raw, high-quality media file for high-resolution environments or to transcode video or audio files at quality levels specific to the needs of certain environments. Content must be wrapped in CDATA tag.
+
+
+
+
+
+
+ Optional identifier
+
+
+
+
+ Either "progressive" for progressive download protocols (such as HTTP) or "streaming" for streaming protocols.
+
+
+
+
+
+
+
+
+
+
+ MIME type. Popular MIME types include, but are not limited to "video/x-ms-wmv" for Windows Media, and "video/x-flv" for Flash Video. Image ads or interactive ads can be included in the MediaFiles section with appropriate Mime types. Flash support was deprecated in January 2017 and is now being removed.
+
+
+
+
+ Pixel dimensions of video, or 0 for audio ads
+
+
+
+
+ Pixel dimensions of video, or 0 for audio ads
+
+
+
+
+ The codec used to produce the media file as specified in RFC 4281.
+
+
+
+
+ Optional field that helps eliminate the need to calculate the size based on bitrate and duration. Units - Bytes
+
+
+
+
+ Type of media file (2D / 3D / 360 / etc). Default value = 2D
+
+
+
+
+
+
+
+
+ For any media file that uses APIs for advanced creative functionality, the InteractivityCreativeFile element is used to identify the file and framework needed to execute advanced functions for the ad.
+
+
+
+
+
+
+ Identifies the MIME type of the file provided.
+
+
+
+
+ identifies the API needed to execute the Creative file if applicable
+
+
+
+
+ Useful for interactive use cases. Identifies whether the ad always drops when the duration is reached, or if it can potentially extend the duration by pausing the underlying video or delaying the adStopped call after adVideoComplete. If it set to true the extension of the duration should be user-initiated (typically by engaging with an interactive element to view additional content).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An ad that is overlain on top of video content during playback
+
+
+
+
+ URLs to ping when user clicks on the the non-linear ad unit. This can occur zero to many times (unbounded). The XSD syntax can't represent that.
+
+
+
+
+
+
+ Identifier provided to ad server for click reports
+
+
+
+
+
+
+
+
+
+
+ An ad that is overlain on top of video content during playback
+
+
+
+
+
+
+ Custom content used to pass information to ad unit
+
+
+
+
+ URI to advertiser page opened on viewer clicks through.
+
+
+
+
+ URLs to ping when user clicks on the the non-linear ad unit.
+
+
+
+
+
+
+ Identifier provided to ad server for click reports
+
+
+
+
+
+
+
+
+
+ Optional identifier
+
+
+
+
+ Pixel dimensions of companion
+
+
+
+
+ Pixel dimensions of companion
+
+
+
+
+ Pixel dimensions of expanding nonlinear ad when in expanded state
+
+
+
+
+ Pixel dimensions of expanding nonlinear ad when in expanded state
+
+
+
+
+ Whether it is acceptable to scale the image.
+
+
+
+
+ Whether the ad must have its aspect ratio maintained when scales
+
+
+
+
+ Suggested duration to display non-linear ad, typically for animation to complete. Expressed in standard time format hh:mm:ss
+
+
+
+
+ The apiFramework defines the method to use for communication with the nonlinear element
+
+
+
+
+
+
+
+
+
+
+
+ Data to be passed into the companion ads. The apiFramework defines the method to use for communication.
+
+
+
+
+ Alt text to be displayed when companion is rendered in HTML environment.
+
+
+
+
+ URL to open as destination page when user clicks on the the companion banner ad.
+
+
+
+
+ A URI to a tracking resource file used to track a companion clickthrough.
+
+
+
+
+
+
+ An id provided by the ad server to track the click in reports.
+
+
+
+
+
+
+
+
+
+ The creativeView should always be requested when present. For Companions creativeView is the only supported event.
+
+
+
+
+
+ Optional identifier
+
+
+
+
+ Pixel dimensions of companion slot
+
+
+
+
+ Pixel dimensions of companion slot
+
+
+
+
+ Pixel dimensions of the companion asset
+
+
+
+
+ Pixel dimensions of the companion asset
+
+
+
+
+ Pixel dimensions of expanding companion ad when in expanded state
+
+
+
+
+ Pixel dimensions of expanding companion ad when in expanded state
+
+
+
+
+ The apiFramework defines the method to use for communication with the companion
+
+
+
+
+ Used to match companion creative to publisher placement areas on the page.
+
+
+
+
+ The pixel ratio for which the icon creative is intended. The pixel ratio is the ratio of physical pixels on the device to the device-independent pixels. An ad intended for display on a device with a pixel ratio that is twice that of a standard 1:1 pixel ratio would use the value "2" Default value is "1"
+
+
+
+
+ Used to indicate when and where to use this companion ad. If this field is empty or not given, default will be used.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ General subclass type for Companion Ad elements. This can occur zero to many times.
+
+
+
+
+
+ How the player should treat a companion ad when multiple are supplied
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The preferred order in which multiple Creatives should be displayed
+
+
+
+
+ Identifies an API needed to execute the creative
+
+
+
+
+ A string used to identify the ad server that provides the creative.
+
+
+
+
+ To be deprecated in future version of VAST. Ad-ID for the creative (formerly ISCI)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Any number of companions in any desired pixel dimensions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Any number of companions in any desired pixel dimensions.
+
+
+
+
+
+
+
+ The UniversalAdId is used to provide a unique creative identifier for the purposes of tracking ad creative. This is used for AD-ID(r) for ads served in the United States. Default value is "unknown"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base type structure used by Inline or Wrapper ad content element types
+
+
+
+
+ Indicates source ad server
+
+
+
+
+
+
+ Internal version used by ad system
+
+
+
+
+
+
+
+
+ URL to request if ad does not play due to error
+
+
+
+
+ XML node for custom extensions, as defined by the ad server. When used, a custom element should be nested under <Extensions> to help separa
+ te custom XML elements from VAST elements.
+
+
+
+
+
+ One instance of <Extension> should be used for each custom extension. The type attribute identifies the MIME type of any code provided in the extension.
+
+
+
+
+
+
+
+ The MIME type of any code that might be included in the extension.
+
+
+
+
+
+
+
+
+
+ A URI that directs the media player to a tracking resource file that the media player must
+ use to notify the ad server when the impression occurs. If there is no reason to include
+ an Impression element, the placeholder "about:blank" should be used instead of a
+ tracking URL
+
+
+
+
+ The price of the ad that can be used in real time bidding systems.
+
+
+
+
+
+
+ The pricing model used.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Three letter ISO-4217 currency symbol that identifies the currency of the value provied. Ex: USD, GBP, etc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The ViewableImpression element allows for tracking URIs to report viewability
+
+
+
+
+ A URI that directs the video player to a tracking resource file that the video player should request at the time that criteria is met for a viewable impression. This can occur zero to many times.
+
+
+
+
+ A URI that directs the video player to a tracking resource file that the video player should request if the ad is executed but never meets criteria for a viewable impression.
+
+
+
+
+ A URI that directs the video player to a tracking resource file that the video player should request if the player cannot determine whether criteria is met for a viewable impression. This can occur zero to many times.
+
+
+
+
+
+ An ad server id for the impression. Impression resources of the same id should be requested at the same time or as close in time as possible to help prevent discrepancies.
+
+
+
+
+
+
+ Verification elements are nested under AdVerifications. The Verification element is used to contain the executable and bootstrapping required to run the measurement code for a single verification vendor. Multiple Verification elements may be used in cases where more than one verification vendor needs to collect data or when different API frameworks are used. At lease one JavaScriptResource or ExecutableResource should be provided. At most one of these resources should selected for execution, as best matches the technology available in the current environment. If the player is willing and able to run one of these resources, it should execute them BEFORE creative playback begins. Otherwise, if no resource can be executed, any appropriate tracking events listed under the <Verification> element must be fired.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CDATA-wrapped metadata string for the verification executable.
+
+
+
+
+
+ An identifier for the verification vendor. The recommended format is [domain]-[useCase], to avoid name collisions. For example, "company.com-omid".
+
+
+
+
+
+
+ The AdVerification element is used to initiate a controlled container where code can be executed for collecting data to verify ad playback details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A string that provides a category code or label that identifies the ad content.
+
+
+
+
+
+
+ A URL for the organizational authority that produced the list being used to identify ad content. Optional unless the publisher requires ad categories. The authority attribute is required if categories are provided.
+
+
+
+
+
+
+
+
+ A container for one or more Creative elements used to provide creative files for ad.
+
+
+
+
+
+
+
+
+
+ A URI to another VAST response that may be another VAST Wrapper or a VAST InLine ad.
+
+
+
+
+
+ a Boolean value that identifies whether subsequent wrappers after a requested VAST response is allowed.
+
+
+
+
+ a Boolean value that identifies whether multiple ads are allowed in the requested VAST response.
+
+
+
+
+ a Boolean value that provides instruction for using an available Ad when the requested VAST response returns no ads.
+
+
+
+
+
+
+
+
+
+
+
+
+ Any ad server that returns a VAST containing an <InLine> ad must generate a pseudo-unique identifier that is appropriate for all involved parties to track the lifecycle of that ad. This should be inserted into the <AdServingId> element, and also be included on all outgoing tracking pixels. The value should be different for each Inline in a VAST. Usage of a GUID is recommended.
+
+
+
+
+ Common name of ad
+
+
+
+
+
+ Name of advertiser as defined by the ad serving party
+
+
+
+
+ A string that provides a category code or label that identifies the ad content.
+
+
+
+
+
+
+ A URI for the organizational authority that produced the list being used to identify ad content.
+
+
+
+
+
+
+
+
+ A container for one or more Creative elements used to provide creative files for ad.
+
+
+
+
+
+
+
+
+
+ Longer description of ad
+
+
+
+
+ An integer value that defines the expiry period (in seconds).
+
+
+
+
+ URL of request to survey vendor
+
+
+
+
+
+
+ MIME type of the resource being served
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_ad_buffet.xml b/client/fluid-player/test/static/vast_ad_buffet.xml
new file mode 100644
index 0000000..b0f60b2
--- /dev/null
+++ b/client/fluid-player/test/static/vast_ad_buffet.xml
@@ -0,0 +1,126 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #1
+ Ad Buffet Ad #1
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #2
+ Ad Buffet Ad #2
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #3
+ Ad Buffet Ad #3
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_ad_buffet_with_error.xml b/client/fluid-player/test/static/vast_ad_buffet_with_error.xml
new file mode 100644
index 0000000..f74cb96
--- /dev/null
+++ b/client/fluid-player/test/static/vast_ad_buffet_with_error.xml
@@ -0,0 +1,105 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #1
+ Ad Buffet Ad #1
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #2
+ Ad Buffet Ad #2
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Ad Buffet Ad #3
+ Ad Buffet Ad #3
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_ad_pod.xml b/client/fluid-player/test/static/vast_ad_pod.xml
new file mode 100644
index 0000000..9523db6
--- /dev/null
+++ b/client/fluid-player/test/static/vast_ad_pod.xml
@@ -0,0 +1,170 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ AD #2 in an Ad Pod
+ AD #2 in an Ad Pod
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ AD #1 in an Ad Pod
+ AD #1 in an Ad Pod
+
+
+
+
+
+
+
+
+
+ iabtechlab
+
+ NonLinear Image
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Stand Alone Ad - Should Not be Played (BUG!)
+ Stand Alone Ad - Should Not be Played (BUG!)
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_cta.xml b/client/fluid-player/test/static/vast_cta.xml
new file mode 100644
index 0000000..d7283fb
--- /dev/null
+++ b/client/fluid-player/test/static/vast_cta.xml
@@ -0,0 +1,76 @@
+
+
+
+ Test
+ Vast CTA test
+
+
+
+ 00:00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+ http://www.example.com/skip
+ http://www.example.com/progress5
+ http://www.example.com/progress10
+ http://www.example.com/progress15
+ http://www.example.com/progress20
+ http://www.example.com/progress25
+
+
+
+
+ https://www.example.com/IconClickThrough
+
+
+
+
+ unknown
+
+
+
+
+
+
+ CTA Text Mobile
+
+
+ CTA Text Desktop
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_cta_no_friendly_url.xml b/client/fluid-player/test/static/vast_cta_no_friendly_url.xml
new file mode 100644
index 0000000..0157b02
--- /dev/null
+++ b/client/fluid-player/test/static/vast_cta_no_friendly_url.xml
@@ -0,0 +1,73 @@
+
+
+
+ Test
+ Vast CTA test
+
+
+
+ 00:00:00
+
+
+
+
+
+
+
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+ http://www.example.com/skip
+ http://www.example.com/progress5
+ http://www.example.com/progress10
+ http://www.example.com/progress15
+ http://www.example.com/progress20
+ http://www.example.com/progress25
+
+
+
+
+ https://www.example.com/IconClickThrough
+
+
+
+
+ unknown
+
+
+
+
+
+
+ CTA Text Mobile
+
+
+ CTA Text Desktop
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_hls.xml b/client/fluid-player/test/static/vast_hls.xml
new file mode 100644
index 0000000..5f716c3
--- /dev/null
+++ b/client/fluid-player/test/static/vast_hls.xml
@@ -0,0 +1,52 @@
+
+
+
+ stripcash.com
+ HLS test
+
+
+
+ 00:00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+ http://www.example.com/skip
+ http://www.example.com/progress5
+ http://www.example.com/progress10
+ http://www.example.com/progress15
+ http://www.example.com/progress20
+ http://www.example.com/progress25
+
+
+ unknown
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_linear.xml b/client/fluid-player/test/static/vast_linear.xml
new file mode 100644
index 0000000..ded0132
--- /dev/null
+++ b/client/fluid-player/test/static/vast_linear.xml
@@ -0,0 +1,72 @@
+
+
+
+ Test
+ Vast Linear
+
+
+
+ 00:00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+ http://www.example.com/skip
+ http://www.example.com/progress5
+ http://www.example.com/progress10
+ http://www.example.com/progress15
+ http://www.example.com/progress20
+ http://www.example.com/progress25
+
+
+
+
+ https://www.example.com/IconClickThrough
+
+
+
+
+ unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_linear_e2e.xml b/client/fluid-player/test/static/vast_linear_e2e.xml
new file mode 100644
index 0000000..38717c1
--- /dev/null
+++ b/client/fluid-player/test/static/vast_linear_e2e.xml
@@ -0,0 +1,72 @@
+
+
+
+ Test
+ Vast Linear
+
+
+
+ 00:00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+ http://www.example.com/skip
+ http://www.example.com/progress5
+ http://www.example.com/progress10
+ http://www.example.com/progress15
+ http://www.example.com/progress20
+ http://www.example.com/progress25
+
+
+
+
+ https://www.example.com/IconClickThrough
+
+
+
+
+ unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_no_ad.xml b/client/fluid-player/test/static/vast_no_ad.xml
new file mode 100644
index 0000000..5c08e88
--- /dev/null
+++ b/client/fluid-player/test/static/vast_no_ad.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/client/fluid-player/test/static/vast_nonlinear.xml b/client/fluid-player/test/static/vast_nonlinear.xml
new file mode 100644
index 0000000..a8a74c6
--- /dev/null
+++ b/client/fluid-player/test/static/vast_nonlinear.xml
@@ -0,0 +1,46 @@
+
+
+
+ iabtechlab
+
+ NonLinear Image
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper.xml b/client/fluid-player/test/static/vast_wrapper.xml
new file mode 100644
index 0000000..33163ce
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_cyclical.xml b/client/fluid-player/test/static/vast_wrapper_cyclical.xml
new file mode 100644
index 0000000..802e0dd
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_cyclical.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false.xml b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false.xml
new file mode 100644
index 0000000..b38b891
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ This is ad #2 in an Ad Pod
+ This is ad #2 in an Ad Pod
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ Play Game Now
+ Play Game Now
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Try for Free
+ Try for Free
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false_http_error.xml b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false_http_error.xml
new file mode 100644
index 0000000..9fc1dc2
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_false_http_error.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ This is a stand alone Ad, from the Ad Buffet
+ This is a stand alone Ad, from the Ad Buffet
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ This is the second ad in a pod
+ This is the second ad in a pod
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Try for Free
+ Try for Free
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true.xml b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true.xml
new file mode 100644
index 0000000..207f39e
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ This is a stand alone Ad, from the Ad Buffet
+ This is a stand alone Ad, from the Ad Buffet
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ Play Game Now
+ Play Game Now
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Try for Free
+ Try for Free
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true_http_error.xml b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true_http_error.xml
new file mode 100644
index 0000000..0425518
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_fallbackOnNoAd_true_http_error.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:22.342
+
+
+
+
+
+
+
+
+
+
+
+
+ samplesite.com
+
+
+
+
+
+
+
+
+
+ This is a stand alone Ad, from the Ad Buffet
+ This is a stand alone Ad, from the Ad Buffet
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:30.0
+
+
+
+
+
+
+
+
+
+
+
+
+ hczog.com
+
+
+
+
+
+
+
+
+
+ Play Game Now
+ Play Game Now
+
+
+
+
+
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+ 00:00:24.799
+
+
+
+
+
+
+
+
+
+
+
+
+ www.zodertracker.com
+
+
+
+
+
+
+
+
+
+ Try for Free
+ Try for Free
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_false.xml b/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_false.xml
new file mode 100644
index 0000000..c18dfa7
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_false.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_true.xml b/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_true.xml
new file mode 100644
index 0000000..8a35b19
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_followAdditionalWrappers_true.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vast_wrapper_to_ad_pod.xml b/client/fluid-player/test/static/vast_wrapper_to_ad_pod.xml
new file mode 100644
index 0000000..aaf8906
--- /dev/null
+++ b/client/fluid-player/test/static/vast_wrapper_to_ad_pod.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ExoClick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/video-thumbnail.jpg b/client/fluid-player/test/static/video-thumbnail.jpg
new file mode 100644
index 0000000..31532c3
Binary files /dev/null and b/client/fluid-player/test/static/video-thumbnail.jpg differ
diff --git a/client/fluid-player/test/static/vpaid_linear.xml b/client/fluid-player/test/static/vpaid_linear.xml
new file mode 100644
index 0000000..fadf221
--- /dev/null
+++ b/client/fluid-player/test/static/vpaid_linear.xml
@@ -0,0 +1,67 @@
+
+
+
+ GDFP
+ Linear VPAID Example
+ Vpaid Linear Video Ad
+ http://www.example.com/error
+ http://www.example.com/impression
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 00:00:10
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/unmute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+
+
+
+
+
+ http://google.com
+ http://www.example.com/click
+
+
+
+
+
+
+ https://googleads.github.io/googleads-ima-html5/vpaid/linear/VpaidVideoAd.js
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/test/static/vpaid_nonlinear.xml b/client/fluid-player/test/static/vpaid_nonlinear.xml
new file mode 100644
index 0000000..dce1811
--- /dev/null
+++ b/client/fluid-player/test/static/vpaid_nonlinear.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ NonLinear VPAID JS
+ Vpaid NonLinear Ad
+ http://www.example.com/error
+ http://www.example.com/impression
+
+
+
+
+ http://www.example.com/start
+ http://www.example.com/firstQuartile
+ http://www.example.com/midpoint
+ http://www.example.com/thirdQuartile
+ http://www.example.com/complete
+ http://www.example.com/mute
+ http://www.example.com/rewind
+ http://www.example.com/pause
+ http://www.example.com/resume
+ http://www.example.com/fullscreen
+ http://www.example.com/creativeView
+ http://www.example.com/acceptInvitation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/fluid-player/vendor/webvtt.js b/client/fluid-player/vendor/webvtt.js
new file mode 100644
index 0000000..26160ac
--- /dev/null
+++ b/client/fluid-player/vendor/webvtt.js
@@ -0,0 +1,702 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+// Not intended to be fast, but if you can make it faster, please help out!
+
+var WebVTTParser = function() {
+ this.parse = function(input, mode) {
+ //XXX need global search and replace for \0
+ var NEWLINE = /\r\n|\r|\n/,
+ startTime = Date.now(),
+ linePos = 0,
+ lines = input.split(NEWLINE),
+ alreadyCollected = false,
+ cues = [],
+ errors = []
+ function err(message, col) {
+ errors.push({message:message, line:linePos+1, col:col})
+ }
+
+ var line = lines[linePos],
+ lineLength = line.length,
+ signature = "WEBVTT",
+ bom = 0,
+ signature_length = signature.length
+
+ /* Byte order mark */
+ if (line[0] === "\ufeff") {
+ bom = 1
+ signature_length += 1
+ }
+ /* SIGNATURE */
+ if (
+ lineLength < signature_length ||
+ line.indexOf(signature) !== 0+bom ||
+ lineLength > signature_length &&
+ line[signature_length] !== " " &&
+ line[signature_length] !== "\t"
+ ) {
+ err("No valid signature. (File needs to start with \"WEBVTT\".)")
+ }
+
+ linePos++
+
+ /* HEADER */
+ while(lines[linePos] != "" && lines[linePos] != undefined) {
+ err("No blank line after the signature.")
+ if(lines[linePos].indexOf("-->") != -1) {
+ alreadyCollected = true
+ break
+ }
+ linePos++
+ }
+
+ /* CUE LOOP */
+ while(lines[linePos] != undefined) {
+ var cue
+ while(!alreadyCollected && lines[linePos] == "") {
+ linePos++
+ }
+ if(!alreadyCollected && lines[linePos] == undefined)
+ break
+
+ /* CUE CREATION */
+ cue = {
+ id:"",
+ startTime:0,
+ endTime:0,
+ pauseOnExit:false,
+ direction:"horizontal",
+ snapToLines:true,
+ linePosition:"auto",
+ textPosition:50,
+ size:100,
+ alignment:"middle",
+ text:"",
+ tree:null
+ }
+
+ var parseTimings = true
+
+ if(lines[linePos].indexOf("-->") == -1) {
+ cue.id = lines[linePos]
+
+ /* COMMENTS
+ Not part of the specification's parser as these would just be ignored. However,
+ we want them to be conforming and not get "Cue identifier cannot be standalone".
+ */
+ if(/^NOTE($|[ \t])/.test(cue.id)) { // .startsWith fails in Chrome
+ linePos++
+ while(lines[linePos] != "" && lines[linePos] != undefined) {
+ if(lines[linePos].indexOf("-->") != -1)
+ err("Cannot have timestamp in a comment.")
+ linePos++
+ }
+ continue
+ }
+
+ linePos++
+
+ if(lines[linePos] == "" || lines[linePos] == undefined) {
+ err("Cue identifier cannot be standalone.")
+ continue
+ }
+
+ if(lines[linePos].indexOf("-->") == -1) {
+ parseTimings = false
+ err("Cue identifier needs to be followed by timestamp.")
+ }
+ }
+
+ /* TIMINGS */
+ alreadyCollected = false
+ var timings = new WebVTTCueTimingsAndSettingsParser(lines[linePos], err)
+ var previousCueStart = 0
+ if(cues.length > 0) {
+ previousCueStart = cues[cues.length-1].startTime
+ }
+ if(parseTimings && !timings.parse(cue, previousCueStart)) {
+ /* BAD CUE */
+
+ cue = null
+ linePos++
+
+ /* BAD CUE LOOP */
+ while(lines[linePos] != "" && lines[linePos] != undefined) {
+ if(lines[linePos].indexOf("-->") != -1) {
+ alreadyCollected = true
+ break
+ }
+ linePos++
+ }
+ continue
+ }
+ linePos++
+
+ /* CUE TEXT LOOP */
+ while(lines[linePos] != "" && lines[linePos] != undefined) {
+ if(lines[linePos].indexOf("-->") != -1) {
+ err("Blank line missing before cue.")
+ alreadyCollected = true
+ break
+ }
+ if(cue.text != "")
+ cue.text += "\n"
+ cue.text += lines[linePos]
+ linePos++
+ }
+
+ /* CUE TEXT PROCESSING */
+ var cuetextparser = new WebVTTCueTextParser(cue.text, err, mode)
+ cue.tree = cuetextparser.parse(cue.startTime, cue.endTime)
+ cues.push(cue)
+ }
+ cues.sort(function(a, b) {
+ if (a.startTime < b.startTime)
+ return -1
+ if (a.startTime > b.startTime)
+ return 1
+ if (a.endTime > b.endTime)
+ return -1
+ if (a.endTime < b.endTime)
+ return 1
+ return 0
+ })
+ /* END */
+ return {cues:cues, errors:errors, time:Date.now()-startTime}
+ }
+}
+
+var WebVTTCueTimingsAndSettingsParser = function(line, errorHandler) {
+ var SPACE = /[\u0020\t\f]/,
+ NOSPACE = /[^\u0020\t\f]/,
+ line = line,
+ pos = 0,
+ err = function(message) {
+ errorHandler(message, pos+1)
+ },
+ spaceBeforeSetting = true
+ function skip(pattern) {
+ while(
+ line[pos] != undefined &&
+ pattern.test(line[pos])
+ ) {
+ pos++
+ }
+ }
+ function collect(pattern) {
+ var str = ""
+ while(
+ line[pos] != undefined &&
+ pattern.test(line[pos])
+ ) {
+ str += line[pos]
+ pos++
+ }
+ return str
+ }
+ /* http://dev.w3.org/html5/webvtt/#collect-a-webvtt-timestamp */
+ function timestamp() {
+ var units = "minutes",
+ val1,
+ val2,
+ val3,
+ val4
+ // 3
+ if(line[pos] == undefined) {
+ err("No timestamp found.")
+ return
+ }
+ // 4
+ if(!/\d/.test(line[pos])) {
+ err("Timestamp must start with a character in the range 0-9.")
+ return
+ }
+ // 5-7
+ val1 = collect(/\d/)
+ if(val1.length > 2 || parseInt(val1, 10) > 59) {
+ units = "hours"
+ }
+ // 8
+ if(line[pos] != ":") {
+ err("No time unit separator found.")
+ return
+ }
+ pos++
+ // 9-11
+ val2 = collect(/\d/)
+ if(val2.length != 2) {
+ err("Must be exactly two digits.")
+ return
+ }
+ // 12
+ if(units == "hours" || line[pos] == ":") {
+ if(line[pos] != ":") {
+ err("No seconds found or minutes is greater than 59.")
+ return
+ }
+ pos++
+ val3 = collect(/\d/)
+ if(val3.length != 2) {
+ err("Must be exactly two digits.")
+ return
+ }
+ } else {
+ val3 = val2
+ val2 = val1
+ val1 = "0"
+ }
+ // 13
+ if(line[pos] != ".") {
+ err("No decimal separator (\".\") found.")
+ return
+ }
+ pos++
+ // 14-16
+ val4 = collect(/\d/)
+ if(val4.length != 3) {
+ err("Milliseconds must be given in three digits.")
+ return
+ }
+ // 17
+ if(parseInt(val2, 10) > 59) {
+ err("You cannot have more than 59 minutes.")
+ return
+ }
+ if(parseInt(val3, 10) > 59) {
+ err("You cannot have more than 59 seconds.")
+ return
+ }
+ return parseInt(val1, 10) * 60 * 60 + parseInt(val2, 10) * 60 + parseInt(val3, 10) + parseInt(val4, 10) / 1000
+ }
+
+ /* http://dev.w3.org/html5/webvtt/#parse-the-webvtt-settings */
+ function parseSettings(input, cue) {
+ var settings = input.split(SPACE),
+ seen = []
+ for(var i=0; i < settings.length; i++) {
+ if(settings[i] == "")
+ continue
+
+ var index = settings[i].indexOf(':'),
+ setting = settings[i].slice(0, index)
+ value = settings[i].slice(index + 1)
+
+ if(seen.indexOf(setting) != -1) {
+ err("Duplicate setting.")
+ }
+ seen.push(setting)
+
+ if(value == "") {
+ err("No value for setting defined.")
+ return
+ }
+
+ if(setting == "vertical") { // writing direction
+ if(value != "rl" && value != "lr") {
+ err("Writing direction can only be set to 'rl' or 'rl'.")
+ continue
+ }
+ cue.direction = value
+ } else if(setting == "line") { // line position
+ if(!/\d/.test(value)) {
+ err("Line position takes a number or percentage.")
+ continue
+ }
+ if(value.indexOf("-", 1) != -1) {
+ err("Line position can only have '-' at the start.")
+ continue
+ }
+ if(value.indexOf("%") != -1 && value.indexOf("%") != value.length-1) {
+ err("Line position can only have '%' at the end.")
+ continue
+ }
+ if(value[0] == "-" && value[value.length-1] == "%") {
+ err("Line position cannot be a negative percentage.")
+ continue
+ }
+ if(value[value.length-1] == "%") {
+ if(parseInt(value, 10) > 100) {
+ err("Line position cannot be >100%.")
+ continue
+ }
+ cue.snapToLines = false
+ }
+ cue.linePosition = parseInt(value, 10)
+ } else if(setting == "position") { // text position
+ if(value[value.length-1] != "%") {
+ err("Text position must be a percentage.")
+ continue
+ }
+ if(parseInt(value, 10) > 100) {
+ err("Size cannot be >100%.")
+ continue
+ }
+ cue.textPosition = parseInt(value, 10)
+ } else if(setting == "size") { // size
+ if(value[value.length-1] != "%") {
+ err("Size must be a percentage.")
+ continue
+ }
+ if(parseInt(value, 10) > 100) {
+ err("Size cannot be >100%.")
+ continue
+ }
+ cue.size = parseInt(value, 10)
+ } else if(setting == "align") { // alignment
+ var alignValues = ["start", "middle", "end", "left", "right"]
+ if(alignValues.indexOf(value) == -1) {
+ err("Alignment can only be set to one of " + alignValues.join(", ") + ".")
+ continue
+ }
+ cue.alignment = value
+ } else {
+ err("Invalid setting.")
+ }
+ }
+ }
+
+ this.parse = function(cue, previousCueStart) {
+ skip(SPACE)
+ cue.startTime = timestamp()
+ if(cue.startTime == undefined) {
+ return
+ }
+ if(cue.startTime < previousCueStart) {
+ err("Start timestamp is not greater than or equal to start timestamp of previous cue.")
+ }
+ if(NOSPACE.test(line[pos])) {
+ err("Timestamp not separated from '-->' by whitespace.")
+ }
+ skip(SPACE)
+ // 6-8
+ if(line[pos] != "-") {
+ err("No valid timestamp separator found.")
+ return
+ }
+ pos++
+ if(line[pos] != "-") {
+ err("No valid timestamp separator found.")
+ return
+ }
+ pos++
+ if(line[pos] != ">") {
+ err("No valid timestamp separator found.")
+ return
+ }
+ pos++
+ if(NOSPACE.test(line[pos])) {
+ err("'-->' not separated from timestamp by whitespace.")
+ }
+ skip(SPACE)
+ cue.endTime = timestamp()
+ if(cue.endTime == undefined) {
+ return
+ }
+ if(cue.endTime <= cue.startTime) {
+ err("End timestamp is not greater than start timestamp.")
+ }
+
+ if(NOSPACE.test(line[pos])) {
+ spaceBeforeSetting = false
+ }
+ skip(SPACE)
+ parseSettings(line.substring(pos), cue)
+ return true
+ }
+ this.parseTimestamp = function() {
+ var ts = timestamp()
+ if(line[pos] != undefined) {
+ err("Timestamp must not have trailing characters.")
+ return
+ }
+ return ts
+ }
+}
+
+var WebVTTCueTextParser = function(line, errorHandler, mode) {
+ var line = line,
+ pos = 0,
+ err = function(message) {
+ if(mode == "metadata")
+ return
+ errorHandler(message, pos+1)
+ }
+
+ this.parse = function(cueStart, cueEnd) {
+ var result = {children:[]},
+ current = result,
+ timestamps = []
+
+ function attach(token) {
+ current.children.push({type:"object", name:token[1], classes:token[2], children:[], parent:current})
+ current = current.children[current.children.length-1]
+ }
+ function inScope(name) {
+ var node = current
+ while(node) {
+ if(node.name == name)
+ return true
+ node = node.parent
+ }
+ return
+ }
+
+ while(line[pos] != undefined) {
+ var token = nextToken()
+ if(token[0] == "text") {
+ current.children.push({type:"text", value:token[1], parent:current})
+ } else if(token[0] == "start tag") {
+ if(mode == "chapters")
+ err("Start tags not allowed in chapter title text.")
+ var name = token[1]
+ if(name != "v" && name != "lang" && token[3] != "") {
+ err("Only and can have an annotation.")
+ }
+ if(
+ name == "c" ||
+ name == "i" ||
+ name == "b" ||
+ name == "u" ||
+ name == "ruby"
+ ) {
+ attach(token)
+ } else if(name == "rt" && current.name == "ruby") {
+ attach(token)
+ } else if(name == "v") {
+ if(inScope("v")) {
+ err(" cannot be nested inside itself.")
+ }
+ attach(token)
+ current.value = token[3] // annotation
+ if(!token[3]) {
+ err(" requires an annotation.")
+ }
+ } else if(name == "lang") {
+ attach(token)
+ current.value = token[3] // language
+ } else {
+ err("Incorrect start tag.")
+ }
+ } else if(token[0] == "end tag") {
+ if(mode == "chapters")
+ err("End tags not allowed in chapter title text.")
+ // XXX check content
+ if(token[1] == current.name) {
+ current = current.parent
+ } else if(token[1] == "ruby" && current.name == "rt") {
+ current = current.parent.parent
+ } else {
+ err("Incorrect end tag.")
+ }
+ } else if(token[0] == "timestamp") {
+ if(mode == "chapters")
+ err("Timestamp not allowed in chapter title text.")
+ var timings = new WebVTTCueTimingsAndSettingsParser(token[1], err),
+ timestamp = timings.parseTimestamp()
+ if(timestamp != undefined) {
+ if(timestamp <= cueStart || timestamp >= cueEnd) {
+ err("Timestamp must be between start timestamp and end timestamp.")
+ }
+ if(timestamps.length > 0 && timestamps[timestamps.length-1] >= timestamp) {
+ err("Timestamp must be greater than any previous timestamp.")
+ }
+ current.children.push({type:"timestamp", value:timestamp, parent:current})
+ timestamps.push(timestamp)
+ }
+ }
+ }
+ while(current.parent) {
+ if(current.name != "v") {
+ err("Required end tag missing.")
+ }
+ current = current.parent
+ }
+ return result
+ }
+
+ function nextToken() {
+ var state = "data",
+ result = "",
+ buffer = "",
+ classes = []
+ while(line[pos-1] != undefined || pos == 0) {
+ var c = line[pos]
+ if(state == "data") {
+ if(c == "&") {
+ buffer = c
+ state = "escape"
+ } else if(c == "<" && result == "") {
+ state = "tag"
+ } else if(c == "<" || c == undefined) {
+ return ["text", result]
+ } else {
+ result += c
+ }
+ } else if(state == "escape") {
+ if(c == "&") {
+ err("Incorrect escape.")
+ result += buffer
+ buffer = c
+ } else if(/[abglmnsprt]/.test(c)) {
+ buffer += c
+ } else if(c == ";") {
+ if(buffer == "&") {
+ result += "&"
+ } else if(buffer == "<") {
+ result += "<"
+ } else if(buffer == ">") {
+ result += ">"
+ } else if(buffer == "&lrm") {
+ result += "\u200e"
+ } else if(buffer == "&rlm") {
+ result += "\u200f"
+ } else if(buffer == " ") {
+ result += "\u00A0"
+ } else {
+ err("Incorrect escape.")
+ result += buffer + ";"
+ }
+ state = "data"
+ } else if(c == "<" || c == undefined) {
+ err("Incorrect escape.")
+ result += buffer
+ return ["text", result]
+ } else {
+ err("Incorrect escape.")
+ result += buffer + c
+ state = "data"
+ }
+ } else if(state == "tag") {
+ if(c == "\t" || c == "\n" || c == "\f" || c == " ") {
+ state = "start tag annotation"
+ } else if(c == ".") {
+ state = "start tag class"
+ } else if(c == "/") {
+ state = "end tag"
+ } else if(/\d/.test(c)) {
+ result = c
+ state = "timestamp tag"
+ } else if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ return ["start tag", "", [], ""]
+ } else {
+ result = c
+ state = "start tag"
+ }
+ } else if(state == "start tag") {
+ if(c == "\t" || c == "\f" || c == " ") {
+ state = "start tag annotation"
+ } else if(c == "\n") {
+ buffer = c
+ state = "start tag annotation"
+ } else if(c == ".") {
+ state = "start tag class"
+ } else if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ return ["start tag", result, [], ""]
+ } else {
+ result += c
+ }
+ } else if(state == "start tag class") {
+ if(c == "\t" || c == "\f" || c == " ") {
+ classes.push(buffer)
+ buffer = ""
+ state = "start tag annotation"
+ } else if(c == "\n") {
+ classes.push(buffer)
+ buffer = c
+ state = "start tag annotation"
+ } else if(c == ".") {
+ classes.push(buffer)
+ buffer = ""
+ } else if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ classes.push(buffer)
+ return ["start tag", result, classes, ""]
+ } else {
+ buffer += c
+ }
+ } else if(state == "start tag annotation") {
+ if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ buffer = buffer.split(/[\u0020\t\f\r\n]+/).filter(function(item) { if(item) return true }).join(" ")
+ return ["start tag", result, classes, buffer]
+ } else {
+ buffer +=c
+ }
+ } else if(state == "end tag") {
+ if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ return ["end tag", result]
+ } else {
+ result += c
+ }
+ } else if(state == "timestamp tag") {
+ if(c == ">" || c == undefined) {
+ if(c == ">") {
+ pos++
+ }
+ return ["timestamp", result]
+ } else {
+ result += c
+ }
+ } else {
+ err("Never happens.") // The joke is it might.
+ }
+ // 8
+ pos++
+ }
+ }
+}
+
+var WebVTTSerializer = function() {
+ function serializeTree(tree) {
+ var result = ""
+ for (var i = 0; i < tree.length; i++) {
+ var node = tree[i]
+ if(node.type == "text") {
+ result += node.value
+ } else if(node.type == "object") {
+ result += "<" + node.name
+ if(node.classes) {
+ for(var y = 0; y < node.classes.length; y++) {
+ result += "." + node.classes[y]
+ }
+ }
+ if(node.value) {
+ result += " " + node.value
+ }
+ result += ">"
+ if(node.children)
+ result += serializeTree(node.children)
+ result += "" + node.name + ">"
+ } else {
+ result += "<" + node.value + ">"
+ }
+ }
+ return result
+ }
+ function serializeCue(cue) {
+ return cue.startTime + " " + cue.endTime + "\n" + serializeTree(cue.tree.children) + "\n\n"
+ }
+ this.serialize = function(cues) {
+ var result = ""
+ for(var i=0;i {
+ const fullVersion = packageJSON.version;
+ const majorVersion = semver.major(packageJSON.version);
+ const cdnRoot = packageJSON.com_fluidplayer.cdn;
+
+ switch (mode) {
+ case 'development':
+ return {
+ path: path.resolve(__dirname, 'dist'),
+ publicPath: '/'
+ };
+ case 'current':
+ return {
+ path: path.resolve(__dirname, 'dist-cdn/v' + majorVersion + '/current/'),
+ publicPath: cdnRoot + '/v' + majorVersion + '/current/'
+ };
+ case 'versioned':
+ return {
+ path: path.resolve(__dirname, 'dist-cdn/' + fullVersion + '/'),
+ publicPath: cdnRoot + '/' + fullVersion + '/'
+ };
+ default:
+ throw 'Unknown distribution type provided in --dist!';
+ }
+}
+
+// Webpack configuration
+module.exports = (env, argv) => {
+ const wpMode = typeof argv.mode !== 'undefined' ? argv.mode : 'development';
+ const wpDebug = wpMode === 'development' && typeof env.debug !== 'undefined' && !!env.debug;
+ const wpDist = typeof env.dist !== 'undefined' ? env.dist : 'development';
+ const wpDistOptions = getDistOptions(wpDist);
+
+ if ('development' !== wpDist && (wpMode !== 'production' || wpDebug)) {
+ throw 'Building a production distribution in development mode or with debug enabled is not allowed!'
+ }
+
+ const plugins = [
+ // Define common variables for use in Fluid Player
+ new webpack.DefinePlugin({
+ FP_BUILD_VERSION: JSON.stringify(packageJSON.version),
+ FP_HOMEPAGE: JSON.stringify(packageJSON.homepage),
+ FP_ENV: JSON.stringify(wpMode),
+ FP_DEBUG: JSON.stringify(wpDebug),
+ FP_WITH_CSS: false
+ })
+ ];
+
+ // Development mode builds and development server specifics
+ if ('development' === wpMode) {
+ // Locate all E2E cases
+ const caseFiles = [];
+ fs.readdirSync(path.resolve(__dirname, 'test/html/')).forEach(file => {
+ if (file === 'special-cases' || file === 'e2e') {
+ return;
+ }
+
+ const absPath = path.resolve(__dirname, 'test/html/', file);
+ const caseHtml = cheerio.load(fs.readFileSync(absPath));
+ const publicName = file.replace('.tpl', '');
+
+ plugins.push(new HtmlWebpackPlugin({
+ template: path.resolve(__dirname, 'test/html/', file),
+ inject: false,
+ filename: publicName,
+ scriptLoading: "blocking",
+ }));
+
+ caseFiles.push({
+ file: publicName,
+ name: caseHtml('title').text()
+ });
+ });
+
+ fs.readdirSync(path.resolve(__dirname, 'test/html/special-cases')).forEach(file => {
+ const publicName = file.replace('.tpl', '');
+
+ plugins.push(new HtmlWebpackPlugin({
+ template: path.resolve(__dirname, 'test/html/special-cases', file),
+ inject: false,
+ filename: publicName,
+ scriptLoading: "blocking",
+ }));
+ });
+
+ fs.readdirSync(path.resolve(__dirname, 'test/html/e2e')).forEach(file => {
+ const publicName = file.replace('.tpl', '');
+
+ plugins.push(new HtmlWebpackPlugin({
+ template: path.resolve(__dirname, 'test/html/e2e', file),
+ inject: false,
+ filename: publicName,
+ scriptLoading: "blocking",
+ }));
+ });
+
+ // Emit all cases as separate HTML pages
+ plugins.push(new HtmlWebpackPlugin({
+ template: path.resolve(__dirname, 'test/index.html'),
+ filename: 'index.html',
+ inject: false,
+ templateParameters: {
+ cases: caseFiles
+ }
+ }));
+
+ // Copy static assets for E2E
+ plugins.push(new CopyPlugin(
+ {
+ patterns: [
+ { from: path.resolve(__dirname, 'test/static/'), to: path.resolve(wpDistOptions.path, 'static') }
+ ]
+ }
+ ));
+ }
+
+ return {
+ devServer: {
+ static: wpDistOptions.path,
+ // index: 'index.html',
+ // allowedHosts: "all", // To use with remote hosting (ie: ngrok)
+ },
+ devtool: wpMode === 'development' ? 'source-map' : false,
+ cache: wpMode !== 'development' ? {
+ type: "filesystem",
+ buildDependencies: {
+ // This makes all dependencies of this file - build dependencies
+ config: [__filename],
+ // By default webpack and loaders are build dependencies
+ }
+ } : undefined,
+ plugins,
+ entry: {
+ fluidplayer: './src/browser.js'
+ },
+ optimization: {
+ minimize: wpMode !== 'development'
+ },
+ output: {
+ filename: '[name].min.js',
+ chunkFilename: '[name].[chunkhash].min.js',
+ path: wpDistOptions.path,
+ publicPath: wpDistOptions.publicPath
+ },
+ module: {
+ rules: [
+ {
+ test: /\.m?js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['@babel/preset-env']
+ }
+ }
+ },
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ {
+ test: /\.svg/,
+ type: 'asset'
+ },
+ ],
+ }
+ };
+}
diff --git a/client/fluid-player/yarn.lock b/client/fluid-player/yarn.lock
new file mode 100644
index 0000000..254e0bb
--- /dev/null
+++ b/client/fluid-player/yarn.lock
@@ -0,0 +1,3899 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@ampproject/remapping@^2.1.0":
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz"
+ integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.1.0"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@babel/code-frame@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz"
+ integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
+ dependencies:
+ "@babel/highlight" "^7.18.6"
+
+"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5":
+ version "7.20.14"
+ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz"
+ integrity sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==
+
+"@babel/core@^7.20.12":
+ version "7.20.12"
+ resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz"
+ integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==
+ dependencies:
+ "@ampproject/remapping" "^2.1.0"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.7"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helpers" "^7.20.7"
+ "@babel/parser" "^7.20.7"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.12"
+ "@babel/types" "^7.20.7"
+ convert-source-map "^1.7.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.2"
+ semver "^6.3.0"
+
+"@babel/generator@^7.20.7":
+ version "7.20.14"
+ resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz"
+ integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==
+ dependencies:
+ "@babel/types" "^7.20.7"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ jsesc "^2.5.1"
+
+"@babel/helper-annotate-as-pure@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz"
+ integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz"
+ integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==
+ dependencies:
+ "@babel/helper-explode-assignable-expression" "^7.18.6"
+ "@babel/types" "^7.18.9"
+
+"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz"
+ integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==
+ dependencies:
+ "@babel/compat-data" "^7.20.5"
+ "@babel/helper-validator-option" "^7.18.6"
+ browserslist "^4.21.3"
+ lru-cache "^5.1.1"
+ semver "^6.3.0"
+
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.5", "@babel/helper-create-class-features-plugin@^7.20.7":
+ version "7.20.12"
+ resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz"
+ integrity sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-member-expression-to-functions" "^7.20.7"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/helper-replace-supers" "^7.20.7"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz"
+ integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ regexpu-core "^5.2.1"
+
+"@babel/helper-define-polyfill-provider@^0.3.3":
+ version "0.3.3"
+ resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz"
+ integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==
+ dependencies:
+ "@babel/helper-compilation-targets" "^7.17.7"
+ "@babel/helper-plugin-utils" "^7.16.7"
+ debug "^4.1.1"
+ lodash.debounce "^4.0.8"
+ resolve "^1.14.2"
+ semver "^6.1.2"
+
+"@babel/helper-environment-visitor@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz"
+ integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
+
+"@babel/helper-explode-assignable-expression@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz"
+ integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz"
+ integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
+ dependencies:
+ "@babel/template" "^7.18.10"
+ "@babel/types" "^7.19.0"
+
+"@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-member-expression-to-functions@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz"
+ integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==
+ dependencies:
+ "@babel/types" "^7.20.7"
+
+"@babel/helper-module-imports@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz"
+ integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11":
+ version "7.20.11"
+ resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz"
+ integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-simple-access" "^7.20.2"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.10"
+ "@babel/types" "^7.20.7"
+
+"@babel/helper-optimise-call-expression@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz"
+ integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+ version "7.20.2"
+ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz"
+ integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
+
+"@babel/helper-remap-async-to-generator@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz"
+ integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-wrap-function" "^7.18.9"
+ "@babel/types" "^7.18.9"
+
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz"
+ integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-member-expression-to-functions" "^7.20.7"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.7"
+ "@babel/types" "^7.20.7"
+
+"@babel/helper-simple-access@^7.20.2":
+ version "7.20.2"
+ resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz"
+ integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==
+ dependencies:
+ "@babel/types" "^7.20.2"
+
+"@babel/helper-skip-transparent-expression-wrappers@^7.20.0":
+ version "7.20.0"
+ resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz"
+ integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==
+ dependencies:
+ "@babel/types" "^7.20.0"
+
+"@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.19.4":
+ version "7.19.4"
+ resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz"
+ integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
+
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+
+"@babel/helper-validator-option@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz"
+ integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
+
+"@babel/helper-wrap-function@^7.18.9":
+ version "7.20.5"
+ resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz"
+ integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==
+ dependencies:
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.20.5"
+ "@babel/types" "^7.20.5"
+
+"@babel/helpers@^7.20.7":
+ version "7.20.13"
+ resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz"
+ integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==
+ dependencies:
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.13"
+ "@babel/types" "^7.20.7"
+
+"@babel/highlight@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz"
+ integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.18.6"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
+"@babel/parser@^7.20.13", "@babel/parser@^7.20.7":
+ version "7.20.15"
+ resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz"
+ integrity sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==
+
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
+ version "7.18.6"
+ 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.18.6.tgz"
+ integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz"
+ integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/plugin-proposal-optional-chaining" "^7.20.7"
+
+"@babel/plugin-proposal-async-generator-functions@^7.20.1":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz"
+ integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-remap-async-to-generator" "^7.18.9"
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+
+"@babel/plugin-proposal-class-properties@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz"
+ integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-proposal-class-static-block@^7.18.6":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz"
+ integrity sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.20.7"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-class-static-block" "^7.14.5"
+
+"@babel/plugin-proposal-dynamic-import@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz"
+ integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+
+"@babel/plugin-proposal-export-namespace-from@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz"
+ integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+
+"@babel/plugin-proposal-json-strings@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz"
+ integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-json-strings" "^7.8.3"
+
+"@babel/plugin-proposal-logical-assignment-operators@^7.18.9":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz"
+ integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
+
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz"
+ integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+
+"@babel/plugin-proposal-numeric-separator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz"
+ integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-numeric-separator" "^7.10.4"
+
+"@babel/plugin-proposal-object-rest-spread@^7.20.2":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz"
+ integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==
+ dependencies:
+ "@babel/compat-data" "^7.20.5"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+ "@babel/plugin-transform-parameters" "^7.20.7"
+
+"@babel/plugin-proposal-optional-catch-binding@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz"
+ integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+
+"@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz"
+ integrity sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+
+"@babel/plugin-proposal-private-methods@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz"
+ integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-proposal-private-property-in-object@^7.18.6":
+ version "7.20.5"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz"
+ integrity sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-create-class-features-plugin" "^7.20.5"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
+
+"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz"
+ integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-syntax-async-generators@^7.8.4":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-class-properties@^7.12.13":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.12.13"
+
+"@babel/plugin-syntax-class-static-block@^7.14.5":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-dynamic-import@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz"
+ integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-export-namespace-from@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz"
+ integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.3"
+
+"@babel/plugin-syntax-import-assertions@^7.20.0":
+ version "7.20.0"
+ resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz"
+ integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.19.0"
+
+"@babel/plugin-syntax-json-strings@^7.8.3":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-numeric-separator@^7.10.4":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-object-rest-spread@^7.8.3":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-chaining@^7.8.3":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-private-property-in-object@^7.14.5":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-top-level-await@^7.14.5":
+ 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==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-transform-arrow-functions@^7.18.6":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz"
+ integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-async-to-generator@^7.18.6":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz"
+ integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==
+ dependencies:
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-remap-async-to-generator" "^7.18.9"
+
+"@babel/plugin-transform-block-scoped-functions@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz"
+ integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-block-scoping@^7.20.2":
+ version "7.20.15"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz"
+ integrity sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-classes@^7.20.2":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz"
+ integrity sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-replace-supers" "^7.20.7"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ globals "^11.1.0"
+
+"@babel/plugin-transform-computed-properties@^7.18.9":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz"
+ integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/template" "^7.20.7"
+
+"@babel/plugin-transform-destructuring@^7.20.2":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz"
+ integrity sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz"
+ integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-duplicate-keys@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz"
+ integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-exponentiation-operator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz"
+ integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==
+ dependencies:
+ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-for-of@^7.18.8":
+ version "7.18.8"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz"
+ integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-function-name@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz"
+ integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==
+ dependencies:
+ "@babel/helper-compilation-targets" "^7.18.9"
+ "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-literals@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz"
+ integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-member-expression-literals@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz"
+ integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-modules-amd@^7.19.6":
+ version "7.20.11"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz"
+ integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-modules-commonjs@^7.19.6":
+ version "7.20.11"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz"
+ integrity sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-simple-access" "^7.20.2"
+
+"@babel/plugin-transform-modules-systemjs@^7.19.6":
+ version "7.20.11"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz"
+ integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==
+ dependencies:
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-validator-identifier" "^7.19.1"
+
+"@babel/plugin-transform-modules-umd@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz"
+ integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1":
+ version "7.20.5"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz"
+ integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.20.5"
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-new-target@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz"
+ integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-object-super@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz"
+ integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/helper-replace-supers" "^7.18.6"
+
+"@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz"
+ integrity sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-property-literals@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz"
+ integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-regenerator@^7.18.6":
+ version "7.20.5"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz"
+ integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ regenerator-transform "^0.15.1"
+
+"@babel/plugin-transform-reserved-words@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz"
+ integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-shorthand-properties@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz"
+ integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-spread@^7.19.0":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz"
+ integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+
+"@babel/plugin-transform-sticky-regex@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz"
+ integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-template-literals@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz"
+ integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-typeof-symbol@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz"
+ integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-unicode-escapes@^7.18.10":
+ version "7.18.10"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz"
+ integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-unicode-regex@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz"
+ integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/preset-env@^7.20.2":
+ version "7.20.2"
+ resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz"
+ integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==
+ dependencies:
+ "@babel/compat-data" "^7.20.1"
+ "@babel/helper-compilation-targets" "^7.20.0"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-validator-option" "^7.18.6"
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9"
+ "@babel/plugin-proposal-async-generator-functions" "^7.20.1"
+ "@babel/plugin-proposal-class-properties" "^7.18.6"
+ "@babel/plugin-proposal-class-static-block" "^7.18.6"
+ "@babel/plugin-proposal-dynamic-import" "^7.18.6"
+ "@babel/plugin-proposal-export-namespace-from" "^7.18.9"
+ "@babel/plugin-proposal-json-strings" "^7.18.6"
+ "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6"
+ "@babel/plugin-proposal-numeric-separator" "^7.18.6"
+ "@babel/plugin-proposal-object-rest-spread" "^7.20.2"
+ "@babel/plugin-proposal-optional-catch-binding" "^7.18.6"
+ "@babel/plugin-proposal-optional-chaining" "^7.18.9"
+ "@babel/plugin-proposal-private-methods" "^7.18.6"
+ "@babel/plugin-proposal-private-property-in-object" "^7.18.6"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.18.6"
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+ "@babel/plugin-syntax-class-properties" "^7.12.13"
+ "@babel/plugin-syntax-class-static-block" "^7.14.5"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+ "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+ "@babel/plugin-syntax-import-assertions" "^7.20.0"
+ "@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"
+ "@babel/plugin-transform-arrow-functions" "^7.18.6"
+ "@babel/plugin-transform-async-to-generator" "^7.18.6"
+ "@babel/plugin-transform-block-scoped-functions" "^7.18.6"
+ "@babel/plugin-transform-block-scoping" "^7.20.2"
+ "@babel/plugin-transform-classes" "^7.20.2"
+ "@babel/plugin-transform-computed-properties" "^7.18.9"
+ "@babel/plugin-transform-destructuring" "^7.20.2"
+ "@babel/plugin-transform-dotall-regex" "^7.18.6"
+ "@babel/plugin-transform-duplicate-keys" "^7.18.9"
+ "@babel/plugin-transform-exponentiation-operator" "^7.18.6"
+ "@babel/plugin-transform-for-of" "^7.18.8"
+ "@babel/plugin-transform-function-name" "^7.18.9"
+ "@babel/plugin-transform-literals" "^7.18.9"
+ "@babel/plugin-transform-member-expression-literals" "^7.18.6"
+ "@babel/plugin-transform-modules-amd" "^7.19.6"
+ "@babel/plugin-transform-modules-commonjs" "^7.19.6"
+ "@babel/plugin-transform-modules-systemjs" "^7.19.6"
+ "@babel/plugin-transform-modules-umd" "^7.18.6"
+ "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1"
+ "@babel/plugin-transform-new-target" "^7.18.6"
+ "@babel/plugin-transform-object-super" "^7.18.6"
+ "@babel/plugin-transform-parameters" "^7.20.1"
+ "@babel/plugin-transform-property-literals" "^7.18.6"
+ "@babel/plugin-transform-regenerator" "^7.18.6"
+ "@babel/plugin-transform-reserved-words" "^7.18.6"
+ "@babel/plugin-transform-shorthand-properties" "^7.18.6"
+ "@babel/plugin-transform-spread" "^7.19.0"
+ "@babel/plugin-transform-sticky-regex" "^7.18.6"
+ "@babel/plugin-transform-template-literals" "^7.18.9"
+ "@babel/plugin-transform-typeof-symbol" "^7.18.9"
+ "@babel/plugin-transform-unicode-escapes" "^7.18.10"
+ "@babel/plugin-transform-unicode-regex" "^7.18.6"
+ "@babel/preset-modules" "^0.1.5"
+ "@babel/types" "^7.20.2"
+ babel-plugin-polyfill-corejs2 "^0.3.3"
+ babel-plugin-polyfill-corejs3 "^0.6.0"
+ babel-plugin-polyfill-regenerator "^0.4.1"
+ core-js-compat "^3.25.1"
+ semver "^6.3.0"
+
+"@babel/preset-modules@^0.1.5":
+ version "0.1.5"
+ resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz"
+ integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+ "@babel/plugin-transform-dotall-regex" "^7.4.4"
+ "@babel/types" "^7.4.4"
+ esutils "^2.0.2"
+
+"@babel/runtime@^7.8.4":
+ version "7.17.9"
+ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz"
+ integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@babel/template@^7.18.10", "@babel/template@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz"
+ integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
+
+"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.13", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7":
+ version "7.20.13"
+ resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz"
+ integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.7"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.20.13"
+ "@babel/types" "^7.20.7"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
+"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.4.4":
+ version "7.20.7"
+ resolved "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz"
+ integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==
+ dependencies:
+ "@babel/helper-string-parser" "^7.19.4"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
+"@discoveryjs/json-ext@^0.5.0":
+ version "0.5.7"
+ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
+ integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
+
+"@jridgewell/gen-mapping@^0.1.0":
+ version "0.1.1"
+ resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz"
+ integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.0"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
+"@jridgewell/gen-mapping@^0.3.0":
+ version "0.3.2"
+ resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/resolve-uri@3.1.0":
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
+"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1":
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz"
+ integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==
+
+"@jridgewell/source-map@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz"
+ integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.0"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@1.4.14":
+ version "1.4.14"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
+"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.17"
+ resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz"
+ integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==
+ dependencies:
+ "@jridgewell/resolve-uri" "3.1.0"
+ "@jridgewell/sourcemap-codec" "1.4.14"
+
+"@leichtgewicht/ip-codec@^2.0.1":
+ version "2.0.4"
+ resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz"
+ integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
+
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+
+"@nodelib/fs.walk@^1.2.3":
+ version "1.2.8"
+ resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@playwright/test@^1.49.0":
+ version "1.49.0"
+ resolved "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz"
+ integrity sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==
+ dependencies:
+ playwright "1.49.0"
+
+"@types/body-parser@*":
+ version "1.19.2"
+ resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz"
+ integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==
+ dependencies:
+ "@types/connect" "*"
+ "@types/node" "*"
+
+"@types/bonjour@^3.5.9":
+ version "3.5.10"
+ resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz"
+ integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==
+ dependencies:
+ "@types/node" "*"
+
+"@types/connect-history-api-fallback@^1.3.5":
+ version "1.3.5"
+ resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz"
+ integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==
+ dependencies:
+ "@types/express-serve-static-core" "*"
+ "@types/node" "*"
+
+"@types/connect@*":
+ version "3.4.35"
+ resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz"
+ integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/eslint-scope@^3.7.3":
+ version "3.7.4"
+ resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz"
+ integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==
+ dependencies:
+ "@types/eslint" "*"
+ "@types/estree" "*"
+
+"@types/eslint@*":
+ version "8.21.0"
+ resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz"
+ integrity sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==
+ dependencies:
+ "@types/estree" "*"
+ "@types/json-schema" "*"
+
+"@types/estree@*", "@types/estree@^0.0.51":
+ version "0.0.51"
+ resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz"
+ integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
+
+"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.31":
+ version "4.17.33"
+ resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz"
+ integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==
+ dependencies:
+ "@types/node" "*"
+ "@types/qs" "*"
+ "@types/range-parser" "*"
+
+"@types/express@*", "@types/express@^4.17.13":
+ version "4.17.16"
+ resolved "https://registry.npmjs.org/@types/express/-/express-4.17.16.tgz"
+ integrity sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "^4.17.31"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
+"@types/html-minifier-terser@^6.0.0":
+ 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==
+
+"@types/http-proxy@^1.17.8":
+ version "1.17.9"
+ resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz"
+ integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==
+ dependencies:
+ "@types/node" "*"
+
+"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+ version "7.0.11"
+ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz"
+ integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
+
+"@types/mime@*":
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz"
+ integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
+
+"@types/node@*", "@types/node@^22.9.1":
+ version "22.10.1"
+ resolved "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz"
+ integrity sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==
+ dependencies:
+ undici-types "~6.20.0"
+
+"@types/qs@*":
+ version "6.9.7"
+ resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
+ integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
+
+"@types/range-parser@*":
+ version "1.2.4"
+ resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz"
+ integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
+
+"@types/retry@0.12.0":
+ version "0.12.0"
+ resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz"
+ integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
+
+"@types/serve-index@^1.9.1":
+ version "1.9.1"
+ resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz"
+ integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==
+ dependencies:
+ "@types/express" "*"
+
+"@types/serve-static@*", "@types/serve-static@^1.13.10":
+ version "1.15.0"
+ resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz"
+ integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==
+ dependencies:
+ "@types/mime" "*"
+ "@types/node" "*"
+
+"@types/sockjs@^0.3.33":
+ version "0.3.33"
+ resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz"
+ integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==
+ dependencies:
+ "@types/node" "*"
+
+"@types/ws@^8.5.1":
+ version "8.5.4"
+ resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz"
+ integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==
+ dependencies:
+ "@types/node" "*"
+
+"@webassemblyjs/ast@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz"
+ integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==
+ dependencies:
+ "@webassemblyjs/helper-numbers" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+
+"@webassemblyjs/floating-point-hex-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz"
+ integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==
+
+"@webassemblyjs/helper-api-error@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz"
+ integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==
+
+"@webassemblyjs/helper-buffer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz"
+ integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==
+
+"@webassemblyjs/helper-numbers@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz"
+ integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==
+ dependencies:
+ "@webassemblyjs/floating-point-hex-parser" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/helper-wasm-bytecode@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz"
+ integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==
+
+"@webassemblyjs/helper-wasm-section@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz"
+ integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+
+"@webassemblyjs/ieee754@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz"
+ integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==
+ dependencies:
+ "@xtuc/ieee754" "^1.2.0"
+
+"@webassemblyjs/leb128@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz"
+ integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==
+ dependencies:
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/utf8@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz"
+ integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==
+
+"@webassemblyjs/wasm-edit@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz"
+ integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/helper-wasm-section" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-opt" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ "@webassemblyjs/wast-printer" "1.11.1"
+
+"@webassemblyjs/wasm-gen@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz"
+ integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wasm-opt@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz"
+ integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+
+"@webassemblyjs/wasm-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz"
+ integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wast-printer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz"
+ integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@xtuc/long" "4.2.2"
+
+"@webpack-cli/configtest@^2.1.0":
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz"
+ integrity sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==
+
+"@webpack-cli/info@^2.0.1":
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz"
+ integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==
+
+"@webpack-cli/serve@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz"
+ integrity sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==
+
+"@xtuc/ieee754@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
+ integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
+
+"@xtuc/long@4.2.2":
+ version "4.2.2"
+ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz"
+ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
+
+accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
+ version "1.3.8"
+ resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz"
+ integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
+ dependencies:
+ mime-types "~2.1.34"
+ negotiator "0.6.3"
+
+acorn-import-assertions@^1.7.6:
+ version "1.8.0"
+ resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz"
+ integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
+
+acorn@^8.5.0, acorn@^8.7.1:
+ version "8.8.2"
+ resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz"
+ integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
+
+ajv-formats@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz"
+ integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==
+ dependencies:
+ ajv "^8.0.0"
+
+ajv-keywords@^3.5.2:
+ version "3.5.2"
+ resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
+ integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+
+ajv-keywords@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz"
+ integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+
+ajv@^6.12.5:
+ version "6.12.6"
+ resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
+ integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+ 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"
+
+ajv@^8.0.0, ajv@^8.8.0:
+ version "8.12.0"
+ resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz"
+ integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+ uri-js "^4.2.2"
+
+ansi-html-community@^0.0.8:
+ 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==
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
+ integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+ dependencies:
+ color-convert "^1.9.0"
+
+anymatch@~3.1.2:
+ version "3.1.3"
+ resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
+ integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
+ dependencies:
+ normalize-path "^3.0.0"
+ picomatch "^2.0.4"
+
+array-flatten@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz"
+ integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
+
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
+ integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
+
+babel-loader@^9.1.2:
+ version "9.1.2"
+ resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz"
+ integrity sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==
+ dependencies:
+ find-cache-dir "^3.3.2"
+ schema-utils "^4.0.0"
+
+babel-plugin-polyfill-corejs2@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz"
+ integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==
+ dependencies:
+ "@babel/compat-data" "^7.17.7"
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+ semver "^6.1.1"
+
+babel-plugin-polyfill-corejs3@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz"
+ integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==
+ dependencies:
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+ core-js-compat "^3.25.1"
+
+babel-plugin-polyfill-regenerator@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz"
+ integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==
+ dependencies:
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+batch@0.6.1:
+ version "0.6.1"
+ resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz"
+ integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
+
+bcp-47-match@^1.0.0, bcp-47-match@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz"
+ integrity sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==
+
+bcp-47-normalize@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz"
+ integrity sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==
+ dependencies:
+ bcp-47 "^1.0.0"
+ bcp-47-match "^1.0.0"
+
+bcp-47@^1.0.0:
+ version "1.0.8"
+ resolved "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz"
+ integrity sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==
+ dependencies:
+ is-alphabetical "^1.0.0"
+ is-alphanumerical "^1.0.0"
+ is-decimal "^1.0.0"
+
+binary-extensions@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
+ integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+body-parser@1.20.1:
+ version "1.20.1"
+ resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz"
+ integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
+ dependencies:
+ bytes "3.1.2"
+ content-type "~1.0.4"
+ debug "2.6.9"
+ depd "2.0.0"
+ destroy "1.2.0"
+ http-errors "2.0.0"
+ iconv-lite "0.4.24"
+ on-finished "2.4.1"
+ qs "6.11.0"
+ raw-body "2.5.1"
+ type-is "~1.6.18"
+ unpipe "1.0.0"
+
+bonjour-service@^1.0.11:
+ version "1.1.0"
+ resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz"
+ integrity sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==
+ dependencies:
+ array-flatten "^2.1.2"
+ dns-equal "^1.0.0"
+ fast-deep-equal "^3.1.3"
+ multicast-dns "^7.2.5"
+
+boolbase@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
+ integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
+ integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^3.0.2, braces@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
+browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4:
+ version "4.21.5"
+ resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz"
+ integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==
+ dependencies:
+ caniuse-lite "^1.0.30001449"
+ electron-to-chromium "^1.4.284"
+ node-releases "^2.0.8"
+ update-browserslist-db "^1.0.10"
+
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz"
+ integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
+
+bytes@3.1.2:
+ version "3.1.2"
+ resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
+ integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
+
+call-bind@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
+ integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
+ dependencies:
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+
+camel-case@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz"
+ integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
+ dependencies:
+ pascal-case "^3.1.2"
+ tslib "^2.0.3"
+
+caniuse-lite@^1.0.30001449:
+ version "1.0.30001450"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz"
+ integrity sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==
+
+chalk@^2.0.0:
+ version "2.4.2"
+ resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
+cheerio-select@^1.5.0:
+ version "1.6.0"
+ resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz"
+ integrity sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==
+ dependencies:
+ css-select "^4.3.0"
+ css-what "^6.0.1"
+ domelementtype "^2.2.0"
+ domhandler "^4.3.1"
+ domutils "^2.8.0"
+
+cheerio@^1.0.0-rc.3:
+ version "1.0.0-rc.10"
+ resolved "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz"
+ integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==
+ dependencies:
+ cheerio-select "^1.5.0"
+ dom-serializer "^1.3.2"
+ domhandler "^4.2.0"
+ htmlparser2 "^6.1.0"
+ parse5 "^6.0.1"
+ parse5-htmlparser2-tree-adapter "^6.0.1"
+ tslib "^2.2.0"
+
+chokidar@^3.5.3:
+ version "3.5.3"
+ resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
+ integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+ 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"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+chrome-trace-event@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz"
+ integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
+
+clean-css@^5.2.2:
+ version "5.3.2"
+ resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz"
+ integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==
+ dependencies:
+ source-map "~0.6.0"
+
+clone-deep@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz"
+ integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
+ dependencies:
+ is-plain-object "^2.0.4"
+ kind-of "^6.0.2"
+ shallow-clone "^3.0.0"
+
+codem-isoboxer@0.3.6:
+ version "0.3.6"
+ resolved "https://registry.npmjs.org/codem-isoboxer/-/codem-isoboxer-0.3.6.tgz"
+ integrity sha512-LuO8/7LW6XuR5ERn1yavXAfodGRhuY2yP60JTZIw5yNYMCE5lUVbk3NFUCJxjnphQH+Xemp5hOGb1LgUXm00Xw==
+
+color-convert@^1.9.0:
+ version "1.9.3"
+ resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
+ integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+ dependencies:
+ color-name "1.1.3"
+
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
+ integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
+colorette@^2.0.10, colorette@^2.0.14:
+ version "2.0.19"
+ resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz"
+ integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
+
+commander@^10.0.1:
+ version "10.0.1"
+ resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz"
+ integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
+
+commander@^2.20.0:
+ 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==
+
+commander@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz"
+ integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
+
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
+ integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
+
+compressible@~2.0.16:
+ version "2.0.18"
+ resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz"
+ integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
+ dependencies:
+ mime-db ">= 1.43.0 < 2"
+
+compression@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz"
+ integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
+ dependencies:
+ accepts "~1.3.5"
+ bytes "3.0.0"
+ compressible "~2.0.16"
+ debug "2.6.9"
+ on-headers "~1.0.2"
+ safe-buffer "5.1.2"
+ vary "~1.1.2"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+
+connect-history-api-fallback@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz"
+ integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
+
+content-disposition@0.5.4:
+ version "0.5.4"
+ resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz"
+ integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
+ dependencies:
+ safe-buffer "5.2.1"
+
+content-type@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz"
+ integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
+
+convert-source-map@^1.7.0:
+ version "1.8.0"
+ resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz"
+ integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
+ dependencies:
+ safe-buffer "~5.1.1"
+
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
+ integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
+
+cookie@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
+ integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+
+copy-webpack-plugin@^11.0.0:
+ version "11.0.0"
+ resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz"
+ integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==
+ dependencies:
+ fast-glob "^3.2.11"
+ glob-parent "^6.0.1"
+ globby "^13.1.1"
+ normalize-path "^3.0.0"
+ schema-utils "^4.0.0"
+ serialize-javascript "^6.0.0"
+
+core-js-compat@^3.25.1:
+ version "3.27.2"
+ resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz"
+ integrity sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==
+ dependencies:
+ browserslist "^4.21.4"
+
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
+cross-spawn@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
+ integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+css-loader@^6.7.3:
+ version "6.7.3"
+ resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz"
+ integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==
+ dependencies:
+ icss-utils "^5.1.0"
+ postcss "^8.4.19"
+ postcss-modules-extract-imports "^3.0.0"
+ postcss-modules-local-by-default "^4.0.0"
+ postcss-modules-scope "^3.0.0"
+ postcss-modules-values "^4.0.0"
+ postcss-value-parser "^4.2.0"
+ semver "^7.3.8"
+
+css-select@^4.1.3, css-select@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz"
+ integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
+ dependencies:
+ boolbase "^1.0.0"
+ css-what "^6.0.1"
+ domhandler "^4.3.1"
+ domutils "^2.8.0"
+ nth-check "^2.0.1"
+
+css-what@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz"
+ integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+
+cssesc@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
+ integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+
+dashjs@^4.5.2:
+ version "4.5.2"
+ resolved "https://registry.npmjs.org/dashjs/-/dashjs-4.5.2.tgz"
+ integrity sha512-WXPk0lPDSaHjiSVoVRh2jQPiMmB1alKUH8hV2CVmaI0vPUeT1wIY7madVE38SthfOmwS9IJViv1RrxrxdGjElg==
+ dependencies:
+ bcp-47-match "^1.0.3"
+ bcp-47-normalize "^1.1.1"
+ codem-isoboxer "0.3.6"
+ es6-promise "^4.2.8"
+ fast-deep-equal "2.0.1"
+ html-entities "^1.2.1"
+ imsc "^1.0.2"
+ localforage "^1.7.1"
+ ua-parser-js "^1.0.2"
+
+debug@^4.1.0, debug@^4.1.1:
+ version "4.3.4"
+ resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
+ integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+ dependencies:
+ ms "2.1.2"
+
+debug@2.6.9:
+ version "2.6.9"
+ resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
+ integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+ dependencies:
+ ms "2.0.0"
+
+default-gateway@^6.0.3:
+ version "6.0.3"
+ resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz"
+ integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==
+ dependencies:
+ execa "^5.0.0"
+
+define-lazy-prop@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz"
+ integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
+
+depd@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
+ integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
+
+depd@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
+ integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
+
+destroy@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
+ integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
+
+detect-node@^2.0.4:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
+ integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
+
+dir-glob@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
+ integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+ dependencies:
+ path-type "^4.0.0"
+
+dns-equal@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz"
+ integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==
+
+dns-packet@^5.2.2:
+ version "5.4.0"
+ resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz"
+ integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==
+ dependencies:
+ "@leichtgewicht/ip-codec" "^2.0.1"
+
+dom-converter@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz"
+ integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==
+ dependencies:
+ utila "~0.4"
+
+dom-serializer@^1.0.1, dom-serializer@^1.3.2:
+ version "1.4.1"
+ resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz"
+ integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.2.0"
+ entities "^2.0.0"
+
+dom-walk@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz"
+ integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
+
+domelementtype@^2.0.1, domelementtype@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz"
+ integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+
+domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz"
+ integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
+ dependencies:
+ domelementtype "^2.2.0"
+
+domutils@^2.5.2, domutils@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz"
+ integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
+ dependencies:
+ dom-serializer "^1.0.1"
+ domelementtype "^2.2.0"
+ domhandler "^4.2.0"
+
+dot-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz"
+ integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
+ integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
+
+electron-to-chromium@^1.4.284:
+ version "1.4.285"
+ resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.285.tgz"
+ integrity sha512-47o4PPgxfU1KMNejz+Dgaodf7YTcg48uOfV1oM6cs3adrl2+7R+dHkt3Jpxqo0LRCbGJEzTKMUt0RdvByb/leg==
+
+encodeurl@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
+ integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
+
+enhanced-resolve@^5.10.0:
+ version "5.12.0"
+ resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz"
+ integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
+entities@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz"
+ integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
+
+envinfo@^7.7.3:
+ version "7.8.1"
+ resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz"
+ integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
+
+es-module-lexer@^0.9.0:
+ version "0.9.3"
+ resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz"
+ integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
+
+es6-promise@^4.2.8:
+ version "4.2.8"
+ resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz"
+ integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+
+escalade@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz"
+ integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
+ integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+
+escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
+
+eslint-scope@5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^4.1.1"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^4.1.1:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
+ integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
+estraverse@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"
+ integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
+
+eventemitter3@^4.0.0:
+ version "4.0.7"
+ resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz"
+ integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+
+events@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
+ integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
+
+execa@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ 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"
+
+express@^4.17.3:
+ version "4.18.2"
+ resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
+ integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
+ dependencies:
+ accepts "~1.3.8"
+ array-flatten "1.1.1"
+ body-parser "1.20.1"
+ content-disposition "0.5.4"
+ content-type "~1.0.4"
+ cookie "0.5.0"
+ cookie-signature "1.0.6"
+ debug "2.6.9"
+ depd "2.0.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ finalhandler "1.2.0"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ path-to-regexp "0.1.7"
+ proxy-addr "~2.0.7"
+ qs "6.11.0"
+ range-parser "~1.2.1"
+ safe-buffer "5.2.1"
+ send "0.18.0"
+ serve-static "1.15.0"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ type-is "~1.6.18"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
+
+fast-deep-equal@^3.1.1:
+ 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==
+
+fast-deep-equal@^3.1.3:
+ 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==
+
+fast-deep-equal@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz"
+ integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==
+
+fast-glob@^3.2.11:
+ version "3.2.12"
+ resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz"
+ integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
+fast-json-stable-stringify@^2.0.0:
+ 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==
+
+fastest-levenshtein@^1.0.12:
+ version "1.0.16"
+ resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz"
+ integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
+
+fastq@^1.6.0:
+ version "1.15.0"
+ resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
+ integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
+ dependencies:
+ reusify "^1.0.4"
+
+faye-websocket@^0.11.3:
+ version "0.11.4"
+ resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz"
+ integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==
+ dependencies:
+ websocket-driver ">=0.5.1"
+
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+finalhandler@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz"
+ integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
+ dependencies:
+ debug "2.6.9"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ statuses "2.0.1"
+ unpipe "~1.0.0"
+
+find-cache-dir@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz"
+ integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==
+ dependencies:
+ commondir "^1.0.1"
+ make-dir "^3.0.2"
+ pkg-dir "^4.1.0"
+
+find-up@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
+ integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+ dependencies:
+ locate-path "^5.0.0"
+ path-exists "^4.0.0"
+
+follow-redirects@^1.0.0:
+ version "1.15.0"
+ resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz"
+ integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==
+
+forwarded@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
+ integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
+
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
+ integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+
+fs-monkey@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz"
+ integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+gensync@^1.0.0-beta.2:
+ 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==
+
+get-intrinsic@^1.0.2:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz"
+ integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
+ dependencies:
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+
+get-stream@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+
+glob-parent@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+glob-parent@^6.0.1:
+ version "6.0.2"
+ resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
+glob-parent@~5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+glob-to-regexp@^0.4.1:
+ 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==
+
+glob@^7.1.3:
+ version "7.2.3"
+ resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
+ integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+ 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"
+
+global@^4.3.1:
+ version "4.4.0"
+ resolved "https://registry.npmjs.org/global/-/global-4.4.0.tgz"
+ integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
+ dependencies:
+ min-document "^2.19.0"
+ process "^0.11.10"
+
+globals@^11.1.0:
+ version "11.12.0"
+ resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
+ integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+
+globby@^13.1.1:
+ version "13.1.3"
+ resolved "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz"
+ integrity sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==
+ dependencies:
+ dir-glob "^3.0.1"
+ fast-glob "^3.2.11"
+ ignore "^5.2.0"
+ merge2 "^1.4.1"
+ slash "^4.0.0"
+
+graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+ version "4.2.10"
+ resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz"
+ integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
+
+handle-thing@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz"
+ integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
+ integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has-symbols@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
+he@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
+ integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
+hls.js@^1.5.13:
+ version "1.5.15"
+ resolved "https://registry.npmjs.org/hls.js/-/hls.js-1.5.15.tgz"
+ integrity sha512-6cD7xN6bycBHaXz2WyPIaHn/iXFizE5au2yvY5q9aC4wfihxAr16C9fUy4nxh2a3wOw0fEgLRa9dN6wsYjlpNg==
+
+hpack.js@^2.1.6:
+ version "2.1.6"
+ resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz"
+ integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==
+ dependencies:
+ inherits "^2.0.1"
+ obuf "^1.0.0"
+ readable-stream "^2.0.1"
+ wbuf "^1.1.0"
+
+html-entities@^1.2.1:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz"
+ integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==
+
+html-entities@^2.3.2:
+ version "2.3.3"
+ resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz"
+ integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==
+
+html-minifier-terser@^6.0.2:
+ version "6.1.0"
+ resolved "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz"
+ integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==
+ 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"
+
+html-webpack-plugin@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz"
+ integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==
+ 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"
+
+htmlparser2@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz"
+ integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+ domutils "^2.5.2"
+ entities "^2.0.0"
+
+http-deceiver@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz"
+ integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==
+
+http-errors@~1.6.2:
+ version "1.6.3"
+ resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz"
+ integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==
+ dependencies:
+ depd "~1.1.2"
+ inherits "2.0.3"
+ setprototypeof "1.1.0"
+ statuses ">= 1.4.0 < 2"
+
+http-errors@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz"
+ integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
+ dependencies:
+ depd "2.0.0"
+ inherits "2.0.4"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ toidentifier "1.0.1"
+
+http-parser-js@>=0.5.1:
+ version "0.5.6"
+ resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz"
+ integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==
+
+http-proxy-middleware@^2.0.3:
+ version "2.0.6"
+ resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz"
+ integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
+ dependencies:
+ "@types/http-proxy" "^1.17.8"
+ http-proxy "^1.18.1"
+ is-glob "^4.0.1"
+ is-plain-obj "^3.0.0"
+ micromatch "^4.0.2"
+
+http-proxy@^1.18.1:
+ version "1.18.1"
+ resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz"
+ integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
+ dependencies:
+ eventemitter3 "^4.0.0"
+ follow-redirects "^1.0.0"
+ requires-port "^1.0.0"
+
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+
+iconv-lite@0.4.24:
+ version "0.4.24"
+ resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
+ integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
+icss-utils@^5.0.0, icss-utils@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz"
+ integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
+
+ignore@^5.2.0:
+ version "5.2.4"
+ resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
+ integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+
+immediate@~3.0.5:
+ version "3.0.6"
+ resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz"
+ integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
+
+import-local@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz"
+ integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
+ dependencies:
+ pkg-dir "^4.2.0"
+ resolve-cwd "^3.0.0"
+
+imsc@^1.0.2:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/imsc/-/imsc-1.1.3.tgz"
+ integrity sha512-IY0hMkVTNoqoYwKEp5UvNNKp/A5jeJUOrIO7judgOyhHT+xC6PA4VBOMAOhdtAYbMRHx9DTgI8p6Z6jhYQPFDA==
+ dependencies:
+ sax "1.2.1"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
+ integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@2, inherits@2.0.4:
+ version "2.0.4"
+ resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+inherits@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
+ integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
+
+interpret@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz"
+ integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
+
+ipaddr.js@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz"
+ integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
+
+ipaddr.js@1.9.1:
+ version "1.9.1"
+ resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
+ integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+
+is-alphabetical@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz"
+ integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
+
+is-alphanumerical@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz"
+ integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
+ dependencies:
+ is-alphabetical "^1.0.0"
+ is-decimal "^1.0.0"
+
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
+
+is-core-module@^2.8.1:
+ version "2.9.0"
+ resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz"
+ integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
+ dependencies:
+ has "^1.0.3"
+
+is-decimal@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz"
+ integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
+
+is-docker@^2.0.0, is-docker@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
+ integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+
+is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
+ integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+
+is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-plain-obj@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz"
+ integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
+
+is-plain-object@^2.0.4:
+ 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==
+ dependencies:
+ isobject "^3.0.1"
+
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
+is-wsl@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
+ integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
+ dependencies:
+ is-docker "^2.0.0"
+
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
+ integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+isobject@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
+ integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
+
+jest-worker@^27.4.5:
+ version "27.5.1"
+ resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz"
+ integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
+ dependencies:
+ "@types/node" "*"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
+js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+jsesc@^2.5.1:
+ version "2.5.2"
+ resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
+ integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+
+jsesc@~0.5.0:
+ version "0.5.0"
+ resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz"
+ integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==
+
+json-parse-even-better-errors@^2.3.1:
+ 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==
+
+json-schema-traverse@^0.4.1:
+ 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==
+
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
+json5@^2.2.2:
+ version "2.2.3"
+ resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
+ integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+
+kind-of@^6.0.2:
+ version "6.0.3"
+ resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz"
+ integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+
+lie@3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz"
+ integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==
+ dependencies:
+ immediate "~3.0.5"
+
+loader-runner@^4.2.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz"
+ integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
+
+localforage@^1.7.1:
+ version "1.10.0"
+ resolved "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz"
+ integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==
+ dependencies:
+ lie "3.1.1"
+
+locate-path@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz"
+ integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+ dependencies:
+ p-locate "^4.1.0"
+
+lodash.debounce@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
+ integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
+
+lodash@^4.17.20, lodash@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+lower-case@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
+ integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
+ dependencies:
+ tslib "^2.0.3"
+
+lru-cache@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz"
+ integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+ dependencies:
+ yallist "^3.0.2"
+
+lru-cache@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
+ integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+ dependencies:
+ yallist "^4.0.0"
+
+make-dir@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
+ integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
+ dependencies:
+ semver "^6.0.0"
+
+media-typer@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
+ integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
+
+memfs@^3.4.3:
+ version "3.4.13"
+ resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz"
+ integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==
+ dependencies:
+ fs-monkey "^1.0.3"
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz"
+ integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
+
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+
+merge2@^1.3.0, merge2@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
+ integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
+ integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
+
+micromatch@^4.0.2, micromatch@^4.0.4:
+ version "4.0.5"
+ resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
+ integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
+ dependencies:
+ braces "^3.0.2"
+ picomatch "^2.3.1"
+
+"mime-db@>= 1.43.0 < 2", mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
+ version "2.1.35"
+ resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+ dependencies:
+ mime-db "1.52.0"
+
+mime@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
+ integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+
+mimic-fn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
+ integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+min-document@^2.19.0:
+ version "2.19.0"
+ resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz"
+ integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
+ dependencies:
+ dom-walk "^0.1.0"
+
+minimalistic-assert@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
+ integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
+
+minimatch@^3.1.1:
+ version "3.1.2"
+ resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
+ integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+ dependencies:
+ brace-expansion "^1.1.7"
+
+ms@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
+ integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
+
+ms@2.1.2:
+ version "2.1.2"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
+ integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+ms@2.1.3:
+ version "2.1.3"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+multicast-dns@^7.2.5:
+ version "7.2.5"
+ resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz"
+ integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==
+ dependencies:
+ dns-packet "^5.2.2"
+ thunky "^1.0.2"
+
+nanoid@^3.3.4:
+ version "3.3.4"
+ resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
+ integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
+
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
+
+neo-async@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
+no-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz"
+ integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
+ dependencies:
+ lower-case "^2.0.2"
+ tslib "^2.0.3"
+
+node-forge@^1:
+ version "1.3.1"
+ resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz"
+ integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
+
+node-releases@^2.0.8:
+ version "2.0.9"
+ resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz"
+ integrity sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+npm-run-path@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz"
+ integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
+ dependencies:
+ path-key "^3.0.0"
+
+nth-check@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz"
+ integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
+ dependencies:
+ boolbase "^1.0.0"
+
+object-inspect@^1.9.0:
+ version "1.12.0"
+ resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz"
+ integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
+
+obuf@^1.0.0, obuf@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz"
+ integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
+
+on-finished@2.4.1:
+ version "2.4.1"
+ resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
+ integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
+ dependencies:
+ ee-first "1.1.1"
+
+on-headers@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz"
+ integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
+ integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+ dependencies:
+ wrappy "1"
+
+onetime@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
+ integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+ dependencies:
+ mimic-fn "^2.1.0"
+
+open@^8.0.9:
+ version "8.4.0"
+ resolved "https://registry.npmjs.org/open/-/open-8.4.0.tgz"
+ integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==
+ dependencies:
+ define-lazy-prop "^2.0.0"
+ is-docker "^2.1.1"
+ is-wsl "^2.2.0"
+
+p-limit@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
+ integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+ dependencies:
+ p-try "^2.0.0"
+
+p-locate@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz"
+ integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+ dependencies:
+ p-limit "^2.2.0"
+
+p-retry@^4.5.0:
+ version "4.6.2"
+ resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz"
+ integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==
+ dependencies:
+ "@types/retry" "0.12.0"
+ retry "^0.13.1"
+
+p-try@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
+ integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+panolens@^0.12.1:
+ version "0.12.1"
+ resolved "https://registry.npmjs.org/panolens/-/panolens-0.12.1.tgz"
+ integrity sha512-2hpjm+rRnDdaLD5Bak49K0Y9/X6vOr1OcyJx5piSA6sCOs1tsgchMgKIwpSGCMpBMHWZ10E/Cz4BIwyXYebt5g==
+ dependencies:
+ three "^0.105.2"
+
+param-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz"
+ integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
+ dependencies:
+ dot-case "^3.0.4"
+ tslib "^2.0.3"
+
+parse5-htmlparser2-tree-adapter@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz"
+ integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
+ dependencies:
+ parse5 "^6.0.1"
+
+parse5@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz"
+ integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
+
+parseurl@~1.3.2, parseurl@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz"
+ integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+
+pascal-case@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz"
+ integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
+
+path-key@^3.0.0, path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
+ integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
+
+path-type@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
+ integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+pkg-dir@^4.1.0, pkg-dir@^4.2.0:
+ 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==
+ dependencies:
+ find-up "^4.0.0"
+
+playwright-core@1.49.0:
+ version "1.49.0"
+ resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz"
+ integrity sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==
+
+playwright@1.49.0:
+ version "1.49.0"
+ resolved "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz"
+ integrity sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==
+ dependencies:
+ playwright-core "1.49.0"
+ optionalDependencies:
+ fsevents "2.3.2"
+
+postcss-modules-extract-imports@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz"
+ integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==
+
+postcss-modules-local-by-default@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz"
+ integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==
+ dependencies:
+ icss-utils "^5.0.0"
+ postcss-selector-parser "^6.0.2"
+ postcss-value-parser "^4.1.0"
+
+postcss-modules-scope@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz"
+ integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==
+ dependencies:
+ postcss-selector-parser "^6.0.4"
+
+postcss-modules-values@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz"
+ integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
+ dependencies:
+ icss-utils "^5.0.0"
+
+postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
+ version "6.0.10"
+ resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz"
+ integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
+ dependencies:
+ cssesc "^3.0.0"
+ util-deprecate "^1.0.2"
+
+postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
+ integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
+
+postcss@^8.4.19:
+ version "8.4.21"
+ resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz"
+ integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
+ dependencies:
+ nanoid "^3.3.4"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
+pretty-error@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz"
+ integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==
+ dependencies:
+ lodash "^4.17.20"
+ renderkid "^3.0.0"
+
+process-nextick-args@~2.0.0:
+ 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==
+
+process@^0.11.10:
+ version "0.11.10"
+ resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
+ integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
+
+proxy-addr@~2.0.7:
+ version "2.0.7"
+ resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz"
+ integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
+ dependencies:
+ forwarded "0.2.0"
+ ipaddr.js "1.9.1"
+
+punycode@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
+ integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
+qs@6.11.0:
+ version "6.11.0"
+ resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz"
+ integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
+ dependencies:
+ side-channel "^1.0.4"
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+randombytes@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
+ integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+ dependencies:
+ safe-buffer "^5.1.0"
+
+range-parser@^1.2.1, range-parser@~1.2.1:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz"
+ integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
+
+raw-body@2.5.1:
+ version "2.5.1"
+ resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz"
+ integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
+ dependencies:
+ bytes "3.1.2"
+ http-errors "2.0.0"
+ iconv-lite "0.4.24"
+ unpipe "1.0.0"
+
+readable-stream@^2.0.1:
+ version "2.3.7"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
+ integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
+ 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"
+
+readable-stream@^3.0.6:
+ version "3.6.0"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
+ integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
+rechoir@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz"
+ integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
+ dependencies:
+ resolve "^1.20.0"
+
+regenerate-unicode-properties@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz"
+ integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==
+ dependencies:
+ regenerate "^1.4.2"
+
+regenerate@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz"
+ integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
+
+regenerator-runtime@^0.13.4:
+ version "0.13.9"
+ resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
+ integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
+
+regenerator-transform@^0.15.1:
+ version "0.15.1"
+ resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz"
+ integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==
+ dependencies:
+ "@babel/runtime" "^7.8.4"
+
+regexpu-core@^5.2.1:
+ version "5.2.2"
+ resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz"
+ integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==
+ dependencies:
+ regenerate "^1.4.2"
+ regenerate-unicode-properties "^10.1.0"
+ regjsgen "^0.7.1"
+ regjsparser "^0.9.1"
+ unicode-match-property-ecmascript "^2.0.0"
+ unicode-match-property-value-ecmascript "^2.1.0"
+
+regjsgen@^0.7.1:
+ version "0.7.1"
+ resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz"
+ integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==
+
+regjsparser@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz"
+ integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==
+ dependencies:
+ jsesc "~0.5.0"
+
+relateurl@^0.2.7:
+ version "0.2.7"
+ resolved "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz"
+ integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==
+
+renderkid@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz"
+ integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==
+ dependencies:
+ css-select "^4.1.3"
+ dom-converter "^0.2.0"
+ htmlparser2 "^6.1.0"
+ lodash "^4.17.21"
+ strip-ansi "^6.0.1"
+
+require-from-string@^2.0.2:
+ 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==
+
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
+ integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
+
+resolve-cwd@^3.0.0:
+ 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==
+ dependencies:
+ resolve-from "^5.0.0"
+
+resolve-from@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
+ integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
+
+resolve@^1.14.2, resolve@^1.20.0:
+ version "1.22.0"
+ resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz"
+ integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
+ dependencies:
+ is-core-module "^2.8.1"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+retry@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz"
+ integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==
+
+reusify@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
+ integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+ dependencies:
+ queue-microtask "^1.2.2"
+
+safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+safe-buffer@5.2.1:
+ version "5.2.1"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+"safer-buffer@>= 2.1.2 < 3":
+ version "2.1.2"
+ resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
+sax@1.2.1:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz"
+ integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==
+
+schema-utils@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz"
+ integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
+ dependencies:
+ "@types/json-schema" "^7.0.8"
+ ajv "^6.12.5"
+ ajv-keywords "^3.5.2"
+
+schema-utils@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz"
+ integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
+ dependencies:
+ "@types/json-schema" "^7.0.8"
+ ajv "^6.12.5"
+ ajv-keywords "^3.5.2"
+
+schema-utils@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz"
+ integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ ajv "^8.8.0"
+ ajv-formats "^2.1.1"
+ ajv-keywords "^5.0.0"
+
+select-hose@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz"
+ integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
+
+selfsigned@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz"
+ integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==
+ dependencies:
+ node-forge "^1"
+
+semver@^6.0.0:
+ version "6.3.0"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^6.1.1:
+ version "6.3.0"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^6.1.2:
+ version "6.3.0"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^6.3.0:
+ version "6.3.0"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^7.3.2, semver@^7.3.8:
+ version "7.3.8"
+ resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz"
+ integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
+ dependencies:
+ lru-cache "^6.0.0"
+
+send@0.18.0:
+ version "0.18.0"
+ resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz"
+ integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
+ dependencies:
+ debug "2.6.9"
+ depd "2.0.0"
+ destroy "1.2.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ mime "1.6.0"
+ ms "2.1.3"
+ on-finished "2.4.1"
+ range-parser "~1.2.1"
+ statuses "2.0.1"
+
+serialize-javascript@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz"
+ integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==
+ dependencies:
+ randombytes "^2.1.0"
+
+serve-index@^1.9.1:
+ version "1.9.1"
+ resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz"
+ integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==
+ dependencies:
+ accepts "~1.3.4"
+ batch "0.6.1"
+ debug "2.6.9"
+ escape-html "~1.0.3"
+ http-errors "~1.6.2"
+ mime-types "~2.1.17"
+ parseurl "~1.3.2"
+
+serve-static@1.15.0:
+ version "1.15.0"
+ resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz"
+ integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
+ dependencies:
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ parseurl "~1.3.3"
+ send "0.18.0"
+
+setprototypeof@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz"
+ integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
+
+setprototypeof@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
+ integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+
+shallow-clone@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz"
+ integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
+ dependencies:
+ kind-of "^6.0.2"
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+side-channel@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
+ integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+ dependencies:
+ call-bind "^1.0.0"
+ get-intrinsic "^1.0.2"
+ object-inspect "^1.9.0"
+
+signal-exit@^3.0.3:
+ version "3.0.7"
+ resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
+slash@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz"
+ integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
+
+sockjs@^0.3.24:
+ version "0.3.24"
+ resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz"
+ integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==
+ dependencies:
+ faye-websocket "^0.11.3"
+ uuid "^8.3.2"
+ websocket-driver "^0.7.4"
+
+source-map-js@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+source-map-support@~0.5.20:
+ 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==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map@^0.6.0, source-map@~0.6.0:
+ version "0.6.1"
+ resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+spdy-transport@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz"
+ integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==
+ dependencies:
+ debug "^4.1.0"
+ detect-node "^2.0.4"
+ hpack.js "^2.1.6"
+ obuf "^1.1.2"
+ readable-stream "^3.0.6"
+ wbuf "^1.7.3"
+
+spdy@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz"
+ integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==
+ dependencies:
+ debug "^4.1.0"
+ handle-thing "^2.0.0"
+ http-deceiver "^1.2.7"
+ select-hose "^2.0.0"
+ spdy-transport "^3.0.0"
+
+"statuses@>= 1.4.0 < 2":
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
+ integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
+
+statuses@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
+ integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
+
+string_decoder@^1.1.1, string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+ dependencies:
+ safe-buffer "~5.1.0"
+
+strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-final-newline@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz"
+ integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+
+style-loader@^3.3.1:
+ version "3.3.1"
+ resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz"
+ integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==
+
+supports-color@^5.3.0:
+ version "5.5.0"
+ resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+ dependencies:
+ has-flag "^3.0.0"
+
+supports-color@^8.0.0:
+ version "8.1.1"
+ resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ 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==
+
+tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz"
+ integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+
+terser-webpack-plugin@^5.1.3:
+ version "5.3.6"
+ resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz"
+ integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.14"
+ jest-worker "^27.4.5"
+ schema-utils "^3.1.1"
+ serialize-javascript "^6.0.0"
+ terser "^5.14.1"
+
+terser@^5.10.0, terser@^5.14.1:
+ version "5.16.3"
+ resolved "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz"
+ integrity sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==
+ dependencies:
+ "@jridgewell/source-map" "^0.3.2"
+ acorn "^8.5.0"
+ commander "^2.20.0"
+ source-map-support "~0.5.20"
+
+three@^0.105.2:
+ version "0.105.2"
+ resolved "https://registry.npmjs.org/three/-/three-0.105.2.tgz"
+ integrity sha512-L3Al37k4g3hVbgFFS251UVtIc25chhyN0/RvXzR0C+uIBToV6EKDG+MZzEXm9L2miGUVMK27W46/VkP6WUZXMg==
+
+thunky@^1.0.2:
+ version "1.1.0"
+ resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz"
+ integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
+ integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
+
+to-regex-range@^5.0.1:
+ 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==
+ dependencies:
+ is-number "^7.0.0"
+
+toidentifier@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
+ integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
+
+tslib@^2.0.3, tslib@^2.2.0:
+ version "2.4.0"
+ resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
+type-is@~1.6.18:
+ version "1.6.18"
+ resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz"
+ integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.24"
+
+ua-parser-js@^1.0.2:
+ version "1.0.33"
+ resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz"
+ integrity sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==
+
+undici-types@~6.20.0:
+ version "6.20.0"
+ resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz"
+ integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
+
+unicode-canonical-property-names-ecmascript@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz"
+ integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==
+
+unicode-match-property-ecmascript@^2.0.0:
+ 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==
+ dependencies:
+ unicode-canonical-property-names-ecmascript "^2.0.0"
+ unicode-property-aliases-ecmascript "^2.0.0"
+
+unicode-match-property-value-ecmascript@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz"
+ integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==
+
+unicode-property-aliases-ecmascript@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz"
+ integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==
+
+unpipe@~1.0.0, unpipe@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
+ integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
+
+update-browserslist-db@^1.0.10:
+ version "1.0.10"
+ resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz"
+ integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
+ dependencies:
+ escalade "^3.1.1"
+ picocolors "^1.0.0"
+
+uri-js@^4.2.2:
+ version "4.4.1"
+ resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
+ integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+ dependencies:
+ punycode "^2.1.0"
+
+util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
+utila@~0.4:
+ version "0.4.0"
+ resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz"
+ integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==
+
+utils-merge@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
+ integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
+
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+vary@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
+ integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
+
+videojs-vtt.js@^0.15.4:
+ version "0.15.4"
+ resolved "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz"
+ integrity sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==
+ dependencies:
+ global "^4.3.1"
+
+watchpack@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz"
+ integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
+ dependencies:
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.1.2"
+
+wbuf@^1.1.0, wbuf@^1.7.3:
+ version "1.7.3"
+ resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz"
+ integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
+ dependencies:
+ minimalistic-assert "^1.0.0"
+
+webpack-cli@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz"
+ integrity sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==
+ dependencies:
+ "@discoveryjs/json-ext" "^0.5.0"
+ "@webpack-cli/configtest" "^2.1.0"
+ "@webpack-cli/info" "^2.0.1"
+ "@webpack-cli/serve" "^2.0.4"
+ colorette "^2.0.14"
+ commander "^10.0.1"
+ cross-spawn "^7.0.3"
+ envinfo "^7.7.3"
+ fastest-levenshtein "^1.0.12"
+ import-local "^3.0.2"
+ interpret "^3.1.1"
+ rechoir "^0.8.0"
+ webpack-merge "^5.7.3"
+
+webpack-dev-middleware@^5.3.1:
+ version "5.3.3"
+ resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz"
+ integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==
+ dependencies:
+ colorette "^2.0.10"
+ memfs "^3.4.3"
+ mime-types "^2.1.31"
+ range-parser "^1.2.1"
+ schema-utils "^4.0.0"
+
+webpack-dev-server@^4.11.1:
+ version "4.11.1"
+ resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz"
+ integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==
+ dependencies:
+ "@types/bonjour" "^3.5.9"
+ "@types/connect-history-api-fallback" "^1.3.5"
+ "@types/express" "^4.17.13"
+ "@types/serve-index" "^1.9.1"
+ "@types/serve-static" "^1.13.10"
+ "@types/sockjs" "^0.3.33"
+ "@types/ws" "^8.5.1"
+ ansi-html-community "^0.0.8"
+ bonjour-service "^1.0.11"
+ chokidar "^3.5.3"
+ colorette "^2.0.10"
+ compression "^1.7.4"
+ connect-history-api-fallback "^2.0.0"
+ default-gateway "^6.0.3"
+ express "^4.17.3"
+ graceful-fs "^4.2.6"
+ html-entities "^2.3.2"
+ http-proxy-middleware "^2.0.3"
+ ipaddr.js "^2.0.1"
+ open "^8.0.9"
+ p-retry "^4.5.0"
+ rimraf "^3.0.2"
+ schema-utils "^4.0.0"
+ selfsigned "^2.1.1"
+ serve-index "^1.9.1"
+ sockjs "^0.3.24"
+ spdy "^4.0.2"
+ webpack-dev-middleware "^5.3.1"
+ ws "^8.4.2"
+
+webpack-merge@^5.7.3:
+ version "5.8.0"
+ resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz"
+ integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
+ dependencies:
+ clone-deep "^4.0.1"
+ wildcard "^2.0.0"
+
+webpack-sources@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz"
+ integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
+
+webpack@^5.75.0:
+ version "5.75.0"
+ resolved "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz"
+ integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==
+ dependencies:
+ "@types/eslint-scope" "^3.7.3"
+ "@types/estree" "^0.0.51"
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/wasm-edit" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ acorn "^8.7.1"
+ acorn-import-assertions "^1.7.6"
+ browserslist "^4.14.5"
+ chrome-trace-event "^1.0.2"
+ enhanced-resolve "^5.10.0"
+ es-module-lexer "^0.9.0"
+ eslint-scope "5.1.1"
+ events "^3.2.0"
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.2.9"
+ json-parse-even-better-errors "^2.3.1"
+ loader-runner "^4.2.0"
+ mime-types "^2.1.27"
+ neo-async "^2.6.2"
+ schema-utils "^3.1.0"
+ tapable "^2.1.1"
+ terser-webpack-plugin "^5.1.3"
+ watchpack "^2.4.0"
+ webpack-sources "^3.2.3"
+
+websocket-driver@^0.7.4, websocket-driver@>=0.5.1:
+ version "0.7.4"
+ resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz"
+ integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
+ dependencies:
+ http-parser-js ">=0.5.1"
+ safe-buffer ">=5.1.0"
+ websocket-extensions ">=0.1.1"
+
+websocket-extensions@>=0.1.1:
+ version "0.1.4"
+ resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz"
+ integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
+
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+wildcard@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz"
+ integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+ws@^8.4.2:
+ version "8.12.0"
+ resolved "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz"
+ integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==
+
+yallist@^3.0.2:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
+ integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
+
+yallist@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
diff --git a/client/src/index.html b/client/index.html
similarity index 79%
rename from client/src/index.html
rename to client/index.html
index ce29e74..bae9af7 100644
--- a/client/src/index.html
+++ b/client/index.html
@@ -3,8 +3,8 @@
- <%= htmlWebpackPlugin.options.title %>
- <%= analytics %>
+ <%- title %>
+ <%- analytics %>
diff --git a/client/package-lock.json b/client/package-lock.json
index a10dd18..779ed43 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -1,93 +1,473 @@
{
"name": "kemono-2-client",
- "version": "1.0.0",
+ "version": "1.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "kemono-2-client",
- "version": "1.0.0",
+ "version": "1.4.0",
+ "hasInstallScript": true,
"license": "ISC",
"dependencies": {
- "@babel/runtime": "^7.22.10",
- "@uppy/core": "^3.4.0",
- "@uppy/dashboard": "^3.5.1",
- "@uppy/form": "^3.0.2",
- "@uppy/tus": "^3.1.3",
- "clsx": "^2.1.0",
- "diff": "^5.1.0",
- "fluid-player": "^3.22.0",
+ "@babel/runtime": "^7.26.7",
+ "@uppy/core": "^4.4.2",
+ "@uppy/dashboard": "^4.3.1",
+ "@uppy/form": "^4.1.1",
+ "@uppy/tus": "^4.2.2",
+ "clsx": "^2.1.1",
+ "diff": "^7.0.0",
+ "fluid-player": "file:./fluid-player",
"micromodal": "^0.4.10",
"purecss": "^3.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^2.0.5",
- "react-router-dom": "^6.24.0",
+ "react-router": "^7.1.5",
"sha256-wasm": "^2.2.2",
- "swagger-ui-react": "^5.17.14",
- "whatwg-fetch": "^3.6.17"
+ "swagger-ui-react": "^5.18.3"
},
"devDependencies": {
- "@babel/core": "^7.22.10",
- "@babel/plugin-transform-runtime": "^7.22.10",
- "@babel/preset-env": "^7.22.10",
- "@babel/preset-react": "^7.24.7",
- "@babel/preset-typescript": "^7.24.7",
- "@hyperjump/json-schema": "^1.9.3",
+ "@babel/core": "^7.26.8",
+ "@babel/plugin-transform-runtime": "^7.26.8",
+ "@babel/preset-env": "^7.26.8",
+ "@babel/preset-react": "^7.26.3",
+ "@babel/preset-typescript": "^7.26.0",
+ "@hyperjump/json-schema": "^1.11.0",
+ "@modyfi/vite-plugin-yaml": "^1.1.0",
"@types/micromodal": "^0.3.5",
- "@types/node": "^20.1.0",
+ "@types/node": "^22.13.1",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/sha256-wasm": "^2.2.3",
- "@types/swagger-ui-react": "^4.18.3",
+ "@types/swagger-ui-react": "^5.18.0",
"@types/webpack-bundle-analyzer": "^4.7.0",
- "babel-loader": "^8.3.0",
+ "@vitejs/plugin-legacy": "^6.0.1",
+ "@vitejs/plugin-react": "^4.3.4",
+ "ajv": "^8.17.1",
+ "babel-loader": "^9.2.1",
"buffer": "^6.0.3",
- "copy-webpack-plugin": "^8.1.1",
- "css-loader": "^5.2.7",
- "fs-extra": "^10.1.0",
- "html-webpack-plugin": "^5.5.3",
- "mini-css-extract-plugin": "^1.6.2",
- "postcss": "^8.4.28",
- "postcss-loader": "^7.3.3",
- "postcss-preset-env": "^9.1.1",
- "rimraf": "^3.0.2",
- "sass": "^1.66.0",
- "sass-loader": "^11.1.1",
+ "copy-webpack-plugin": "^12.0.2",
+ "css-loader": "^7.1.2",
+ "fs-extra": "^11.3.0",
+ "html-webpack-plugin": "^5.6.3",
+ "mini-css-extract-plugin": "^2.9.2",
+ "postcss": "^8.5.1",
+ "postcss-loader": "^8.1.1",
+ "postcss-preset-env": "^10.1.3",
+ "rimraf": "^6.0.1",
+ "sass": "^1.84.0",
+ "sass-loader": "^16.0.4 ",
"stream-browserify": "^3.0.0",
- "style-loader": "^2.0.0",
- "ts-loader": "^9.5.1",
- "typescript": "^5.3.3",
- "webpack": "^5.88.2",
+ "style-loader": "^4.0.0",
+ "terser": "^5.39.0",
+ "ts-loader": "^9.5.2",
+ "typescript": "^5.7.3",
+ "vite": "^6.1.0",
+ "vite-css-modules": "^1.8.4",
+ "vite-plugin-html": "^3.2.2",
+ "vite-plugin-static-copy": "^2.2.0",
+ "webpack": "^5.97.1",
"webpack-bundle-analyzer": "^4.10.2",
- "webpack-cli": "^5.1.4",
- "webpack-dev-server": "^4.15.1",
+ "webpack-cli": "^6.0.1",
+ "webpack-dev-server": "^5.2.0",
"webpack-manifest-plugin": "^5.0.0",
- "webpack-merge": "^5.9.0",
- "yaml": "^2.4.5"
+ "webpack-merge": "^6.0.1",
+ "yaml": "^2.7.0"
}
},
- "node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
- "dev": true,
+ "fluid-player": {
+ "version": "3.46.0",
+ "license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "dashjs": "^4.5.2",
+ "es6-promise": "^4.2.8",
+ "hls.js": "^1.5.13",
+ "panolens": "^0.12.1",
+ "videojs-vtt.js": "^0.15.4"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.12",
+ "@babel/preset-env": "^7.20.2",
+ "@playwright/test": "^1.49.0",
+ "@types/node": "^22.9.1",
+ "babel-loader": "^9.1.2",
+ "cheerio": "^1.0.0-rc.3",
+ "copy-webpack-plugin": "^11.0.0",
+ "css-loader": "^6.7.3",
+ "html-webpack-plugin": "^5.5.0",
+ "semver": "^7.3.2",
+ "style-loader": "^3.3.1",
+ "webpack": "^5.75.0",
+ "webpack-cli": "^5.1.1",
+ "webpack-dev-server": "^4.11.1"
+ }
+ },
+ "fluid-player/node_modules/@webpack-cli/info": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "fluid-player/node_modules/@webpack-cli/serve": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "fluid-player/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "fluid-player/node_modules/copy-webpack-plugin": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz",
+ "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-glob": "^3.2.11",
+ "glob-parent": "^6.0.1",
+ "globby": "^13.1.1",
+ "normalize-path": "^3.0.0",
+ "schema-utils": "^4.0.0",
+ "serialize-javascript": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ }
+ },
+ "fluid-player/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
+ }
+ }
+ },
+ "fluid-player/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"
+ }
+ },
+ "fluid-player/node_modules/globby": {
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
+ "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.3.0",
+ "ignore": "^5.2.4",
+ "merge2": "^1.4.1",
+ "slash": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "fluid-player/node_modules/html-entities": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
+ "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/mdevils"
+ },
+ {
+ "type": "patreon",
+ "url": "https://patreon.com/mdevils"
+ }
+ ],
+ "license": "MIT"
+ },
+ "fluid-player/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "fluid-player/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "fluid-player/node_modules/slash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
+ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "fluid-player/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"
+ }
+ },
+ "fluid-player/node_modules/webpack-cli": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
+ "colorette": "^2.0.14",
+ "commander": "^10.0.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "fluid-player/node_modules/webpack-dev-server": {
+ "version": "4.15.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz",
+ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/bonjour": "^3.5.9",
+ "@types/connect-history-api-fallback": "^1.3.5",
+ "@types/express": "^4.17.13",
+ "@types/serve-index": "^1.9.1",
+ "@types/serve-static": "^1.13.10",
+ "@types/sockjs": "^0.3.33",
+ "@types/ws": "^8.5.5",
+ "ansi-html-community": "^0.0.8",
+ "bonjour-service": "^1.0.11",
+ "chokidar": "^3.5.3",
+ "colorette": "^2.0.10",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^2.0.0",
+ "default-gateway": "^6.0.3",
+ "express": "^4.17.3",
+ "graceful-fs": "^4.2.6",
+ "html-entities": "^2.3.2",
+ "http-proxy-middleware": "^2.0.3",
+ "ipaddr.js": "^2.0.1",
+ "launch-editor": "^2.6.0",
+ "open": "^8.0.9",
+ "p-retry": "^4.5.0",
+ "rimraf": "^3.0.2",
+ "schema-utils": "^4.0.0",
+ "selfsigned": "^2.1.1",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.24",
+ "spdy": "^4.0.2",
+ "webpack-dev-middleware": "^5.3.4",
+ "ws": "^8.13.0"
+ },
+ "bin": {
+ "webpack-dev-server": "bin/webpack-dev-server.js"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.37.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack": {
+ "optional": true
+ },
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "fluid-player/node_modules/webpack-merge": {
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "fluid-player/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/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
@@ -95,34 +475,37 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
- "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
+ "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz",
- "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz",
+ "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.22.10",
- "@babel/generator": "^7.22.10",
- "@babel/helper-compilation-targets": "^7.22.10",
- "@babel/helper-module-transforms": "^7.22.9",
- "@babel/helpers": "^7.22.10",
- "@babel/parser": "^7.22.10",
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.10",
- "@babel/types": "^7.22.10",
- "convert-source-map": "^1.7.0",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.8",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.7",
+ "@babel/parser": "^7.26.8",
+ "@babel/template": "^7.26.8",
+ "@babel/traverse": "^7.26.8",
+ "@babel/types": "^7.26.8",
+ "@types/gensync": "^1.0.0",
+ "convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
- "json5": "^2.2.2",
+ "json5": "^2.2.3",
"semver": "^6.3.1"
},
"engines": {
@@ -134,55 +517,45 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
- "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz",
+ "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.25.6",
+ "@babel/parser": "^7.26.8",
+ "@babel/types": "^7.26.8",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
+ "jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
- "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz",
- "integrity": "sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.10"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz",
- "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
+ "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.9",
- "@babel/helper-validator-option": "^7.22.5",
- "browserslist": "^4.21.9",
+ "@babel/compat-data": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -191,18 +564,18 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
- "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+ "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/helper-replace-supers": "^7.25.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/traverse": "^7.25.4",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"semver": "^6.3.1"
},
"engines": {
@@ -213,13 +586,14 @@
}
},
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz",
- "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
+ "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "regexpu-core": "^5.3.1",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
"engines": {
@@ -230,10 +604,11 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz",
- "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+ "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
@@ -245,79 +620,44 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
- "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
- "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
- "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+ "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.8",
- "@babel/types": "^7.24.8"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
- "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.2"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -327,22 +667,22 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
- "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+ "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -350,14 +690,15 @@
}
},
"node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz",
- "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-wrap-function": "^7.22.9"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-wrap-function": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -367,15 +708,15 @@
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
- "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
+ "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/traverse": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -384,50 +725,24 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
- "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+ "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -435,9 +750,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -445,9 +760,9 @@
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -455,57 +770,42 @@
}
},
"node_modules/@babel/helper-wrap-function": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz",
- "integrity": "sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+ "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-function-name": "^7.22.5",
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.10"
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz",
- "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.10",
- "@babel/types": "^7.22.10"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz",
+ "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz",
+ "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.25.6"
+ "@babel/types": "^7.26.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -514,13 +814,47 @@
"node": ">=6.0.0"
}
},
- "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.22.5",
- "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.22.5.tgz",
- "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==",
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+ "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+ "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "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.25.9",
+ "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.25.9.tgz",
+ "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -530,14 +864,15 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz",
- "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -546,6 +881,23 @@
"@babel/core": "^7.13.0"
}
},
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+ "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "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",
@@ -558,76 +910,14 @@
"@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,
- "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,
- "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,
- "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-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz",
- "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -637,12 +927,13 @@
}
},
"node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz",
- "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -651,140 +942,14 @@
"@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,
- "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,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
- "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
+ "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.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,
- "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,
- "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,
- "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,
- "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,
- "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,
- "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,
- "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,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -794,13 +959,13 @@
}
},
"node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz",
- "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
+ "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -826,12 +991,13 @@
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz",
- "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+ "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -841,15 +1007,15 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz",
- "integrity": "sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
+ "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.9",
- "@babel/plugin-syntax-async-generators": "^7.8.4"
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-remap-async-to-generator": "^7.25.9",
+ "@babel/traverse": "^7.26.8"
},
"engines": {
"node": ">=6.9.0"
@@ -859,14 +1025,15 @@
}
},
"node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz",
- "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.5"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -876,12 +1043,13 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz",
- "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
+ "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -891,12 +1059,13 @@
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz",
- "integrity": "sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+ "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -906,13 +1075,14 @@
}
},
"node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz",
- "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+ "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -922,14 +1092,14 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz",
- "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -939,19 +1109,17 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz",
- "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+ "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.22.6",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"globals": "^11.1.0"
},
"engines": {
@@ -962,13 +1130,14 @@
}
},
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz",
- "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+ "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/template": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/template": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -978,12 +1147,13 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz",
- "integrity": "sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+ "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -993,13 +1163,14 @@
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz",
- "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+ "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1009,12 +1180,13 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz",
- "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+ "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1023,14 +1195,31 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz",
- "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==",
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+ "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1040,13 +1229,13 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz",
- "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+ "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1056,13 +1245,13 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz",
- "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+ "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1072,12 +1261,14 @@
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz",
- "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+ "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1087,14 +1278,15 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz",
- "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+ "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1104,13 +1296,13 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz",
- "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+ "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1120,12 +1312,13 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz",
- "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+ "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1135,13 +1328,13 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz",
- "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+ "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1151,12 +1344,13 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz",
- "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+ "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1166,13 +1360,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz",
- "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+ "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1182,15 +1377,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
- "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+ "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.8",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-simple-access": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1200,15 +1394,16 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz",
- "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+ "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1218,13 +1413,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz",
- "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+ "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1234,13 +1430,14 @@
}
},
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
- "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1250,12 +1447,13 @@
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz",
- "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+ "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1265,13 +1463,13 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz",
- "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==",
+ "version": "7.26.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
+ "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1281,13 +1479,13 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz",
- "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+ "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1297,16 +1495,15 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz",
- "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+ "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.22.5"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1316,13 +1513,14 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz",
- "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+ "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1332,13 +1530,13 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz",
- "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+ "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1348,14 +1546,14 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz",
- "integrity": "sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1365,12 +1563,13 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz",
- "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+ "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1380,13 +1579,14 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz",
- "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+ "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1396,15 +1596,15 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz",
- "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+ "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1414,12 +1614,13 @@
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz",
- "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+ "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1429,13 +1630,13 @@
}
},
"node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz",
- "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz",
+ "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1445,17 +1646,17 @@
}
},
"node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz",
- "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz",
+ "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/plugin-syntax-jsx": "^7.24.7",
- "@babel/types": "^7.25.2"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-syntax-jsx": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1465,13 +1666,45 @@
}
},
"node_modules/@babel/plugin-transform-react-jsx-development": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz",
- "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz",
+ "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.24.7"
+ "@babel/plugin-transform-react-jsx": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+ "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+ "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1481,14 +1714,14 @@
}
},
"node_modules/@babel/plugin-transform-react-pure-annotations": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz",
- "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz",
+ "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1498,12 +1731,13 @@
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz",
- "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+ "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.25.9",
"regenerator-transform": "^0.15.2"
},
"engines": {
@@ -1513,13 +1747,31 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz",
- "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==",
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+ "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+ "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1529,16 +1781,17 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.10.tgz",
- "integrity": "sha512-RchI7HePu1eu0CYNKHHHQdfenZcM4nz8rew5B1VWqeRKdcwW5aQ5HeG9eTUbWiAS1UrmHVLmoxTWHt3iLD/NhA==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz",
+ "integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "babel-plugin-polyfill-corejs2": "^0.4.5",
- "babel-plugin-polyfill-corejs3": "^0.8.3",
- "babel-plugin-polyfill-regenerator": "^0.5.2",
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.10.6",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
"semver": "^6.3.1"
},
"engines": {
@@ -1549,12 +1802,13 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz",
- "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+ "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1564,13 +1818,14 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz",
- "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+ "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1580,12 +1835,13 @@
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz",
- "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+ "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1595,12 +1851,13 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz",
- "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz",
+ "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1610,12 +1867,13 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz",
- "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz",
+ "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1625,17 +1883,17 @@
}
},
"node_modules/@babel/plugin-transform-typescript": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz",
- "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.8.tgz",
+ "integrity": "sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-create-class-features-plugin": "^7.25.0",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/plugin-syntax-typescript": "^7.24.7"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-syntax-typescript": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1645,12 +1903,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz",
- "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+ "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1660,13 +1919,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz",
- "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+ "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1676,13 +1936,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz",
- "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+ "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1692,13 +1953,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz",
- "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+ "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1708,90 +1970,80 @@
}
},
"node_modules/@babel/preset-env": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.10.tgz",
- "integrity": "sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz",
+ "integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.9",
- "@babel/helper-compilation-targets": "^7.22.10",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-option": "^7.22.5",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5",
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.22.5",
- "@babel/plugin-syntax-import-attributes": "^7.22.5",
- "@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",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.22.5",
- "@babel/plugin-transform-async-generator-functions": "^7.22.10",
- "@babel/plugin-transform-async-to-generator": "^7.22.5",
- "@babel/plugin-transform-block-scoped-functions": "^7.22.5",
- "@babel/plugin-transform-block-scoping": "^7.22.10",
- "@babel/plugin-transform-class-properties": "^7.22.5",
- "@babel/plugin-transform-class-static-block": "^7.22.5",
- "@babel/plugin-transform-classes": "^7.22.6",
- "@babel/plugin-transform-computed-properties": "^7.22.5",
- "@babel/plugin-transform-destructuring": "^7.22.10",
- "@babel/plugin-transform-dotall-regex": "^7.22.5",
- "@babel/plugin-transform-duplicate-keys": "^7.22.5",
- "@babel/plugin-transform-dynamic-import": "^7.22.5",
- "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
- "@babel/plugin-transform-export-namespace-from": "^7.22.5",
- "@babel/plugin-transform-for-of": "^7.22.5",
- "@babel/plugin-transform-function-name": "^7.22.5",
- "@babel/plugin-transform-json-strings": "^7.22.5",
- "@babel/plugin-transform-literals": "^7.22.5",
- "@babel/plugin-transform-logical-assignment-operators": "^7.22.5",
- "@babel/plugin-transform-member-expression-literals": "^7.22.5",
- "@babel/plugin-transform-modules-amd": "^7.22.5",
- "@babel/plugin-transform-modules-commonjs": "^7.22.5",
- "@babel/plugin-transform-modules-systemjs": "^7.22.5",
- "@babel/plugin-transform-modules-umd": "^7.22.5",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
- "@babel/plugin-transform-new-target": "^7.22.5",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5",
- "@babel/plugin-transform-numeric-separator": "^7.22.5",
- "@babel/plugin-transform-object-rest-spread": "^7.22.5",
- "@babel/plugin-transform-object-super": "^7.22.5",
- "@babel/plugin-transform-optional-catch-binding": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.22.10",
- "@babel/plugin-transform-parameters": "^7.22.5",
- "@babel/plugin-transform-private-methods": "^7.22.5",
- "@babel/plugin-transform-private-property-in-object": "^7.22.5",
- "@babel/plugin-transform-property-literals": "^7.22.5",
- "@babel/plugin-transform-regenerator": "^7.22.10",
- "@babel/plugin-transform-reserved-words": "^7.22.5",
- "@babel/plugin-transform-shorthand-properties": "^7.22.5",
- "@babel/plugin-transform-spread": "^7.22.5",
- "@babel/plugin-transform-sticky-regex": "^7.22.5",
- "@babel/plugin-transform-template-literals": "^7.22.5",
- "@babel/plugin-transform-typeof-symbol": "^7.22.5",
- "@babel/plugin-transform-unicode-escapes": "^7.22.10",
- "@babel/plugin-transform-unicode-property-regex": "^7.22.5",
- "@babel/plugin-transform-unicode-regex": "^7.22.5",
- "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
+ "@babel/plugin-transform-arrow-functions": "^7.25.9",
+ "@babel/plugin-transform-async-generator-functions": "^7.26.8",
+ "@babel/plugin-transform-async-to-generator": "^7.25.9",
+ "@babel/plugin-transform-block-scoped-functions": "^7.26.5",
+ "@babel/plugin-transform-block-scoping": "^7.25.9",
+ "@babel/plugin-transform-class-properties": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
+ "@babel/plugin-transform-classes": "^7.25.9",
+ "@babel/plugin-transform-computed-properties": "^7.25.9",
+ "@babel/plugin-transform-destructuring": "^7.25.9",
+ "@babel/plugin-transform-dotall-regex": "^7.25.9",
+ "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-dynamic-import": "^7.25.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.26.3",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-for-of": "^7.25.9",
+ "@babel/plugin-transform-function-name": "^7.25.9",
+ "@babel/plugin-transform-json-strings": "^7.25.9",
+ "@babel/plugin-transform-literals": "^7.25.9",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+ "@babel/plugin-transform-modules-amd": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.26.3",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+ "@babel/plugin-transform-modules-umd": "^7.25.9",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-new-target": "^7.25.9",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
+ "@babel/plugin-transform-numeric-separator": "^7.25.9",
+ "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+ "@babel/plugin-transform-object-super": "^7.25.9",
+ "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9",
+ "@babel/plugin-transform-private-methods": "^7.25.9",
+ "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+ "@babel/plugin-transform-property-literals": "^7.25.9",
+ "@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+ "@babel/plugin-transform-reserved-words": "^7.25.9",
+ "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+ "@babel/plugin-transform-spread": "^7.25.9",
+ "@babel/plugin-transform-sticky-regex": "^7.25.9",
+ "@babel/plugin-transform-template-literals": "^7.26.8",
+ "@babel/plugin-transform-typeof-symbol": "^7.26.7",
+ "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+ "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
"@babel/preset-modules": "0.1.6-no-external-plugins",
- "@babel/types": "^7.22.10",
- "babel-plugin-polyfill-corejs2": "^0.4.5",
- "babel-plugin-polyfill-corejs3": "^0.8.3",
- "babel-plugin-polyfill-regenerator": "^0.5.2",
- "core-js-compat": "^3.31.0",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.40.0",
"semver": "^6.3.1"
},
"engines": {
@@ -1801,6 +2053,20 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.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",
@@ -1816,18 +2082,18 @@
}
},
"node_modules/@babel/preset-react": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz",
- "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz",
+ "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-validator-option": "^7.24.7",
- "@babel/plugin-transform-react-display-name": "^7.24.7",
- "@babel/plugin-transform-react-jsx": "^7.24.7",
- "@babel/plugin-transform-react-jsx-development": "^7.24.7",
- "@babel/plugin-transform-react-pure-annotations": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-transform-react-display-name": "^7.25.9",
+ "@babel/plugin-transform-react-jsx": "^7.25.9",
+ "@babel/plugin-transform-react-jsx-development": "^7.25.9",
+ "@babel/plugin-transform-react-pure-annotations": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1837,17 +2103,17 @@
}
},
"node_modules/@babel/preset-typescript": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz",
- "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz",
+ "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-validator-option": "^7.24.7",
- "@babel/plugin-syntax-jsx": "^7.24.7",
- "@babel/plugin-transform-modules-commonjs": "^7.24.7",
- "@babel/plugin-transform-typescript": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-syntax-jsx": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.25.9",
+ "@babel/plugin-transform-typescript": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1856,16 +2122,11 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
- "dev": true
- },
"node_modules/@babel/runtime": {
- "version": "7.22.10",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz",
- "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz",
+ "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==",
+ "license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1874,9 +2135,9 @@
}
},
"node_modules/@babel/runtime-corejs3": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.6.tgz",
- "integrity": "sha512-Gz0Nrobx8szge6kQQ5Z5MX9L3ObqNwCQY1PSwSNzreFL7aHGxv8Fp2j3ETV6/wWdbiV+mW6OSm8oQhg3Tcsniw==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.7.tgz",
+ "integrity": "sha512-55gRV8vGrCIYZnaQHQrD92Lo/hYE3Sj5tmbuf0hhHR7sj2CWhEhHU89hbq+UVDXvFG1zUVXJhUkEq1eAfqXtFw==",
"license": "MIT",
"dependencies": {
"core-js-pure": "^3.30.2",
@@ -1887,32 +2148,32 @@
}
},
"node_modules/@babel/template": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
- "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz",
+ "integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/code-frame": "^7.26.2",
+ "@babel/parser": "^7.26.8",
+ "@babel/types": "^7.26.8"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
- "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz",
+ "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.6",
- "@babel/parser": "^7.25.6",
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.8",
+ "@babel/parser": "^7.26.8",
+ "@babel/template": "^7.26.8",
+ "@babel/types": "^7.26.8",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1921,30 +2182,29 @@
}
},
"node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz",
+ "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@braintree/sanitize-url": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.2.tgz",
- "integrity": "sha512-NVf/1YycDMs6+FxS0Tb/W8MjJRDQdXF+tBfDtZ5UZeiRUkTmwKc4vmYCKZTyymfJk1gnMsauvZSX/HiV9jOABw==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.4.tgz",
+ "integrity": "sha512-hPYRrKFoI+nuckPgDJfyYAkybFvheo4usS0Vw0HNAe+fmGBQA5Az37b/yStO284atBoqqdOUhKJ3d9Zw3PQkcQ==",
"license": "MIT"
},
"node_modules/@csstools/cascade-layer-name-parser": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.4.tgz",
- "integrity": "sha512-zXMGsJetbLoXe+gjEES07MEGjL0Uy3hMxmnGtVBrRpVKr5KV9OgCB09zr/vLrsEtoVQTgJFewxaU8IYSAE4tjg==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz",
+ "integrity": "sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA==",
"dev": true,
"funding": [
{
@@ -1956,18 +2216,19 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/color-helpers": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-3.0.0.tgz",
- "integrity": "sha512-rBODd1rY01QcenD34QxbQxLc1g+Uh7z1X/uzTHNQzJUnFCT9/EZYI7KWq+j0YfWMXJsRJ8lVkqBcB0R/qLr+yg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz",
+ "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==",
"dev": true,
"funding": [
{
@@ -1979,14 +2240,15 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
}
},
"node_modules/@csstools/css-calc": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.1.3.tgz",
- "integrity": "sha512-7mJZ8gGRtSQfQKBQFi5N0Z+jzNC0q8bIkwojP1W0w+APzEqHu5wJoGVsvKxVnVklu9F8tW1PikbBRseYnAdv+g==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz",
+ "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==",
"dev": true,
"funding": [
{
@@ -1998,18 +2260,19 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/css-color-parser": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-1.2.3.tgz",
- "integrity": "sha512-YaEnCoPTdhE4lPQFH3dU4IEk8S+yCnxS88wMv45JzlnMfZp57hpqA6qf2gX8uv7IJTJ/43u6pTQmhy7hCjlz7g==",
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz",
+ "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==",
"dev": true,
"funding": [
{
@@ -2021,22 +2284,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/color-helpers": "^3.0.0",
- "@csstools/css-calc": "^1.1.3"
+ "@csstools/color-helpers": "^5.0.1",
+ "@csstools/css-calc": "^2.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/css-parser-algorithms": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz",
- "integrity": "sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
+ "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
"dev": true,
"funding": [
{
@@ -2048,17 +2312,18 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/css-tokenizer": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz",
- "integrity": "sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
+ "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
"dev": true,
"funding": [
{
@@ -2070,14 +2335,15 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.4.tgz",
- "integrity": "sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz",
+ "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==",
"dev": true,
"funding": [
{
@@ -2089,18 +2355,19 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/postcss-cascade-layers": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-4.0.0.tgz",
- "integrity": "sha512-dVPVVqQG0FixjM9CG/+8eHTsCAxRKqmNh6H69IpruolPlnEF1611f2AoLK8TijTSAsqBSclKd4WHs1KUb/LdJw==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz",
+ "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==",
"dev": true,
"funding": [
{
@@ -2112,21 +2379,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^3.0.0",
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-color-function": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-3.0.1.tgz",
- "integrity": "sha512-+vrvCQeUifpMeyd42VQ3JPWGQ8cO19+TnGbtfq1SDSgZzRapCQO4aK9h/jhMOKPnxGzbA57oS0aHgP/12N9gSQ==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.7.tgz",
+ "integrity": "sha512-aDHYmhNIHR6iLw4ElWhf+tRqqaXwKnMl0YsQ/X105Zc4dQwe6yJpMrTN6BwOoESrkDjOYMOfORviSSLeDTJkdQ==",
"dev": true,
"funding": [
{
@@ -2138,23 +2406,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-color-mix-function": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-2.0.1.tgz",
- "integrity": "sha512-Z5cXkLiccKIVcUTe+fAfjUD7ZUv0j8rq3dSoBpM6I49dcw+50318eYrwUZa3nyb4xNx7ntNNUPmesAc87kPE2Q==",
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.7.tgz",
+ "integrity": "sha512-e68Nev4CxZYCLcrfWhHH4u/N1YocOfTmw67/kVX5Rb7rnguqqLyxPjhHWjSBX8o4bmyuukmNf3wrUSU3//kT7g==",
"dev": true,
"funding": [
{
@@ -2166,23 +2436,54 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-content-alt-text": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz",
+ "integrity": "sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-exponential-functions": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-1.0.0.tgz",
- "integrity": "sha512-FPndJ/7oGlML7/4EhLi902wGOukO0Nn37PjwOQGc0BhhjQPy3np3By4d3M8s9Cfmp9EHEKgUHRN2DQ5HLT/hTw==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.6.tgz",
+ "integrity": "sha512-IgJA5DQsQLu/upA3HcdvC6xEMR051ufebBTIXZ5E9/9iiaA7juXWz1ceYj814lnDYP/7eWjZnw0grRJlX4eI6g==",
"dev": true,
"funding": [
{
@@ -2194,22 +2495,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-calc": "^1.1.3",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-font-format-keywords": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-3.0.0.tgz",
- "integrity": "sha512-ntkGj+1uDa/u6lpjPxnkPcjJn7ChO/Kcy08YxctOZI7vwtrdYvFhmE476dq8bj1yna306+jQ9gzXIG/SWfOaRg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz",
+ "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==",
"dev": true,
"funding": [
{
@@ -2221,20 +2523,50 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-gamut-mapping": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.7.tgz",
+ "integrity": "sha512-gzFEZPoOkY0HqGdyeBXR3JP218Owr683u7KOZazTK7tQZBE8s2yhg06W1tshOqk7R7SWvw9gkw2TQogKpIW8Xw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-gradients-interpolation-method": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-4.0.1.tgz",
- "integrity": "sha512-IHeFIcksjI8xKX7PWLzAyigM3UvJdZ4btejeNa7y/wXxqD5dyPPZuY55y8HGTrS6ETVTRqfIznoCPtTzIX7ygQ==",
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.7.tgz",
+ "integrity": "sha512-WgEyBeg6glUeTdS2XT7qeTFBthTJuXlS9GFro/DVomj7W7WMTamAwpoP4oQCq/0Ki2gvfRYFi/uZtmRE14/DFA==",
"dev": true,
"funding": [
{
@@ -2246,23 +2578,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-hwb-function": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-3.0.1.tgz",
- "integrity": "sha512-FYe2K8EOYlL1BUm2HTXVBo6bWAj0xl4khOk6EFhQHy/C5p3rlr8OcetzQuwMeNQ3v25nB06QTgqUHoOUwoEqhA==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.7.tgz",
+ "integrity": "sha512-LKYqjO+wGwDCfNIEllessCBWfR4MS/sS1WXO+j00KKyOjm7jDW2L6jzUmqASEiv/kkJO39GcoIOvTTfB3yeBUA==",
"dev": true,
"funding": [
{
@@ -2274,22 +2608,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-ic-unit": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-3.0.0.tgz",
- "integrity": "sha512-FH3+zfOfsgtX332IIkRDxiYLmgwyNk49tfltpC6dsZaO4RV2zWY6x9VMIC5cjvmjlDO7DIThpzqaqw2icT8RbQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz",
+ "integrity": "sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA==",
"dev": true,
"funding": [
{
@@ -2301,21 +2638,46 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^3.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-initial": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.0.tgz",
+ "integrity": "sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-is-pseudo-class": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-4.0.0.tgz",
- "integrity": "sha512-0I6siRcDymG3RrkNTSvHDMxTQ6mDyYE8awkcaHNgtYacd43msl+4ZWDfQ1yZQ/viczVWjqJkLmPiRHSgxn5nZA==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz",
+ "integrity": "sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ==",
"dev": true,
"funding": [
{
@@ -2327,21 +2689,51 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^3.0.0",
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-light-dark-function": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz",
+ "integrity": "sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-float-and-clear": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-2.0.0.tgz",
- "integrity": "sha512-Wki4vxsF6icRvRz8eF9bPpAvwaAt0RHwhVOyzfoFg52XiIMjb6jcbHkGxwpJXP4DVrnFEwpwmrz5aTRqOW82kg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz",
+ "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==",
"dev": true,
"funding": [
{
@@ -2353,17 +2745,64 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-logical-overflow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz",
+ "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-logical-overscroll-behavior": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz",
+ "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-resize": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-2.0.0.tgz",
- "integrity": "sha512-lCQ1aX8c5+WI4t5EoYf3alTzJNNocMqTb+u1J9CINdDhFh1fjovqK+0aHalUHsNstZmzFPNzIkU4Mb3eM9U8SA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz",
+ "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==",
"dev": true,
"funding": [
{
@@ -2375,20 +2814,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-viewport-units": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-2.0.1.tgz",
- "integrity": "sha512-R5s19SscS7CHoxvdYNMu2Y3WDwG4JjdhsejqjunDB1GqfzhtHSvL7b5XxCkUWqm2KRl35hI6kJ4HEaCDd/3BXg==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz",
+ "integrity": "sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw==",
"dev": true,
"funding": [
{
@@ -2400,20 +2840,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-media-minmax": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.0.7.tgz",
- "integrity": "sha512-5LGLdu8cJgRPmvkjUNqOPKIKeHbyQmoGKooB5Rh0mp5mLaNI9bl+IjFZ2keY0cztZYsriJsGf6Lu8R5XetuwoQ==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.6.tgz",
+ "integrity": "sha512-J1+4Fr2W3pLZsfxkFazK+9kr96LhEYqoeBszLmFjb6AjYs+g9oDAw3J5oQignLKk3rC9XHW+ebPTZ9FaW5u5pg==",
"dev": true,
"funding": [
{
@@ -2425,23 +2867,24 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/css-calc": "^1.1.3",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/media-query-list-parser": "^2.1.4"
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/media-query-list-parser": "^4.0.2"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-2.0.2.tgz",
- "integrity": "sha512-kQJR6NvTRidsaRjCdHGjra2+fLoFiDQOm5B2aZrhmXqng/hweXjruboKzB326rxQO2L0m0T+gCKbZgyuncyhLg==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz",
+ "integrity": "sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ==",
"dev": true,
"funding": [
{
@@ -2453,22 +2896,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/media-query-list-parser": "^2.1.4"
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/media-query-list-parser": "^4.0.2"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-nested-calc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-3.0.0.tgz",
- "integrity": "sha512-HsB66aDWAouOwD/GcfDTS0a7wCuVWaTpXcjl5VKP0XvFxDiU+r0T8FG7xgb6ovZNZ+qzvGIwRM+CLHhDgXrYgQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz",
+ "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==",
"dev": true,
"funding": [
{
@@ -2480,20 +2924,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-normalize-display-values": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-3.0.0.tgz",
- "integrity": "sha512-6Nw55PRXEKEVqn3bzA8gRRPYxr5tf5PssvcE5DRA/nAxKgKtgNZMCHCSd1uxTCWeyLnkf6h5tYRSB0P1Vh/K/A==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz",
+ "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==",
"dev": true,
"funding": [
{
@@ -2505,20 +2951,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-oklab-function": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-3.0.1.tgz",
- "integrity": "sha512-3TIz+dCPlQPzz4yAEYXchUpfuU2gRYK4u1J+1xatNX85Isg4V+IbLyppblWLV4Vb6npFF8qsHN17rNuxOIy/6w==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.7.tgz",
+ "integrity": "sha512-I6WFQIbEKG2IO3vhaMGZDkucbCaUSXMxvHNzDdnfsTCF5tc0UlV3Oe2AhamatQoKFjBi75dSEMrgWq3+RegsOQ==",
"dev": true,
"funding": [
{
@@ -2530,23 +2977,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-progressive-custom-properties": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-3.0.0.tgz",
- "integrity": "sha512-2/D3CCL9DN2xhuUTP8OKvKnaqJ1j4yZUxuGLsCUOQ16wnDAuMLKLkflOmZF5tsPh/02VPeXRmqIN+U595WAulw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz",
+ "integrity": "sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q==",
"dev": true,
"funding": [
{
@@ -2558,20 +3007,49 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-random-function": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-1.0.2.tgz",
+ "integrity": "sha512-vBCT6JvgdEkvRc91NFoNrLjgGtkLWt47GKT6E2UDn3nd8ZkMBiziQ1Md1OiKoSsgzxsSnGKG3RVdhlbdZEkHjA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-relative-color-syntax": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-2.0.1.tgz",
- "integrity": "sha512-9B8br/7q0bjD1fV3yE22izjc7Oy5hDbDgwdFEz207cdJHYC9yQneJzP3H+/w3RgC7uyfEVhyyhkGRx5YAfJtmg==",
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.7.tgz",
+ "integrity": "sha512-apbT31vsJVd18MabfPOnE977xgct5B1I+Jpf+Munw3n6kKb1MMuUmGGH+PT9Hm/fFs6fe61Q/EWnkrb4bNoNQw==",
"dev": true,
"funding": [
{
@@ -2583,23 +3061,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-scope-pseudo-class": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-3.0.0.tgz",
- "integrity": "sha512-GFNVsD97OuEcfHmcT0/DAZWAvTM/FFBDQndIOLawNc1Wq8YqpZwBdHa063Lq+Irk7azygTT+Iinyg3Lt76p7rg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz",
+ "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==",
"dev": true,
"funding": [
{
@@ -2611,20 +3091,49 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-sign-functions": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.1.tgz",
+ "integrity": "sha512-MslYkZCeMQDxetNkfmmQYgKCy4c+w9pPDfgOBCJOo/RI1RveEUdZQYtOfrC6cIZB7sD7/PHr2VGOcMXlZawrnA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-stepped-value-functions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-3.0.1.tgz",
- "integrity": "sha512-y1sykToXorFE+5cjtp//xAMWEAEple0kcZn2QhzEFIZDDNvGOCp5JvvmmPGsC3eDlj6yQp70l9uXZNLnimEYfA==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.6.tgz",
+ "integrity": "sha512-/dwlO9w8vfKgiADxpxUbZOWlL5zKoRIsCymYoh1IPuBsXODKanKnfuZRr32DEqT0//3Av1VjfNZU9yhxtEfIeA==",
"dev": true,
"funding": [
{
@@ -2636,22 +3145,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-calc": "^1.1.3",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-text-decoration-shorthand": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-3.0.0.tgz",
- "integrity": "sha512-BAa1MIMJmEZlJ+UkPrkyoz3DC7kLlIl2oDya5yXgvUrelpwxddgz8iMp69qBStdXwuMyfPx46oZcSNx8Z0T2eA==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz",
+ "integrity": "sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw==",
"dev": true,
"funding": [
{
@@ -2663,21 +3173,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/color-helpers": "^3.0.0",
+ "@csstools/color-helpers": "^5.0.1",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-trigonometric-functions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-3.0.1.tgz",
- "integrity": "sha512-hW+JPv0MPQfWC1KARgvJI6bisEUFAZWSvUNq/khGCupYV/h6Z9R2ZFz0Xc633LXBst0ezbXpy7NpnPurSx5Klw==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.6.tgz",
+ "integrity": "sha512-c4Y1D2Why/PeccaSouXnTt6WcNHJkoJRidV2VW9s5gJ97cNxnLgQ4Qj8qOqkIR9VmTQKJyNcbF4hy79ZQnWD7A==",
"dev": true,
"funding": [
{
@@ -2689,22 +3200,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-calc": "^1.1.3",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0"
+ "@csstools/css-calc": "^2.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-unset-value": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-3.0.0.tgz",
- "integrity": "sha512-P0JD1WHh3avVyKKRKjd0dZIjCEeaBer8t1BbwGMUDtSZaLhXlLNBqZ8KkqHzYWXOJgHleXAny2/sx8LYl6qhEA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz",
+ "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==",
"dev": true,
"funding": [
{
@@ -2716,17 +3228,18 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/@csstools/selector-specificity": {
+ "node_modules/@csstools/selector-resolve-nested": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz",
- "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz",
+ "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==",
"dev": true,
"funding": [
{
@@ -2738,11 +3251,58 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
+ "node_modules/@csstools/selector-specificity": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz",
+ "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
+ "node_modules/@csstools/utilities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz",
+ "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
}
},
"node_modules/@discoveryjs/json-ext": {
@@ -2754,6 +3314,431 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
+ "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
+ "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
+ "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
+ "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
+ "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
+ "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
+ "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
+ "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
+ "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
+ "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
+ "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
+ "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
+ "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
+ "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
+ "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
+ "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
+ "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
+ "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
+ "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
+ "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
+ "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
+ "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@hyperjump/browser": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@hyperjump/browser/-/browser-1.1.4.tgz",
@@ -2787,9 +3772,9 @@
}
},
"node_modules/@hyperjump/json-schema": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/@hyperjump/json-schema/-/json-schema-1.9.3.tgz",
- "integrity": "sha512-NZyQ+PSQKUVIO0PInwqk2EOOObJD/ZqR9awzZeOddwtJyLZaxim9/xizZ6gGxGZi5ZGIdIB1mkBTM9fBu85E4A==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@hyperjump/json-schema/-/json-schema-1.11.0.tgz",
+ "integrity": "sha512-gX1YNObOybUW6tgJjvb1lomNbI/VnY+EBPokmEGy9Lk8cgi+gE0vXhX1XDgIpUUA4UXfgHEn5I1mga5vHgOttg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2848,6 +3833,53 @@
"url": "https://github.com/sponsors/jdesrosiers"
}
},
+ "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.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
@@ -2893,10 +3925,11 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
@@ -2909,11 +3942,84 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@jsonjoy.com/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/json-pack": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz",
+ "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/base64": "^1.1.1",
+ "@jsonjoy.com/util": "^1.1.2",
+ "hyperdyperid": "^1.2.0",
+ "thingies": "^1.20.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/util": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz",
+ "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
"node_modules/@leichtgewicht/ip-codec": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
- "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
- "dev": true
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@modyfi/vite-plugin-yaml": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@modyfi/vite-plugin-yaml/-/vite-plugin-yaml-1.1.0.tgz",
+ "integrity": "sha512-L26xfzkSo1yamODCAtk/ipVlL6OEw2bcJ92zunyHu8zxi7+meV0zefA9xscRMDCsMY8xL3C3wi3DhMiPxcbxbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "5.1.0",
+ "js-yaml": "4.1.0",
+ "tosource": "2.0.0-alpha.3"
+ },
+ "peerDependencies": {
+ "vite": "^3.2.7 || ^4.0.5 || ^5.0.5"
+ }
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
@@ -2950,6 +4056,346 @@
"node": ">= 8"
}
},
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
+ "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.5",
+ "node-addon-api": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.1",
+ "@parcel/watcher-darwin-arm64": "2.5.1",
+ "@parcel/watcher-darwin-x64": "2.5.1",
+ "@parcel/watcher-freebsd-x64": "2.5.1",
+ "@parcel/watcher-linux-arm-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm-musl": "2.5.1",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm64-musl": "2.5.1",
+ "@parcel/watcher-linux-x64-glibc": "2.5.1",
+ "@parcel/watcher-linux-x64-musl": "2.5.1",
+ "@parcel/watcher-win32-arm64": "2.5.1",
+ "@parcel/watcher-win32-ia32": "2.5.1",
+ "@parcel/watcher-win32-x64": "2.5.1"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
+ "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
+ "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
+ "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
+ "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
+ "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
+ "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
+ "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
+ "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
+ "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
+ "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
+ "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
+ "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
+ "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher/node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/@playwright/test": {
+ "version": "1.49.1",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz",
+ "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.49.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.28",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
@@ -2957,23 +4403,323 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@remix-run/router": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.0.tgz",
- "integrity": "sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==",
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
"engines": {
"node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.7.tgz",
+ "integrity": "sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.7.tgz",
+ "integrity": "sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.7.tgz",
+ "integrity": "sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.7.tgz",
+ "integrity": "sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.7.tgz",
+ "integrity": "sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.7.tgz",
+ "integrity": "sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.7.tgz",
+ "integrity": "sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.7.tgz",
+ "integrity": "sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.7.tgz",
+ "integrity": "sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.7.tgz",
+ "integrity": "sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.7.tgz",
+ "integrity": "sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.7.tgz",
+ "integrity": "sha512-vrDk9JDa/BFkxcS2PbWpr0C/LiiSLxFbNOBgfbW6P8TBe9PPHx9Wqbvx2xgNi1TOAyQHQJ7RZFqBiEohm79r0w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.7.tgz",
+ "integrity": "sha512-rB+ejFyjtmSo+g/a4eovDD1lHWHVqizN8P0Hm0RElkINpS0XOdpaXloqM4FBkF9ZWEzg6bezymbpLmeMldfLTw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.7.tgz",
+ "integrity": "sha512-nNXNjo4As6dNqRn7OrsnHzwTgtypfRA3u3AKr0B3sOOo+HkedIbn8ZtFnB+4XyKJojIfqDKmbIzO1QydQ8c+Pw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.7.tgz",
+ "integrity": "sha512-9kPVf9ahnpOMSGlCxXGv980wXD0zRR3wyk8+33/MXQIpQEOpaNe7dEHm5LMfyRZRNt9lMEQuH0jUKj15MkM7QA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.7.tgz",
+ "integrity": "sha512-7wJPXRWTTPtTFDFezA8sle/1sdgxDjuMoRXEKtx97ViRxGGkVQYovem+Q8Pr/2HxiHp74SSRG+o6R0Yq0shPwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.7.tgz",
+ "integrity": "sha512-MN7aaBC7mAjsiMEZcsJvwNsQVNZShgES/9SzWp1HC9Yjqb5OpexYnRjF7RmE4itbeesHMYYQiAtUAQaSKs2Rfw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.7.tgz",
+ "integrity": "sha512-aeawEKYswsFu1LhDM9RIgToobquzdtSc4jSVqHV8uApz4FVvhFl/mKh92wc8WpFc6aYCothV/03UjY6y7yLgbg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.7.tgz",
+ "integrity": "sha512-4ZedScpxxIrVO7otcZ8kCX1mZArtH2Wfj3uFCxRJ9NO80gg1XV0U/b2f/MKaGwj2X3QopHfoWiDQ917FRpwY3w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@scarf/scarf": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
+ "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+ "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@swagger-api/apidom-ast": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.9.tgz",
- "integrity": "sha512-SAOQrFSFwgDiI4QSIPDwAIJEb4Za+8bu45sNojgV3RMtCz+n4Agw66iqGsDib5YSI/Cg1h4AKFovT3iWdfGWfw==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.12.tgz",
+ "integrity": "sha512-KdJ+8PyYvfnHgpqrC0WWDRJLVx6+YkmYgAGpsdOa8S/p6btJdCUozeqpcXawmGqwAX/9jCXbmKdia3v3fUrP0w==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -2981,14 +4727,14 @@
}
},
"node_modules/@swagger-api/apidom-core": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-alpha.9.tgz",
- "integrity": "sha512-vGl8BWRf6ODl39fxElcIOjRE2QG5AJhn8tTNMqjjHB/2WppNBuxOVStYZeVJoWfK03OPK8v4Fp/TAcaP9+R7DQ==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.12.tgz",
+ "integrity": "sha512-CAr6aSk9l9ZJUneHpmwk4Br0NZhFLy2QRHoPmr2pWMlAn+0YC4eRYtwOEB8PVsCmP83D4MiXU5zi6cOZyV/cVw==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-ast": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-ast": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"minim": "~0.23.8",
"ramda": "~0.30.0",
@@ -2998,39 +4744,39 @@
}
},
"node_modules/@swagger-api/apidom-error": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-alpha.9.tgz",
- "integrity": "sha512-FU/2sFSgsICB9HYFELJ79caRpXXzlAV41QTHsAM46WfRehbzZUQpOBQm4jRi3qJGSa/Jk+mQ7Vt8HLRFMpJFfg==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.12.tgz",
+ "integrity": "sha512-p74a/8GgitGIYvjD5WmROEHv2bGCnDKug3QpJvC5+g36ErZQp428+fK5hhfKQuCo0rjD2fZvs27S17Zh8y0zFw==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7"
}
},
"node_modules/@swagger-api/apidom-json-pointer": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-alpha.9.tgz",
- "integrity": "sha512-/W8Ktbgbs29zdhed6KHTFk0qmuIRbvEFi8wu2MHGQ5UT4i99Bdu2OyUiayhnpejWztfQxDgL08pjrQPEwgY8Yg==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.12.tgz",
+ "integrity": "sha512-JuCqMVfDSWJ7JcdPjYgGjNlqjmKQwxuQh7uKKBLTpNccmXYT+x7WemPuzcWjVVHDd5plw8yQ0YvaU0HlqjS1mA==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-ns-api-design-systems": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-alpha.9.tgz",
- "integrity": "sha512-aduC2vbwGgn6ia9IkKpqBYBaKyIDGM/80M3oU3DFgaYIIwynzuwVpN1TkBOLIFy3mAzkWoYKUS0jdZJhMy/6Ug==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.12.tgz",
+ "integrity": "sha512-D4MAnm1Jiame1KfxkboYU/gRsvlDaplFE3SGjdg/dG3vTOHWXzm5ta8pEf3naPuo8+fXt0rcMxf2edaFHnPLWA==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3038,30 +4784,62 @@
}
},
"node_modules/@swagger-api/apidom-ns-asyncapi-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-hZjxXJgMt517ADnAauWJh01k7WNRwkbWT5p6b7AXF2H3tl549A2hhLnIg3BBSE3GwB3Nv25GyrI3aA/1dFVC8A==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-3R1AdZdUNo2rw9PudkWfP0f556DFTjUn9mBdbLHQPhcmdIRTJQAMDNy2FhN6ZiEg4ggG31Hyk2AY/97CAxHd6A==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
"ts-mixer": "^6.0.3"
}
},
- "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-alpha.9.tgz",
- "integrity": "sha512-OfX4UBb08C0xD5+F80dQAM2yt5lXxcURWkVEeCwxz7i23BB3nNEbnZXNV91Qo9eaJflPh8dO9iiHQxvfw5IgSg==",
+ "node_modules/@swagger-api/apidom-ns-json-schema-2019-09": {
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.12.tgz",
+ "integrity": "sha512-mrcWwAfCcUDiPrGymowZqnrOpOk7hUNDkW9WjsMe3bFiTrCm4EsQYvGtyWAtB/0yo7hNBMGXYEtDWfGBsw8AyA==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-ast": "^1.0.0-alpha.9",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.12",
+ "@types/ramda": "~0.30.0",
+ "ramda": "~0.30.0",
+ "ramda-adjunct": "^5.0.0",
+ "ts-mixer": "^6.0.4"
+ }
+ },
+ "node_modules/@swagger-api/apidom-ns-json-schema-2020-12": {
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.12.tgz",
+ "integrity": "sha512-SW0Jtty3o12OwpTAVJEewurvTSIhxJ72TZlMSk5L36jvekzqKfLL7aBYRCEE9QkV3rxTjxOf0WK/tYLRMKUbzw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-2019-09": "^1.0.0-beta.12",
+ "@types/ramda": "~0.30.0",
+ "ramda": "~0.30.0",
+ "ramda-adjunct": "^5.0.0",
+ "ts-mixer": "^6.0.4"
+ }
+ },
+ "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": {
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.12.tgz",
+ "integrity": "sha512-Z3PnEEdkGnr6zomFAgmkkDGrwlj3bbbEJBfXsshxRuXf3i5RymiURFy42CfKa5Tmx3rw8rSw393p0TkHqS0NIg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-ast": "^1.0.0-beta.12",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3069,16 +4847,15 @@
}
},
"node_modules/@swagger-api/apidom-ns-json-schema-draft-6": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-alpha.9.tgz",
- "integrity": "sha512-qzUVRSSrnlYGMhK6w57o/RboNvy1FO0iFgEnTk56dD4wN49JRNuFqKI18IgXc1W2r9tTTG70nG1khe4cPE8TNg==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.12.tgz",
+ "integrity": "sha512-QvubeYZvRd19Q8VVP4xGGYTuSVgLQqEp/epe8LXcrFJvgF6A9CTUxkfKVxL4+Q5a9DFaKTZKNYwkRaPzisvnWQ==",
"license": "Apache-2.0",
- "optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3086,16 +4863,15 @@
}
},
"node_modules/@swagger-api/apidom-ns-json-schema-draft-7": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-alpha.9.tgz",
- "integrity": "sha512-Zml8Z8VCckdFjvTogaec1dabd85hg1+xZDseWcCuD0tYkaTY/sZ8zzI0dz6/4HsKCb58qjiWSa0w60N8Syr6WQ==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.12.tgz",
+ "integrity": "sha512-UIU/vY5xBhYeBEykmXMvQRaIXqWWNWc/RPG5L8LrfILoZhzZbjqcdRMf5w4wQWqteQxXxkpDdkcHVBsJxcQtJg==",
"license": "Apache-2.0",
- "optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3103,16 +4879,16 @@
}
},
"node_modules/@swagger-api/apidom-ns-openapi-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-WUZxt7Gs7P4EQsGtoD6cKAjf0uDJhkUxsIW9Bb4EAgO6tdp7LlXhbJ0fJ2QycCLY717SfJbvGLfhuSfTYo4Iow==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-61I3NcH2agyPmNXW7JOoxshjVr7YVekHnEaYfl3VYTc0mT2KcRhcDWM0cufQdGeIJPR9SdFcSZ01aRQUUTj3fQ==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3120,15 +4896,15 @@
}
},
"node_modules/@swagger-api/apidom-ns-openapi-3-0": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-alpha.9.tgz",
- "integrity": "sha512-7ra5uoZGrfCn1LabfJLueChPcYXyg24//LCYBtjTstyueqd5Vp7JCPeP5NnJSAaqVAP47r8ygceBPoxNp9k1EQ==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.12.tgz",
+ "integrity": "sha512-6TWUagR1/Y9HB8t75/vrkHHDV5c5K0S72Wywx7PoDyNgQ1Jxy3p6iwuSHfTwJYH+/hAxg3f91i6HXXyrHB5RAg==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3136,16 +4912,17 @@
}
},
"node_modules/@swagger-api/apidom-ns-openapi-3-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-nQOwNQgf0C8EVjf2loAAl4ifRuVOdcqycvXUdcTpsUfHN3fbndR8IKpb26mQNmnACmqgmX+LkbMdW9b+K6089g==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-IayaLSawWo5rAyM2nRY6faTfK8cJQ+mGGR94NOmsjcUQw9IljY9uX7PXj3izOdFlXFYjgR1P+mIhuuXyDuw4qg==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-ast": "^1.0.0-alpha.9",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-ast": "^1.0.0-beta.12",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-json-pointer": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3153,15 +4930,15 @@
}
},
"node_modules/@swagger-api/apidom-ns-workflows-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-yKo0p8OkQmDib93Kt1yqWmI7JsD6D9qUHxr/SCuAmNNWny1hxm7cZGoKJwJlGd0uAg84j4vmzWOlG3AsJbnT8g==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-ALQbORmsql7HJjlCWMzOfTIqc0O0gCJbp3je+uzp2Y3Cu2BlQgu7aZAGly+GdM1rWNJosm0ZOGG1KTfgJaTZxw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
@@ -3169,272 +4946,336 @@
}
},
"node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-alpha.9.tgz",
- "integrity": "sha512-xfVMR4HrTzXU0HB4TtxwkNbUIa/cQrPa0BWutJZ0fMYMAtUox2s8GsFYnJfZP52XfpSHFM1VPclivorZqET14g==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.12.tgz",
+ "integrity": "sha512-DjFZmSmoMmSu9gHWcpWGuaZd5o2eD5xkhHwL2QjvFvH7UXBxxhrx89RwNmHt1Hy5De4fV+zlB/7TsL7FsV4i8Q==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-alpha.9.tgz",
- "integrity": "sha512-lJZkrhZ8qRTtc5fSLKefCv8j7Xzo8UBfMjpqTJhmETAtU8YfVV2i2znjgxJpm0QwV6FVQqGfK1+ASZQWPLiVcA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.12.tgz",
+ "integrity": "sha512-bWJ0KylVPNeAqI/KPqaT1PfmIlWFx7fY5MBsIccn9iSB880oUSB+XLmIRpFBOSh5iPM7Dn6GTg3gdnVJRk5fNA==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-65nmKdPzw4C1bmtYn+3zoxXCI6Gnobr0StI9XE0YWiK+lpso7RH3Cgyl1yPZ0DBRVGzP+Fn9FVzmDNulEfR95w==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-UAbPIKHNYUy4MOWGyPSkafgipX0zwndSidqG9AUzeDe4t5yldnBRPnCTnUHecSqktIzq5Tz6mViNTc1/uY9lOg==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-RLI4FpVB3vB6mIuT77yrsv5V2LMZ80dW9XpV+Fmbd4Jkdj+ysAFwT38cI4AsUMOxixpTDIXY1oWD7AjvylHhQQ==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-gT6Z2ReDxELPE6ZzDxf/wQM+AcG13eXGLDcYTOOKacBruWsh8Aa/iF9ZW0DlJckE+vlDgvbhlkxsiHIExOY41g==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-json": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-alpha.9.tgz",
- "integrity": "sha512-aOewp8/3zobf/O+5Jx8y7+bX3BPRfRlHIv15qp4YVTsLs6gLISWSzTO9JpWe9cR+AfhpsAalFq4t1LwIkmLk4A==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.12.tgz",
+ "integrity": "sha512-Bt7oCylNzf49MRsnnWayIqh2QBIVRGq35k/dcmb0J8QP94GDLfbOCXn0kvuRJvQIK/aJFlBFVMVn47GKQibqfg==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-ast": "^1.0.0-alpha.9",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-ast": "^1.0.0-beta.12",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
- "tree-sitter": "=0.20.4",
- "tree-sitter-json": "=0.20.2",
- "web-tree-sitter": "=0.20.3"
+ "tree-sitter": "=0.22.1",
+ "tree-sitter-json": "=0.24.8",
+ "web-tree-sitter": "=0.24.5"
+ }
+ },
+ "node_modules/@swagger-api/apidom-parser-adapter-json/node_modules/node-addon-api": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz",
+ "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
+ "node_modules/@swagger-api/apidom-parser-adapter-json/node_modules/tree-sitter": {
+ "version": "0.22.1",
+ "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.1.tgz",
+ "integrity": "sha512-gRO+jk2ljxZlIn20QRskIvpLCMtzuLl5T0BY6L9uvPYD17uUrxlxWkvYCiVqED2q2q7CVtY52Uex4WcYo2FEXw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-addon-api": "^8.2.1",
+ "node-gyp-build": "^4.8.2"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-zgtsAfkplCFusX2P/saqdn10J8P3kQizCXxHLvxd2j0EhMJk2wfu4HYN5Pej/7/qf/OR1QZxqtacwebd4RfpXA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-zMrLeDvDOCGgMNYMW9iuAlOtA+mCa4msBM70tgVdg/89SdS4K5MxVptmpRHQAODdv1oErm2ChVmzFcuPHH38qw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-alpha.9.tgz",
- "integrity": "sha512-iPuHf0cAZSUhSv8mB0FnVgatTc26cVYohgqz2cvjoGofdqoh5KKIfxOkWlIhm+qGuBp71CfZUrPYPRsd0dHgeg==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.12.tgz",
+ "integrity": "sha512-tJznOQ+8iEOfKU01hLt6FHLgsRfd5zugnNFuNTvS7oJt6xtQ9vqFS/uKajMSOq6p+irAF6dWI+C5f+1AdDOvnw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-jwkfO7tzZyyrAgok+O9fKFOv1q/5njMb9DBc3D/ZF3ZLTcnEw8uj4V2HkjKxUweH5k8ip/gc8ueKmO/i7p2fng==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-HLToO8Jqo06p70h3MWA2FkkNSfRi2M9fjNW3V94nCb6ECMIfgppgw+FDwawskvBNH6RfZqN7OBgq19Vly/sgbw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-jEIDpjbjwFKXQXS/RHJeA4tthsguLoz+nJPYS3AOLfuSiby5QXsKTxgqHXxG/YJqF1xJbZL+5KcF8UyiDePumw==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-mdg1/80lkoMVla3rvH7GeIuyj70YONJ3CnnBKJ/FIsFjgAViiC3mT5UnP6HmNQ+ZhAl1IvTmkdeI4GQsNtuW/g==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-alpha.9.tgz",
- "integrity": "sha512-ieJL8dfIF8fmP3uJRNh/duJa3cCIIv6MzUe6o4uPT/oTDroy4qIATvnq9Dq/gtAv6rcPRpA9VhyghJ1DmjKsZQ==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.12.tgz",
+ "integrity": "sha512-vUgsJjoItuL+6yOxAFzuMEdPsL3qzwvqZnlwXSPXyCdnzrChzfmWM083LvxyyuQQaBRAhzoYcxSsavZq9MQuUg==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-EatIH7PZQSNDsRn9ompc62MYzboY7wAkjfYz+2FzBaSA8Vl5/+740qGQj22tu/xhwW4K72aV2NNL1m47QVF7hA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-HHKxKrs99UZmymMScnyEz8VYwicJj78H0iLsuYjIJDggtvKx/kHxTM16/vAe9et7q/uP+BqP/hyUKNeS7n23Kw==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-LylC2cQdAmvR7bXqwMwBt6FHTMVGinwIdI8pjl4EbPT9hCVm1rdED53caTYM4gCm+CJGRw20r4gb9vn3+N6RrA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-soKD4N7JUvgiPRdsWGJ53itp5mcueoSvb6ikcMneEOu9wxL3y40aCK5Vb76UuVKRZmqWRXpgs3kl5oL34Bno9Q==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-alpha.9.tgz",
- "integrity": "sha512-TlA4+1ca33D7fWxO5jKBytSCv86IGI4Lze4JfrawWUXZ5efhi4LiNmW5TrGlZUyvL7yJtZcA4tn3betlj6jVwA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-beta.12.tgz",
+ "integrity": "sha512-+1GZknZH3shdViUubKTCOolZzday+h3Cxp9PQDb8LgGJcxu40HHf44YZdZNsmkDLXqd2t7+NGbt2EXum7CTgtA==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.9",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.12",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
}
},
"node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-alpha.9.tgz",
- "integrity": "sha512-jSIHEB7lbh+MP3BhYIXFkeivDR01kugXN70e5FskW7oet2TIARsVEPheWKQFSP1U8bUZA4bsp9h9gOQ9xEeErw==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.12.tgz",
+ "integrity": "sha512-SP5Sz1ywsW3vZxrl+/NBGDNvP/rZJ8tm8+0OQJ+HISwcpwSR92rYDUEYBuuxPX1Bw4c1V0UkQqqEVf59NksCsQ==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-ast": "^1.0.0-alpha.9",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
- "@swagger-api/apidom-error": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-ast": "^1.0.0-beta.12",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
+ "@swagger-api/apidom-error": "^1.0.0-beta.12",
+ "@tree-sitter-grammars/tree-sitter-yaml": "=0.7.0",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0",
- "tree-sitter": "=0.20.4",
- "tree-sitter-yaml": "=0.5.0",
- "web-tree-sitter": "=0.20.3"
+ "tree-sitter": "=0.22.1",
+ "web-tree-sitter": "=0.24.5"
+ }
+ },
+ "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/@tree-sitter-grammars/tree-sitter-yaml": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@tree-sitter-grammars/tree-sitter-yaml/-/tree-sitter-yaml-0.7.0.tgz",
+ "integrity": "sha512-GOMIK3IaDvECD0eZEhAsLl03RMtM1E8StxuGMn6PpMKFg7jyQ+jSzxJZ4Jmc/tYitah9/AECt8o4tlRQ5yEZQg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-addon-api": "^8.3.0",
+ "node-gyp-build": "^4.8.4"
+ },
+ "peerDependencies": {
+ "tree-sitter": "^0.22.1"
+ },
+ "peerDependenciesMeta": {
+ "tree-sitter": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/node-addon-api": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz",
+ "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
+ "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/tree-sitter": {
+ "version": "0.22.1",
+ "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.1.tgz",
+ "integrity": "sha512-gRO+jk2ljxZlIn20QRskIvpLCMtzuLl5T0BY6L9uvPYD17uUrxlxWkvYCiVqED2q2q7CVtY52Uex4WcYo2FEXw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-addon-api": "^8.2.1",
+ "node-gyp-build": "^4.8.2"
}
},
"node_modules/@swagger-api/apidom-reference": {
- "version": "1.0.0-alpha.9",
- "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-alpha.9.tgz",
- "integrity": "sha512-KQ6wB5KplqdSsjxdA8BaQulj5zlF5VBCd5KP3RN/9vvixgsD/gyrVY59nisdzmPTqiL6yjhk612eQ96MgG8KiA==",
+ "version": "1.0.0-beta.12",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.12.tgz",
+ "integrity": "sha512-4A5dvra9NCsl9Dp3x3UyNV3tyTl1LJwvNowaLfMuY5r8jtQLzkcCW+CLPyP2Y64qeT30sklZp7/M3VVd6jKPOg==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
- "@swagger-api/apidom-core": "^1.0.0-alpha.9",
+ "@swagger-api/apidom-core": "^1.0.0-beta.12",
"@types/ramda": "~0.30.0",
- "axios": "^1.4.0",
+ "axios": "^1.7.4",
"minimatch": "^7.4.3",
"process": "^0.11.10",
"ramda": "~0.30.0",
"ramda-adjunct": "^5.0.0"
},
"optionalDependencies": {
- "@swagger-api/apidom-error": "^1.0.0-alpha.1",
- "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.1",
- "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.1",
- "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-workflows-json-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-workflows-yaml-1": "^1.0.0-alpha.1",
- "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.1"
+ "@swagger-api/apidom-error": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-json-pointer": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-workflows-json-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-workflows-yaml-1": "^1.0.0-beta.3 <1.0.0-rc.0",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.3 <1.0.0-rc.0"
}
},
"node_modules/@swagger-api/apidom-reference/node_modules/brace-expansion": {
@@ -3461,80 +5302,152 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/@swaggerexpert/cookie": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@swaggerexpert/cookie/-/cookie-1.4.1.tgz",
+ "integrity": "sha512-ZRbRC2017wMs+uZeIOC55ghwgbTxeolo+s6I0njzqina7MTrOhz8WMfTj0KGk3hfBUO/yhTQD/aQZ0lQHEIKxQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "apg-lite": "^1.0.3"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
"node_modules/@transloadit/prettier-bytes": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.9.tgz",
- "integrity": "sha512-pCvdmea/F3Tn4hAtHqNXmjcixSaroJJ+L3STXlYJdir1g1m2mRQpWbN8a4SvgQtaw2930Ckhdx8qXdXBFMKbAA=="
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.3.5.tgz",
+ "integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==",
+ "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.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "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.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
},
"node_modules/@types/body-parser": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
- "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "version": "1.19.5",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
+ "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/bonjour": {
- "version": "3.5.10",
- "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz",
- "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz",
+ "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/connect": {
- "version": "3.4.35",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
- "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/connect-history-api-fallback": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
- "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz",
+ "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express-serve-static-core": "*",
"@types/node": "*"
}
},
+ "node_modules/@types/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
- "version": "8.44.2",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz",
- "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==",
+ "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.4",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
- "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "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.1",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
- "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
- "dev": true
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/express": {
- "version": "4.17.17",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
- "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
+ "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -3543,10 +5456,11 @@
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "4.17.35",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
- "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
+ "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
@@ -3554,6 +5468,26 @@
"@types/send": "*"
}
},
+ "node_modules/@types/express/node_modules/@types/express-serve-static-core": {
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/gensync": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz",
+ "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/hast": {
"version": "2.3.10",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
@@ -3570,16 +5504,18 @@
"dev": true
},
"node_modules/@types/http-errors": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
- "dev": true
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
+ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/http-proxy": {
- "version": "1.17.11",
- "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz",
- "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==",
+ "version": "1.17.16",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz",
+ "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
@@ -3598,16 +5534,31 @@
"license": "MIT"
},
"node_modules/@types/mime": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
- "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
- "dev": true
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.5.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz",
- "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==",
- "dev": true
+ "version": "22.13.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
+ "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/node-forge": {
+ "version": "1.3.11",
+ "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz",
+ "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
},
"node_modules/@types/prop-types": {
"version": "15.7.12",
@@ -3616,10 +5567,11 @@
"devOptional": true
},
"node_modules/@types/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
- "dev": true
+ "version": "6.9.18",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
+ "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/ramda": {
"version": "0.30.2",
@@ -3631,10 +5583,11 @@
}
},
"node_modules/@types/range-parser": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
- "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
- "dev": true
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/react": {
"version": "18.2.73",
@@ -3659,36 +5612,40 @@
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/send": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
- "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
+ "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-index": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
- "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==",
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz",
+ "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/serve-static": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
- "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/http-errors": "*",
- "@types/mime": "*",
- "@types/node": "*"
+ "@types/node": "*",
+ "@types/send": "*"
}
},
"node_modules/@types/sha256-wasm": {
@@ -3702,18 +5659,19 @@
}
},
"node_modules/@types/sockjs": {
- "version": "0.3.33",
- "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz",
- "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==",
+ "version": "0.3.36",
+ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz",
+ "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/swagger-ui-react": {
- "version": "4.18.3",
- "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz",
- "integrity": "sha512-Mo/R7IjDVwtiFPs84pWvh5pI9iyNGBjmfielxqbOh2Jv+8WVSDVe8Nu25kb5BOuV2xmGS3o33jr6nwDJMBcX+Q==",
+ "version": "5.18.0",
+ "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-5.18.0.tgz",
+ "integrity": "sha512-c2M9adVG7t28t1pq19K9Jt20VLQf0P/fwJwnfcmsVVsdkwCWhRmbKDu+tIs0/NGwJ/7GY8lBx+iKZxuDI5gDbw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3745,340 +5703,448 @@
}
},
"node_modules/@types/ws": {
- "version": "8.5.5",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz",
- "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==",
+ "version": "8.5.14",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
+ "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@uppy/companion-client": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-3.3.0.tgz",
- "integrity": "sha512-ogU0QieutbM0A6/yxK91w1Ge4KTC+eAGQMk6JKZu58b435dLScRTCsWGFSSIvt1U8RDY7YDCyl51zawh+A+5CQ==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-4.4.1.tgz",
+ "integrity": "sha512-ardMacShsfzaIbqHEH48YlpzWZkBj1qhAj0Dvn3r31p9d0HA5xFUvAdLYrZ6ezKvZ0RcDbf0SB5qCrQMkjscXQ==",
+ "license": "MIT",
"dependencies": {
- "@uppy/utils": "^5.4.3",
- "namespace-emitter": "^2.0.1"
+ "@uppy/utils": "^6.1.1",
+ "namespace-emitter": "^2.0.1",
+ "p-retry": "^6.1.0"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^4.4.1"
+ }
+ },
+ "node_modules/@uppy/companion-client/node_modules/@types/retry": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
+ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
+ "license": "MIT"
+ },
+ "node_modules/@uppy/companion-client/node_modules/p-retry": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
+ "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.2",
+ "is-network-error": "^1.0.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@uppy/companion-client/node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
}
},
"node_modules/@uppy/core": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/@uppy/core/-/core-3.4.0.tgz",
- "integrity": "sha512-95NNyXZfuNfB6sgna41fNNPRuTqjrHdlVzkXaJlZzghAckIxNz2CoeMYA1rtgn9o8ykKa2Zdz4kk2MEq8Qy4fw==",
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@uppy/core/-/core-4.4.2.tgz",
+ "integrity": "sha512-df0fQtPEd5W/e5M/CWIXQb/O0rBb+LCz4HTN5Bkqm0UDzW2JFR9mrxnL0dfh3ikVlUq+9vNjAeBr9P0aluIiFg==",
+ "license": "MIT",
"dependencies": {
- "@transloadit/prettier-bytes": "0.0.9",
- "@uppy/store-default": "^3.0.3",
- "@uppy/utils": "^5.4.3",
+ "@transloadit/prettier-bytes": "^0.3.4",
+ "@uppy/store-default": "^4.2.0",
+ "@uppy/utils": "^6.1.2",
"lodash": "^4.17.21",
"mime-match": "^1.0.2",
"namespace-emitter": "^2.0.1",
- "nanoid": "^4.0.0",
+ "nanoid": "^5.0.9",
"preact": "^10.5.13"
}
},
"node_modules/@uppy/dashboard": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-3.5.1.tgz",
- "integrity": "sha512-Fb3FFg4n3QuoLsFb2Cp2wnlEXJ9bYq/uy4d68USqrkAAHiFiT+/y07Lvrf2BN4H5UFCzWEMhgaBrwo792DwxjQ==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-4.3.1.tgz",
+ "integrity": "sha512-I/D4mL48ZYVu3yztv0hdNGcWj37kxXWfpFeJiKLR5n3+G7XDv2rBjy1UPohpmAeFSfDXNbhs1LVGxoB0pF2mMw==",
+ "license": "MIT",
"dependencies": {
- "@transloadit/prettier-bytes": "0.0.7",
- "@uppy/informer": "^3.0.3",
- "@uppy/provider-views": "^3.5.0",
- "@uppy/status-bar": "^3.2.4",
- "@uppy/thumbnail-generator": "^3.0.4",
- "@uppy/utils": "^5.4.3",
+ "@transloadit/prettier-bytes": "^0.3.4",
+ "@uppy/informer": "^4.2.1",
+ "@uppy/provider-views": "^4.4.1",
+ "@uppy/status-bar": "^4.1.1",
+ "@uppy/thumbnail-generator": "^4.1.1",
+ "@uppy/utils": "^6.1.1",
"classnames": "^2.2.6",
- "is-shallow-equal": "^1.0.1",
"lodash": "^4.17.21",
"memoize-one": "^6.0.0",
- "nanoid": "^4.0.0",
- "preact": "^10.5.13"
+ "nanoid": "^5.0.9",
+ "preact": "^10.5.13",
+ "shallow-equal": "^3.0.0"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.1"
}
},
- "node_modules/@uppy/dashboard/node_modules/@transloadit/prettier-bytes": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz",
- "integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA=="
- },
"node_modules/@uppy/form": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@uppy/form/-/form-3.0.2.tgz",
- "integrity": "sha512-o1wQy23Yh8q8oh+ZHxwx6RAJFWcoRL9p42l6W1X+9y9MyduXYyHPIRvib6QOp9MHJiqITDpAQQyoHPHSkdYi8Q==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@uppy/form/-/form-4.1.1.tgz",
+ "integrity": "sha512-S4GqnFOp0Q+el8iz6tTYYdcr4vw2HU5AIeZmKT+vJdYj74JnMGWCJuaAn7VN8w5Bm28bgYoK5M37cGviMB0yrw==",
+ "license": "MIT",
"dependencies": {
- "@uppy/utils": "^5.3.0",
+ "@uppy/utils": "^6.1.1",
"get-form-data": "^3.0.0"
},
"peerDependencies": {
- "@uppy/core": "^3.2.0"
+ "@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/informer": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@uppy/informer/-/informer-3.0.3.tgz",
- "integrity": "sha512-jMMlZ0bCJ2ruJJ0LMl7pJrM/b0e9vjVEHvYYdQghnRSRDSMONcTJXEqNZ0Lu4x7OZR1SGvqqchFk7n3vAsuERw==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@uppy/informer/-/informer-4.2.1.tgz",
+ "integrity": "sha512-0en8Py47pl6RMDrgUfqFoF807W5kK5AKVJNT1SkTsLiGg5anmTIMuvmNG3k6LN4cn9P/rKyEHSdGcoBBUj9u7Q==",
+ "license": "MIT",
"dependencies": {
- "@uppy/utils": "^5.4.3",
+ "@uppy/utils": "^6.1.1",
"preact": "^10.5.13"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/provider-views": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/@uppy/provider-views/-/provider-views-3.5.0.tgz",
- "integrity": "sha512-xSp5xQ6NsPLS2XJdsdBQCLgQELEd0BvVM2R34/XFyGTSqeA4NJKHfM6kSKwjW/jkj26CyFN5nth6CGeNaaKQ+w==",
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@uppy/provider-views/-/provider-views-4.4.2.tgz",
+ "integrity": "sha512-YGrPJuydrksmMCjvo7Ty7/lDLNo/Y8zsOgWgWmVbXB0V5aRvqY49LeKY8HDlOXclKmn6dl5CeQFf7p46txRNGQ==",
+ "license": "MIT",
"dependencies": {
- "@uppy/utils": "^5.4.3",
+ "@uppy/utils": "^6.1.2",
"classnames": "^2.2.6",
- "nanoid": "^4.0.0",
- "p-queue": "^7.3.4",
+ "nanoid": "^5.0.9",
+ "p-queue": "^8.0.0",
"preact": "^10.5.13"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.2"
}
},
"node_modules/@uppy/status-bar": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@uppy/status-bar/-/status-bar-3.2.4.tgz",
- "integrity": "sha512-WuK0LRmz7H7iBDV0VO+iUNoXmhbyeCEAWzslX0nqhkGuMchIQprVwd80ZegACySajqcpV1RDNxdhmgtCbRn8wA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@uppy/status-bar/-/status-bar-4.1.1.tgz",
+ "integrity": "sha512-hi20TLg/02XPuIPL3AAb19qRVM+fUulQ6E8lVdZDNjjvBUKscRNAY/ifcRPYx19wl1JSja6MHT8vcaBLwBwjPg==",
+ "license": "MIT",
"dependencies": {
- "@transloadit/prettier-bytes": "0.0.9",
- "@uppy/utils": "^5.4.3",
+ "@transloadit/prettier-bytes": "^0.3.4",
+ "@uppy/utils": "^6.1.1",
"classnames": "^2.2.6",
"preact": "^10.5.13"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/store-default": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-3.0.3.tgz",
- "integrity": "sha512-/zlvQNj4HjkthI+7dNdj/8mOlTg1Zb1gJ/ZsOxof0g3xXD+OAwm7asRnOwpfj2dos+lExdW/zMn8XsRGsuvb6Q=="
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-4.2.0.tgz",
+ "integrity": "sha512-PieFVa8yTvRHIqsNKfpO/yaJw5Ae/hT7uT58ryw7gvCBY5bHrNWxH5N0XFe8PFHMpLpLn8v3UXGx9ib9QkB6+Q==",
+ "license": "MIT"
},
"node_modules/@uppy/thumbnail-generator": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-3.0.4.tgz",
- "integrity": "sha512-f7E+4F6UWunX3jnV3wfL+k5zQaukKmD1z2qYbmRg5OuE9CxDJrNdAVk14KDAi79seejPJa6VVfCgGjTlIGLaRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-4.1.1.tgz",
+ "integrity": "sha512-65znkGNgVTbVte51IKOhgxOpHGSwYj9Qik2jF2ZBocMbhBY4gPkWFwqMrKQBfddA9KbUa4jVe1psxhAQTzYgiA==",
+ "license": "MIT",
"dependencies": {
- "@uppy/utils": "^5.4.3",
+ "@uppy/utils": "^6.1.1",
"exifr": "^7.0.0"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/tus": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@uppy/tus/-/tus-3.1.3.tgz",
- "integrity": "sha512-AY4tXHfeM+btnG9uKWc2ZiPhnB29xEFTudVbVmC/vEN6oBeKuJVF9NF7z9s34cRxptvvrZsv8pnRkvPJkTdfyQ==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@uppy/tus/-/tus-4.2.2.tgz",
+ "integrity": "sha512-fauUHqoLDtyRXwoaIyWM8ctuJ+SAXdjuM2eyoPYcGtpVaEGa+AS7IQkJkWz2RrWSdLCHL9O+fk6jKr+0PIDEpQ==",
+ "license": "MIT",
"dependencies": {
- "@uppy/companion-client": "^3.3.0",
- "@uppy/utils": "^5.4.3",
- "tus-js-client": "^3.0.0"
+ "@uppy/companion-client": "^4.4.1",
+ "@uppy/utils": "^6.1.1",
+ "tus-js-client": "^4.2.3"
},
"peerDependencies": {
- "@uppy/core": "^3.4.0"
+ "@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/utils": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-5.4.3.tgz",
- "integrity": "sha512-ewQTWQ5Wu1/ocz/lLCkhoXQwHLRktFK4CxrOsZmeCLK9LxjD1GOwSFjOuL199WDQKXiCle6SVlAJGQ3SDlXVkg==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-6.1.2.tgz",
+ "integrity": "sha512-PCrw6v51M6p3hlrlB2INmcocen4Dyjun1SobjVZRBkg4wutQE8ihZfSrH5ZE8UXFelufhtO16wlaZMi0EHk84w==",
+ "license": "MIT",
"dependencies": {
"lodash": "^4.17.21",
"preact": "^10.5.13"
}
},
- "node_modules/@webassemblyjs/ast": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
- "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "node_modules/@vitejs/plugin-legacy": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-6.0.1.tgz",
+ "integrity": "sha512-rMAUn0qXwCemlky7ZmaeP8va5Woz/6yVohDaTu7Wd+Jydi/Z/VmTDBlSOUbYFmfhDaVpV4ppWLiaUOPWqo9H6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ "@babel/core": "^7.26.7",
+ "@babel/preset-env": "^7.26.7",
+ "browserslist": "^4.24.4",
+ "browserslist-to-esbuild": "^2.1.1",
+ "core-js": "^3.40.0",
+ "magic-string": "^0.30.17",
+ "regenerator-runtime": "^0.14.1",
+ "systemjs": "^6.15.1"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "peerDependencies": {
+ "terser": "^5.16.0",
+ "vite": "^6.0.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
+ "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.26.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.25.9",
+ "@babel/plugin-transform-react-jsx-source": "^7.25.9",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.14.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
- "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
- "dev": true
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
- "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
- "dev": true
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
- "dev": true
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
- "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "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.11.6",
- "@webassemblyjs/helper-api-error": "1.11.6",
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
- "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
- "dev": true
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
- "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "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.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6"
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
- "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
- "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
- "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
- "dev": true
+ "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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
- "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "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.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-opt": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6",
- "@webassemblyjs/wast-printer": "1.11.6"
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
- "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "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.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
- "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "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.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6"
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
- "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "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.11.6",
- "@webassemblyjs/helper-api-error": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@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.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
- "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "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.11.6",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webpack-cli/configtest": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
- "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz",
+ "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
}
},
"node_modules/@webpack-cli/info": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
- "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz",
+ "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
}
},
"node_modules/@webpack-cli/serve": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
- "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz",
+ "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
},
"peerDependenciesMeta": {
"webpack-dev-server": {
@@ -4090,13 +6156,15 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true
+ "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
+ "dev": true,
+ "license": "Apache-2.0"
},
"node_modules/accepts": {
"version": "1.3.8",
@@ -4112,9 +6180,9 @@
}
},
"node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"license": "MIT",
"bin": {
@@ -4124,15 +6192,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-import-assertions": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
- "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
- "dev": true,
- "peerDependencies": {
- "acorn": "^8"
- }
- },
"node_modules/acorn-walk": {
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
@@ -4147,15 +6206,16 @@
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"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"
+ "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",
@@ -4179,42 +6239,25 @@
}
}
},
- "node_modules/ajv-formats/node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "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.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
+ "fast-deep-equal": "^3.1.3"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "peerDependencies": {
+ "ajv": "^8.8.2"
}
},
- "node_modules/ajv-formats/node_modules/fast-deep-equal": {
+ "node_modules/ajv-keywords/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
- },
- "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
- },
- "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,
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
+ "license": "MIT"
},
"node_modules/ajv/node_modules/fast-deep-equal": {
"version": "3.1.3",
@@ -4244,16 +6287,16 @@
}
},
"node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
"engines": {
- "node": ">=4"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/anymatch": {
@@ -4261,6 +6304,7 @@
"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"
@@ -4281,19 +6325,18 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/array-flatten": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
- "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
- "dev": true
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"dev": true,
- "engines": {
- "node": ">=8"
- }
+ "license": "MIT"
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
@@ -4311,9 +6354,9 @@
}
},
"node_modules/autoprefixer": {
- "version": "10.4.15",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz",
- "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==",
+ "version": "10.4.20",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
"dev": true,
"funding": [
{
@@ -4329,12 +6372,13 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "browserslist": "^4.21.10",
- "caniuse-lite": "^1.0.30001520",
- "fraction.js": "^4.2.0",
+ "browserslist": "^4.23.3",
+ "caniuse-lite": "^1.0.30001646",
+ "fraction.js": "^4.3.7",
"normalize-range": "^0.1.2",
- "picocolors": "^1.0.0",
+ "picocolors": "^1.0.1",
"postcss-value-parser": "^4.2.0"
},
"bin": {
@@ -4348,9 +6392,9 @@
}
},
"node_modules/axios": {
- "version": "1.7.7",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
- "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
+ "version": "1.7.9",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
+ "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -4364,32 +6408,32 @@
"integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
},
"node_modules/babel-loader": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz",
- "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz",
+ "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "find-cache-dir": "^3.3.1",
- "loader-utils": "^2.0.0",
- "make-dir": "^3.1.0",
- "schema-utils": "^2.6.5"
+ "find-cache-dir": "^4.0.0",
+ "schema-utils": "^4.0.0"
},
"engines": {
- "node": ">= 8.9"
+ "node": ">= 14.15.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0",
- "webpack": ">=2"
+ "@babel/core": "^7.12.0",
+ "webpack": ">=5"
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz",
- "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==",
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+ "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.4.2",
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -4397,25 +6441,27 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz",
- "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==",
+ "version": "0.10.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+ "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.2",
- "core-js-compat": "^3.31.0"
+ "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "core-js-compat": "^3.38.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz",
- "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+ "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.2"
+ "@babel/helper-define-polyfill-provider": "^0.6.3"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -4487,77 +6533,36 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/big.js": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
- "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "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"
- }
- },
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
- "node_modules/bl/node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "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",
- "optional": true,
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
- "qs": "6.11.0",
- "raw-body": "2.5.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -4571,6 +6576,7 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -4580,6 +6586,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -4588,16 +6595,16 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/bonjour-service": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz",
- "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
+ "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "array-flatten": "^2.1.2",
- "dns-equal": "^1.0.0",
"fast-deep-equal": "^3.1.3",
"multicast-dns": "^7.2.5"
}
@@ -4606,7 +6613,8 @@
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
@@ -4619,27 +6627,29 @@
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "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.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/browserslist": {
- "version": "4.21.10",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
- "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
"dev": true,
"funding": [
{
@@ -4655,11 +6665,12 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001517",
- "electron-to-chromium": "^1.4.477",
- "node-releases": "^2.0.13",
- "update-browserslist-db": "^1.0.11"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
@@ -4668,6 +6679,25 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/browserslist-to-esbuild": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/browserslist-to-esbuild/-/browserslist-to-esbuild-2.1.1.tgz",
+ "integrity": "sha512-KN+mty6C3e9AN8Z5dI1xeN15ExcRNeISoC3g7V0Kax/MMF9MSoYA2G7lkTTcVUFntiEjkpI0HNgqJC1NjdyNUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "meow": "^13.0.0"
+ },
+ "bin": {
+ "browserslist-to-esbuild": "cli/index.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "browserslist": "*"
+ }
+ },
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -4697,6 +6727,22 @@
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -4706,14 +6752,32 @@
"node": ">= 0.8"
}
},
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4724,6 +6788,7 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -4739,9 +6804,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001521",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001521.tgz",
- "integrity": "sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==",
+ "version": "1.0.30001699",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
+ "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
"dev": true,
"funding": [
{
@@ -4756,21 +6821,53 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "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": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/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/chalk/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/character-entities": {
@@ -4803,17 +6900,211 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "node_modules/cheerio": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+ "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "encoding-sniffer": "^0.2.0",
+ "htmlparser2": "^9.1.0",
+ "parse5": "^7.1.2",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^6.19.5",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.17"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/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/cheerio/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/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/cheerio/node_modules/htmlparser2": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
"dev": true,
"funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
{
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
}
],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "entities": "^4.5.0"
+ }
+ },
+ "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",
@@ -4826,17 +7117,13 @@
"engines": {
"node": ">= 8.10.0"
},
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
- "node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "license": "ISC",
- "optional": true
- },
"node_modules/chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
@@ -4869,6 +7156,7 @@
"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",
@@ -4879,9 +7167,10 @@
}
},
"node_modules/clsx": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
- "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -4892,19 +7181,22 @@
"integrity": "sha512-4XOTqEzBWrGOZaMd+sTED2hLpzfBbiQCf1W6OBGkIHqk1D8uwy8WFLazVbdQwfDpQ+vf39lqTGPa9IhWW0roTA=="
},
"node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "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.3"
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
"node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "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"
},
@@ -4954,11 +7246,12 @@
"node": ">= 12"
}
},
- "node_modules/commondir": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
- "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
- "dev": true
+ "node_modules/common-path-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz",
+ "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/compressible": {
"version": "2.0.18",
@@ -5015,7 +7308,8 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/connect-history-api-fallback": {
"version": "2.0.0",
@@ -5026,11 +7320,19 @@
"node": ">=0.8"
}
},
+ "node_modules/consola": {
+ "version": "2.15.3",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
+ "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
},
@@ -5048,16 +7350,18 @@
}
},
"node_modules/convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
- "dev": true
+ "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/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -5066,7 +7370,8 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/copy-to-clipboard": {
"version": "3.3.3",
@@ -5078,21 +7383,21 @@
}
},
"node_modules/copy-webpack-plugin": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-8.1.1.tgz",
- "integrity": "sha512-rYM2uzRxrLRpcyPqGceRBDpxxUV8vcDqIKxAUKfcnFpcrPxT5+XvhTxv7XLjo5AvEJFPdAE3zCogG2JVahqgSQ==",
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz",
+ "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-glob": "^3.2.5",
- "glob-parent": "^5.1.1",
- "globby": "^11.0.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.1",
+ "globby": "^14.0.0",
"normalize-path": "^3.0.0",
- "p-limit": "^3.1.0",
- "schema-utils": "^3.0.0",
- "serialize-javascript": "^5.0.1"
+ "schema-utils": "^4.2.0",
+ "serialize-javascript": "^6.0.2"
},
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
@@ -5102,31 +7407,39 @@
"webpack": "^5.1.0"
}
},
- "node_modules/copy-webpack-plugin/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==",
+ "node_modules/copy-webpack-plugin/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": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
+ "is-glob": "^4.0.3"
},
"engines": {
- "node": ">= 10.13.0"
- },
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz",
+ "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
"funding": {
"type": "opencollective",
- "url": "https://opencollective.com/webpack"
+ "url": "https://opencollective.com/core-js"
}
},
"node_modules/core-js-compat": {
- "version": "3.32.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz",
- "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==",
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz",
+ "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "browserslist": "^4.21.10"
+ "browserslist": "^4.24.3"
},
"funding": {
"type": "opencollective",
@@ -5134,9 +7447,9 @@
}
},
"node_modules/core-js-pure": {
- "version": "3.38.1",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz",
- "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==",
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz",
+ "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
@@ -5151,28 +7464,38 @@
"dev": true
},
"node_modules/cosmiconfig": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
- "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "import-fresh": "^3.2.1",
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
"js-yaml": "^4.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0"
+ "parse-json": "^5.2.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "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",
@@ -5183,9 +7506,9 @@
}
},
"node_modules/css-blank-pseudo": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-6.0.0.tgz",
- "integrity": "sha512-VbfLlOWO7sBHBTn6pwDQzc07Z0SDydgDBfNfCE0nvrehdBNv9RKsuupIRa/qal0+fBZhAALyQDPMKz5lnvcchw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz",
+ "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==",
"dev": true,
"funding": [
{
@@ -5197,20 +7520,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/css-has-pseudo": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-6.0.0.tgz",
- "integrity": "sha512-X+r+JBuoO37FBOWVNhVJhxtSBUFHgHbrcc0CjFT28JEdOw1qaDwABv/uunyodUuSy2hMPe9j/HjssxSlvUmKjg==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz",
+ "integrity": "sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==",
"dev": true,
"funding": [
{
@@ -5222,44 +7546,53 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^3.0.0",
- "postcss-selector-parser": "^6.0.13",
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/css-loader": {
- "version": "5.2.7",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz",
- "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
+ "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"icss-utils": "^5.1.0",
- "loader-utils": "^2.0.0",
- "postcss": "^8.2.15",
- "postcss-modules-extract-imports": "^3.0.0",
- "postcss-modules-local-by-default": "^4.0.0",
- "postcss-modules-scope": "^3.0.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.1.0",
- "schema-utils": "^3.0.0",
- "semver": "^7.3.5"
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^4.27.0 || ^5.0.0"
+ "@rspack/core": "0.x || 1.x",
+ "webpack": "^5.27.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
}
},
"node_modules/css-loader/node_modules/lru-cache": {
@@ -5274,24 +7607,6 @@
"node": ">=10"
}
},
- "node_modules/css-loader/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,
- "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/css-loader/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -5314,9 +7629,9 @@
"dev": true
},
"node_modules/css-prefers-color-scheme": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-9.0.0.tgz",
- "integrity": "sha512-03QGAk/FXIRseDdLb7XAiu6gidQ0Nd8945xuM7VFVPpc6goJsG9uIO8xQjTxwbPdPIIV4o4AJoOJyt8gwDl67g==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz",
+ "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==",
"dev": true,
"funding": [
{
@@ -5328,8 +7643,9 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -5370,9 +7686,9 @@
"license": "MIT"
},
"node_modules/cssdb": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.0.tgz",
- "integrity": "sha512-1hN+I3r4VqSNQ+OmMXxYexnumbOONkSil0TWMebVXHtzYW4tRRPovUNHPHj2d4nrgOuYJ8Vs3XwvywsuwwXNNA==",
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.2.3.tgz",
+ "integrity": "sha512-9BDG5XmJrJQQnJ51VFxXCAtpZ5ebDlAREmO8sxMOVU0aSxN/gocbctjIG5LMh3WBUq+xTlb/jw2LoljBEqraTA==",
"dev": true,
"funding": [
{
@@ -5383,7 +7699,8 @@
"type": "github",
"url": "https://github.com/sponsors/csstools"
}
- ]
+ ],
+ "license": "MIT-0"
},
"node_modules/cssesc": {
"version": "3.0.0",
@@ -5406,7 +7723,8 @@
"node_modules/custom-error-instance": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
- "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
+ "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==",
+ "license": "ISC"
},
"node_modules/dashjs": {
"version": "4.7.1",
@@ -5449,22 +7767,6 @@
}
}
},
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -5483,11 +7785,42 @@
"node": ">=0.10.0"
}
},
+ "node_modules/default-browser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
+ "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
+ "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
"integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"execa": "^5.0.0"
},
@@ -5500,6 +7833,7 @@
"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"
}
@@ -5518,6 +7852,7 @@
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -5527,21 +7862,12 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/detect-libc": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
- "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
- "license": "Apache-2.0",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
@@ -5549,9 +7875,10 @@
"dev": true
},
"node_modules/diff": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
- "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -5568,17 +7895,12 @@
"node": ">=8"
}
},
- "node_modules/dns-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
- "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==",
- "dev": true
- },
"node_modules/dns-packet": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz",
- "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==",
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
+ "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@leichtgewicht/ip-codec": "^2.0.1"
},
@@ -5642,9 +7964,9 @@
}
},
"node_modules/dompurify": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.4.tgz",
- "integrity": "sha512-2gnshi6OshmuKil8rMZuQCGiUF3cUxHY3NGDzUAdUx/NPEe5DVnO8BDoAQouvgwnx0R/+a6jUn36Z0FSdq8vww==",
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
+ "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
"license": "(MPL-2.0 OR Apache-2.0)"
},
"node_modules/domutils": {
@@ -5671,6 +7993,29 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/dotenv": {
+ "version": "16.4.7",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dotenv-expand": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz",
+ "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/drange": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz",
@@ -5680,6 +8025,21 @@
"node": ">=4"
}
},
+ "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/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -5687,51 +8047,93 @@
"dev": true,
"license": "MIT"
},
+ "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/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "dev": true
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.496",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz",
- "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==",
- "dev": true
- },
- "node_modules/emojis-list": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
- "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
"engines": {
- "node": ">= 4"
+ "node": ">=0.10.0"
}
},
- "node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.96",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz",
+ "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==",
"dev": true,
+ "license": "ISC"
+ },
+ "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/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+ "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
+ "dev": true,
"license": "MIT",
- "optional": true,
"dependencies": {
- "once": "^1.4.0"
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/encoding-sniffer/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/enhanced-resolve": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
- "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "version": "5.18.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+ "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -5749,11 +8151,22 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/envinfo": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz",
- "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==",
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
+ "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
+ "dev": true,
+ "license": "MIT",
"bin": {
"envinfo": "dist/cli.js"
},
@@ -5766,26 +8179,102 @@
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-module-lexer": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
"integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
"dev": true
},
+ "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/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "node_modules/esbuild": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
+ "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
"dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.24.2",
+ "@esbuild/android-arm": "0.24.2",
+ "@esbuild/android-arm64": "0.24.2",
+ "@esbuild/android-x64": "0.24.2",
+ "@esbuild/darwin-arm64": "0.24.2",
+ "@esbuild/darwin-x64": "0.24.2",
+ "@esbuild/freebsd-arm64": "0.24.2",
+ "@esbuild/freebsd-x64": "0.24.2",
+ "@esbuild/linux-arm": "0.24.2",
+ "@esbuild/linux-arm64": "0.24.2",
+ "@esbuild/linux-ia32": "0.24.2",
+ "@esbuild/linux-loong64": "0.24.2",
+ "@esbuild/linux-mips64el": "0.24.2",
+ "@esbuild/linux-ppc64": "0.24.2",
+ "@esbuild/linux-riscv64": "0.24.2",
+ "@esbuild/linux-s390x": "0.24.2",
+ "@esbuild/linux-x64": "0.24.2",
+ "@esbuild/netbsd-arm64": "0.24.2",
+ "@esbuild/netbsd-x64": "0.24.2",
+ "@esbuild/openbsd-arm64": "0.24.2",
+ "@esbuild/openbsd-x64": "0.24.2",
+ "@esbuild/sunos-x64": "0.24.2",
+ "@esbuild/win32-arm64": "0.24.2",
+ "@esbuild/win32-ia32": "0.24.2",
+ "@esbuild/win32-x64": "0.24.2"
+ }
+ },
+ "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"
}
@@ -5796,16 +8285,6 @@
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"dev": true
},
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -5849,6 +8328,13 @@
"node": ">=4.0"
}
},
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -5863,6 +8349,7 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -5870,7 +8357,8 @@
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
- "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true
},
"node_modules/events": {
"version": "3.3.0",
@@ -5886,6 +8374,7 @@
"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",
@@ -5907,50 +8396,42 @@
"node_modules/exifr": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz",
- "integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw=="
- },
- "node_modules/expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
- "license": "(MIT OR WTFPL)",
- "optional": true,
- "engines": {
- "node": ">=6"
- }
+ "integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==",
+ "license": "MIT"
},
"node_modules/express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.5.0",
+ "cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
- "finalhandler": "1.2.0",
+ "finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
+ "merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
+ "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7",
- "qs": "6.11.0",
+ "qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
@@ -5959,19 +8440,18 @@
},
"engines": {
"node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
- "node_modules/express/node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
- "dev": true
- },
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -5980,7 +8460,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-deep-equal": {
"version": "2.0.1",
@@ -5988,16 +8469,17 @@
"integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w=="
},
"node_modules/fast-glob": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
- "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
- "micromatch": "^4.0.4"
+ "micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
@@ -6013,7 +8495,15 @@
"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
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
+ "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
@@ -6058,11 +8548,45 @@
"node": ">=0.8.0"
}
},
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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"
},
@@ -6071,13 +8595,14 @@
}
},
"node_modules/finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"debug": "2.6.9",
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
@@ -6093,6 +8618,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -6101,23 +8627,99 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/find-cache-dir": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
- "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz",
+ "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "commondir": "^1.0.1",
- "make-dir": "^3.0.2",
- "pkg-dir": "^4.1.0"
+ "common-path-prefix": "^3.0.0",
+ "pkg-dir": "^7.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.16"
},
"funding": {
- "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/find-up": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
+ "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^7.1.0",
+ "path-exists": "^5.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/locate-path": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+ "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^6.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-cache-dir/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/find-cache-dir/node_modules/path-exists": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/pkg-dir": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz",
+ "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/find-up": {
@@ -6133,18 +8735,20 @@
"node": ">=8"
}
},
- "node_modules/fluid-player": {
- "version": "3.22.0",
- "resolved": "https://registry.npmjs.org/fluid-player/-/fluid-player-3.22.0.tgz",
- "integrity": "sha512-SyR7hBjB1+sHAApE4Emo5xcIXVz72c68BhLwaGb8EjwEJ9NnWOtMHZGDZeOg4sg2DN5OWo95XPzUhNSHxOmtLw==",
- "dependencies": {
- "dashjs": "^4.5.2",
- "es6-promise": "^4.2.8",
- "hls.js": "^1.3.2",
- "panolens": "^0.12.1",
- "videojs-vtt.js": "^0.15.4"
+ "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/fluid-player": {
+ "resolved": "fluid-player",
+ "link": true
+ },
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
@@ -6165,10 +8769,40 @@
}
}
},
+ "node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "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/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
@@ -6192,21 +8826,23 @@
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fraction.js": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
- "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "*"
},
"funding": {
"type": "patreon",
- "url": "https://www.patreon.com/infusion"
+ "url": "https://github.com/sponsors/rawify"
}
},
"node_modules/fresh": {
@@ -6214,42 +8850,39 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "license": "MIT",
- "optional": true
- },
"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==",
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=14.14"
}
},
"node_modules/fs-monkey": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz",
- "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==",
- "dev": true
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz",
+ "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==",
+ "dev": true,
+ "license": "Unlicense"
},
"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
+ "dev": true,
+ "license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.2",
@@ -6266,10 +8899,24 @@
}
},
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generic-names": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-4.0.0.tgz",
+ "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loader-utils": "^3.2.0"
+ }
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
@@ -6286,25 +8933,50 @@
"integrity": "sha512-1d53Kn08wlPuLu31/boF1tW2WRYKw3xAWae3mqcjqpDjoqVBtXolbQnudbbEFyFWL7+2SLGRAFdotxNY06V7MA=="
},
"node_modules/get-intrinsic": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
- "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3"
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.0",
+ "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-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-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"
},
@@ -6312,18 +8984,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
- "license": "MIT",
- "optional": true
- },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
+ "license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -6355,7 +9022,8 @@
"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
+ "dev": true,
+ "license": "BSD-2-Clause"
},
"node_modules/global": {
"version": "4.4.0",
@@ -6371,30 +9039,68 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
+ "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
+ "@sindresorhus/merge-streams": "^2.1.0",
+ "fast-glob": "^3.3.3",
+ "ignore": "^7.0.3",
+ "path-type": "^6.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.3.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globby/node_modules/ignore": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
+ "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/globby/node_modules/path-type": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
+ "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -6435,32 +9141,21 @@
}
},
"node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "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": ">=4"
- }
- },
- "node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=8"
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "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"
},
@@ -6468,6 +9163,19 @@
"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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
@@ -6514,9 +9222,10 @@
}
},
"node_modules/hls.js": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.4.10.tgz",
- "integrity": "sha512-wAVSj4Fm2MqOHy5+BlYnlKxXvJlv5IuZHjlzHu18QmjRzSDFQiUDWdHs5+NsFMQrgKEBwuWDcyvaMC9dUzJ5Uw=="
+ "version": "1.5.17",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.17.tgz",
+ "integrity": "sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==",
+ "license": "Apache-2.0"
},
"node_modules/hpack.js": {
"version": "2.1.6",
@@ -6594,10 +9303,11 @@
}
},
"node_modules/html-webpack-plugin": {
- "version": "5.5.3",
- "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz",
- "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==",
+ "version": "5.6.3",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz",
+ "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/html-minifier-terser": "^6.0.0",
"html-minifier-terser": "^6.0.2",
@@ -6613,7 +9323,16 @@
"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": {
@@ -6646,6 +9365,7 @@
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
@@ -6668,6 +9388,7 @@
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
@@ -6678,10 +9399,11 @@
}
},
"node_modules/http-proxy-middleware": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
- "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/http-proxy": "^1.17.8",
"http-proxy": "^1.18.1",
@@ -6706,15 +9428,27 @@
"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/hyperdyperid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz",
+ "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.18"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
@@ -6770,13 +9504,15 @@
"node_modules/immutable": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.2.tgz",
- "integrity": "sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA=="
+ "integrity": "sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==",
+ "peer": true
},
"node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "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"
@@ -6819,7 +9555,9 @@
"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"
@@ -6830,13 +9568,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "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",
- "optional": true
- },
"node_modules/interpret": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
@@ -6890,13 +9621,15 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"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"
},
@@ -6930,6 +9663,7 @@
"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"
},
@@ -6949,6 +9683,16 @@
"node": ">=0.10.0"
}
},
+ "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-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -6971,11 +9715,59 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container/node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-network-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz",
+ "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"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"
}
@@ -6985,6 +9777,7 @@
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
"integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -6997,6 +9790,7 @@
"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"
},
@@ -7004,11 +9798,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-shallow-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-shallow-equal/-/is-shallow-equal-1.0.1.tgz",
- "integrity": "sha512-lq5RvK+85Hs5J3p4oA4256M1FEffzmI533ikeDHvJd42nouRRx5wBzt36JuviiGe5dIPyHON/d0/Up+PBo6XkQ=="
- },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -7025,6 +9814,7 @@
"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"
},
@@ -7049,15 +9839,52 @@
"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/jackspeak": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
+ "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"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",
@@ -7067,43 +9894,21 @@
"node": ">= 10.13.0"
}
},
- "node_modules/jest-worker/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,
- "engines": {
- "node": ">=8"
- }
- },
- "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,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/jiti": {
- "version": "1.19.3",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz",
- "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==",
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
+ "license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
}
},
"node_modules/js-base64": {
- "version": "3.7.5",
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz",
- "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA=="
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz",
+ "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==",
+ "license": "BSD-3-Clause"
},
"node_modules/js-file-download": {
"version": "0.4.12",
@@ -7128,15 +9933,16 @@
}
},
"node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "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": ">=4"
+ "node": ">=6"
}
},
"node_modules/json-parse-even-better-errors": {
@@ -7146,10 +9952,11 @@
"dev": true
},
"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
+ "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/json-stringify-deterministic": {
"version": "1.0.12",
@@ -7197,27 +10004,20 @@
"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/klona": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
- "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/launch-editor": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz",
- "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==",
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz",
+ "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"picocolors": "^1.0.0",
- "shell-quote": "^1.7.3"
+ "shell-quote": "^1.8.1"
}
},
"node_modules/lie": {
@@ -7232,7 +10032,8 @@
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/loader-runner": {
"version": "4.3.0",
@@ -7244,17 +10045,13 @@
}
},
"node_modules/loader-utils": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
- "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz",
+ "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==",
"dev": true,
- "dependencies": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- },
+ "license": "MIT",
"engines": {
- "node": ">=8.9.0"
+ "node": ">= 12.13.0"
}
},
"node_modules/localforage": {
@@ -7286,6 +10083,7 @@
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz",
"integrity": "sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==",
+ "license": "MIT",
"dependencies": {
"lodash._stringtopath": "~4.8.0"
}
@@ -7293,12 +10091,14 @@
"node_modules/lodash._basetostring": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz",
- "integrity": "sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw=="
+ "integrity": "sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw==",
+ "license": "MIT"
},
"node_modules/lodash._baseuniq": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
"integrity": "sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==",
+ "license": "MIT",
"dependencies": {
"lodash._createset": "~4.0.0",
"lodash._root": "~3.0.0"
@@ -7307,17 +10107,20 @@
"node_modules/lodash._createset": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
- "integrity": "sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA=="
+ "integrity": "sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==",
+ "license": "MIT"
},
"node_modules/lodash._root": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
- "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ=="
+ "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==",
+ "license": "MIT"
},
"node_modules/lodash._stringtopath": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz",
"integrity": "sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==",
+ "license": "MIT",
"dependencies": {
"lodash._basetostring": "~4.12.0"
}
@@ -7330,12 +10133,14 @@
"node_modules/lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
- "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
+ "license": "MIT"
},
"node_modules/lodash.uniqby": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz",
"integrity": "sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==",
+ "license": "MIT",
"dependencies": {
"lodash._baseiteratee": "~4.7.0",
"lodash._baseuniq": "~4.6.0"
@@ -7380,23 +10185,29 @@
"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/make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "semver": "^6.0.0"
- },
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "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": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">= 0.4"
}
},
"node_modules/media-typer": {
@@ -7404,6 +10215,7 @@
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -7413,6 +10225,7 @@
"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"
},
@@ -7425,17 +10238,35 @@
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
+ "node_modules/meow": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
- "dev": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/merge2": {
"version": "1.4.1",
@@ -7451,17 +10282,19 @@
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@@ -7481,6 +10314,7 @@
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true,
+ "license": "MIT",
"bin": {
"mime": "cli.js"
},
@@ -7520,23 +10354,11 @@
"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/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
@@ -7546,42 +10368,24 @@
}
},
"node_modules/mini-css-extract-plugin": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz",
- "integrity": "sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz",
+ "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "loader-utils": "^2.0.0",
- "schema-utils": "^3.0.0",
- "webpack-sources": "^1.1.0"
+ "schema-utils": "^4.0.0",
+ "tapable": "^2.2.1"
},
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^4.4.0 || ^5.0.0"
- }
- },
- "node_modules/mini-css-extract-plugin/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,
- "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"
+ "webpack": "^5.0.0"
}
},
"node_modules/minim": {
@@ -7607,6 +10411,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -7614,23 +10419,16 @@
"node": "*"
}
},
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "optional": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
}
},
- "node_modules/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "license": "MIT",
- "optional": true
- },
"node_modules/mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
@@ -7652,6 +10450,7 @@
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
"integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"dns-packet": "^5.2.2",
"thunky": "^1.0.2"
@@ -7665,42 +10464,29 @@
"resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
"integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
},
- "node_modules/nan": {
- "version": "2.20.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
- "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
- "license": "MIT",
- "optional": true
- },
"node_modules/nanoassert": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz",
"integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA=="
},
"node_modules/nanoid": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
- "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==",
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz",
+ "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": "^18 || >=20"
}
},
- "node_modules/napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
- "license": "MIT",
- "optional": true
- },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -7735,38 +10521,20 @@
"tslib": "^2.0.3"
}
},
- "node_modules/node-abi": {
- "version": "3.67.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz",
- "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-abi/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "license": "ISC",
- "optional": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"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==",
"license": "MIT"
},
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -7808,15 +10576,40 @@
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
"dev": true,
+ "license": "(BSD-3-Clause OR GPL-2.0)",
"engines": {
"node": ">= 6.13.0"
}
},
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "license": "MIT",
+ "optional": true,
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/node-html-parser": {
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz",
+ "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-select": "^4.2.1",
+ "he": "1.2.0"
+ }
+ },
"node_modules/node-releases": {
- "version": "2.0.13",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
- "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
- "dev": true
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -7832,6 +10625,7 @@
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -7841,6 +10635,7 @@
"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"
},
@@ -7870,10 +10665,14 @@
}
},
"node_modules/object-inspect": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
- "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "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"
}
@@ -7889,6 +10688,7 @@
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
@@ -7909,7 +10709,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"wrappy": "1"
}
@@ -7919,6 +10719,7 @@
"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"
},
@@ -7934,6 +10735,7 @@
"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",
@@ -7947,24 +10749,24 @@
}
},
"node_modules/openapi-path-templating": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.6.0.tgz",
- "integrity": "sha512-1atBNwOUrZXthTvlvvX8k8ovFEF3iA8mDidYMkdOtvVdndBhTrspbwGXNOzEUaJhm9iUl4Tf5uQaeTLAJvwPig==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-2.1.0.tgz",
+ "integrity": "sha512-fLs5eJmLyU8wPRz+JSH5uLE7TE4Ohg6VHOtj0C0AlD3GTCCcw2LgKW6MSN1A8ZBKHEg2O4/d02knmVU1nvGAKQ==",
"license": "Apache-2.0",
"dependencies": {
- "apg-lite": "^1.0.3"
+ "apg-lite": "^1.0.4"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/openapi-server-url-templating": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.1.0.tgz",
- "integrity": "sha512-dtyTFKx2xVcO0W8JKaluXIHC9l/MLjHeflBaWjiWNMCHp/TBs9dEjQDbj/VFlHR4omFOKjjmqm1pW1aCAhmPBg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.3.0.tgz",
+ "integrity": "sha512-DPlCms3KKEbjVQb0spV6Awfn6UWNheuG/+folQPzh/wUaKwuqvj8zt5gagD7qoyxtE03cIiKPgLFS3Q8Bz00uQ==",
"license": "Apache-2.0",
"dependencies": {
- "apg-lite": "^1.0.3"
+ "apg-lite": "^1.0.4"
},
"engines": {
"node": ">=12.20.0"
@@ -7981,15 +10783,16 @@
}
},
"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==",
+ "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": "^0.1.0"
+ "yocto-queue": "^1.0.0"
},
"engines": {
- "node": ">=10"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -8023,25 +10826,33 @@
}
},
"node_modules/p-queue": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.3.4.tgz",
- "integrity": "sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.0.tgz",
+ "integrity": "sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==",
+ "license": "MIT",
"dependencies": {
- "eventemitter3": "^4.0.7",
- "p-timeout": "^5.0.2"
+ "eventemitter3": "^5.0.1",
+ "p-timeout": "^6.1.2"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-queue/node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "license": "MIT"
+ },
"node_modules/p-retry": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
"integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/retry": "0.12.0",
"retry": "^0.13.1"
@@ -8055,16 +10866,18 @@
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/p-timeout": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz",
- "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==",
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz",
+ "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==",
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -8079,6 +10892,13 @@
"node": ">=6"
}
},
+ "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/panolens": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/panolens/-/panolens-0.12.1.tgz",
@@ -8102,6 +10922,7 @@
"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"
},
@@ -8132,6 +10953,7 @@
"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",
@@ -8145,6 +10967,75 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse5": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
+ "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^4.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/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/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -8183,6 +11074,7 @@
"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"
}
@@ -8202,11 +11094,39 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
+ "node_modules/path-scurry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+ "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
+ "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
"node_modules/path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
- "dev": true
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/path-type": {
"version": "4.0.0",
@@ -8217,11 +11137,19 @@
"node": ">=8"
}
},
+ "node_modules/pathe": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz",
+ "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
+ "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.1",
@@ -8247,10 +11175,42 @@
"node": ">=8"
}
},
+ "node_modules/playwright": {
+ "version": "1.49.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz",
+ "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.49.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.49.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz",
+ "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/postcss": {
- "version": "8.4.28",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz",
- "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==",
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
+ "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
"dev": true,
"funding": [
{
@@ -8266,29 +11226,37 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-attribute-case-insensitive": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-6.0.2.tgz",
- "integrity": "sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz",
+ "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -8310,9 +11278,9 @@
}
},
"node_modules/postcss-color-functional-notation": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-6.0.0.tgz",
- "integrity": "sha512-kaWTgnhRKFtfMF8H0+NQBFxgr5CGg05WGe07Mc1ld6XHwwRWlqSbHOW0zwf+BtkBQpsdVUu7+gl9dtdvhWMedw==",
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.7.tgz",
+ "integrity": "sha512-EZvAHsvyASX63vXnyXOIynkxhaHRSsdb7z6yiXKIovGXAolW4cMZ3qoh7k3VdTsLBS6VGdksGfIo3r6+waLoOw==",
"dev": true,
"funding": [
{
@@ -8324,40 +11292,52 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^3.0.0",
- "postcss-value-parser": "^4.2.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-color-hex-alpha": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-9.0.2.tgz",
- "integrity": "sha512-SfPjgr//VQ/DOCf80STIAsdAs7sbIbxATvVmd+Ec7JvR8onz9pjawhq3BJM3Pie40EE3TyB0P6hft16D33Nlyg==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz",
+ "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-color-rebeccapurple": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-9.0.0.tgz",
- "integrity": "sha512-RmUFL+foS05AKglkEoqfx+KFdKRVmqUAxlHNz4jLqIi7046drIPyerdl4B6j/RA2BSP8FI8gJcHmLRrwJOMnHw==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz",
+ "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==",
"dev": true,
"funding": [
{
@@ -8369,20 +11349,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-custom-media": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.0.tgz",
- "integrity": "sha512-NxDn7C6GJ7X8TsWOa8MbCdq9rLERRLcPfQSp856k1jzMreL8X9M6iWk35JjPRIb9IfRnVohmxAylDRx7n4Rv4g==",
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz",
+ "integrity": "sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ==",
"dev": true,
"funding": [
{
@@ -8394,23 +11376,24 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.3",
- "@csstools/css-parser-algorithms": "^2.3.0",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/media-query-list-parser": "^2.1.2"
+ "@csstools/cascade-layer-name-parser": "^2.0.4",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/media-query-list-parser": "^4.0.2"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-custom-properties": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.0.tgz",
- "integrity": "sha512-q4VgtIKSy5+KcUvQ0WxTjDy9DZjQ5VCXAZ9+tT9+aPMbA0z6s2t1nMw0QHszru1ib5ElkXl9JUpYYU37VVUs7g==",
+ "version": "14.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz",
+ "integrity": "sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A==",
"dev": true,
"funding": [
{
@@ -8422,23 +11405,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.4",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
+ "@csstools/cascade-layer-name-parser": "^2.0.4",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-custom-selectors": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.4.tgz",
- "integrity": "sha512-TU2xyUUBTlpiLnwyE2ZYMUIYB41MKMkBZ8X8ntkqRDQ8sdBLhFFsPgNcOliBd5+/zcK51C9hRnSE7hKUJMxQSw==",
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz",
+ "integrity": "sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg==",
"dev": true,
"funding": [
{
@@ -8450,23 +11435,24 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.3",
- "@csstools/css-parser-algorithms": "^2.3.0",
- "@csstools/css-tokenizer": "^2.1.1",
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/cascade-layer-name-parser": "^2.0.4",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-dir-pseudo-class": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-8.0.0.tgz",
- "integrity": "sha512-Oy5BBi0dWPwij/IA+yDYj+/OBMQ9EPqAzTHeSNUYrUWdll/PRJmcbiUj0MNcsBi681I1gcSTLvMERPaXzdbvJg==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz",
+ "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==",
"dev": true,
"funding": [
{
@@ -8478,20 +11464,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-double-position-gradients": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-5.0.0.tgz",
- "integrity": "sha512-wR8npIkrIVUTicUpCWSSo1f/g7gAEIH70FMqCugY4m4j6TX4E0T2Q5rhfO0gqv00biBZdLyb+HkW8x6as+iJNQ==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz",
+ "integrity": "sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg==",
"dev": true,
"funding": [
{
@@ -8503,21 +11490,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^3.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-focus-visible": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-9.0.0.tgz",
- "integrity": "sha512-zA4TbVaIaT8npZBEROhZmlc+GBKE8AELPHXE7i4TmIUEQhw/P/mSJfY9t6tBzpQ1rABeGtEOHYrW4SboQeONMQ==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz",
+ "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==",
"dev": true,
"funding": [
{
@@ -8529,20 +11518,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-focus-within": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-8.0.0.tgz",
- "integrity": "sha512-E7+J9nuQzZaA37D/MUZMX1K817RZGDab8qw6pFwzAkDd/QtlWJ9/WTKmzewNiuxzeq6WWY7ATiRePVoDKp+DnA==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz",
+ "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==",
"dev": true,
"funding": [
{
@@ -8554,11 +11544,12 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -8574,9 +11565,9 @@
}
},
"node_modules/postcss-gap-properties": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-5.0.0.tgz",
- "integrity": "sha512-YjsEEL6890P7MCv6fch6Am1yq0EhQCJMXyT4LBohiu87+4/WqR7y5W3RIv53WdA901hhytgRvjlrAhibhW4qsA==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz",
+ "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==",
"dev": true,
"funding": [
{
@@ -8588,17 +11579,18 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-image-set-function": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-6.0.0.tgz",
- "integrity": "sha512-bg58QnJexFpPBU4IGPAugAPKV0FuFtX5rHYNSKVaV91TpHN7iwyEzz1bkIPCiSU5+BUN00e+3fV5KFrwIgRocw==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz",
+ "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==",
"dev": true,
"funding": [
{
@@ -8610,29 +11602,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^2.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/postcss-initial": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
- "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
- "dev": true,
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
"node_modules/postcss-lab-function": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-6.0.1.tgz",
- "integrity": "sha512-/Xl6JitDh7jWkcOLxrHcAlEaqkxyaG3g4iDMy5RyhNaiQPJ9Egf2+Mxp1W2qnH5jB2bj59f3RbdKmC6qx1IcXA==",
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.7.tgz",
+ "integrity": "sha512-+ONj2bpOQfsCKZE2T9VGMyVVdGcGUpr7u3SVfvkJlvhTRmDCfY25k4Jc8fubB9DclAPR4+w8uVtDZmdRgdAHig==",
"dev": true,
"funding": [
{
@@ -8644,39 +11629,51 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.2",
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0"
+ "@csstools/css-color-parser": "^3.0.7",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/utilities": "^2.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-loader": {
- "version": "7.3.3",
- "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz",
- "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==",
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz",
+ "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cosmiconfig": "^8.2.0",
- "jiti": "^1.18.2",
- "semver": "^7.3.8"
+ "cosmiconfig": "^9.0.0",
+ "jiti": "^1.20.0",
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">= 14.15.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
"postcss": "^7.0.0 || ^8.0.1",
"webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
}
},
"node_modules/postcss-loader/node_modules/lru-cache": {
@@ -8713,9 +11710,9 @@
"dev": true
},
"node_modules/postcss-logical": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-7.0.0.tgz",
- "integrity": "sha512-zYf3vHkoW82f5UZTEXChTJvH49Yl9X37axTZsJGxrCG2kOUwtaAoz9E7tqYg0lsIoJLybaL8fk/2mOi81zVIUw==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.0.0.tgz",
+ "integrity": "sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg==",
"dev": true,
"funding": [
{
@@ -8727,21 +11724,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-modules-extract-imports": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
- "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "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"
},
@@ -8750,13 +11749,14 @@
}
},
"node_modules/postcss-modules-local-by-default": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz",
- "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==",
+ "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": "^6.0.2",
+ "postcss-selector-parser": "^7.0.0",
"postcss-value-parser": "^4.1.0"
},
"engines": {
@@ -8767,12 +11767,13 @@
}
},
"node_modules/postcss-modules-scope": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
- "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+ "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": "^6.0.4"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
"node": "^10 || ^12 || >= 14"
@@ -8797,9 +11798,9 @@
}
},
"node_modules/postcss-nesting": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.0.1.tgz",
- "integrity": "sha512-6LCqCWP9pqwXw/njMvNK0hGY44Fxc4B2EsGbn6xDcxbNRzP8GYoxT7yabVVMLrX3quqOJ9hg2jYMsnkedOf8pA==",
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
+ "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==",
"dev": true,
"funding": [
{
@@ -8811,21 +11812,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^3.0.0",
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/selector-resolve-nested": "^3.0.0",
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-opacity-percentage": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-2.0.0.tgz",
- "integrity": "sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz",
+ "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==",
"dev": true,
"funding": [
{
@@ -8837,17 +11840,18 @@
"url": "https://liberapay.com/mrcgrtz"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "postcss": "^8.2"
+ "postcss": "^8.4"
}
},
"node_modules/postcss-overflow-shorthand": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-5.0.0.tgz",
- "integrity": "sha512-2rlxDyeSics/hC2FuMdPnWiP9WUPZ5x7FTuArXLFVpaSQ2woPSfZS4RD59HuEokbZhs/wPUQJ1E3MT6zVv94MQ==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz",
+ "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==",
"dev": true,
"funding": [
{
@@ -8859,11 +11863,12 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -8879,9 +11884,9 @@
}
},
"node_modules/postcss-place": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-9.0.0.tgz",
- "integrity": "sha512-qLEPD9VPH5opDVemwmRaujODF9nExn24VOC3ghgVLEvfYN7VZLwJHes0q/C9YR5hI2UC3VgBE8Wkdp1TxCXhtg==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz",
+ "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==",
"dev": true,
"funding": [
{
@@ -8893,20 +11898,21 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-preset-env": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-9.1.1.tgz",
- "integrity": "sha512-rMPEqyTLm8JLbvaHnDAdQg6SN4Z/NDOsm+CRefg4HmSOiNpTcBXaw4RAaQbfTNe8BB75l4NpoQ6sMdrutdEpdQ==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.1.3.tgz",
+ "integrity": "sha512-9qzVhcMFU/MnwYHyYpJz4JhGku/4+xEiPTmhn0hj3IxnUYlEF9vbh7OC1KoLAnenS6Fgg43TKNp9xcuMeAi4Zw==",
"dev": true,
"funding": [
{
@@ -8918,76 +11924,83 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-cascade-layers": "^4.0.0",
- "@csstools/postcss-color-function": "^3.0.1",
- "@csstools/postcss-color-mix-function": "^2.0.1",
- "@csstools/postcss-exponential-functions": "^1.0.0",
- "@csstools/postcss-font-format-keywords": "^3.0.0",
- "@csstools/postcss-gradients-interpolation-method": "^4.0.1",
- "@csstools/postcss-hwb-function": "^3.0.1",
- "@csstools/postcss-ic-unit": "^3.0.0",
- "@csstools/postcss-is-pseudo-class": "^4.0.0",
- "@csstools/postcss-logical-float-and-clear": "^2.0.0",
- "@csstools/postcss-logical-resize": "^2.0.0",
- "@csstools/postcss-logical-viewport-units": "^2.0.1",
- "@csstools/postcss-media-minmax": "^1.0.7",
- "@csstools/postcss-media-queries-aspect-ratio-number-values": "^2.0.2",
- "@csstools/postcss-nested-calc": "^3.0.0",
- "@csstools/postcss-normalize-display-values": "^3.0.0",
- "@csstools/postcss-oklab-function": "^3.0.1",
- "@csstools/postcss-progressive-custom-properties": "^3.0.0",
- "@csstools/postcss-relative-color-syntax": "^2.0.1",
- "@csstools/postcss-scope-pseudo-class": "^3.0.0",
- "@csstools/postcss-stepped-value-functions": "^3.0.1",
- "@csstools/postcss-text-decoration-shorthand": "^3.0.0",
- "@csstools/postcss-trigonometric-functions": "^3.0.1",
- "@csstools/postcss-unset-value": "^3.0.0",
- "autoprefixer": "^10.4.14",
- "browserslist": "^4.21.10",
- "css-blank-pseudo": "^6.0.0",
- "css-has-pseudo": "^6.0.0",
- "css-prefers-color-scheme": "^9.0.0",
- "cssdb": "^7.7.0",
- "postcss-attribute-case-insensitive": "^6.0.2",
+ "@csstools/postcss-cascade-layers": "^5.0.1",
+ "@csstools/postcss-color-function": "^4.0.7",
+ "@csstools/postcss-color-mix-function": "^3.0.7",
+ "@csstools/postcss-content-alt-text": "^2.0.4",
+ "@csstools/postcss-exponential-functions": "^2.0.6",
+ "@csstools/postcss-font-format-keywords": "^4.0.0",
+ "@csstools/postcss-gamut-mapping": "^2.0.7",
+ "@csstools/postcss-gradients-interpolation-method": "^5.0.7",
+ "@csstools/postcss-hwb-function": "^4.0.7",
+ "@csstools/postcss-ic-unit": "^4.0.0",
+ "@csstools/postcss-initial": "^2.0.0",
+ "@csstools/postcss-is-pseudo-class": "^5.0.1",
+ "@csstools/postcss-light-dark-function": "^2.0.7",
+ "@csstools/postcss-logical-float-and-clear": "^3.0.0",
+ "@csstools/postcss-logical-overflow": "^2.0.0",
+ "@csstools/postcss-logical-overscroll-behavior": "^2.0.0",
+ "@csstools/postcss-logical-resize": "^3.0.0",
+ "@csstools/postcss-logical-viewport-units": "^3.0.3",
+ "@csstools/postcss-media-minmax": "^2.0.6",
+ "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.4",
+ "@csstools/postcss-nested-calc": "^4.0.0",
+ "@csstools/postcss-normalize-display-values": "^4.0.0",
+ "@csstools/postcss-oklab-function": "^4.0.7",
+ "@csstools/postcss-progressive-custom-properties": "^4.0.0",
+ "@csstools/postcss-random-function": "^1.0.2",
+ "@csstools/postcss-relative-color-syntax": "^3.0.7",
+ "@csstools/postcss-scope-pseudo-class": "^4.0.1",
+ "@csstools/postcss-sign-functions": "^1.1.1",
+ "@csstools/postcss-stepped-value-functions": "^4.0.6",
+ "@csstools/postcss-text-decoration-shorthand": "^4.0.1",
+ "@csstools/postcss-trigonometric-functions": "^4.0.6",
+ "@csstools/postcss-unset-value": "^4.0.0",
+ "autoprefixer": "^10.4.19",
+ "browserslist": "^4.23.1",
+ "css-blank-pseudo": "^7.0.1",
+ "css-has-pseudo": "^7.0.2",
+ "css-prefers-color-scheme": "^10.0.0",
+ "cssdb": "^8.2.3",
+ "postcss-attribute-case-insensitive": "^7.0.1",
"postcss-clamp": "^4.1.0",
- "postcss-color-functional-notation": "^6.0.0",
- "postcss-color-hex-alpha": "^9.0.2",
- "postcss-color-rebeccapurple": "^9.0.0",
- "postcss-custom-media": "^10.0.0",
- "postcss-custom-properties": "^13.3.0",
- "postcss-custom-selectors": "^7.1.4",
- "postcss-dir-pseudo-class": "^8.0.0",
- "postcss-double-position-gradients": "^5.0.0",
- "postcss-focus-visible": "^9.0.0",
- "postcss-focus-within": "^8.0.0",
+ "postcss-color-functional-notation": "^7.0.7",
+ "postcss-color-hex-alpha": "^10.0.0",
+ "postcss-color-rebeccapurple": "^10.0.0",
+ "postcss-custom-media": "^11.0.5",
+ "postcss-custom-properties": "^14.0.4",
+ "postcss-custom-selectors": "^8.0.4",
+ "postcss-dir-pseudo-class": "^9.0.1",
+ "postcss-double-position-gradients": "^6.0.0",
+ "postcss-focus-visible": "^10.0.1",
+ "postcss-focus-within": "^9.0.1",
"postcss-font-variant": "^5.0.0",
- "postcss-gap-properties": "^5.0.0",
- "postcss-image-set-function": "^6.0.0",
- "postcss-initial": "^4.0.1",
- "postcss-lab-function": "^6.0.1",
- "postcss-logical": "^7.0.0",
- "postcss-nesting": "^12.0.1",
- "postcss-opacity-percentage": "^2.0.0",
- "postcss-overflow-shorthand": "^5.0.0",
+ "postcss-gap-properties": "^6.0.0",
+ "postcss-image-set-function": "^7.0.0",
+ "postcss-lab-function": "^7.0.7",
+ "postcss-logical": "^8.0.0",
+ "postcss-nesting": "^13.0.1",
+ "postcss-opacity-percentage": "^3.0.0",
+ "postcss-overflow-shorthand": "^6.0.0",
"postcss-page-break": "^3.0.4",
- "postcss-place": "^9.0.0",
- "postcss-pseudo-class-any-link": "^9.0.0",
+ "postcss-place": "^10.0.0",
+ "postcss-pseudo-class-any-link": "^10.0.1",
"postcss-replace-overflow-wrap": "^4.0.0",
- "postcss-selector-not": "^7.0.1",
- "postcss-value-parser": "^4.2.0"
+ "postcss-selector-not": "^8.0.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-pseudo-class-any-link": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-9.0.0.tgz",
- "integrity": "sha512-QNCYIL98VKFKY6HGDEJpF6+K/sg9bxcUYnOmNHJxZS5wsFDFaVoPeG68WAuhsqwbIBSo/b9fjEnTwY2mTSD+uA==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz",
+ "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==",
"dev": true,
"funding": [
{
@@ -8999,11 +12012,12 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -9019,29 +12033,37 @@
}
},
"node_modules/postcss-selector-not": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-7.0.1.tgz",
- "integrity": "sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz",
+ "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
- "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -9057,9 +12079,9 @@
"dev": true
},
"node_modules/postcss/node_modules/nanoid": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
- "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
@@ -9067,6 +12089,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -9083,33 +12106,6 @@
"url": "https://opencollective.com/preact"
}
},
- "node_modules/prebuild-install": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
- "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- },
- "bin": {
- "prebuild-install": "bin.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/pretty-error": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
@@ -9158,6 +12154,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
"integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==",
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"retry": "^0.12.0",
@@ -9182,6 +12179,7 @@
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
@@ -9195,6 +12193,7 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.10"
}
@@ -9205,22 +12204,12 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
- "node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/punycode": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
- "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "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"
}
@@ -9231,12 +12220,13 @@
"integrity": "sha512-IdYbGwbmuA7Hy9ACIO1q7ks4xGLcJSVHxJT2BXIz2c4Ve1aSrNU5bAzA1ILT4Gmdy5K59ruWoRPf9WvJZU5fbA=="
},
"node_modules/qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "side-channel": "^1.0.4"
+ "side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@@ -9322,15 +12312,17 @@
"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/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@@ -9346,26 +12338,11 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "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)",
- "optional": true,
- "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/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@@ -9496,36 +12473,47 @@
}
}
},
- "node_modules/react-router": {
- "version": "6.24.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.0.tgz",
- "integrity": "sha512-sQrgJ5bXk7vbcC4BxQxeNa5UmboFm35we1AFK0VvQaz9g0LzxEIuLOhHIoZ8rnu9BO21ishGeL9no1WB76W/eg==",
+ "node_modules/react-refresh": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@remix-run/router": "1.17.0"
- },
"engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8"
+ "node": ">=0.10.0"
}
},
- "node_modules/react-router-dom": {
- "version": "6.24.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.0.tgz",
- "integrity": "sha512-960sKuau6/yEwS8e+NVEidYQb1hNjAYM327gjEyXlc6r3Skf2vtwuJ2l7lssdegD2YjoKG5l8MsVyeTDlVeY8g==",
+ "node_modules/react-router": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz",
+ "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==",
"license": "MIT",
"dependencies": {
- "@remix-run/router": "1.17.0",
- "react-router": "6.24.0"
+ "@types/cookie": "^0.6.0",
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0",
+ "turbo-stream": "2.4.0"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=20.0.0"
},
"peerDependencies": {
- "react": ">=16.8",
- "react-dom": ">=16.8"
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router/node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/react-syntax-highlighter": {
@@ -9548,7 +12536,7 @@
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -9563,6 +12551,7 @@
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -9625,13 +12614,15 @@
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/regenerate-unicode-properties": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
- "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"regenerate": "^1.4.2"
},
@@ -9640,29 +12631,32 @@
}
},
"node_modules/regenerator-runtime": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
},
"node_modules/regenerator-transform": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
"integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.8.4"
}
},
"node_modules/regexpu-core": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
- "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/regjsgen": "^0.8.0",
"regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsparser": "^0.9.1",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.1.0"
},
@@ -9670,25 +12664,37 @@
"node": ">=4"
}
},
- "node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "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.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/relateurl": {
@@ -9810,6 +12816,7 @@
"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"
}
@@ -9827,6 +12834,7 @@
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -9842,20 +12850,127 @@
}
},
"node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
+ "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "glob": "^7.1.3"
+ "glob": "^11.0.0",
+ "package-json-from-dist": "^1.0.0"
},
"bin": {
- "rimraf": "bin.js"
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/rimraf/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
+ "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^4.0.1",
+ "minimatch": "^10.0.0",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/minimatch": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
+ "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.34.7",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.7.tgz",
+ "integrity": "sha512-8qhyN0oZ4x0H6wmBgfKxJtxM7qS98YJ0k0kNh5ECVtuchIJ7z9IVVvzpmtQyT10PXKMtBxYr1wQ5Apg8RS8kXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.34.7",
+ "@rollup/rollup-android-arm64": "4.34.7",
+ "@rollup/rollup-darwin-arm64": "4.34.7",
+ "@rollup/rollup-darwin-x64": "4.34.7",
+ "@rollup/rollup-freebsd-arm64": "4.34.7",
+ "@rollup/rollup-freebsd-x64": "4.34.7",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.34.7",
+ "@rollup/rollup-linux-arm-musleabihf": "4.34.7",
+ "@rollup/rollup-linux-arm64-gnu": "4.34.7",
+ "@rollup/rollup-linux-arm64-musl": "4.34.7",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.34.7",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.34.7",
+ "@rollup/rollup-linux-riscv64-gnu": "4.34.7",
+ "@rollup/rollup-linux-s390x-gnu": "4.34.7",
+ "@rollup/rollup-linux-x64-gnu": "4.34.7",
+ "@rollup/rollup-linux-x64-musl": "4.34.7",
+ "@rollup/rollup-win32-arm64-msvc": "4.34.7",
+ "@rollup/rollup-win32-ia32-msvc": "4.34.7",
+ "@rollup/rollup-win32-x64-msvc": "4.34.7",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
+ "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -9905,13 +13020,14 @@
"dev": true
},
"node_modules/sass": {
- "version": "1.66.1",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz",
- "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==",
+ "version": "1.84.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.84.0.tgz",
+ "integrity": "sha512-XDAbhEPJRxi7H0SxrnOpiXFQoUJHwkR2u3Zc4el+fK/Tt5Hpzw5kkQ59qVDfvdaUq6gCrEZIbySFBM2T9DNKHg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
+ "chokidar": "^4.0.0",
+ "immutable": "^5.0.2",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
@@ -9919,32 +13035,36 @@
},
"engines": {
"node": ">=14.0.0"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
}
},
"node_modules/sass-loader": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.1.1.tgz",
- "integrity": "sha512-fOCp/zLmj1V1WHDZbUbPgrZhA7HKXHEqkslzB+05U5K9SbSbcmH91C7QLW31AsXikxUMaxXRhhcqWZAxUMLDyA==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.4.tgz",
+ "integrity": "sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "klona": "^2.0.4",
"neo-async": "^2.6.2"
},
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "fibers": ">= 3.1.0",
- "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0",
+ "@rspack/core": "0.x || 1.x",
+ "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"sass": "^1.3.0",
+ "sass-embedded": "*",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
- "fibers": {
+ "@rspack/core": {
"optional": true
},
"node-sass": {
@@ -9952,9 +13072,52 @@
},
"sass": {
"optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
}
}
},
+ "node_modules/sass/node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/sass/node_modules/immutable": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz",
+ "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sass/node_modules/readdirp": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
+ "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/sax": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
@@ -9969,17 +13132,19 @@
}
},
"node_modules/schema-utils": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
- "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/json-schema": "^7.0.5",
- "ajv": "^6.12.4",
- "ajv-keywords": "^3.5.2"
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
},
"engines": {
- "node": ">= 8.9.0"
+ "node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
@@ -9993,11 +13158,13 @@
"dev": true
},
"node_modules/selfsigned": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz",
- "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz",
+ "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
+ "@types/node-forge": "^1.3.0",
"node-forge": "^1"
},
"engines": {
@@ -10014,10 +13181,11 @@
}
},
"node_modules/send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
@@ -10042,6 +13210,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -10050,13 +13219,25 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
},
"node_modules/send/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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/serialize-error": {
"version": "8.1.0",
@@ -10074,10 +13255,11 @@
}
},
"node_modules/serialize-javascript": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
- "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
}
@@ -10161,25 +13343,33 @@
}
},
"node_modules/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
- "send": "0.18.0"
+ "send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/sha.js": {
"version": "2.4.11",
@@ -10208,6 +13398,7 @@
"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"
},
@@ -10215,6 +13406,12 @@
"node": ">=8"
}
},
+ "node_modules/shallow-equal": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz",
+ "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==",
+ "license": "MIT"
+ },
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
@@ -10243,10 +13440,14 @@
}
},
"node_modules/shell-quote": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
- "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -10262,14 +13463,76 @@
}
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "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": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "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.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "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"
@@ -10280,53 +13543,6 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
- "node_modules/simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "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",
- "optional": true
- },
- "node_modules/simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "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",
- "optional": true,
- "dependencies": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
"node_modules/sirv": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
@@ -10343,12 +13559,16 @@
}
},
"node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sockjs": {
@@ -10378,10 +13598,11 @@
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "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"
}
@@ -10447,6 +13668,7 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -10465,11 +13687,81 @@
"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==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
+ "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/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-width-cjs/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/string-width/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -10482,74 +13774,61 @@
"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-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": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/style-loader": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz",
- "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz",
+ "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==",
"dev": true,
- "dependencies": {
- "loader-utils": "^2.0.0",
- "schema-utils": "^3.0.0"
- },
+ "license": "MIT",
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^4.0.0 || ^5.0.0"
- }
- },
- "node_modules/style-loader/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,
- "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"
+ "webpack": "^5.27.0"
}
},
"node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "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": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/supports-preserve-symlinks-flag": {
@@ -10565,51 +13844,45 @@
}
},
"node_modules/swagger-client": {
- "version": "3.29.2",
- "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.29.2.tgz",
- "integrity": "sha512-7dOIAodJeUsYbvWTpDODY2+bfJcZ34WG84TByMet76OJ/ZjOLHZtJSgMFxEvnh9+yR0qn8wvHUdfg27ylg2eiQ==",
+ "version": "3.34.0",
+ "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.34.0.tgz",
+ "integrity": "sha512-DQyg74J1XjpzmoOrSX0/x8OP7feeEzLTQ4ILe15TJ7oTXeC6XKQvnc5z59H5rW7vFxe+rkMlbzLCg/ri0w7Rag==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.22.15",
- "@swagger-api/apidom-core": ">=1.0.0-alpha.9 <1.0.0-beta.0",
- "@swagger-api/apidom-error": ">=1.0.0-alpha.9 <1.0.0-beta.0",
- "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.9 <1.0.0-beta.0",
- "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-alpha.9 <1.0.0-beta.0",
- "@swagger-api/apidom-reference": ">=1.0.0-alpha.9 <1.0.0-beta.0",
- "cookie": "~0.6.0",
+ "@scarf/scarf": "=1.4.0",
+ "@swagger-api/apidom-core": ">=1.0.0-beta.11 <1.0.0-rc.0",
+ "@swagger-api/apidom-error": ">=1.0.0-beta.11 <1.0.0-rc.0",
+ "@swagger-api/apidom-json-pointer": ">=1.0.0-beta.11 <1.0.0-rc.0",
+ "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-beta.11 <1.0.0-rc.0",
+ "@swagger-api/apidom-reference": ">=1.0.0-beta.11 <1.0.0-rc.0",
+ "@swaggerexpert/cookie": "^1.4.1",
"deepmerge": "~4.3.0",
"fast-json-patch": "^3.0.0-1",
"js-yaml": "^4.1.0",
"neotraverse": "=0.6.18",
"node-abort-controller": "^3.1.1",
"node-fetch-commonjs": "^3.3.2",
- "openapi-path-templating": "^1.5.1",
- "openapi-server-url-templating": "^1.0.0",
+ "openapi-path-templating": "^2.0.1",
+ "openapi-server-url-templating": "^1.2.0",
+ "ramda": "^0.30.1",
"ramda-adjunct": "^5.0.0"
}
},
- "node_modules/swagger-client/node_modules/cookie": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/swagger-ui-react": {
- "version": "5.17.14",
- "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.17.14.tgz",
- "integrity": "sha512-mCXerZrbcn4ftPYifUF0+iKIRTHoVCv0HcJc/sXl9nCe3oeWdsjmOWVqKabzzAkAa0NwsbKNJFv2UL/Ivnf6VQ==",
+ "version": "5.18.3",
+ "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.18.3.tgz",
+ "integrity": "sha512-TlcIdQlcbdvRpUP3+B/J08ARM6cC29eMRrNxhTjP/MtYlbuGg6DWET7Is65YTlsk3TE6NhRYVgf3sdqcLooIBw==",
"license": "Apache-2.0",
"dependencies": {
- "@babel/runtime-corejs3": "^7.24.5",
- "@braintree/sanitize-url": "=7.0.2",
+ "@babel/runtime-corejs3": "^7.24.7",
+ "@braintree/sanitize-url": "=7.0.4",
+ "@scarf/scarf": "=1.4.0",
"base64-js": "^1.5.1",
"classnames": "^2.5.1",
"css.escape": "1.5.1",
"deep-extend": "0.6.0",
- "dompurify": "=3.1.4",
+ "dompurify": "=3.1.6",
"ieee754": "^1.2.1",
"immutable": "^3.x.x",
"js-file-download": "^0.4.12",
@@ -10628,10 +13901,10 @@
"redux": "^5.0.1",
"redux-immutable": "^4.0.0",
"remarkable": "^2.0.1",
- "reselect": "^5.1.0",
+ "reselect": "^5.1.1",
"serialize-error": "^8.1.0",
"sha.js": "^2.4.11",
- "swagger-client": "^3.28.1",
+ "swagger-client": "^3.34.0",
"url-parse": "^1.5.10",
"xml": "=1.0.1",
"xml-but-prettier": "^1.0.1",
@@ -10651,6 +13924,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/systemjs": {
+ "version": "6.15.1",
+ "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.15.1.tgz",
+ "integrity": "sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -10660,41 +13940,12 @@
"node": ">=6"
}
},
- "node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/terser": {
- "version": "5.19.2",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
- "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
+ "version": "5.39.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
+ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -10709,16 +13960,17 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.9",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
- "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+ "version": "5.3.11",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz",
+ "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.16.8"
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -10742,39 +13994,25 @@
}
}
},
- "node_modules/terser-webpack-plugin/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,
- "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/terser-webpack-plugin/node_modules/serialize-javascript": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
- "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
- "dev": true,
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
"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
},
+ "node_modules/thingies": {
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz",
+ "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==",
+ "dev": true,
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=10.18"
+ },
+ "peerDependencies": {
+ "tslib": "^2"
+ }
+ },
"node_modules/three": {
"version": "0.105.2",
"resolved": "https://registry.npmjs.org/three/-/three-0.105.2.tgz",
@@ -10784,22 +14022,15 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
- "engines": {
- "node": ">=4"
- }
+ "license": "MIT"
},
"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"
},
@@ -10818,10 +14049,20 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.6"
}
},
+ "node_modules/tosource": {
+ "version": "2.0.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz",
+ "integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@@ -10832,45 +14073,83 @@
"node": ">=6"
}
},
+ "node_modules/tree-dump": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz",
+ "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
"node_modules/tree-sitter": {
- "version": "0.20.4",
- "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz",
- "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==",
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz",
+ "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
+ "peer": true,
"dependencies": {
- "nan": "^2.17.0",
- "prebuild-install": "^7.1.1"
+ "node-addon-api": "^8.0.0",
+ "node-gyp-build": "^4.8.0"
}
},
"node_modules/tree-sitter-json": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.2.tgz",
- "integrity": "sha512-eUxrowp4F1QEGk/i7Sa+Xl8Crlfp7J0AXxX1QdJEQKQYMWhgMbCIgyQvpO3Q0P9oyTrNQxRLlRipDS44a8EtRw==",
+ "version": "0.24.8",
+ "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.24.8.tgz",
+ "integrity": "sha512-Tc9ZZYwHyWZ3Tt1VEw7Pa2scu1YO7/d2BCBbKTx5hXwig3UfdQjsOPkPyLpDJOn/m1UBEWYAtSdGAwCSyagBqQ==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "nan": "^2.18.0"
+ "node-addon-api": "^8.2.2",
+ "node-gyp-build": "^4.8.2"
+ },
+ "peerDependencies": {
+ "tree-sitter": "^0.21.1"
+ },
+ "peerDependenciesMeta": {
+ "tree-sitter": {
+ "optional": true
+ }
}
},
- "node_modules/tree-sitter-yaml": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz",
- "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==",
- "hasInstallScript": true,
+ "node_modules/tree-sitter-json/node_modules/node-addon-api": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz",
+ "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==",
"license": "MIT",
"optional": true,
- "dependencies": {
- "nan": "^2.14.0"
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
+ "node_modules/tree-sitter/node_modules/node-addon-api": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz",
+ "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
}
},
"node_modules/ts-loader": {
- "version": "9.5.1",
- "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
- "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
+ "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"chalk": "^4.1.0",
"enhanced-resolve": "^5.0.0",
@@ -10886,64 +14165,6 @@
"webpack": "^5.0.0"
}
},
- "node_modules/ts-loader/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,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/ts-loader/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,
- "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/ts-loader/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,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/ts-loader/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
- },
- "node_modules/ts-loader/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,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ts-loader/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -10980,18 +14201,6 @@
"node": ">= 8"
}
},
- "node_modules/ts-loader/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,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ts-loader/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -11015,23 +14224,17 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
- "node_modules/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "license": "Apache-2.0",
- "optional": true,
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
+ "node_modules/turbo-stream": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
+ "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
+ "license": "ISC"
},
"node_modules/tus-js-client": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.1.tgz",
- "integrity": "sha512-SZzWP62jEFLmROSRZx+uoGLKqsYWMGK/m+PiNehPVWbCm7/S9zRIMaDxiaOcKdMnFno4luaqP5E+Y1iXXPjP0A==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-4.3.1.tgz",
+ "integrity": "sha512-ZLeYmjrkaU1fUsKbIi8JML52uAocjEZtBx4DKjRrqzrZa0O4MYwT6db+oqePlspV+FxXJAyFBc/L5gwUi2OFsg==",
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.1.2",
"combine-errors": "^3.0.3",
@@ -11040,6 +14243,9 @@
"lodash.throttle": "^4.1.1",
"proper-lockfile": "^4.1.2",
"url-parse": "^1.5.7"
+ },
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/type-fest": {
@@ -11059,6 +14265,7 @@
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
@@ -11077,10 +14284,11 @@
}
},
"node_modules/typescript": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
- "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"dev": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -11107,11 +14315,29 @@
"node": "*"
}
},
- "node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "node_modules/undici": {
+ "version": "6.21.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
+ "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "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"
}
@@ -11121,6 +14347,7 @@
"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"
@@ -11130,10 +14357,11 @@
}
},
"node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -11143,10 +14371,24 @@
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
"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/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -11161,6 +14403,7 @@
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -11172,9 +14415,9 @@
"license": "MIT"
},
"node_modules/update-browserslist-db": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
- "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
+ "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
"dev": true,
"funding": [
{
@@ -11190,9 +14433,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -11206,6 +14450,7 @@
"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"
}
@@ -11232,7 +14477,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "devOptional": true
+ "dev": true
},
"node_modules/utila": {
"version": "0.4.0",
@@ -11245,6 +14490,7 @@
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
@@ -11275,11 +14521,248 @@
"global": "^4.3.1"
}
},
- "node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "node_modules/vite": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
+ "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.24.2",
+ "postcss": "^8.5.1",
+ "rollup": "^4.30.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-css-modules": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/vite-css-modules/-/vite-css-modules-1.8.4.tgz",
+ "integrity": "sha512-FpHXNyih8rs7TnnzYuLyPvGHWUJ98tJSEFQDjXK/undcidQr5uIPeBZOsojTBVFk7T+Bd9U/ucdJFNUojTNrRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@rollup/pluginutils": "^5.1.4",
+ "generic-names": "^4.0.0",
+ "icss-utils": "^5.1.0",
+ "magic-string": "^0.30.17",
+ "postcss-modules-extract-imports": "^3.1.0",
+ "postcss-modules-local-by-default": "^4.2.0",
+ "postcss-modules-scope": "^3.2.1",
+ "postcss-modules-values": "^4.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/vite-css-modules?sponsor=1"
+ },
+ "peerDependencies": {
+ "lightningcss": "^1.23.0",
+ "postcss": "^8.4.33",
+ "vite": "^5.0.12 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "lightningcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-css-modules/node_modules/@rollup/pluginutils": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
+ "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-css-modules/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vite-plugin-html": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-html/-/vite-plugin-html-3.2.2.tgz",
+ "integrity": "sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^4.2.0",
+ "colorette": "^2.0.16",
+ "connect-history-api-fallback": "^1.6.0",
+ "consola": "^2.15.3",
+ "dotenv": "^16.0.0",
+ "dotenv-expand": "^8.0.2",
+ "ejs": "^3.1.6",
+ "fast-glob": "^3.2.11",
+ "fs-extra": "^10.0.1",
+ "html-minifier-terser": "^6.1.0",
+ "node-html-parser": "^5.3.3",
+ "pathe": "^0.2.0"
+ },
+ "peerDependencies": {
+ "vite": ">=2.0.0"
+ }
+ },
+ "node_modules/vite-plugin-html/node_modules/@rollup/pluginutils": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
+ "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "estree-walker": "^2.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/vite-plugin-html/node_modules/connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/vite-plugin-html/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/vite-plugin-static-copy": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz",
+ "integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.3",
+ "fast-glob": "^3.2.11",
+ "fs-extra": "^11.1.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0"
+ }
+ },
+ "node_modules/vite/node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
+ "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -11307,41 +14790,41 @@
}
},
"node_modules/web-tree-sitter": {
- "version": "0.20.3",
- "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz",
- "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==",
+ "version": "0.24.5",
+ "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz",
+ "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==",
"license": "MIT",
"optional": true
},
"node_modules/webpack": {
- "version": "5.88.2",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
- "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+ "version": "5.97.1",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz",
+ "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/eslint-scope": "^3.7.3",
- "@types/estree": "^1.0.0",
- "@webassemblyjs/ast": "^1.11.5",
- "@webassemblyjs/wasm-edit": "^1.11.5",
- "@webassemblyjs/wasm-parser": "^1.11.5",
- "acorn": "^8.7.1",
- "acorn-import-assertions": "^1.9.0",
- "browserslist": "^4.14.5",
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.6",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.14.0",
+ "browserslist": "^4.24.0",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.15.0",
+ "enhanced-resolve": "^5.17.1",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.3.7",
- "watchpack": "^2.4.0",
+ "terser-webpack-plugin": "^5.3.10",
+ "watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
"bin": {
@@ -11433,42 +14916,40 @@
}
},
"node_modules/webpack-cli": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
- "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz",
+ "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.1.1",
- "@webpack-cli/info": "^2.0.2",
- "@webpack-cli/serve": "^2.0.5",
+ "@discoveryjs/json-ext": "^0.6.1",
+ "@webpack-cli/configtest": "^3.0.1",
+ "@webpack-cli/info": "^3.0.1",
+ "@webpack-cli/serve": "^3.0.1",
"colorette": "^2.0.14",
- "commander": "^10.0.1",
+ "commander": "^12.1.0",
"cross-spawn": "^7.0.3",
- "envinfo": "^7.7.3",
+ "envinfo": "^7.14.0",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2",
"interpret": "^3.1.1",
"rechoir": "^0.8.0",
- "webpack-merge": "^5.7.3"
+ "webpack-merge": "^6.0.1"
},
"bin": {
"webpack-cli": "bin/cli.js"
},
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "5.x.x"
+ "webpack": "^5.82.0"
},
"peerDependenciesMeta": {
- "@webpack-cli/generators": {
- "optional": true
- },
"webpack-bundle-analyzer": {
"optional": true
},
@@ -11477,20 +14958,32 @@
}
}
},
- "node_modules/webpack-cli/node_modules/commander": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
- "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
+ "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14"
+ "node": ">=14.17.0"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/webpack-dev-middleware": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
- "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+ "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"colorette": "^2.0.10",
"memfs": "^3.4.3",
@@ -11509,114 +15002,53 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
- "node_modules/webpack-dev-middleware/node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.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,
- "dependencies": {
- "fast-deep-equal": "^3.1.3"
- },
- "peerDependencies": {
- "ajv": "^8.8.2"
- }
- },
- "node_modules/webpack-dev-middleware/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
- },
- "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
- },
- "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
- "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "ajv": "^8.9.0",
- "ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.1.0"
- },
- "engines": {
- "node": ">= 12.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/webpack-dev-server": {
- "version": "4.15.1",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz",
- "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz",
+ "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/bonjour": "^3.5.9",
- "@types/connect-history-api-fallback": "^1.3.5",
- "@types/express": "^4.17.13",
- "@types/serve-index": "^1.9.1",
- "@types/serve-static": "^1.13.10",
- "@types/sockjs": "^0.3.33",
- "@types/ws": "^8.5.5",
+ "@types/bonjour": "^3.5.13",
+ "@types/connect-history-api-fallback": "^1.5.4",
+ "@types/express": "^4.17.21",
+ "@types/serve-index": "^1.9.4",
+ "@types/serve-static": "^1.15.5",
+ "@types/sockjs": "^0.3.36",
+ "@types/ws": "^8.5.10",
"ansi-html-community": "^0.0.8",
- "bonjour-service": "^1.0.11",
- "chokidar": "^3.5.3",
+ "bonjour-service": "^1.2.1",
+ "chokidar": "^3.6.0",
"colorette": "^2.0.10",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
- "default-gateway": "^6.0.3",
- "express": "^4.17.3",
+ "express": "^4.21.2",
"graceful-fs": "^4.2.6",
- "html-entities": "^2.3.2",
- "http-proxy-middleware": "^2.0.3",
- "ipaddr.js": "^2.0.1",
- "launch-editor": "^2.6.0",
- "open": "^8.0.9",
- "p-retry": "^4.5.0",
- "rimraf": "^3.0.2",
- "schema-utils": "^4.0.0",
- "selfsigned": "^2.1.1",
+ "http-proxy-middleware": "^2.0.7",
+ "ipaddr.js": "^2.1.0",
+ "launch-editor": "^2.6.1",
+ "open": "^10.0.3",
+ "p-retry": "^6.2.0",
+ "schema-utils": "^4.2.0",
+ "selfsigned": "^2.4.1",
"serve-index": "^1.9.1",
"sockjs": "^0.3.24",
"spdy": "^4.0.2",
- "webpack-dev-middleware": "^5.3.1",
- "ws": "^8.13.0"
+ "webpack-dev-middleware": "^7.4.2",
+ "ws": "^8.18.0"
},
"bin": {
"webpack-dev-server": "bin/webpack-dev-server.js"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "^4.37.0 || ^5.0.0"
+ "webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"webpack": {
@@ -11627,79 +15059,137 @@
}
}
},
- "node_modules/webpack-dev-server/node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "node_modules/webpack-dev-server/node_modules/@types/retry": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
+ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webpack-dev-server/node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/is-wsl": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/memfs": {
+ "version": "4.17.0",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz",
+ "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/json-pack": "^1.0.3",
+ "@jsonjoy.com/util": "^1.3.0",
+ "tree-dump": "^1.0.1",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "url": "https://github.com/sponsors/streamich"
}
},
- "node_modules/webpack-dev-server/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==",
+ "node_modules/webpack-dev-server/node_modules/open": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
+ "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.3"
- },
- "peerDependencies": {
- "ajv": "^8.8.2"
- }
- },
- "node_modules/webpack-dev-server/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
- },
- "node_modules/webpack-dev-server/node_modules/html-entities": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz",
- "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/mdevils"
- },
- {
- "type": "patreon",
- "url": "https://patreon.com/mdevils"
- }
- ]
- },
- "node_modules/webpack-dev-server/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
- },
- "node_modules/webpack-dev-server/node_modules/schema-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
- "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "ajv": "^8.9.0",
- "ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.1.0"
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "is-wsl": "^3.1.0"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/p-retry": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
+ "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.2",
+ "is-network-error": "^1.0.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz",
+ "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "colorette": "^2.0.10",
+ "memfs": "^4.6.0",
+ "mime-types": "^2.1.31",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack": {
+ "optional": true
+ }
}
},
"node_modules/webpack-manifest-plugin": {
@@ -11732,34 +15222,68 @@
}
},
"node_modules/webpack-merge": {
- "version": "5.9.0",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz",
- "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==",
+ "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",
- "wildcard": "^2.0.0"
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.1"
},
"engines": {
- "node": ">=10.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/webpack-merge/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
- },
- "node_modules/webpack-sources": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
- "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "source-list-map": "^2.0.0",
- "source-map": "~0.6.1"
+ "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/webpack/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/webpack/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/webpack/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/webpack/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
@@ -11810,10 +15334,41 @@
"node": ">=0.8.0"
}
},
- "node_modules/whatwg-fetch": {
- "version": "3.6.17",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz",
- "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ=="
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-encoding/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/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/which": {
"version": "2.0.2",
@@ -11835,17 +15390,122 @@
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
"integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
},
+ "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/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-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==",
- "devOptional": true
+ "dev": true
},
"node_modules/ws": {
- "version": "8.13.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
- "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10.0.0"
},
@@ -11890,12 +15550,13 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/yaml": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
- "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -11906,12 +15567,13 @@
}
},
"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==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
+ "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
diff --git a/client/package.json b/client/package.json
index 8a8234c..c273183 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,14 +1,20 @@
{
"name": "kemono-2-client",
- "version": "1.0.0",
+ "version": "1.4.0",
"description": "frontend for kemono 2",
"private": true,
"author": "BassOfBass",
"license": "ISC",
"scripts": {
- "dev": "webpack serve --config webpack.dev.js",
- "validate": "node scripts/validate.mjs",
- "build": "webpack --config webpack.prod.js"
+ "start": "vite preview --config ./vite.prod.mjs",
+ "postinstall": "cd \"fluid-player\" && npm install",
+ "dev": "vite --config ./vite.dev.mjs",
+ "validate": "node scripts/validate.mjs && tsc --noEmit",
+ "prebuild": "cd \"fluid-player\" && npm run build",
+ "build": "vite build --config ./vite.prod.mjs"
+ },
+ "overrides": {
+ "vite": "$vite"
},
"imports": {
"#storage/*": "./src/browser/storage/*/index.ts",
@@ -23,61 +29,69 @@
"#api/*": "./src/api/*/index.ts"
},
"dependencies": {
- "@babel/runtime": "^7.22.10",
- "@uppy/core": "^3.4.0",
- "@uppy/dashboard": "^3.5.1",
- "@uppy/form": "^3.0.2",
- "@uppy/tus": "^3.1.3",
- "clsx": "^2.1.0",
- "diff": "^5.1.0",
- "fluid-player": "^3.22.0",
+ "@babel/runtime": "^7.26.7",
+ "@uppy/core": "^4.4.2",
+ "@uppy/dashboard": "^4.3.1",
+ "@uppy/form": "^4.1.1",
+ "@uppy/tus": "^4.2.2",
+ "clsx": "^2.1.1",
+ "diff": "^7.0.0",
+ "fluid-player": "file:./fluid-player",
"micromodal": "^0.4.10",
"purecss": "^3.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^2.0.5",
- "react-router-dom": "^6.24.0",
+ "react-router": "^7.1.5",
"sha256-wasm": "^2.2.2",
- "swagger-ui-react": "^5.17.14",
- "whatwg-fetch": "^3.6.17"
+ "swagger-ui-react": "^5.18.3"
},
"devDependencies": {
- "@babel/core": "^7.22.10",
- "@babel/plugin-transform-runtime": "^7.22.10",
- "@babel/preset-env": "^7.22.10",
- "@babel/preset-react": "^7.24.7",
- "@babel/preset-typescript": "^7.24.7",
- "@hyperjump/json-schema": "^1.9.3",
+ "@babel/core": "^7.26.8",
+ "@babel/plugin-transform-runtime": "^7.26.8",
+ "@babel/preset-env": "^7.26.8",
+ "@babel/preset-react": "^7.26.3",
+ "@babel/preset-typescript": "^7.26.0",
+ "@hyperjump/json-schema": "^1.11.0",
+ "@modyfi/vite-plugin-yaml": "^1.1.0",
"@types/micromodal": "^0.3.5",
- "@types/node": "^20.1.0",
+ "@types/node": "^22.13.1",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/sha256-wasm": "^2.2.3",
- "@types/swagger-ui-react": "^4.18.3",
+ "@types/swagger-ui-react": "^5.18.0",
"@types/webpack-bundle-analyzer": "^4.7.0",
- "babel-loader": "^8.3.0",
+ "@vitejs/plugin-legacy": "^6.0.1",
+ "@vitejs/plugin-react": "^4.3.4",
+ "ajv": "^8.17.1",
+ "babel-loader": "^9.2.1",
"buffer": "^6.0.3",
- "copy-webpack-plugin": "^8.1.1",
- "css-loader": "^5.2.7",
- "fs-extra": "^10.1.0",
- "html-webpack-plugin": "^5.5.3",
- "mini-css-extract-plugin": "^1.6.2",
- "postcss": "^8.4.28",
- "postcss-loader": "^7.3.3",
- "postcss-preset-env": "^9.1.1",
- "rimraf": "^3.0.2",
- "sass": "^1.66.0",
- "sass-loader": "^11.1.1",
+ "copy-webpack-plugin": "^12.0.2",
+ "css-loader": "^7.1.2",
+ "fs-extra": "^11.3.0",
+ "html-webpack-plugin": "^5.6.3",
+ "mini-css-extract-plugin": "^2.9.2",
+ "postcss": "^8.5.1",
+ "postcss-loader": "^8.1.1",
+ "postcss-preset-env": "^10.1.3",
+ "rimraf": "^6.0.1",
+ "sass": "^1.84.0",
+ "sass-loader": "^16.0.4 ",
"stream-browserify": "^3.0.0",
- "style-loader": "^2.0.0",
- "ts-loader": "^9.5.1",
- "typescript": "^5.3.3",
- "webpack": "^5.88.2",
+ "style-loader": "^4.0.0",
+ "terser": "^5.39.0",
+ "ts-loader": "^9.5.2",
+ "typescript": "^5.7.3",
+ "vite": "^6.1.0",
+ "vite-css-modules": "^1.8.4",
+ "vite-plugin-html": "^3.2.2",
+ "vite-plugin-static-copy": "^2.2.0",
+ "webpack": "^5.97.1",
"webpack-bundle-analyzer": "^4.10.2",
- "webpack-cli": "^5.1.4",
- "webpack-dev-server": "^4.15.1",
+ "webpack-cli": "^6.0.1",
+ "webpack-dev-server": "^5.2.0",
"webpack-manifest-plugin": "^5.0.0",
- "webpack-merge": "^5.9.0",
- "yaml": "^2.4.5"
+ "webpack-merge": "^6.0.1",
+ "yaml": "^2.7.0"
}
}
diff --git a/client/scripts/validate.mjs b/client/scripts/validate.mjs
index 7eee874..67b4c3b 100644
--- a/client/scripts/validate.mjs
+++ b/client/scripts/validate.mjs
@@ -4,26 +4,29 @@ import fs from "node:fs/promises";
import { cwd } from "node:process";
import { validate } from "@hyperjump/json-schema/openapi-3-1";
import YAML from "yaml";
+import { parseConfiguration } from "../configs/parse-config.js";
const schemaPath = path.join(cwd(), "..", "src", "pages", "api", "schema.yaml");
run().catch((error) => {
console.error(error);
process.exitCode = 1;
+ process.exit();
});
async function run() {
- const fileContent = await fs.readFile(schemaPath, { encoding: "utf8" });
- const parsedSchema = YAML.parse(fileContent)
- const output = await validate(
- "https://spec.openapis.org/oas/3.1/schema-base",
- parsedSchema,
- // the library doesn't support values beyond `"FLAG"` and `"BASIC"`
- // but it's the only library in js which can validate OpenAPI 3.1 schemas
- "BASIC"
- );
+ parseConfiguration();
+ // const fileContent = await fs.readFile(schemaPath, { encoding: "utf8" });
+ // const parsedSchema = YAML.parse(fileContent)
+ // const output = await validate(
+ // "https://spec.openapis.org/oas/3.1/schema-base",
+ // parsedSchema,
+ // // the library doesn't support values beyond `"FLAG"` and `"BASIC"`
+ // // but it's the only library in js which can validate OpenAPI 3.1 schemas
+ // "BASIC"
+ // );
- if (!output.valid) {
- throw new Error("Failed to validate OpenAPI Schema.")
- }
+ // if (!output.valid) {
+ // throw new Error("Failed to validate OpenAPI Schema.")
+ // }
}
diff --git a/client/src/api/account/account.ts b/client/src/api/account/account.ts
index 5df66d9..4282ba4 100644
--- a/client/src/api/account/account.ts
+++ b/client/src/api/account/account.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IAccount } from "#entities/account";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/api/account/administrator/account.ts b/client/src/api/account/administrator/account.ts
new file mode 100644
index 0000000..4e9da46
--- /dev/null
+++ b/client/src/api/account/administrator/account.ts
@@ -0,0 +1,11 @@
+import { apiV2Fetch } from "#lib/api";
+import { IAccount } from "#entities/account";
+
+export async function apiFetchAccount(accountID: number) {
+ const pathSpec = `/account/administrator/account/{account_id}`;
+ const path = `/account/administrator/account/${accountID}`;
+
+ const result = await apiV2Fetch(pathSpec, "GET", path);
+
+ return result;
+}
diff --git a/client/src/api/account/administrator/accounts.ts b/client/src/api/account/administrator/accounts.ts
index 1af870d..4584aa4 100644
--- a/client/src/api/account/administrator/accounts.ts
+++ b/client/src/api/account/administrator/accounts.ts
@@ -1,40 +1,46 @@
-import { IAccontRole, IAccount } from "#entities/account";
-import { IPagination } from "#lib/pagination";
-import { apiFetch } from "../../fetch";
+import { apiV2Fetch } from "#lib/api";
+import { IAccount } from "#entities/account";
-interface IResult {
- pagination: IPagination;
- accounts: IAccount[];
- role_list: IAccontRole[];
- currentPage: "admin";
-}
-
-export async function fetchAccounts(
- page?: number,
- name?: string,
- role?: string,
- limit?: number
-) {
+export async function apiCountAccounts(name?: string, role?: string) {
+ const pathSpec = `/account/administrator/accounts`;
const path = `/account/administrator/accounts`;
- const params = new URLSearchParams();
-
- if (page) {
- params.set("page", String(page));
- }
+ const searchParams = new URLSearchParams();
if (name) {
- params.set("name", name);
+ searchParams.set("name", name);
}
if (role) {
- params.set("role", role);
+ searchParams.set("role", role);
}
- if (limit) {
- params.set("limit", String(limit));
- }
-
- const result = await apiFetch(path, { method: "GET" }, params);
+ const result = await apiV2Fetch(pathSpec, "GET", path, {
+ searchParams,
+ });
+
+ return result;
+}
+
+export async function apiFetchAccounts(
+ page: number,
+ name?: string,
+ role?: string
+) {
+ const pathSpec = `/account/administrator/accounts/{page}`;
+ const path = `/account/administrator/accounts/${page}`;
+ const searchParams = new URLSearchParams();
+
+ if (name) {
+ searchParams.set("name", name);
+ }
+
+ if (role) {
+ searchParams.set("role", role);
+ }
+
+ const result = await apiV2Fetch(pathSpec, "GET", path, {
+ searchParams,
+ });
return result;
}
diff --git a/client/src/api/account/administrator/change-roles.ts b/client/src/api/account/administrator/change-roles.ts
index 5dd7f4c..f881c12 100644
--- a/client/src/api/account/administrator/change-roles.ts
+++ b/client/src/api/account/administrator/change-roles.ts
@@ -1,26 +1,22 @@
-import { apiFetch } from "../../fetch";
+import { apiV2Fetch } from "#lib/api";
interface IBody {
- moderator?: number[];
- consumer?: number[];
+ role: string;
}
-export async function fetchChangeRolesOfAccounts(
- moderators?: string[],
- consumers?: string[]
+export async function apiChangeTargetAccountRole(
+ accountID: number,
+ role: string
) {
- const path = `/account/administrator/accounts`;
- const body: IBody = {};
+ const pathSpec = `/account/administrator/account/{account_id}`;
+ const path = `/account/administrator/account/${accountID}`;
+ const body: IBody = {
+ role,
+ };
- if (moderators && moderators.length !== 0) {
- body.moderator = moderators.map((id) => Number(id));
- }
+ const targetAccountID = await apiV2Fetch(pathSpec, "PATCH", path, {
+ body,
+ });
- if (consumers && consumers.length !== 0) {
- body.consumer = consumers.map((id) => Number(id));
- }
-
- await apiFetch(path, { method: "POST", body });
-
- return true;
+ return targetAccountID;
}
diff --git a/client/src/api/account/administrator/index.ts b/client/src/api/account/administrator/index.ts
index efda5b5..a4c1526 100644
--- a/client/src/api/account/administrator/index.ts
+++ b/client/src/api/account/administrator/index.ts
@@ -1,2 +1,3 @@
-export { fetchAccounts } from "./accounts";
-export { fetchChangeRolesOfAccounts } from "./change-roles";
+export { apiCountAccounts, apiFetchAccounts } from "./accounts";
+export { apiChangeTargetAccountRole } from "./change-roles";
+export { apiFetchAccount } from "./account";
diff --git a/client/src/api/account/auto-import-keys/get.ts b/client/src/api/account/auto-import-keys/get.ts
index 780af68..fd152e4 100644
--- a/client/src/api/account/auto-import-keys/get.ts
+++ b/client/src/api/account/auto-import-keys/get.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IAutoImportKey } from "#entities/account";
-import { apiFetch } from "../../fetch";
interface IResult {
props: {
diff --git a/client/src/api/account/auto-import-keys/revoke.ts b/client/src/api/account/auto-import-keys/revoke.ts
index fe94fe1..1658129 100644
--- a/client/src/api/account/auto-import-keys/revoke.ts
+++ b/client/src/api/account/auto-import-keys/revoke.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../../fetch";
+import { apiFetch } from "#lib/api";
interface IBody {
revoke: number[];
diff --git a/client/src/api/account/change-password.ts b/client/src/api/account/change-password.ts
index 4d5eb0f..ed647cf 100644
--- a/client/src/api/account/change-password.ts
+++ b/client/src/api/account/change-password.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IBody {
"current-password": string;
diff --git a/client/src/api/account/dms/get.ts b/client/src/api/account/dms/get.ts
index 95cf6f3..12b3cf8 100644
--- a/client/src/api/account/dms/get.ts
+++ b/client/src/api/account/dms/get.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IUnapprovedDM } from "#entities/dms";
-import { apiFetch } from "../../fetch";
interface IResult {
currentPage: "import";
diff --git a/client/src/api/account/dms/review.ts b/client/src/api/account/dms/review.ts
index 5d6b6a5..7fa1059 100644
--- a/client/src/api/account/dms/review.ts
+++ b/client/src/api/account/dms/review.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../../fetch";
+import { apiFetch } from "#lib/api";
interface IBody {
approved_hashes: string[];
diff --git a/client/src/api/account/favorites/favorite-post.ts b/client/src/api/account/favorites/favorite-post.ts
index 435f6fe..a9be04b 100644
--- a/client/src/api/account/favorites/favorite-post.ts
+++ b/client/src/api/account/favorites/favorite-post.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../../fetch";
+import { apiFetch } from "#lib/api";
export async function apiFavoritePost(
service: string,
diff --git a/client/src/api/account/favorites/favorite-profile.ts b/client/src/api/account/favorites/favorite-profile.ts
index 4dd7add..9e6db7c 100644
--- a/client/src/api/account/favorites/favorite-profile.ts
+++ b/client/src/api/account/favorites/favorite-profile.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../../fetch";
+import { apiFetch } from "#lib/api";
export async function apiFavoriteProfile(service: string, profileID: string) {
const path = `/favorites/creator/${service}/${profileID}`;
diff --git a/client/src/api/account/favorites/get-favourite-artists.ts b/client/src/api/account/favorites/get-favourite-artists.ts
index b579f45..665297f 100644
--- a/client/src/api/account/favorites/get-favourite-artists.ts
+++ b/client/src/api/account/favorites/get-favourite-artists.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IFavouriteArtist } from "#entities/account";
-import { apiFetch } from "../../fetch";
export async function fetchFavouriteProfiles() {
const path = `/account/favorites`;
diff --git a/client/src/api/account/favorites/get-favourite-posts.ts b/client/src/api/account/favorites/get-favourite-posts.ts
index 3c32a4e..5b2b964 100644
--- a/client/src/api/account/favorites/get-favourite-posts.ts
+++ b/client/src/api/account/favorites/get-favourite-posts.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IFavouritePost } from "#entities/account";
-import { apiFetch } from "../../fetch";
export async function fetchFavouritePosts() {
const path = `/account/favorites`;
diff --git a/client/src/api/account/moderator/profile-link-requests.ts b/client/src/api/account/moderator/profile-link-requests.ts
index 1744820..05cbcb2 100644
--- a/client/src/api/account/moderator/profile-link-requests.ts
+++ b/client/src/api/account/moderator/profile-link-requests.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IProfileLinkRequest } from "#entities/account";
-import { apiFetch } from "../../fetch";
export async function fetchProfileLinkRequests() {
const path = `/account/moderator/tasks/creator_links`;
diff --git a/client/src/api/account/notifications.ts b/client/src/api/account/notifications.ts
index c4fb9b0..20a8b6b 100644
--- a/client/src/api/account/notifications.ts
+++ b/client/src/api/account/notifications.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { INotification } from "#entities/account";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/api/account/profiles.ts b/client/src/api/account/profiles.ts
index b541720..e1390e7 100644
--- a/client/src/api/account/profiles.ts
+++ b/client/src/api/account/profiles.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IArtist } from "#entities/profiles";
-import { apiFetch } from "../fetch";
interface IResult {
message: string
diff --git a/client/src/api/authentication/login.ts b/client/src/api/authentication/login.ts
index 6b87158..d49a89e 100644
--- a/client/src/api/authentication/login.ts
+++ b/client/src/api/authentication/login.ts
@@ -1,6 +1,5 @@
import { IAccount } from "#entities/account";
-import { apiFetch } from "../fetch";
-import { ensureAPIError } from "#lib/api";
+import { apiFetch, ensureAPIError } from "#lib/api";
import { fetchAccount } from "../account/account";
export async function fetchLoginAccount(username: string, password: string) {
diff --git a/client/src/api/authentication/logout.ts b/client/src/api/authentication/logout.ts
index 70c487b..5939fc4 100644
--- a/client/src/api/authentication/logout.ts
+++ b/client/src/api/authentication/logout.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
export async function fetchLogoutAccount() {
const path = `/authentication/logout`;
diff --git a/client/src/api/authentication/register.ts b/client/src/api/authentication/register.ts
index 0d99f05..fc4d1f2 100644
--- a/client/src/api/authentication/register.ts
+++ b/client/src/api/authentication/register.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
export async function fetchRegisterAccount(
userName: string,
diff --git a/client/src/api/dms/all.ts b/client/src/api/dms/all.ts
index 102e5a5..205f0fe 100644
--- a/client/src/api/dms/all.ts
+++ b/client/src/api/dms/all.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IApprovedDM } from "#entities/dms";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/api/dms/has-pending.ts b/client/src/api/dms/has-pending.ts
index df67b28..3e7be2b 100644
--- a/client/src/api/dms/has-pending.ts
+++ b/client/src/api/dms/has-pending.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
export async function fetchHasPendingDMs() {
const path = `/has_pending_dms`;
diff --git a/client/src/api/dms/profile.ts b/client/src/api/dms/profile.ts
index a5eeb89..b32b5d7 100644
--- a/client/src/api/dms/profile.ts
+++ b/client/src/api/dms/profile.ts
@@ -1,6 +1,6 @@
+import { apiFetch } from "#lib/api";
import { IArtist } from "#entities/profiles";
import { IApprovedDM } from "#entities/dms";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/api/errors.ts b/client/src/api/errors.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/client/src/api/files/archive-file.ts b/client/src/api/files/archive-file.ts
index e5d6359..ca47f40 100644
--- a/client/src/api/files/archive-file.ts
+++ b/client/src/api/files/archive-file.ts
@@ -1,30 +1,30 @@
+import { apiV2Fetch } from "#lib/api";
import { IArchiveFile } from "#entities/files";
-import { apiFetch } from "../fetch";
-interface IResult {
- archive: IArchiveFile | null
- file_serving_enabled: boolean
-}
+export async function apiFetchArchiveFile(fileHash: string) {
+ const pathSpec = `/file/{file_hash}`;
+ const path = `/file/${fileHash}`;
-export async function fetchArchiveFile(fileHash: string) {
- const path = `/posts/archives/${fileHash}`
-
- const result = await apiFetch( path, { method: "GET" })
-
- return result
-}
-
-export async function fetchSetArchiveFilePassword(
- archiveHash: string,
- password: string
-) {
- const path = `/set_password`;
- const params = new URLSearchParams([
- ["file_hash", archiveHash],
- ["password", password],
- ]);
-
- const result = await apiFetch(path, { method: "GET" }, params);
+ const result = await apiV2Fetch(pathSpec, "GET", path);
+
+ return result;
+}
+
+interface IBody {
+ password: string;
+}
+
+export async function apiSetArchiveFilePassword(
+ archiveHash: string,
+ password: string
+) {
+ const pathSpec = `/file/{file_hash}`;
+ const path = `/file/${archiveHash}`;
+ const body: IBody = {
+ password,
+ };
+
+ const result = await apiV2Fetch(pathSpec, "PATCH", path, { body });
return result;
}
diff --git a/client/src/api/files/index.ts b/client/src/api/files/index.ts
index a45d565..7c7d598 100644
--- a/client/src/api/files/index.ts
+++ b/client/src/api/files/index.ts
@@ -1,2 +1,2 @@
-export { fetchArchiveFile, fetchSetArchiveFilePassword } from "./archive-file";
+export { apiFetchArchiveFile, apiSetArchiveFilePassword } from "./archive-file";
export { fetchSearchFileByHash } from "./search-by-hash";
diff --git a/client/src/api/files/search-by-hash.ts b/client/src/api/files/search-by-hash.ts
index a4bacea..5a2046a 100644
--- a/client/src/api/files/search-by-hash.ts
+++ b/client/src/api/files/search-by-hash.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IResult {
id: number;
diff --git a/client/src/api/imports/create-import.ts b/client/src/api/imports/create-import.ts
index dd9b7a2..1e03057 100644
--- a/client/src/api/imports/create-import.ts
+++ b/client/src/api/imports/create-import.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IBody {
session_key: string;
diff --git a/client/src/api/imports/get-import.ts b/client/src/api/imports/get-import.ts
index 94376a3..f3430e3 100644
--- a/client/src/api/imports/get-import.ts
+++ b/client/src/api/imports/get-import.ts
@@ -1,7 +1,7 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
-export async function fetchImportLogs(importID: string) {
- const path = `/importer/logs/${importID}`;
+export async function fetchImportLogs(importId: string): Promise> {
+ const path = `/importer/logs/${importId}`;
const result = await apiFetch(path, { method: "GET" });
diff --git a/client/src/api/posts/announcements.ts b/client/src/api/posts/announcements.ts
index 968d6fc..10ace35 100644
--- a/client/src/api/posts/announcements.ts
+++ b/client/src/api/posts/announcements.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IAnnouncement } from "#entities/posts";
-import { apiFetch } from "../fetch";
export async function fetchAnnouncements(service: string, profileID: string) {
const path = `/${service}/user/${profileID}/announcements`;
diff --git a/client/src/api/posts/flag.ts b/client/src/api/posts/flag.ts
index 3f122b9..c7ea1fc 100644
--- a/client/src/api/posts/flag.ts
+++ b/client/src/api/posts/flag.ts
@@ -1,25 +1,14 @@
-import { ensureAPIError } from "#lib/api";
-import { HTTP_STATUS } from "#lib/http";
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
-export async function flagPost(
- service: string,
- profileID: string,
- postID: string
-) {
- const path = `/${service}/user/${profileID}/post/${postID}/flag`;
-
- try {
- await apiFetch(path, { method: "POST" });
-
- return true;
- } catch (error) {
- ensureAPIError(error);
-
- if (error.response.status !== HTTP_STATUS.CONFLICT) {
- throw error;
- }
-
- return true;
- }
+interface FlagPostParams {
+ service: string;
+ creatorId: string;
+ postId: string;
+ reason: string;
+}
+
+export async function flagPost({ service, creatorId, postId, reason }: FlagPostParams): Promise {
+ let path = `/${service}/user/${creatorId}/post/${postId}/flag`;
+
+ return await apiFetch(path, { method: "POST", body: { reason } });
}
diff --git a/client/src/api/posts/popular.ts b/client/src/api/posts/popular.ts
index e988cb8..71aa408 100644
--- a/client/src/api/posts/popular.ts
+++ b/client/src/api/posts/popular.ts
@@ -1,23 +1,44 @@
-import { IPopularPostsPeriod, IPostWithFavorites } from "#entities/posts";
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
+import { IPopularPostsPeriod, IPost } from "#entities/posts";
interface IResult {
info: {
+ /**
+ * Datetime string.
+ */
date: string;
+ /**
+ * Datetime string.
+ */
min_date: string;
+ /**
+ * Datetime string.
+ */
max_date: string;
+ /**
+ * Value is a tuple of date strings.
+ */
navigation_dates: Record;
+ /**
+ * Human description of range.
+ */
range_desc: string;
scale: IPopularPostsPeriod;
};
props: {
currentPage: "popular_posts";
+ /**
+ * Date string.
+ */
today: string;
+ /**
+ * Date string.
+ */
earliest_date_for_popular: string;
limit: number;
count: number;
};
- results: IPostWithFavorites[];
+ results: IPost[];
base: {};
result_previews: (
| { type: "thumbnail"; server: string; name: string; path: string }
@@ -47,7 +68,7 @@ export async function fetchPopularPosts(
params.set("o", String(offset));
}
- const result = await apiFetch(path, { method: "GET" });
+ const result = await apiFetch(path, { method: "GET" }, params);
return result;
}
diff --git a/client/src/api/posts/post.ts b/client/src/api/posts/post.ts
index d85712c..569800b 100644
--- a/client/src/api/posts/post.ts
+++ b/client/src/api/posts/post.ts
@@ -1,3 +1,4 @@
+import { apiFetch } from "#lib/api";
import {
IComment,
IPost,
@@ -6,7 +7,6 @@ import {
IPostRevision,
IPostVideo,
} from "#entities/posts";
-import { apiFetch } from "../fetch";
interface IResult {
post: IPost;
@@ -15,7 +15,7 @@ interface IResult {
videos: IPostVideo[];
props: {
service: string;
- flagged?: 0;
+ flagged: string | null;
revisions: [number, IPost][];
};
}
@@ -26,7 +26,14 @@ export async function fetchPost(
postID: string
) {
const path = `/${service}/user/${profileID}/post/${postID}`;
- const result = await apiFetch(path, { method: "GET" });
+ const ifModifiedDate = new Date();
+
+ ifModifiedDate.setFullYear(ifModifiedDate.getFullYear() - 1);
+
+ const headers = new Headers([
+ ["If-Modified-Since", ifModifiedDate.toUTCString()],
+ ]);
+ const result = await apiFetch(path, { method: "GET", headers });
return result;
}
@@ -37,7 +44,14 @@ export async function fetchPostComments(
postID: string
) {
const path = `/${service}/user/${profileID}/post/${postID}/comments`;
- const result = await apiFetch(path, { method: "GET" });
+ const ifModifiedDate = new Date();
+
+ ifModifiedDate.setFullYear(ifModifiedDate.getFullYear() - 1);
+
+ const headers = new Headers([
+ ["If-Modified-Since", ifModifiedDate.toUTCString()],
+ ]);
+ const result = await apiFetch(path, { method: "GET", headers });
return result;
}
diff --git a/client/src/api/posts/posts.ts b/client/src/api/posts/posts.ts
index 0e08673..4ede419 100644
--- a/client/src/api/posts/posts.ts
+++ b/client/src/api/posts/posts.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IPost } from "#entities/posts";
-import { apiFetch } from "../fetch";
interface IResult {
count: number;
diff --git a/client/src/api/posts/random.ts b/client/src/api/posts/random.ts
index 3ef08dc..8414e18 100644
--- a/client/src/api/posts/random.ts
+++ b/client/src/api/posts/random.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IResult {
service: string;
diff --git a/client/src/api/posts/revision.ts b/client/src/api/posts/revision.ts
index 50924d3..61a88eb 100644
--- a/client/src/api/posts/revision.ts
+++ b/client/src/api/posts/revision.ts
@@ -1,3 +1,4 @@
+import { apiFetch } from "#lib/api";
import { IArtistDetails } from "#entities/profiles";
import {
IComment,
@@ -7,14 +8,13 @@ import {
IPostRevision,
IPostVideo,
} from "#entities/posts";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
currentPage: "revisions";
service: string;
artist: IArtistDetails;
- flagged?: 0;
+ flagged: string | null;
revisions: [number, IPostRevision][];
};
post: IPost;
diff --git a/client/src/api/profiles/discord/index.ts b/client/src/api/profiles/discord/index.ts
index 487a305..9874422 100644
--- a/client/src/api/profiles/discord/index.ts
+++ b/client/src/api/profiles/discord/index.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IDiscordChannelMessage } from "#entities/posts";
-import { apiFetch } from "../../fetch";
export async function fetchDiscordServer(serverID: string) {
const path = `/discord/channel/lookup/${serverID}`;
diff --git a/client/src/api/profiles/fancards.ts b/client/src/api/profiles/fancards.ts
index ac87b90..a2fea77 100644
--- a/client/src/api/profiles/fancards.ts
+++ b/client/src/api/profiles/fancards.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IFanCard } from "#entities/files";
-import { apiFetch } from "../fetch";
export async function fetchFanboxProfileFancards(profileID: string) {
const path = `/fanbox/user/${profileID}/fancards`;
diff --git a/client/src/api/profiles/links.ts b/client/src/api/profiles/links.ts
index eb361b6..a60af6d 100644
--- a/client/src/api/profiles/links.ts
+++ b/client/src/api/profiles/links.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IResult
extends Array<{
diff --git a/client/src/api/profiles/posts.ts b/client/src/api/profiles/posts.ts
index ea23d1a..84051ee 100644
--- a/client/src/api/profiles/posts.ts
+++ b/client/src/api/profiles/posts.ts
@@ -1,6 +1,6 @@
+import { apiFetch } from "#lib/api";
import { IArtist } from "#entities/profiles";
import { IPost } from "#entities/posts";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/api/profiles/profile.ts b/client/src/api/profiles/profile.ts
index b051d3d..4dbef88 100644
--- a/client/src/api/profiles/profile.ts
+++ b/client/src/api/profiles/profile.ts
@@ -1,13 +1,21 @@
+import { apiFetch } from "#lib/api";
import { IArtistDetails } from "#entities/profiles";
-import { apiFetch } from "../fetch";
export async function fetchArtistProfile(
service: string,
artistID: string
): Promise {
const path = `/${service}/user/${artistID}/profile`;
+ const ifModifiedDate = new Date();
+
+ ifModifiedDate.setFullYear(ifModifiedDate.getFullYear() - 1);
+
+ const headers = new Headers([
+ ["If-Modified-Since", ifModifiedDate.toUTCString()],
+ ]);
const result = await apiFetch(path, {
method: "GET",
+ headers,
});
return result;
diff --git a/client/src/api/profiles/profiles.ts b/client/src/api/profiles/profiles.ts
index 413d96c..ef37500 100644
--- a/client/src/api/profiles/profiles.ts
+++ b/client/src/api/profiles/profiles.ts
@@ -1,6 +1,6 @@
+import { apiFetch } from "#lib/api";
import { IArtistWithFavs } from "#entities/profiles";
import { IS_DEVELOPMENT } from "#env/derived-vars";
-import { apiFetch } from "../fetch";
export async function fetchProfiles(): Promise {
const path = IS_DEVELOPMENT ? "/creators" : "/creators.txt";
diff --git a/client/src/api/profiles/random.ts b/client/src/api/profiles/random.ts
index 57aa891..cc12a58 100644
--- a/client/src/api/profiles/random.ts
+++ b/client/src/api/profiles/random.ts
@@ -1,4 +1,4 @@
-import { apiFetch } from "../fetch";
+import { apiFetch } from "#lib/api";
interface IArtistData {
service: string;
diff --git a/client/src/api/shares/profile.ts b/client/src/api/shares/profile.ts
index a4c4753..12acbee 100644
--- a/client/src/api/shares/profile.ts
+++ b/client/src/api/shares/profile.ts
@@ -1,6 +1,6 @@
+import { apiFetch } from "#lib/api";
import { IArtist } from "#entities/profiles";
import { IShare } from "#entities/files";
-import { apiFetch } from "../fetch";
interface IResult {
results: IShare[];
diff --git a/client/src/api/shares/share.ts b/client/src/api/shares/share.ts
index 8e2d2ca..5a8f783 100644
--- a/client/src/api/shares/share.ts
+++ b/client/src/api/shares/share.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IShare, IShareFile } from "#entities/files";
-import { apiFetch } from "../fetch";
interface IResult {
share: IShare;
diff --git a/client/src/api/shares/shares.ts b/client/src/api/shares/shares.ts
index 749a57d..26ca2af 100644
--- a/client/src/api/shares/shares.ts
+++ b/client/src/api/shares/shares.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { IShare } from "#entities/files";
-import { apiFetch } from "../fetch";
interface IResult {
base: Record;
diff --git a/client/src/api/tags/all.ts b/client/src/api/tags/all.ts
index 82a195f..09ac55b 100644
--- a/client/src/api/tags/all.ts
+++ b/client/src/api/tags/all.ts
@@ -1,5 +1,5 @@
+import { apiFetch } from "#lib/api";
import { ITag } from "#entities/tags"
-import { apiFetch } from "../fetch"
interface IResult {
props: { currentPage: "tags" }
diff --git a/client/src/api/tags/profile.ts b/client/src/api/tags/profile.ts
index ec94fbb..12bc242 100644
--- a/client/src/api/tags/profile.ts
+++ b/client/src/api/tags/profile.ts
@@ -1,6 +1,6 @@
+import { apiFetch } from "#lib/api";
import { IArtist } from "#entities/profiles";
import { ITag } from "#entities/tags";
-import { apiFetch } from "../fetch";
interface IResult {
props: {
diff --git a/client/src/browser/hooks/use-client.tsx b/client/src/browser/hooks/use-client.tsx
index 9c37724..46eefef 100644
--- a/client/src/browser/hooks/use-client.tsx
+++ b/client/src/browser/hooks/use-client.tsx
@@ -5,34 +5,34 @@ import {
useEffect,
useState,
} from "react";
+import { isRegisteredAccount } from "#entities/account";
-interface IClientContext {
- isClient: boolean;
-}
+type IClientContext = undefined | { isRegistered: boolean };
-const defaultContext: IClientContext = { isClient: false };
-const ClientContext = createContext(defaultContext);
+const ClientContext = createContext(undefined);
interface IProps {
children?: ReactNode;
}
export function ClientProvider({ children }: IProps) {
- const [isClient, switchIsClient] = useState(false);
+ const [client, changeClient] = useState();
useEffect(() => {
- switchIsClient(true);
+ (async () => {
+ const isRegistered = await isRegisteredAccount();
+ const clientData: IClientContext = { isRegistered };
+ changeClient(clientData);
+ })();
}, []);
return (
-
- {children}
-
+ {children}
);
}
-export function useClient(): boolean {
- const { isClient } = useContext(ClientContext);
+export function useClient(): IClientContext {
+ const context = useContext(ClientContext);
- return isClient;
+ return context;
}
diff --git a/client/src/browser/hooks/use-route-path-pattern.tsx b/client/src/browser/hooks/use-route-path-pattern.tsx
index 81a7ce3..bf7a70b 100644
--- a/client/src/browser/hooks/use-route-path-pattern.tsx
+++ b/client/src/browser/hooks/use-route-path-pattern.tsx
@@ -1,4 +1,4 @@
-import { useLocation } from "react-router-dom";
+import { useLocation } from "react-router";
/**
* TODO: path pattern without circular reference
diff --git a/client/src/components/ads/ads.tsx b/client/src/components/advs/ads.tsx
similarity index 96%
rename from client/src/components/ads/ads.tsx
rename to client/src/components/advs/ads.tsx
index e6c27b8..9880183 100644
--- a/client/src/components/ads/ads.tsx
+++ b/client/src/components/advs/ads.tsx
@@ -1,4 +1,4 @@
-import { useLocation } from "react-router-dom";
+import { useLocation } from "react-router";
import { HEADER_AD, MIDDLE_AD, FOOTER_AD, SLIDER_AD } from "#env/env-vars";
import { DangerousContent } from "#components/dangerous-content";
diff --git a/client/src/components/ads/index.ts b/client/src/components/advs/index.ts
similarity index 100%
rename from client/src/components/ads/index.ts
rename to client/src/components/advs/index.ts
diff --git a/client/src/components/buttons/buttons.tsx b/client/src/components/buttons/buttons.tsx
index ccb5014..9d5b083 100644
--- a/client/src/components/buttons/buttons.tsx
+++ b/client/src/components/buttons/buttons.tsx
@@ -1,6 +1,9 @@
import { ReactNode } from "react";
import { IBlockProps, createBlockComponent } from "#components/meta";
+/**
+ * TODO: `onClick` required
+ */
interface IProps extends IBlockProps<"button"> {
className?: string;
isFocusable?: boolean;
diff --git a/client/src/components/cards/_index.scss b/client/src/components/cards/_index.scss
index fe557c0..37b0a13 100644
--- a/client/src/components/cards/_index.scss
+++ b/client/src/components/cards/_index.scss
@@ -1,6 +1,5 @@
@use "card_list";
@use "base";
-@use "account";
@use "post";
@use "profile";
@use "dm";
diff --git a/client/src/components/cards/account.scss b/client/src/components/cards/account.scss
deleted file mode 100644
index 5fd39b4..0000000
--- a/client/src/components/cards/account.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-@use "../../css/sass-mixins" as mixins;
-
-.account-card {
- @include mixins.article-card();
-
- &__body {
- flex: 1 1 auto;
- }
-}
diff --git a/client/src/components/cards/account.tsx b/client/src/components/cards/account.tsx
deleted file mode 100644
index c867cc8..0000000
--- a/client/src/components/cards/account.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Timestamp } from "#components/dates";
-import { IAccount } from "#entities/account";
-
-interface IProps {
- account: IAccount;
-}
-
-export function AccountCard({ account }: IProps) {
- const { id, username, role, created_at } = account;
-
- return (
-
-
-
-
-
-
-
- );
-}
diff --git a/client/src/components/cards/base.scss b/client/src/components/cards/base.scss
index 17acf8c..ecdfffa 100644
--- a/client/src/components/cards/base.scss
+++ b/client/src/components/cards/base.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.card {
display: grid;
diff --git a/client/src/components/cards/card_list.scss b/client/src/components/cards/card_list.scss
index 4b13e69..0487147 100644
--- a/client/src/components/cards/card_list.scss
+++ b/client/src/components/cards/card_list.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.card-list {
--local-flex-flow: row wrap;
diff --git a/client/src/components/cards/dm.module.scss b/client/src/components/cards/dm.module.scss
new file mode 100644
index 0000000..3855c0e
--- /dev/null
+++ b/client/src/components/cards/dm.module.scss
@@ -0,0 +1,3 @@
+.content {
+ font-family: inherit;
+}
diff --git a/client/src/components/cards/dm.scss b/client/src/components/cards/dm.scss
index 07f8bee..d073c8c 100644
--- a/client/src/components/cards/dm.scss
+++ b/client/src/components/cards/dm.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.dm-card {
position: relative;
diff --git a/client/src/components/cards/dm.tsx b/client/src/components/cards/dm.tsx
index c15be33..b0f625a 100644
--- a/client/src/components/cards/dm.tsx
+++ b/client/src/components/cards/dm.tsx
@@ -5,6 +5,8 @@ import { IApprovedDM } from "#entities/dms";
import { paysites } from "#entities/paysites";
import { FancyLink } from "../links";
+import * as styles from "./dm.module.scss"
+
interface IProps {
dm: IApprovedDM;
isPrivate?: boolean;
@@ -64,7 +66,7 @@ export function DMCard({
-
{dm.content}
+
{dm.content}
diff --git a/client/src/components/cards/index.ts b/client/src/components/cards/index.ts
index 193ce4b..c38a563 100644
--- a/client/src/components/cards/index.ts
+++ b/client/src/components/cards/index.ts
@@ -1,8 +1,7 @@
export { CardList } from "./card_list";
export { NoResults } from "./no_results";
export { Card, CardHeader, CardBody, CardFooter } from "./base";
-export { AccountCard } from "./account";
-export { PostCard, PostFavoriteCard } from "./post";
+export { PostCard } from "./post";
export { ArtistCard } from "./profile";
export { DMCard } from "./dm";
export { ShareCard } from "./share";
diff --git a/client/src/components/cards/no_results.scss b/client/src/components/cards/no_results.scss
index f36302b..7d53f03 100644
--- a/client/src/components/cards/no_results.scss
+++ b/client/src/components/cards/no_results.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.card--no-results {
flex: 0 1 $width-phone;
diff --git a/client/src/components/cards/post.scss b/client/src/components/cards/post.scss
index d94606f..4006ad2 100644
--- a/client/src/components/cards/post.scss
+++ b/client/src/components/cards/post.scss
@@ -1,12 +1,9 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.post-card {
width: var(--card-size);
height: var(--card-size);
- text-shadow:
- -1px -1px 0 #000,
- 1px -1px 0 #000,
- -1px 1px 0 #000,
+ text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000,
1px 1px 0 #000;
color: white;
font-size: 80%;
@@ -17,6 +14,12 @@
border-width: 2px;
}
+ &--fav-profile {
+ border-bottom-color: var(--favourite-colour2-secondary);
+ border-bottom-style: solid;
+ border-bottom-width: 2px;
+ }
+
&:hover {
& > a {
top: -5px;
@@ -52,9 +55,7 @@
padding: 0;
position: relative;
top: 0;
- transition:
- top ease 0.1s,
- background ease 0.1s,
+ transition: top ease 0.1s, background ease 0.1s,
border-bottom-color ease 0.1s;
&:not(:hover):not(:active):not(:focus) {
@@ -100,4 +101,15 @@
align-items: center;
}
}
+
+ &__profile {
+ color: white;
+ border-color: transparent;
+ border-style: solid;
+ border-width: 2px;
+
+ &--fav {
+ border-color: var(--favourite-colour2-primary);
+ }
+ }
}
diff --git a/client/src/components/cards/post.tsx b/client/src/components/cards/post.tsx
index 107d6eb..e2fce08 100644
--- a/client/src/components/cards/post.tsx
+++ b/client/src/components/cards/post.tsx
@@ -3,49 +3,68 @@ import { THUMBNAILS_PREPEND } from "#env/env-vars";
import { createPostURL } from "#lib/urls";
import { Timestamp } from "#components/dates";
import { KemonoLink } from "#components/links";
-import { IPost, IPostWithFavorites } from "#entities/posts";
+import { IPost } from "#entities/posts";
interface IProps {
post: IPost;
isFavourite?: boolean;
isServiceIconsDisabled?: boolean;
+ isFavouriteProfile?: boolean;
+ showFavCount?: boolean;
}
-const fileExtendsions = [".gif", ".jpeg", ".jpg", ".jpe", ".png", ".webp"];
+const fileExtensions = [".gif", ".jpeg", ".jpg", ".jpe", ".png", ".webp"];
const someServices = ["fansly", "candfans", "boosty", "gumroad"];
export function PostCard({
post,
isServiceIconsDisabled,
isFavourite = false,
+ isFavouriteProfile,
+ showFavCount,
}: IProps) {
const {
service,
- user: artistID,
+ user: profileID,
id,
title,
content,
published,
attachments,
+ fav_count,
} = post;
- const postLink = String(createPostURL(service, artistID, id));
+ const postLink = String(createPostURL(service, profileID, id));
const srcNS = findNamespace(post);
+ const blockClassName = clsx(
+ "post-card",
+ "post-card--preview",
+ );
+ const blockClassNameHeader = clsx(
+ "post-card__header",
+ (isFavourite || isFavouriteProfile) && "post-card__header--fav"
+ );
+ const blockClassNameFooter = clsx(
+ "post-card__footer",
+ (isFavourite || isFavouriteProfile) && "post-card__footer--fav"
+ );
+ const trimmedTitle = title?.trim();
+ const parsedTitle = !trimmedTitle
+ ? undefined
+ : trimmedTitle.length > 50
+ ? `${trimmedTitle.slice(0, 50)}...`
+ : trimmedTitle;
return (
-
- {title && title !== "DM"
- ? title
+
+ {parsedTitle && parsedTitle !== "DM"
+ ? parsedTitle
: !content || content?.length < 50
? content
: `${content.slice(0, 50)}...`}
@@ -60,12 +79,12 @@ export function PostCard({
)}
-
+
{!published ? undefined :
}
- {!attachments.length ? (
+ {!attachments?.length ? (
<>No attachments>
) : (
<>
@@ -73,6 +92,14 @@ export function PostCard({
{attachments.length === 1 ? "attachment" : "attachments"}
>
)}
+
+ {showFavCount && (
+ <>
+
+ {Math.floor(fav_count ?? 0)}{" "}
+ {fav_count === 1 ? "favorite" : "favorites"}
+ >
+ )}
{isServiceIconsDisabled ? undefined : (
@@ -85,85 +112,10 @@ export function PostCard({
);
}
-interface IFavProps {
- post: IPostWithFavorites;
- isServiceIconsDisabled?: boolean;
-}
-
-export function PostFavoriteCard({ post, isServiceIconsDisabled }: IFavProps) {
- const {
- service,
- user: profileID,
- id,
- title,
- content,
- published,
- attachments,
- fav_count,
- } = post;
- const postLink = String(createPostURL(service, profileID, id));
- const srcNS = findNamespace(post);
-
- return (
-
-
-
- {title && title !== "DM"
- ? title
- : !content || content?.length < 50
- ? content
- : `${content.slice(0, 50)}...`}
-
-
- {srcNS.src && (
-
-
-
- )}
-
-
-
-
- );
-}
-
function findNamespace(post: IPost) {
const srcNS: { found: boolean; src?: string } = { found: false };
const path = post.file?.path?.toLowerCase();
- const isValidpath = path && fileExtendsions.find((ext) => path.endsWith(ext));
+ const isValidpath = path && fileExtensions.find((ext) => path.endsWith(ext));
if (isValidpath) {
srcNS.src = path;
@@ -171,7 +123,7 @@ function findNamespace(post: IPost) {
if (!isValidpath && someServices.includes(post.service)) {
const matchedFile = post.attachments.find((file) =>
- fileExtendsions.find((ext) => file.path?.endsWith(ext))
+ fileExtensions.find((ext) => file.path?.endsWith(ext))
);
srcNS.src = matchedFile?.path;
diff --git a/client/src/components/cards/profile.scss b/client/src/components/cards/profile.scss
index 5d328cd..8539387 100644
--- a/client/src/components/cards/profile.scss
+++ b/client/src/components/cards/profile.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.user-card {
position: relative;
diff --git a/client/src/components/dates/timestamp.tsx b/client/src/components/dates/timestamp.tsx
index 64ec191..e79f1b5 100644
--- a/client/src/components/dates/timestamp.tsx
+++ b/client/src/components/dates/timestamp.tsx
@@ -12,10 +12,12 @@ interface IProps {
export function Timestamp({ time, isRelative, className, children }: IProps) {
const isClient = useClient();
+ let dateTime = new Date(time);
+ let formatted = `${dateTime.getFullYear()}-${dateTime.getMonth().toString().padStart(2, "0")}-${dateTime.getDay().toString().padStart(2, "0")}`;
return (
-
- {!isClient ? : children ?? time}
+
+ {!isClient ? : children ?? formatted}
);
}
diff --git a/client/src/components/details/details.module.scss b/client/src/components/details/details.module.scss
new file mode 100644
index 0000000..445c02b
--- /dev/null
+++ b/client/src/components/details/details.module.scss
@@ -0,0 +1,6 @@
+@use "../../css/config/variables/sass" as *;
+
+.summary {
+ padding: $size-small 0;
+ cursor: pointer;
+}
diff --git a/client/src/components/details/details.tsx b/client/src/components/details/details.tsx
index bde6ac8..3e2b55b 100644
--- a/client/src/components/details/details.tsx
+++ b/client/src/components/details/details.tsx
@@ -1,6 +1,8 @@
import { ReactNode } from "react";
import { IBlockProps, createBlockComponent } from "#components/meta";
+import * as styles from "./details.module.scss";
+
interface IProps extends IBlockProps<"details"> {
summary: ReactNode;
}
@@ -10,7 +12,7 @@ export const Details = createBlockComponent(undefined, Component);
function Component({ summary, children, ...props }: IProps) {
return (
- {summary}
+ {summary}
{children && {children}
}
);
diff --git a/client/src/components/errors/api-error.tsx b/client/src/components/errors/api-error.tsx
index c0c4c39..ec6b71b 100644
--- a/client/src/components/errors/api-error.tsx
+++ b/client/src/components/errors/api-error.tsx
@@ -1,32 +1,49 @@
-import { APIError } from "#lib/api";
+import { APIError, APIV2Error } from "#lib/api";
+import { HTTP_STATUS } from "#lib/http";
import { DescriptionList, DescriptionSection } from "#components/lists";
-import { Preformatted } from "#components/formatting";
-interface IProps {
+interface IAPIErrorViewProps {
routePathPattern: string;
error: APIError;
}
-export function APIErrorView({ routePathPattern, error }: IProps) {
+interface IAPIV2ErrorViewProps {
+ routePathPattern: string;
+ error: APIV2Error;
+}
+
+export function APIErrorView({ routePathPattern, error }: IAPIErrorViewProps) {
const { name, message, request, response } = error;
+ const { status } = response;
+ const errorOrigin =
+ status >= HTTP_STATUS.INTERNAL_SERVER_ERROR
+ ? status === HTTP_STATUS.SERVICE_UNAVAILABLE
+ ? "Server (no need to report since owner should be aware of it)"
+ : "Server"
+ : "Client (this browser and/or this site's scripts and/or client's network)";
return (
{routePathPattern}}
+ dKey="Originated from"
+ dValue={errorOrigin}
+ isValuePreformatted
+ />
+
+
{name}}
+ dValue={name}
isHorizontal
+ isValuePreformatted
/>
- {message}}
- />
+
{request.url}}
+ dValue={request.url}
+ isValuePreformatted
/>
{request.method}}
+ dValue={request.method}
isHorizontal
+ isValuePreformatted
/>
}
@@ -50,29 +69,34 @@ export function APIErrorView({ routePathPattern, error }: IProps) {
dKey="Response"
dValue={
- {response.url}}
- />
+ {request.url !== response.url && (
+
+ )}
No> : <>Yes>}
+ dKey="Status code"
+ dValue={response.status}
+ isHorizontal
+ isValuePreformatted
/>
- {response.status}}
- />
-
- {response.statusText}}
- />
+ {response.statusText && (
+
+ )}
{response.type}}
+ dValue={response.type}
+ isHorizontal
+ isValuePreformatted
/>
}
@@ -80,3 +104,80 @@ export function APIErrorView({ routePathPattern, error }: IProps) {
);
}
+
+export function APIV2ErrorView({
+ routePathPattern,
+ error,
+}: IAPIV2ErrorViewProps) {
+ const {
+ name,
+ message,
+ request,
+ response,
+ pathSpec,
+ error: responseError,
+ } = error;
+ const { status } = response;
+ const errorOrigin =
+ status >= HTTP_STATUS.INTERNAL_SERVER_ERROR
+ ? status === HTTP_STATUS.SERVICE_UNAVAILABLE
+ ? "Server (no need to report since owner should be aware of it)"
+ : "Server"
+ : "Client (this browser and/or this site's scripts and/or client's network)";
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/components/errors/error-view.tsx b/client/src/components/errors/error-view.tsx
index 08eee37..c9bc0d5 100644
--- a/client/src/components/errors/error-view.tsx
+++ b/client/src/components/errors/error-view.tsx
@@ -1,16 +1,17 @@
import { InvalidErrorType, isError } from "#lib/errors";
+import { isAPIError, isAPIV2Error } from "#lib/api";
+import { isFetchError } from "#lib/fetch";
import { useRoutePathPattern } from "#hooks";
import {
DescriptionList,
DescriptionSection,
IDescriptionListProps,
} from "#components/lists";
-import { createBlockComponent } from "#components/meta";
import { Details } from "#components/details";
-import { Preformatted } from "#components/formatting";
-import { isAPIError } from "#lib/api";
-import { APIErrorView } from "./api-error";
+import { createBlockComponent } from "#components/meta";
+import { APIErrorView, APIV2ErrorView } from "./api-error";
import { InvalidErrorView } from "./invalid-error";
+import { FetchErrorView } from "./fetch-error";
interface IProps extends IDescriptionListProps {
error: unknown;
@@ -24,37 +25,50 @@ function Component({ error, ...props }: IProps) {
return !isError(error) ? (
{routePathPattern}}
+ dKey="Page"
+ dValue={routePathPattern}
+ isValuePreformatted
/>
+
Unknown Error}
+ dValue="Unknown Error"
isHorizontal
+ isValuePreformatted
/>
+
{String(error)}}
+ dValue={{String(error)} }
/>
) : error instanceof InvalidErrorType ? (
) : isAPIError(error) ? (
+ ) : isAPIV2Error(error) ? (
+
+ ) : isFetchError(error) ? (
+
) : (
{routePathPattern}}
+ dKey="Page"
+ dValue={routePathPattern}
+ isValuePreformatted
/>
+
{error.name}}
+ dValue={error.name}
isHorizontal
+ isValuePreformatted
/>
+
{error.message}}
+ dValue={error.message}
+ isValuePreformatted
/>
{!error.cause ? undefined : (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/components/errors/invalid-error.tsx b/client/src/components/errors/invalid-error.tsx
index 3196441..79ed07f 100644
--- a/client/src/components/errors/invalid-error.tsx
+++ b/client/src/components/errors/invalid-error.tsx
@@ -1,6 +1,5 @@
import { InvalidErrorType } from "#lib/errors";
import { DescriptionList, DescriptionSection } from "#components/lists";
-import { Preformatted } from "#components/formatting";
interface IProps {
routePathPattern: string;
@@ -12,24 +11,24 @@ export function InvalidErrorView({ routePathPattern, error }: IProps) {
return (
{routePathPattern}}
+ dKey="Page"
+ dValue={routePathPattern}
+ isValuePreformatted
/>
{name}}
+ dValue={name}
isHorizontal
+ isValuePreformatted
/>
- {message}}
- />
+
{String(payload)}}
+ dValue={String(payload)}
+ isValuePreformatted
/>
);
diff --git a/client/src/components/formatting/pre.module.scss b/client/src/components/formatting/pre.module.scss
new file mode 100644
index 0000000..02e70e5
--- /dev/null
+++ b/client/src/components/formatting/pre.module.scss
@@ -0,0 +1,5 @@
+@use "../../css/config/variables/sass.scss" as *;
+
+.block {
+ overflow-wrap: anywhere;
+}
diff --git a/client/src/components/formatting/pre.tsx b/client/src/components/formatting/pre.tsx
index f8ff361..801771e 100644
--- a/client/src/components/formatting/pre.tsx
+++ b/client/src/components/formatting/pre.tsx
@@ -1,8 +1,10 @@
import { IBlockProps, createBlockComponent } from "#components/meta";
+import * as styles from "./pre.module.scss";
+
interface IProps extends IBlockProps<"pre"> {}
-export const Preformatted = createBlockComponent(undefined, Component)
+export const Preformatted = createBlockComponent(styles, Component)
function Component({...props}:IProps) {
return
diff --git a/client/src/components/forms/client.module.scss b/client/src/components/forms/client.module.scss
new file mode 100644
index 0000000..1e562dd
--- /dev/null
+++ b/client/src/components/forms/client.module.scss
@@ -0,0 +1,7 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ border: $size-thin solid var(--colour0-tertirary);
+ padding: $size-small;
+ border-radius: 10px;
+}
diff --git a/client/src/components/forms/client.tsx b/client/src/components/forms/client.tsx
new file mode 100644
index 0000000..7c71564
--- /dev/null
+++ b/client/src/components/forms/client.tsx
@@ -0,0 +1,97 @@
+import clsx from "clsx";
+import { type ReactNode, useState, useEffect } from "react";
+import type { Navigation } from "react-router";
+import { IBlockProps, createBlockComponent } from "#components/meta";
+import { Details } from "#components/details";
+import { ErrorView } from "#components/errors";
+import { FormSection } from "./sections/section";
+import { ButtonSubmit } from "./submit_button";
+import { ISubmitEvent } from "./types";
+
+import * as styles from "./client.module.scss";
+
+export interface IFormClientProps
+ extends Omit, "onSubmit" | "children"> {
+ onSubmit: (event: ISubmitEvent) => Promise;
+ statusSection?: null;
+ submitButton?: (state: Navigation["state"]) => ReactNode;
+ children?: ReactNode | ((state: Navigation["state"]) => ReactNode);
+}
+
+/**
+ * A form which only works client-side.
+ *
+ * Because I have no idea how to make an "actionless"
+ * `react-router` form.
+ */
+export const FormClient = createBlockComponent(styles, Component);
+
+export function Component({
+ className,
+ children,
+ onSubmit,
+ submitButton,
+ statusSection,
+ ...props
+}: IFormClientProps) {
+ const [state, changeStatus] = useState("loading");
+ const [error, changeError] = useState();
+
+ useEffect(() => changeStatus("idle"), []);
+
+ async function handleSubmit(event: ISubmitEvent) {
+ event.preventDefault();
+
+ if (state !== "idle") {
+ return;
+ }
+
+ try {
+ changeStatus("submitting");
+ await onSubmit(event);
+ changeError(undefined);
+ } catch (error) {
+ changeError(error as Error);
+ } finally {
+ changeStatus("idle");
+ }
+ }
+
+ return (
+
+ );
+}
diff --git a/client/src/components/forms/index.ts b/client/src/components/forms/index.ts
index b828d70..1f6ae4c 100644
--- a/client/src/components/forms/index.ts
+++ b/client/src/components/forms/index.ts
@@ -1,4 +1,6 @@
-export { FormRouter } from "./router";
-export type { IFormProps } from "./router";
+export { FormRouter, type IFormProps } from "./router";
+export { FormClient } from "./client";
export { ButtonSubmit } from "./submit_button";
-export { FormSection } from "./section";
+export { FormSection } from "./sections/section";
+export { Label } from "./label";
+export type { ISubmitEvent } from "./types";
diff --git a/client/src/components/forms/inputs/base.tsx b/client/src/components/forms/inputs/base.tsx
new file mode 100644
index 0000000..e2671df
--- /dev/null
+++ b/client/src/components/forms/inputs/base.tsx
@@ -0,0 +1,12 @@
+import clsx from "clsx";
+import { IRequiredSome } from "#lib/types";
+import { IChildlessBlockProps, createBlockComponent } from "#components/meta";
+
+export interface IInputBaseProps
+ extends IRequiredSome, "id" | "name"> {}
+
+export const InputBase = createBlockComponent(undefined, Component);
+
+function Component({ className, ...props }: IInputBaseProps) {
+ return ;
+}
diff --git a/client/src/components/forms/inputs/hidden.tsx b/client/src/components/forms/inputs/hidden.tsx
index 9545298..f43654b 100644
--- a/client/src/components/forms/inputs/hidden.tsx
+++ b/client/src/components/forms/inputs/hidden.tsx
@@ -1,9 +1,9 @@
-import { ComponentPropsWithoutRef } from "react";
+import { IInputBaseProps, InputBase } from "./base";
-interface IProps extends Omit, "type"> {
- name: string
+interface IProps extends Omit {
+ name: string;
}
export function InputHidden({ ...props }: IProps) {
- return ;
+ return ;
}
diff --git a/client/src/components/forms/inputs/index.ts b/client/src/components/forms/inputs/index.ts
index 16b2e89..ea3efe9 100644
--- a/client/src/components/forms/inputs/index.ts
+++ b/client/src/components/forms/inputs/index.ts
@@ -1 +1,6 @@
+export { InputText, type IInputTextProps } from "./text";
export { InputHidden } from "./hidden";
+export { Select, Option } from "./select";
+export { InputRadio, type IInputRadioProps } from "./radio";
+export { InputNumber, type IInputNumberProps } from "./number";
+export { InputInteger, type IInputIntegerProps } from "./integer";
diff --git a/client/src/components/forms/inputs/integer.tsx b/client/src/components/forms/inputs/integer.tsx
new file mode 100644
index 0000000..4612dcb
--- /dev/null
+++ b/client/src/components/forms/inputs/integer.tsx
@@ -0,0 +1,10 @@
+import { createBlockComponent } from "#components/meta";
+import { InputNumber, type IInputNumberProps } from "./number";
+
+export interface IInputIntegerProps extends Omit {}
+
+export const InputInteger = createBlockComponent(undefined, Component);
+
+function Component({ ...props }: IInputNumberProps) {
+ return ;
+}
diff --git a/client/src/components/forms/inputs/number.tsx b/client/src/components/forms/inputs/number.tsx
new file mode 100644
index 0000000..bd7cc43
--- /dev/null
+++ b/client/src/components/forms/inputs/number.tsx
@@ -0,0 +1,15 @@
+import { createBlockComponent } from "#components/meta";
+import { IInputBaseProps, InputBase } from "./base";
+
+export interface IInputNumberProps
+ extends Omit {
+ defaultValue?: number;
+ min?: number;
+ max?: number;
+}
+
+export const InputNumber = createBlockComponent(undefined, Component);
+
+function Component({ ...props }: IInputNumberProps) {
+ return ;
+}
diff --git a/client/src/components/forms/inputs/radio.tsx b/client/src/components/forms/inputs/radio.tsx
new file mode 100644
index 0000000..dea7bc7
--- /dev/null
+++ b/client/src/components/forms/inputs/radio.tsx
@@ -0,0 +1,10 @@
+import { createBlockComponent } from "#components/meta";
+import { IInputBaseProps, InputBase } from "./base";
+
+export interface IInputRadioProps extends Omit {}
+
+export const InputRadio = createBlockComponent(undefined, Component);
+
+function Component({ ...props }: IInputRadioProps) {
+ return ;
+}
diff --git a/client/src/components/forms/inputs/select.tsx b/client/src/components/forms/inputs/select.tsx
new file mode 100644
index 0000000..624aeea
--- /dev/null
+++ b/client/src/components/forms/inputs/select.tsx
@@ -0,0 +1,18 @@
+import clsx from "clsx";
+import { IRequiredSome } from "#lib/types";
+import { IBlockProps, createBlockComponent } from "#components/meta";
+
+interface ISelectProps
+ extends IRequiredSome, "id" | "name"> {}
+interface IOptionProps extends IBlockProps<"option"> {}
+
+export const Select = createBlockComponent(undefined, SelectComponent);
+export const Option = createBlockComponent(undefined, OptionComponent);
+
+function SelectComponent({ className, ...props }: ISelectProps) {
+ return ;
+}
+
+function OptionComponent({ className, ...props }: IOptionProps) {
+ return ;
+}
diff --git a/client/src/components/forms/inputs/text.tsx b/client/src/components/forms/inputs/text.tsx
new file mode 100644
index 0000000..22fc5ad
--- /dev/null
+++ b/client/src/components/forms/inputs/text.tsx
@@ -0,0 +1,10 @@
+import { createBlockComponent } from "#components/meta";
+import { IInputBaseProps, InputBase } from "./base";
+
+export interface IInputTextProps extends Omit {}
+
+export const InputText = createBlockComponent(undefined, Component);
+
+function Component({ ...props }: IInputTextProps) {
+ return ;
+}
diff --git a/client/src/components/forms/label.tsx b/client/src/components/forms/label.tsx
new file mode 100644
index 0000000..3526a4c
--- /dev/null
+++ b/client/src/components/forms/label.tsx
@@ -0,0 +1,19 @@
+import { ReactNode } from "react";
+import clsx from "clsx";
+import { IRequiredSome } from "#lib/types";
+import { createBlockComponent, type IBlockProps } from "#components/meta";
+
+interface IProps extends IRequiredSome, "htmlFor"> {
+ semicolon?: ReactNode;
+}
+
+export const Label = createBlockComponent(undefined, Component);
+
+function Component({ className, semicolon, children, ...props }: IProps) {
+ return (
+
+ {children}
+ {semicolon === null ? undefined : semicolon ?? ":"}
+
+ );
+}
diff --git a/client/src/components/forms/router.module.scss b/client/src/components/forms/router.module.scss
new file mode 100644
index 0000000..1e562dd
--- /dev/null
+++ b/client/src/components/forms/router.module.scss
@@ -0,0 +1,7 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ border: $size-thin solid var(--colour0-tertirary);
+ padding: $size-small;
+ border-radius: 10px;
+}
diff --git a/client/src/components/forms/router.tsx b/client/src/components/forms/router.tsx
index f33cd3d..2b3d9a8 100644
--- a/client/src/components/forms/router.tsx
+++ b/client/src/components/forms/router.tsx
@@ -6,12 +6,18 @@ import {
Navigation,
useActionData,
useNavigation,
-} from "react-router-dom";
-import { FormSection } from "./section";
+ FormMethod,
+} from "react-router";
+import { Details } from "#components/details";
+import { ErrorView } from "#components/errors";
+import { FormSection } from "./sections/section";
import { ButtonSubmit } from "./submit_button";
+import * as styles from "./router.module.scss";
+
export interface IFormProps
- extends Omit {
+ extends Omit {
+ method: Uppercase;
statusSection?: null;
submitButton?: (state: Navigation["state"]) => ReactNode;
successElement?: (data: IActionData) => ReactNode;
@@ -19,7 +25,7 @@ export interface IFormProps
}
/**
- * `react-router` specific form element.
+ * TODO: incorporate [`useFetcher`](https://reactrouter.com/6.28.1/hooks/use-fetcher)
*/
export function FormRouter({
className,
@@ -45,7 +51,9 @@ export function FormRouter({
) : actionData instanceof Error ? (
- {String(actionData)}
+
+
+
) : actionData && successElement ? (
diff --git a/client/src/components/forms/section.tsx b/client/src/components/forms/section.tsx
deleted file mode 100644
index cd2f1b7..0000000
--- a/client/src/components/forms/section.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import clsx from "clsx";
-import { ComponentPropsWithoutRef } from "react";
-
-interface IProps extends ComponentPropsWithoutRef<"div"> {}
-
-export function FormSection({ className, ...props }: IProps) {
- return
;
-}
diff --git a/client/src/components/forms/sections/fieldset.tsx b/client/src/components/forms/sections/fieldset.tsx
new file mode 100644
index 0000000..a1620cf
--- /dev/null
+++ b/client/src/components/forms/sections/fieldset.tsx
@@ -0,0 +1,28 @@
+import { ReactNode } from "react";
+import clsx from "clsx";
+import { IBlockProps, createBlockComponent } from "#components/meta";
+
+export interface IFormFieldsetProps extends IBlockProps<"fieldset"> {
+ legend: ReactNode;
+}
+interface ILegendProps extends IBlockProps<"legend"> {}
+
+export const FormFieldset = createBlockComponent(undefined, FieldsetComponent);
+
+function FieldsetComponent({
+ className,
+ legend,
+ children,
+ ...props
+}: IFormFieldsetProps) {
+ return (
+
+ {legend}
+ {children}
+
+ );
+}
+
+function Legend({ ...props }: ILegendProps) {
+ return ;
+}
diff --git a/client/src/components/forms/sections/index.ts b/client/src/components/forms/sections/index.ts
new file mode 100644
index 0000000..781752c
--- /dev/null
+++ b/client/src/components/forms/sections/index.ts
@@ -0,0 +1,5 @@
+export { FormSectionText } from "./text";
+export { FormSectionSelect } from "./select";
+export { FormSectionRadio } from "./radio";
+export { FormSectionRadioGroup } from "./radio-group";
+export { FormSectionInteger } from "./integer";
diff --git a/client/src/components/forms/sections/integer.tsx b/client/src/components/forms/sections/integer.tsx
new file mode 100644
index 0000000..bba4c10
--- /dev/null
+++ b/client/src/components/forms/sections/integer.tsx
@@ -0,0 +1,36 @@
+import { createBlockComponent } from "#components/meta";
+import { InputInteger, type IInputIntegerProps } from "../inputs";
+import { Label } from "../label";
+import { FormSection } from "./section";
+import { IBaseFormSectionProps } from "./types";
+
+interface IProps
+ extends Omit,
+ Pick {}
+
+export const FormSectionInteger = createBlockComponent(undefined, Component);
+
+function Component({
+ id,
+ name,
+ label,
+ defaultValue,
+ min,
+ max,
+ children,
+ ...props
+}: IProps) {
+ return (
+
+ {label}
+
+ {children && {children}
}
+
+ );
+}
diff --git a/client/src/components/forms/sections/radio-group.module.scss b/client/src/components/forms/sections/radio-group.module.scss
new file mode 100644
index 0000000..0cb0887
--- /dev/null
+++ b/client/src/components/forms/sections/radio-group.module.scss
@@ -0,0 +1,6 @@
+@use "../../../css/config/variables/sass" as *;
+
+.block {
+ display: grid;
+ gap: $size-normal;
+}
diff --git a/client/src/components/forms/sections/radio-group.tsx b/client/src/components/forms/sections/radio-group.tsx
new file mode 100644
index 0000000..a41da3a
--- /dev/null
+++ b/client/src/components/forms/sections/radio-group.tsx
@@ -0,0 +1,16 @@
+import { ReactNode } from "react";
+import { createBlockComponent } from "#components/meta";
+import { FormFieldset } from "./fieldset";
+import { IBaseFormFieldsetProps } from "./types";
+
+import * as styles from "./radio-group.module.scss";
+
+interface IProps extends Omit {
+ radios: (id: string, name: string) => ReactNode;
+}
+
+export const FormSectionRadioGroup = createBlockComponent(styles, Component);
+
+function Component({ id, name, radios, children, ...props }: IProps) {
+ return {radios(id, name)} ;
+}
diff --git a/client/src/components/forms/sections/radio.module.scss b/client/src/components/forms/sections/radio.module.scss
new file mode 100644
index 0000000..8e289f1
--- /dev/null
+++ b/client/src/components/forms/sections/radio.module.scss
@@ -0,0 +1,23 @@
+@use "../../../css/config/variables/sass" as *;
+
+.block {
+ display: grid;
+ grid-template:
+ "input label"
+ / 2em 1fr;
+ justify-items: flex-start;
+ align-items: center;
+ gap: $size-normal;
+ padding: 0;
+}
+
+.input {
+ grid-area: input;
+}
+
+.label {
+ grid-area: label;
+ align-content: center;
+ width: 100%;
+ height: 100%;
+}
diff --git a/client/src/components/forms/sections/radio.tsx b/client/src/components/forms/sections/radio.tsx
new file mode 100644
index 0000000..a007192
--- /dev/null
+++ b/client/src/components/forms/sections/radio.tsx
@@ -0,0 +1,37 @@
+import { createBlockComponent } from "#components/meta";
+import { InputRadio } from "../inputs";
+import { Label } from "../label";
+import { FormSection } from "./section";
+import { IBaseFormSectionProps } from "./types";
+
+import * as styles from "./radio.module.scss";
+
+interface IProps extends Omit {}
+
+export const FormSectionRadio = createBlockComponent(styles, Component);
+
+function Component({
+ id,
+ name,
+ label,
+ required,
+ defaultValue,
+ defaultChecked,
+ ...props
+}: IProps) {
+ return (
+
+
+
+ {label}
+
+
+ );
+}
diff --git a/client/src/components/forms/sections/section.tsx b/client/src/components/forms/sections/section.tsx
new file mode 100644
index 0000000..c72b90d
--- /dev/null
+++ b/client/src/components/forms/sections/section.tsx
@@ -0,0 +1,10 @@
+import clsx from "clsx";
+import { IBlockProps, createBlockComponent } from "#components/meta";
+
+export interface IFormSectionProps extends IBlockProps<"div"> {}
+
+export const FormSection = createBlockComponent(undefined, Component);
+
+function Component({ className, ...props }: IFormSectionProps) {
+ return
;
+}
diff --git a/client/src/components/forms/sections/select.tsx b/client/src/components/forms/sections/select.tsx
new file mode 100644
index 0000000..7467b00
--- /dev/null
+++ b/client/src/components/forms/sections/select.tsx
@@ -0,0 +1,34 @@
+import { ReactNode } from "react";
+import { createBlockComponent } from "#components/meta";
+import { Select } from "../inputs";
+import { Label } from "../label";
+import { FormSection } from "./section";
+import { IBaseFormSectionProps } from "./types";
+
+interface IProps extends IBaseFormSectionProps {
+ options: ReactNode;
+}
+
+export const FormSectionSelect = createBlockComponent(undefined, Component);
+
+function Component({
+ id,
+ name,
+ label,
+ defaultValue,
+ options,
+ children,
+ ...props
+}: IProps) {
+ return (
+
+ {label}
+
+
+ {options}
+
+
+ {children && {children}
}
+
+ );
+}
diff --git a/client/src/components/forms/sections/text.tsx b/client/src/components/forms/sections/text.tsx
new file mode 100644
index 0000000..9bca96b
--- /dev/null
+++ b/client/src/components/forms/sections/text.tsx
@@ -0,0 +1,26 @@
+import { createBlockComponent } from "#components/meta";
+import { InputText } from "../inputs";
+import { Label } from "../label";
+import { FormSection } from "./section";
+import { IBaseFormSectionProps } from "./types";
+
+interface IProps extends IBaseFormSectionProps {}
+
+export const FormSectionText = createBlockComponent(undefined, Component);
+
+function Component({
+ id,
+ name,
+ label,
+ defaultValue,
+ children,
+ ...props
+}: IProps) {
+ return (
+
+ {label}
+
+ {children && {children}
}
+
+ );
+}
diff --git a/client/src/components/forms/sections/types.ts b/client/src/components/forms/sections/types.ts
new file mode 100644
index 0000000..0ea9c69
--- /dev/null
+++ b/client/src/components/forms/sections/types.ts
@@ -0,0 +1,18 @@
+import { ReactNode } from "react";
+import { IFormSectionProps } from "./section";
+import { IRequiredSome } from "#lib/types";
+import { IFormFieldsetProps } from "./fieldset";
+
+export interface IBaseFormSectionProps
+ extends IRequiredSome {
+ name: string;
+ label: ReactNode;
+ required?: boolean
+}
+
+export interface IBaseFormFieldsetProps
+ extends IRequiredSome {
+ name: string;
+ label: ReactNode;
+ required?: boolean
+}
diff --git a/client/src/components/layout/footer.module.scss b/client/src/components/layout/footer.module.scss
new file mode 100644
index 0000000..a07f5ca
--- /dev/null
+++ b/client/src/components/layout/footer.module.scss
@@ -0,0 +1,6 @@
+@use "../../css/config/variables/sass.scss" as *;
+
+.version {
+ overflow-wrap: anywhere;
+ text-align: center;
+}
diff --git a/client/src/components/layout/footer.tsx b/client/src/components/layout/footer.tsx
index b011134..b456bf6 100644
--- a/client/src/components/layout/footer.tsx
+++ b/client/src/components/layout/footer.tsx
@@ -1,11 +1,33 @@
-import { FOOTER_ITEMS } from "#env/env-vars";
+import { FOOTER_ITEMS, GIT_COMMIT_HASH, BUILD_DATE } from "#env/env-vars";
+import { DescriptionList, DescriptionSection } from "#components/lists";
+import { Preformatted } from "#components/formatting";
+
+import * as styles from "./footer.module.scss";
export function GlobalFooter() {
return (
-
- {FOOTER_ITEMS?.map((item, index) => (
-
- ))}
-
+
+ {GIT_COMMIT_HASH && (
+
+
+ {BUILD_DATE}
+
+ }
+ />
+
+ )}
+
+
+ {FOOTER_ITEMS?.map((item, index) => (
+
+ ))}
+
+
);
}
diff --git a/client/src/components/layout/shell.scss b/client/src/components/layout/shell.scss
index 7634b3b..77d0dcc 100644
--- a/client/src/components/layout/shell.scss
+++ b/client/src/components/layout/shell.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.global-footer {
padding: 5px 20px;
@@ -9,7 +9,6 @@
.footer {
list-style-type: none;
- font-size: 14px;
text-align: center;
padding: 0;
@@ -146,8 +145,7 @@
}
}
- & > .main,
- & > .global-footer {
+ & > .main {
padding: 1em;
@media (max-width: $sidebar-min-width) {
@@ -155,6 +153,10 @@
}
}
+ & > .global-footer {
+ padding: 1em;
+ }
+
.header {
width: 100%;
height: 2.5rem;
@@ -164,7 +166,6 @@
padding: 0 10px 0 5px;
margin-top: calc(-1.2rem - 20px);
transition: margin-top 250ms ease-in-out 0s;
- overflow-x: hidden;
@media (max-width: $sidebar-min-width) {
margin-top: 0;
diff --git a/client/src/components/layout/shell.tsx b/client/src/components/layout/shell.tsx
index 1a2040a..970a3f6 100644
--- a/client/src/components/layout/shell.tsx
+++ b/client/src/components/layout/shell.tsx
@@ -1,7 +1,7 @@
import clsx from "clsx";
import { Fragment, useEffect, useState, type ReactNode } from "react";
import { HelmetProvider } from "react-helmet-async";
-import { Link, Outlet, ScrollRestoration, useLocation } from "react-router-dom";
+import { Link, Outlet, ScrollRestoration, useLocation } from "react-router";
import {
ARTISTS_OR_CREATORS,
BANNER_GLOBAL,
@@ -237,6 +237,12 @@ function AccountEntry() {
useEffect(() => {
(async () => {
+ const isRegistered = await isRegisteredAccount();
+
+ if (!isRegistered) {
+ return;
+ }
+
const isPending = await fetchHasPendingDMs();
switchPendingDMsForReview(isPending);
})();
@@ -400,9 +406,8 @@ function GlobalBody({
{children}
-
+
+
);
}
diff --git a/client/src/components/layout/sidebar.scss b/client/src/components/layout/sidebar.scss
index 2f6bb0a..0c89778 100644
--- a/client/src/components/layout/sidebar.scss
+++ b/client/src/components/layout/sidebar.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.global-sidebar {
position: fixed;
diff --git a/client/src/components/layout/sidebar.tsx b/client/src/components/layout/sidebar.tsx
index 997b5b0..87768cc 100644
--- a/client/src/components/layout/sidebar.tsx
+++ b/client/src/components/layout/sidebar.tsx
@@ -1,6 +1,6 @@
import clsx from "clsx";
import type { ReactNode } from "react";
-import { Link } from "react-router-dom";
+import { Link } from "react-router";
interface INavListProps {
items: INavItem[][];
diff --git a/client/src/components/links/links.scss b/client/src/components/links/links.scss
index 80074e9..7221791 100644
--- a/client/src/components/links/links.scss
+++ b/client/src/components/links/links.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables.scss" as *;
+@use "../../css/config/variables/sass" as *;
.fancy-link {
&--download {
@@ -11,6 +11,7 @@
&--button {
display: grid;
align-items: center;
+ justify-items: center;
min-height: $button-min-height;
min-width: $button-min-width;
background-color: var(--local-colour2-secondary);
diff --git a/client/src/components/links/links.tsx b/client/src/components/links/links.tsx
index 6878cb9..bbdf756 100644
--- a/client/src/components/links/links.tsx
+++ b/client/src/components/links/links.tsx
@@ -1,6 +1,6 @@
import clsx from "clsx";
-import { ComponentPropsWithoutRef, PropsWithoutRef, ReactNode } from "react";
-import { NavLink, NavLinkProps } from "react-router-dom";
+import { ReactNode } from "react";
+import { NavLink, NavLinkProps } from "react-router";
export interface IFancyLinkProps extends IBaseLinkProps {
isNoop?: boolean;
@@ -24,7 +24,9 @@ interface IEmailLinkProps extends Omit {
email: string;
}
-interface ILinkButtonProps extends IBaseLinkProps {
+interface ILinkButtonProps
+ extends Omit,
+ Pick {
isNoop?: boolean;
}
@@ -126,16 +128,24 @@ export function LinkButton({
url,
isNoop,
className,
+ end,
children,
}: ILinkButtonProps) {
return (
-
+ clsx(
+ "fancy-link",
+ "fancy-link--button",
+ typeof className === "function" ? className(...args) : className
+ )
+ }
+ to={url}
+ end={end}
target={!isNoop ? undefined : "_blank"}
rel={!isNoop ? undefined : "noopener noreferrer"}
>
{children ?? url}
-
+
);
}
diff --git a/client/src/components/lists/details.module.scss b/client/src/components/lists/description.module.scss
similarity index 97%
rename from client/src/components/lists/details.module.scss
rename to client/src/components/lists/description.module.scss
index 0cb4303..3a1bec4 100644
--- a/client/src/components/lists/details.module.scss
+++ b/client/src/components/lists/description.module.scss
@@ -41,6 +41,3 @@
.term {
font-weight: bold;
}
-
-.definition {
-}
diff --git a/client/src/components/lists/details.tsx b/client/src/components/lists/description.tsx
similarity index 73%
rename from client/src/components/lists/details.tsx
rename to client/src/components/lists/description.tsx
index 9253f6f..2721da5 100644
--- a/client/src/components/lists/details.tsx
+++ b/client/src/components/lists/description.tsx
@@ -1,8 +1,9 @@
import clsx from "clsx";
import { type ReactNode } from "react";
import { createBlockComponent, type IBlockProps } from "#components/meta";
+import { Preformatted } from "#components/formatting";
-import styles from "./details.module.scss";
+import * as styles from "./description.module.scss";
export interface IDescriptionListProps extends IBlockProps<"dl"> {}
@@ -10,6 +11,7 @@ export interface IDescriptionSectionProps extends IBlockProps<"div"> {
dKey?: ReactNode;
dValue?: ReactNode;
isHorizontal?: boolean;
+ isValuePreformatted?: boolean;
}
export interface IDescriptionTermProps extends IBlockProps<"dt"> {}
@@ -20,9 +22,12 @@ export const DescriptionList = createBlockComponent(styles, DLComponent);
/**
* Section of the details list.
*/
-export const DescriptionSection = createBlockComponent(styles.section, DSComponent);
+export const DescriptionSection = createBlockComponent(
+ styles.section,
+ DSComponent
+);
export const DescriptionTerm = createBlockComponent(styles.term, DTComponent);
-export const DescriptionDetails = createBlockComponent(styles.definition, DDComponent);
+export const DescriptionDetails = createBlockComponent(undefined, DDComponent);
function DLComponent({ children, ...blockProps }: IDescriptionListProps) {
return {children} ;
@@ -32,6 +37,7 @@ function DSComponent({
dKey,
dValue,
isHorizontal = false,
+ isValuePreformatted = false,
className,
children,
...blockProps
@@ -42,13 +48,18 @@ function DSComponent({
isHorizontal && styles.section_horizontal
);
-
return (
{children ?? (
<>
{dKey}:
-
{dValue}
+
+ {isValuePreformatted ? (
+ {dValue}
+ ) : (
+ dValue
+ )}
+
>
)}
diff --git a/client/src/components/lists/index.ts b/client/src/components/lists/index.ts
index 9905c89..39ff591 100644
--- a/client/src/components/lists/index.ts
+++ b/client/src/components/lists/index.ts
@@ -3,11 +3,11 @@ export {
DescriptionSection,
DescriptionTerm,
DescriptionDetails,
-} from "./details";
+} from "./description";
export type {
IDescriptionListProps,
IDescriptionSectionProps,
IDescriptionTermProps,
IDescriptionDetailsProps,
-} from "./details";
-export { ListUnordered, ListOrdered, ListItem } from "./standard";
+} from "./description";
+export { List, ListUnordered, ListOrdered, ListItem } from "./list";
diff --git a/client/src/components/lists/list.module.scss b/client/src/components/lists/list.module.scss
new file mode 100644
index 0000000..dd4114d
--- /dev/null
+++ b/client/src/components/lists/list.module.scss
@@ -0,0 +1,5 @@
+@use "../../css/config/variables/sass" as *;
+
+.ordered {
+ list-style-type: decimal-leading-zero;
+}
diff --git a/client/src/components/lists/list.tsx b/client/src/components/lists/list.tsx
new file mode 100644
index 0000000..2255d0e
--- /dev/null
+++ b/client/src/components/lists/list.tsx
@@ -0,0 +1,63 @@
+import { forwardRef, LegacyRef } from "react";
+import { createBlockComponent, IBlockProps } from "#components/meta";
+
+import * as styles from "./list.module.scss"
+
+export type IListProps =
+ | ({ isOrdered: true } & IListOrderedProps)
+ | IListUnorderedProps;
+interface IListUnorderedProps extends IBlockProps<"ul"> {}
+interface IListOrderedProps extends IBlockProps<"ol"> {}
+interface IListItemProps extends IBlockProps<"li"> {}
+
+export const List = forwardRef(
+ createBlockComponent(undefined, ListComponent)
+);
+
+export const ListUnordered = forwardRef(
+ createBlockComponent(undefined, ListUnorderedComponent)
+);
+
+export const ListOrdered = forwardRef(
+ createBlockComponent(styles.ordered, ListOrderedComponent)
+);
+
+export const ListItem = forwardRef(
+ createBlockComponent(undefined, ListItemComponent)
+);
+
+function ListComponent(
+ props: IListProps,
+ ref: LegacyRef
+) {
+ if ("isOrdered" in props) {
+ const { isOrdered, ...restProps } = props;
+
+ return (
+ } {...restProps} />
+ );
+ }
+
+ return ;
+}
+
+function ListUnorderedComponent(
+ { ...props }: IListUnorderedProps,
+ ref: LegacyRef
+) {
+ return ;
+}
+
+function ListOrderedComponent(
+ { ...props }: IListOrderedProps,
+ ref: LegacyRef
+) {
+ return ;
+}
+
+function ListItemComponent(
+ { ...props }: IListItemProps,
+ ref: LegacyRef
+) {
+ return ;
+}
diff --git a/client/src/components/lists/standard.tsx b/client/src/components/lists/standard.tsx
deleted file mode 100644
index eeeb1f2..0000000
--- a/client/src/components/lists/standard.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { createBlockComponent, IBlockProps } from "#components/meta";
-
-interface IListUnorderedProps extends IBlockProps<"ul"> {}
-interface IListOrderedProps extends IBlockProps<"ol"> {}
-interface IListItemProps extends IBlockProps<"li"> {}
-
-export const ListUnordered = createBlockComponent(
- undefined,
- ListUnorderedComponent
-);
-
-export const ListOrdered = createBlockComponent(undefined, ListOrderedComponent);
-
-export const ListItem = createBlockComponent(undefined, ListItemComponent);
-
-function ListUnorderedComponent({ ...props }: IListUnorderedProps) {
- return ;
-}
-
-function ListOrderedComponent({ ...props }: IListOrderedProps) {
- return ;
-}
-
-function ListItemComponent({ ...props }: IListItemProps) {
- return ;
-}
diff --git a/client/src/components/modal/index.ts b/client/src/components/modal/index.ts
new file mode 100644
index 0000000..18fc26b
--- /dev/null
+++ b/client/src/components/modal/index.ts
@@ -0,0 +1 @@
+export { Modal } from "./modal";
diff --git a/client/src/components/modal/modal.module.scss b/client/src/components/modal/modal.module.scss
new file mode 100644
index 0000000..728d2a9
--- /dev/null
+++ b/client/src/components/modal/modal.module.scss
@@ -0,0 +1,17 @@
+.modal {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ border: 0.125em solid var(--colour0-tertirary);
+ border-radius: 10px;
+ padding: 0.125em;
+
+ &::modal {
+ background-color: black;
+ }
+
+ &::backdrop {
+ background: rgba(0, 0, 0, 0.4);
+ }
+}
diff --git a/client/src/components/modal/modal.tsx b/client/src/components/modal/modal.tsx
new file mode 100644
index 0000000..457ce6d
--- /dev/null
+++ b/client/src/components/modal/modal.tsx
@@ -0,0 +1,47 @@
+import { KeyboardEvent, MouseEvent, ReactNode, useEffect, useRef } from "react";
+
+import * as styles from "./modal.module.scss";
+
+interface IModalProps {
+ children: ReactNode;
+ isOpen: boolean;
+ className: string;
+ onClose?: () => void;
+}
+
+export function Modal({ children, isOpen, className, onClose }: IModalProps) {
+ const modalRef = useRef(null);
+
+ useEffect(() => {
+ const modalElement = modalRef.current;
+ if (!modalElement) return;
+
+ if (isOpen) {
+ modalElement.showModal();
+ } else {
+ modalElement.close();
+ }
+ }, [isOpen]);
+
+ function handleClose() {
+ onClose?.();
+ }
+
+ function onKeyDown(event: KeyboardEvent) {
+ if (event.key === "Escape") {
+ handleClose();
+ }
+ }
+
+ function onClick(event: MouseEvent) {
+ if ((event.target as HTMLDialogElement)?.contains(modalRef.current)) {
+ handleClose();
+ }
+ }
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/client/src/components/overviews/index.ts b/client/src/components/overviews/index.ts
new file mode 100644
index 0000000..7b640df
--- /dev/null
+++ b/client/src/components/overviews/index.ts
@@ -0,0 +1,10 @@
+export {
+ Overview,
+ OverviewHeader,
+ OverviewBody,
+ OverviewFooter,
+ type IOverviewProps,
+ type IOverviewHeaderProps,
+ type IOverviewBodyProps,
+ type IOverviewFooterProps,
+} from "./overview";
diff --git a/client/src/components/overviews/overview.module.scss b/client/src/components/overviews/overview.module.scss
new file mode 100644
index 0000000..3b116a8
--- /dev/null
+++ b/client/src/components/overviews/overview.module.scss
@@ -0,0 +1,42 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: auto 1fr auto;
+ grid-template-areas:
+ "header"
+ "body"
+ "footer";
+ gap: $size-little;
+ max-width: $width-lcd;
+ background-color: var(--colour1-secondary);
+ border-radius: $radius-normal;
+ padding: $size-small;
+
+ @media (min-width: $width-tablet) {
+ gap: $size-normal;
+ padding: $size-big;
+ }
+}
+
+.header {
+ grid-area: header;
+ align-self: flex-start;
+ background-color: var(--colour1-tertiary);
+ padding: $size-normal;
+}
+
+.body {
+ grid-area: body;
+ align-self: center;
+ background-color: var(--colour1-tertiary);
+ padding: $size-normal;
+}
+
+.footer {
+ grid-area: footer;
+ align-self: flex-end;
+ background-color: var(--colour1-tertiary);
+ padding: $size-normal;
+}
diff --git a/client/src/components/overviews/overview.tsx b/client/src/components/overviews/overview.tsx
new file mode 100644
index 0000000..7652399
--- /dev/null
+++ b/client/src/components/overviews/overview.tsx
@@ -0,0 +1,35 @@
+import { IBlockProps, createBlockComponent } from "#components/meta";
+
+import * as styles from "./overview.module.scss";
+
+export interface IOverviewProps extends IBlockProps<"article"> {}
+export interface IOverviewHeaderProps extends IBlockProps<"header"> {}
+export interface IOverviewBodyProps extends IBlockProps<"section"> {}
+export interface IOverviewFooterProps extends IBlockProps<"footer"> {}
+
+export const Overview = createBlockComponent(styles.block, OverviewComponent);
+export const OverviewHeader = createBlockComponent(
+ styles.header,
+ OverviewHeaderComponent
+);
+export const OverviewBody = createBlockComponent(
+ styles.body,
+ OverviewBodyComponent
+);
+export const OverviewFooter = createBlockComponent(
+ styles.footer,
+ OverviewFooterComponent
+);
+
+function OverviewComponent({ ...props }: IOverviewProps) {
+ return ;
+}
+function OverviewHeaderComponent({ ...props }: IOverviewHeaderProps) {
+ return ;
+}
+function OverviewBodyComponent({ ...props }: IOverviewBodyProps) {
+ return ;
+}
+function OverviewFooterComponent({ ...props }: IOverviewFooterProps) {
+ return ;
+}
diff --git a/client/src/components/pages/account.tsx b/client/src/components/pages/account.tsx
index 934749c..dc7afb7 100644
--- a/client/src/components/pages/account.tsx
+++ b/client/src/components/pages/account.tsx
@@ -1,9 +1,9 @@
-import { isRegisteredAccount } from "#entities/account";
+import { getAccountRole, isRegisteredAccount } from "#entities/account";
import {
LoaderFunction,
LoaderFunctionArgs,
ActionFunction,
-} from "react-router-dom";
+} from "react-router";
export function createAccountPageLoader(
loader?: LoaderFunction
@@ -23,6 +23,16 @@ export function createAccountPageLoader(
};
}
+export async function validateAccountPageLoader(
+ ...args: Parameters
+): Promise {
+ const isRegistered = await isRegisteredAccount();
+
+ if (!isRegistered) {
+ throw new Error("You must be registered to access this page.");
+ }
+}
+
export async function validateAccountPageAction(
...args: Parameters
): Promise {
@@ -32,3 +42,27 @@ export async function validateAccountPageAction(
throw new Error("You must be registered to access this page.");
}
}
+
+export async function validateAdministratorPageLoader(
+ ...args: Parameters
+): Promise {
+ await validateAccountPageLoader(...args);
+
+ const role = await getAccountRole();
+
+ if (role !== "administrator") {
+ throw new Error("Account is not administrator.");
+ }
+}
+
+export async function validateAdministratorPageAction(
+ ...args: Parameters
+): Promise {
+ await validateAccountPageAction(...args);
+
+ const role = await getAccountRole();
+
+ if (role !== "administrator") {
+ throw new Error("Account is not administrator.");
+ }
+}
diff --git a/client/src/components/pages/error.tsx b/client/src/components/pages/error.tsx
index fd14560..11be7d5 100644
--- a/client/src/components/pages/error.tsx
+++ b/client/src/components/pages/error.tsx
@@ -1,10 +1,10 @@
-import { useRouteError, isRouteErrorResponse } from "react-router-dom";
+import { useRouteError, isRouteErrorResponse } from "react-router";
import { DescriptionList, DescriptionSection } from "#components/lists";
import { Preformatted } from "#components/formatting";
import { ErrorView } from "#components/errors";
import { PageSkeleton } from "./site";
-import styles from "./error.module.scss";
+import * as styles from "./error.module.scss";
export function ErrorPage() {
const error = useRouteError();
diff --git a/client/src/components/pages/index.ts b/client/src/components/pages/index.ts
index bc3a87a..bd448ce 100644
--- a/client/src/components/pages/index.ts
+++ b/client/src/components/pages/index.ts
@@ -1,4 +1,10 @@
-export { createAccountPageLoader, validateAccountPageAction } from "./account";
+export {
+ createAccountPageLoader,
+ validateAccountPageLoader,
+ validateAccountPageAction,
+ validateAdministratorPageLoader,
+ validateAdministratorPageAction,
+} from "./account";
export { ProfilePageSkeleton } from "./profile";
export { PageSkeleton } from "./site";
export { ErrorPage } from "./error";
diff --git a/client/src/components/pages/site.scss b/client/src/components/pages/site.scss
index cebc4a9..b531a8f 100644
--- a/client/src/components/pages/site.scss
+++ b/client/src/components/pages/site.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section {
margin: 0 auto;
diff --git a/client/src/components/pagination/collection.module.scss b/client/src/components/pagination/collection.module.scss
new file mode 100644
index 0000000..5d40e39
--- /dev/null
+++ b/client/src/components/pagination/collection.module.scss
@@ -0,0 +1,7 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ display: flex;
+ flex-flow: column nowrap;
+ gap: $size-normal;
+}
diff --git a/client/src/components/pagination/index.ts b/client/src/components/pagination/index.ts
index c6255ef..43da415 100644
--- a/client/src/components/pagination/index.ts
+++ b/client/src/components/pagination/index.ts
@@ -1,2 +1,5 @@
+export { Pagination } from "./pagination";
+export { PaginationLocal } from "./local";
+export { PaginationInfo } from "./pagination-info";
export { Paginator } from "./paginator";
-export { Pagination, PaginationController } from "./paginator_new";
+export { PaginationController } from "./paginator_new";
diff --git a/client/src/components/pagination/local.module.scss b/client/src/components/pagination/local.module.scss
new file mode 100644
index 0000000..c59e5fc
--- /dev/null
+++ b/client/src/components/pagination/local.module.scss
@@ -0,0 +1,95 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ width: 100%;
+ max-width: $width-mobile;
+ background-color: var(--colour1-tertiary);
+ border: $size-thin solid var(--colour0-tertirary);
+ border-radius: 10px;
+ margin: 0 auto;
+}
+
+.list {
+ position: relative;
+ display: grid;
+ grid:
+ "current current" auto
+ "previous next" auto
+ "first last" auto
+ / auto;
+ gap: $size-normal;
+ list-style: none;
+ padding: $size-small;
+ margin: 0;
+}
+
+.page {
+ min-width: 6em;
+}
+
+.single {
+ display: grid;
+ justify-items: center;
+}
+
+.current {
+ grid-area: current;
+ justify-self: stretch;
+ display: grid;
+ justify-items: stretch;
+ min-height: 4em;
+}
+
+.previous {
+ grid-area: previous;
+ justify-self: flex-start;
+}
+
+.next {
+ grid-area: next;
+ justify-self: flex-end;
+}
+
+.first {
+ grid-area: first;
+ justify-self: flex-start;
+}
+
+.last {
+ grid-area: last;
+ justify-self: flex-end;
+}
+
+.form {
+ position: absolute;
+ display: grid;
+ justify-items: center;
+ min-height: 11.6em;
+ // the form is not aware of the padding on the parent container
+ // so we substract it instead
+ width: calc(100% - $size-small);
+ border: none;
+ padding: 0;
+ visibility: hidden;
+
+ transition-duration: var(--duration-global);
+ transition-property: background-color;
+
+ &:focus-within {
+ background-color: var(--colour1-tertiary);
+ visibility: visible;
+
+ & .submit {
+ opacity: 1;
+ }
+ }
+}
+
+.number {
+ visibility: visible;
+}
+
+.submit {
+ min-width: 6em;
+ opacity: 0;
+}
diff --git a/client/src/components/pagination/local.tsx b/client/src/components/pagination/local.tsx
new file mode 100644
index 0000000..af868c9
--- /dev/null
+++ b/client/src/components/pagination/local.tsx
@@ -0,0 +1,148 @@
+import { useEffect } from "react";
+import { IPagination } from "#lib/pagination";
+import { parseInt } from "#lib/numbers";
+import { DescriptionList, DescriptionSection } from "#components/lists";
+import {
+ ButtonSubmit,
+ FormClient,
+ FormSection,
+ type ISubmitEvent,
+} from "#components/forms";
+import { FormSectionInteger } from "#components/forms/sections";
+import { Button } from "#components/buttons";
+
+import * as styles from "./local.module.scss";
+
+interface IProps {
+ pagination: IPagination;
+
+ formID: string;
+ onPageChange: (nextPage: number) => Promise;
+}
+
+/**
+ * Pagination for lists which do not incur navigation.
+ */
+export function PaginationLocal({ pagination, onPageChange, formID }: IProps) {
+ const { total_pages, current_page } = pagination;
+ const previousPage = Math.max(current_page - 1, 1);
+ const nextPage = Math.min(current_page + 1, total_pages);
+
+ return (
+
+
+
+ {total_pages === 1 ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+ await onPageChange(previousPage)}
+ >
+ Previous
+
+
+
+
+ await onPageChange(nextPage)}
+ >
+ Next
+
+
+
+
+ await onPageChange(1)}
+ >
+ First
+
+
+
+
+ await onPageChange(total_pages)}
+ >
+ Last
+
+
+
+
+ );
+}
+
+interface ICurrentPageProps
+ extends Pick {}
+
+function CurrentPage({ pagination, formID, onPageChange }: ICurrentPageProps) {
+ const { current_page, total_pages } = pagination;
+
+ // change the value of uncontrolled input
+ // without going through whole controlled input setup
+ useEffect(() => {}, [current_page]);
+
+ async function handlePageChange(event: ISubmitEvent) {
+ const nextPageValue = event.currentTarget.elements["page"]?.value.trim();
+
+ if (!nextPageValue) {
+ return;
+ }
+
+ const nextPage = parseInt(nextPageValue);
+
+ if (nextPage === current_page) {
+ return;
+ }
+
+ await onPageChange(nextPage);
+ }
+
+ return (
+
+ {(state) => (
+ <>
+
+
+
+ Go
+
+ >
+ )}
+
+ );
+}
diff --git a/client/src/components/pagination/pagination-info.module.scss b/client/src/components/pagination/pagination-info.module.scss
new file mode 100644
index 0000000..5aca3b3
--- /dev/null
+++ b/client/src/components/pagination/pagination-info.module.scss
@@ -0,0 +1,7 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ text-align: center;
+ background-color: var(--colour1-tertiary);
+ padding: $size-small;
+}
diff --git a/client/src/components/pagination/pagination-info.tsx b/client/src/components/pagination/pagination-info.tsx
new file mode 100644
index 0000000..b65b053
--- /dev/null
+++ b/client/src/components/pagination/pagination-info.tsx
@@ -0,0 +1,26 @@
+import { LegacyRef, forwardRef } from "react";
+import { IPagination } from "#lib/pagination";
+import { IBlockProps, createBlockComponent } from "#components/meta";
+
+import * as styles from "./pagination-info.module.scss";
+
+interface IPaginationInfoProps extends IBlockProps<"div"> {
+ pagination: IPagination;
+}
+
+export const PaginationInfo = forwardRef(
+ createBlockComponent(styles, Component)
+);
+
+export function Component(
+ { pagination, ...props }: IPaginationInfoProps,
+ ref: LegacyRef
+) {
+ const { total_count, current_min, current_max } = pagination;
+
+ return (
+
+ Showing elements from {current_min} to {current_max} out of {total_count}.
+
+ );
+}
diff --git a/client/src/components/pagination/pagination.module.scss b/client/src/components/pagination/pagination.module.scss
new file mode 100644
index 0000000..25068f2
--- /dev/null
+++ b/client/src/components/pagination/pagination.module.scss
@@ -0,0 +1,99 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ width: 100%;
+ max-width: $width-mobile;
+ background-color: var(--colour1-tertiary);
+ border-radius: 10px;
+ margin: 0 auto;
+}
+
+.list {
+ position: relative;
+ display: grid;
+ grid:
+ "current current" auto
+ "previous next" auto
+ "first last" auto
+ / auto;
+ gap: $size-normal;
+ list-style: none;
+ padding: $size-small;
+ margin: 0;
+}
+
+.page {
+ color: var(--colour0-secondary);
+ padding: $size-small;
+}
+
+.link {
+ min-width: 6em;
+}
+
+.single {
+ display: grid;
+ justify-items: center;
+}
+
+.current {
+ grid-area: current;
+ justify-self: stretch;
+ display: grid;
+ justify-items: stretch;
+ min-height: 4em;
+}
+
+.previous {
+ grid-area: previous;
+ justify-self: flex-start;
+}
+
+.next {
+ grid-area: next;
+ justify-self: flex-end;
+}
+
+.first {
+ grid-area: first;
+ justify-self: flex-start;
+}
+
+.last {
+ grid-area: last;
+ justify-self: flex-end;
+}
+
+.form {
+ position: absolute;
+ display: grid;
+ justify-items: center;
+ min-height: 11.6em;
+ // the form is not aware of the padding on the parent container
+ // so we substract it instead
+ width: calc(100% - $size-small);
+ border: none;
+ padding: 0;
+ visibility: hidden;
+
+ transition-duration: var(--duration-global);
+ transition-property: background-color;
+
+ &:focus-within {
+ background-color: var(--colour1-tertiary);
+ visibility: visible;
+
+ & .submit {
+ opacity: 1;
+ }
+ }
+}
+
+.number {
+ visibility: visible;
+}
+
+.submit {
+ min-width: 6em;
+ opacity: 0;
+}
diff --git a/client/src/components/pagination/pagination.tsx b/client/src/components/pagination/pagination.tsx
new file mode 100644
index 0000000..0739acd
--- /dev/null
+++ b/client/src/components/pagination/pagination.tsx
@@ -0,0 +1,147 @@
+import { IPagination, createPagination } from "#lib/pagination";
+import { LinkButton } from "#components/links";
+import { DescriptionList, DescriptionSection } from "#components/lists";
+import { ButtonSubmit, FormRouter, FormSection } from "#components/forms";
+import { FormSectionInteger } from "#components/forms/sections";
+import { InputHidden } from "#components/forms/inputs";
+
+import * as styles from "./pagination.module.scss";
+
+interface IProps {
+ pagination: IPagination;
+ action: string;
+ constructURL: (page: number) => string;
+ formID?: string;
+ extraValues?: Record;
+}
+
+export function Pagination({
+ formID = "pagination",
+ pagination,
+ constructURL,
+ action,
+ extraValues,
+}: IProps) {
+ const { total_pages, current_page } = pagination;
+ const previousPage = Math.max(current_page - 1, 1);
+ const nextPage = Math.min(current_page + 1, total_pages);
+
+ return (
+
+
+
+ {total_pages === 1 ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+ {current_page === 1 ? (
+ Previous
+ ) : (
+
+ Previous
+
+ )}
+
+
+
+ {current_page === total_pages ? (
+ Next
+ ) : (
+
+ Next
+
+ )}
+
+
+
+ {current_page === 1 ? (
+ First
+ ) : (
+
+ First
+
+ )}
+
+
+
+ {current_page === total_pages ? (
+ Last
+ ) : (
+
+ Last
+
+ )}
+
+
+
+ );
+}
+
+interface ICurrentPageProps
+ extends Pick {}
+
+function CurrentPage({
+ pagination,
+ action,
+ formID,
+ extraValues,
+}: ICurrentPageProps) {
+ const { current_page, total_pages } = pagination;
+ const processedValues = !extraValues
+ ? undefined
+ : Object.entries(extraValues).filter(([_, value]) => value);
+
+ return (
+
+ {(state) => (
+ <>
+
+
+ {processedValues?.map(([key, value], index) => (
+
+ ))}
+
+
+ Go
+
+ >
+ )}
+
+ );
+}
diff --git a/client/src/components/pagination/paginator_new.scss b/client/src/components/pagination/paginator_new.scss
index 2153f99..fe0486e 100644
--- a/client/src/components/pagination/paginator_new.scss
+++ b/client/src/components/pagination/paginator_new.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables.scss" as *;
+@use "../../css/config/variables/sass" as *;
.paginator {
&__count {
diff --git a/client/src/components/pagination/paginator_new.tsx b/client/src/components/pagination/paginator_new.tsx
index 80b216c..3805fc0 100644
--- a/client/src/components/pagination/paginator_new.tsx
+++ b/client/src/components/pagination/paginator_new.tsx
@@ -25,6 +25,7 @@ export function Pagination({
constructURL,
className,
}: IPaginationProps) {
+ // @ts-ignore
const { current_page, total_pages, current_count, offset, count } =
pagination;
const previousPage = current_page - 1;
diff --git a/client/src/components/pagination/wrapper.module.scss b/client/src/components/pagination/wrapper.module.scss
new file mode 100644
index 0000000..93e2019
--- /dev/null
+++ b/client/src/components/pagination/wrapper.module.scss
@@ -0,0 +1 @@
+@use "../../css/config/variables/sass" as *;
diff --git a/client/src/components/pagination/wrapper.tsx b/client/src/components/pagination/wrapper.tsx
new file mode 100644
index 0000000..74a433b
--- /dev/null
+++ b/client/src/components/pagination/wrapper.tsx
@@ -0,0 +1,12 @@
+import { createPagination } from "#lib/pagination";
+
+interface IPaginationWrapperProps {
+ items: unknown[];
+}
+
+export function PaginationWrapper({ items }: IPaginationWrapperProps) {
+ const totalCount = items.length;
+ const pagination = createPagination(totalCount);
+
+ return
;
+}
diff --git a/client/src/components/tooltip.scss b/client/src/components/tooltip.scss
index 5b298ee..d4a1871 100644
--- a/client/src/components/tooltip.scss
+++ b/client/src/components/tooltip.scss
@@ -1,4 +1,4 @@
-@use "../css/config/variables" as *;
+@use "../css/config/variables/sass" as *;
.tooltip {
--local-x: 0;
diff --git a/client/src/css/_index.scss b/client/src/css/_index.scss
index e049833..575aad4 100644
--- a/client/src/css/_index.scss
+++ b/client/src/css/_index.scss
@@ -1,4 +1,4 @@
-@use "config/variables";
+@use "config/variables.scss";
@use "animations";
@use "sass-mixins";
@use "base";
diff --git a/client/src/css/attributes.scss b/client/src/css/attributes.scss
index 59ec40f..d8dd7ac 100644
--- a/client/src/css/attributes.scss
+++ b/client/src/css/attributes.scss
@@ -1,4 +1,4 @@
-@use "config/variables" as *;
+@use "config/variables/sass" as *;
/* Attributes */
// only selectors by attributes
// and their pseudo-classes/elements go there
diff --git a/client/src/css/base.scss b/client/src/css/base.scss
index d50dc6e..becd37f 100644
--- a/client/src/css/base.scss
+++ b/client/src/css/base.scss
@@ -1,4 +1,4 @@
-@use "config/variables" as *;
+@use "config/variables/sass" as *;
html {
box-sizing: border-box;
@@ -40,42 +40,40 @@ div[id="root"] {
main {
}
-h1 {
- text-transform: capitalize;
- font-size: 1.7rem;
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
font-weight: normal;
+ word-break: break-word;
margin: 0;
}
+h1 {
+ font-size: 2em;
+}
+
h2 {
font-size: 1.6rem;
- font-weight: normal;
line-height: 1.35;
- margin: 0;
}
h3 {
font-size: 1.5rem;
- font-weight: normal;
- margin: 0;
}
h4 {
font-size: 1.4rem;
- font-weight: normal;
- margin: 0;
}
h5 {
font-size: 1.3rem;
- font-weight: normal;
- margin: 0;
}
h6 {
font-size: 1.2rem;
- font-weight: normal;
- margin: 0;
}
p,
diff --git a/client/src/css/blocks/form.scss b/client/src/css/blocks/form.scss
index df242de..fbac849 100644
--- a/client/src/css/blocks/form.scss
+++ b/client/src/css/blocks/form.scss
@@ -1,4 +1,4 @@
-@use "../config/variables.scss" as *;
+@use "../config/variables/sass" as *;
.form {
max-width: $width-mobile;
diff --git a/client/src/css/config/variables.scss b/client/src/css/config/variables.scss
index a92e887..6818721 100644
--- a/client/src/css/config/variables.scss
+++ b/client/src/css/config/variables.scss
@@ -1,33 +1,4 @@
-/* SASS variables */
-// screen widths
-$width-feature: 240px;
-$width-mobile: 360px;
-$width-phone: 480px;
-$width-tablet: 720px;
-$width-laptop: 1280px;
-$width-desktop: 1920px;
-
-// sizes for borders/padding/margins/gaps
-$size-nano: 0.0625em;
-$size-thin: 0.125em;
-$size-little: 0.25em;
-$size-small: 0.5em;
-$size-normal: 1em;
-$size-big: 2em;
-$size-large: 3em;
-
-// border radii
-$radius-small: 5px;
-$radius-normal: 10px;
-$radius-big: 15px;
-$radius-round: 50%;
-
-// buttons
-$button-min-width: 44px;
-$button-min-height: 44px;
-
-// min sidebar width do not touch
-$sidebar-min-width: 1020px;
+@use "./variables/sass.scss" as *;
/* CSS variables */
:root {
@@ -61,7 +32,8 @@ $sidebar-min-width: 1020px;
--positive-colour1-secondary: hsl(120, 100%, 30%);
--negative-colour1-primary: hsl(0, 100%, 60%);
--favourite-colour1-primary: hsl(51, 100%, 50%);
- --favourite-colour2-primary: hsl(60, 100%, 30%);
+ --favourite-colour2-primary: hsl(60, 100%, 40%);
+ --favourite-colour2-secondary: hsl(60, 100%, 20%);
/* END Buttons */
/* Links */
diff --git a/client/src/css/config/variables/sass.scss b/client/src/css/config/variables/sass.scss
new file mode 100644
index 0000000..4d1ae64
--- /dev/null
+++ b/client/src/css/config/variables/sass.scss
@@ -0,0 +1,31 @@
+/* SASS variables */
+// screen widths
+$width-feature: 240px;
+$width-mobile: 360px;
+$width-phone: 480px;
+$width-tablet: 720px;
+$width-lcd: 1024px;
+$width-laptop: 1280px;
+$width-desktop: 1920px;
+
+// sizes for borders/padding/margins/gaps
+$size-nano: 0.0625em;
+$size-thin: 0.125em;
+$size-little: 0.25em;
+$size-small: 0.5em;
+$size-normal: 1em;
+$size-big: 2em;
+$size-large: 3em;
+
+// border radii
+$radius-small: 5px;
+$radius-normal: 10px;
+$radius-big: 15px;
+$radius-round: 50%;
+
+// buttons
+$button-min-width: 44px;
+$button-min-height: 44px;
+
+// min sidebar width do not touch
+$sidebar-min-width: 1020px;
diff --git a/client/src/css/sass-mixins.scss b/client/src/css/sass-mixins.scss
index 992441a..9e8365c 100644
--- a/client/src/css/sass-mixins.scss
+++ b/client/src/css/sass-mixins.scss
@@ -1,5 +1,5 @@
/* SASS mixins go there */
-@use "config/variables" as *;
+@use "config/variables/sass" as *;
@mixin article_card() {
display: flex;
diff --git a/client/src/entities/account/index.ts b/client/src/entities/account/index.ts
index 9f1a409..a11a3e9 100644
--- a/client/src/entities/account/index.ts
+++ b/client/src/entities/account/index.ts
@@ -1,3 +1,11 @@
+export {
+ accountRoles,
+ visibleRoles,
+ getAccountRole,
+ isValidAccountRole,
+ ensureAccountRole,
+} from "./lib/roles";
+export type { IAccountRole as IAccontRole } from "./lib/roles";
export {
findFavouriteProfiles,
isFavouriteProfile,
@@ -20,10 +28,9 @@ export {
} from "./lib/auth";
export { notificationTypes } from "./notifications";
export type { INotificationType } from "./notifications";
-export { accountRoles } from "./roles";
-export type { IAccontRole } from "./roles";
export { AutoImportKeyCard } from "./service_key";
export { NotificationItem } from "./notification";
+export { AccountPreview } from "./preview";
export type {
IAccount,
IFavouriteArtist,
diff --git a/client/src/entities/account/lib/roles.ts b/client/src/entities/account/lib/roles.ts
new file mode 100644
index 0000000..ec6a7bc
--- /dev/null
+++ b/client/src/entities/account/lib/roles.ts
@@ -0,0 +1,29 @@
+import { getLocalStorageItem } from "#storage/local";
+
+export const accountRoles = ["consumer", "moderator", "administrator"] as const;
+export const visibleRoles = [
+ "consumer",
+ "moderator",
+] as const satisfies Exclude[];
+
+export type IAccountRole = (typeof accountRoles)[number];
+
+export function isValidAccountRole(input: unknown): input is IAccountRole {
+ return accountRoles.includes(input as IAccountRole);
+}
+
+export function ensureAccountRole(
+ input: unknown
+): asserts input is IAccountRole {
+ if (!isValidAccountRole(input)) {
+ throw new Error(`Invalid account role.`);
+ }
+}
+
+export async function getAccountRole(): Promise {
+ const localRole = getLocalStorageItem("role");
+
+ ensureAccountRole(localRole);
+
+ return localRole;
+}
diff --git a/client/src/entities/account/notifications.ts b/client/src/entities/account/notifications.ts
index 680aea8..0c5bcdd 100644
--- a/client/src/entities/account/notifications.ts
+++ b/client/src/entities/account/notifications.ts
@@ -1,7 +1,7 @@
-import { IAccontRole } from "./roles";
+import { IAccountRole } from "./lib/roles";
export const notificationTypes = {
- 1: (extraInfo: { old_role: IAccontRole; new_role: IAccontRole }) =>
+ 1: (extraInfo: { old_role: IAccountRole; new_role: IAccountRole }) =>
`Your role was changed from ${extraInfo.old_role} to ${extraInfo.new_role}.`,
} as const;
diff --git a/client/src/entities/account/preview.module.scss b/client/src/entities/account/preview.module.scss
new file mode 100644
index 0000000..74b1167
--- /dev/null
+++ b/client/src/entities/account/preview.module.scss
@@ -0,0 +1,19 @@
+@use "../../css/config/variables/sass" as *;
+@use "../../css/sass-mixins" as mixins;
+
+.block {
+ @include mixins.article-card();
+
+ & {
+ gap: $size-normal;
+ padding: 1em;
+ }
+
+ & > * {
+ padding: 0;
+ }
+}
+
+.body {
+ flex: 1 1 auto;
+}
diff --git a/client/src/entities/account/preview.tsx b/client/src/entities/account/preview.tsx
new file mode 100644
index 0000000..f9b1e1f
--- /dev/null
+++ b/client/src/entities/account/preview.tsx
@@ -0,0 +1,41 @@
+import clsx from "clsx";
+import { createAccountDetailsPageURL } from "#lib/urls";
+import { Timestamp } from "#components/dates";
+import { DescriptionList, DescriptionSection } from "#components/lists";
+import { LinkButton } from "#components/links";
+import { IAccount } from "./types";
+
+import * as styles from "./preview.module.scss";
+
+interface IProps {
+ account: IAccount;
+}
+
+export function AccountPreview({ account }: IProps) {
+ const { id, username, role, created_at } = account;
+
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/entities/account/roles.ts b/client/src/entities/account/roles.ts
deleted file mode 100644
index bea0d44..0000000
--- a/client/src/entities/account/roles.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const accountRoles = ["consumer", "moderator", "administrator"] as const;
-
-export type IAccontRole = (typeof accountRoles)[number];
diff --git a/client/src/entities/account/types.ts b/client/src/entities/account/types.ts
index 6224cd4..3b24492 100644
--- a/client/src/entities/account/types.ts
+++ b/client/src/entities/account/types.ts
@@ -1,11 +1,11 @@
import { INotificationType } from "./notifications";
-import { IAccontRole } from "./roles";
+import { IAccountRole } from "./lib/roles";
export interface IAccount {
id: number;
username: string;
created_at: string;
- role: IAccontRole;
+ role: IAccountRole;
}
/**
@@ -17,7 +17,7 @@ export interface INotification {
type: INotificationType;
created_at: string;
- extra_info: { old_role: IAccontRole; new_role: IAccontRole };
+ extra_info: { old_role: IAccountRole; new_role: IAccountRole };
isSeen: boolean;
}
@@ -50,7 +50,7 @@ export interface IProfileLinkRequest {
id: string
requester: {
username: string
- role: IAccontRole
+ role: IAccountRole
}
from_creator: {
service: string
diff --git a/client/src/entities/administrator/account-overview.tsx b/client/src/entities/administrator/account-overview.tsx
new file mode 100644
index 0000000..1cd4e38
--- /dev/null
+++ b/client/src/entities/administrator/account-overview.tsx
@@ -0,0 +1,80 @@
+import { Timestamp } from "#components/dates";
+import { FormRouter } from "#components/forms";
+import {
+ FormSectionRadio,
+ FormSectionRadioGroup,
+} from "#components/forms/sections";
+import { DescriptionList, DescriptionSection } from "#components/lists";
+import { createBlockComponent } from "#components/meta";
+import {
+ Overview,
+ OverviewHeader,
+ OverviewBody,
+ IOverviewProps,
+ OverviewFooter,
+} from "#components/overviews";
+import { IAccount } from "#entities/account";
+
+interface IProps extends IOverviewProps {
+ account: IAccount;
+}
+
+export const AccountOverview = createBlockComponent(undefined, Component);
+
+function Component({ account, ...props }: IProps) {
+ const { id, username, role, created_at } = account;
+ const formID = `update-account-${id}`;
+
+ return (
+
+
+ {/* TODO: replace with a heading component */}
+ {username}
+ {id}
+
+
+
+
+
+ }
+ />
+
+
+
+
+ {/* TODO: rewrite with `useFetcher` */}
+ "Submit changes"}
+ >
+ (
+ <>
+ Consumer>}
+ defaultChecked={role === "consumer"}
+ defaultValue="consumer"
+ />
+ Moderator>}
+ defaultChecked={role === "moderator"}
+ defaultValue="moderator"
+ />
+ >
+ )}
+ >
+
+
+
+ );
+}
diff --git a/client/src/entities/administrator/index.ts b/client/src/entities/administrator/index.ts
new file mode 100644
index 0000000..cbbaed6
--- /dev/null
+++ b/client/src/entities/administrator/index.ts
@@ -0,0 +1 @@
+export { AccountOverview } from "./account-overview";
diff --git a/client/src/entities/files/archive-overview.tsx b/client/src/entities/files/archive-overview.tsx
new file mode 100644
index 0000000..ad66a6e
--- /dev/null
+++ b/client/src/entities/files/archive-overview.tsx
@@ -0,0 +1,117 @@
+import { IS_FILE_SERVING_ENABLED } from "#env/env-vars";
+import { createArchiveFileURL } from "#lib/urls";
+import { createBlockComponent } from "#components/meta";
+import { Details } from "#components/details";
+import { FormRouter } from "#components/forms";
+import { FormSectionText } from "#components/forms/sections";
+import { KemonoLink } from "#components/links";
+import {
+ DescriptionList,
+ DescriptionSection,
+ List,
+ ListItem,
+} from "#components/lists";
+import {
+ Overview,
+ OverviewHeader,
+ OverviewBody,
+ IOverviewProps,
+} from "#components/overviews";
+import { IArchiveFile } from "./types";
+
+interface IProps extends IOverviewProps {
+ archiveFile: IArchiveFile;
+}
+
+export const ArchiveFileOverview = createBlockComponent(undefined, Component);
+
+function Component({ id, archiveFile, ...props }: IProps) {
+ const { file, file_list, password } = archiveFile;
+ const { hash } = file;
+ const formID = `${id}-update`;
+
+ return (
+
+
+ {/* TODO: replace with a heading component */}
+ {file.hash}
+ {password ? (
+
+
+ ? (
+ // empty string means it needs password because reasons
+ password === ""
+ ) : (
+
+
Archive needs a password, but none was provided.
+
+ "Send"}
+ >
+
+
+
+
+ )
+ ) : undefined}
+
+
+
+ {file_list.length === 0 ? (
+ <>Archive is empty or missing password.>
+ ) : (
+
+ {file_list.map((filename, index) => (
+
+ ))}
+
+ )}
+
+
+ );
+}
+
+interface IFileItemProps {
+ name: string;
+ archiveHash: string;
+ archiveExtension: string;
+ password?: string;
+}
+
+function FileItem({
+ name,
+ archiveHash,
+ archiveExtension,
+ password,
+}: IFileItemProps) {
+ return (
+
+ {!IS_FILE_SERVING_ENABLED ? (
+ name
+ ) : (
+
+ {name}
+
+ )}
+
+ );
+}
diff --git a/client/src/entities/files/file_hash_search.tsx b/client/src/entities/files/file_hash_search.tsx
index 7db354f..de7c143 100644
--- a/client/src/entities/files/file_hash_search.tsx
+++ b/client/src/entities/files/file_hash_search.tsx
@@ -1,6 +1,6 @@
import { FormRouter, FormSection } from "#components/forms";
-import styles from "./file_hash_search.module.scss";
+import * as styles from "./file_hash_search.module.scss";
interface IProps {
id: string;
diff --git a/client/src/entities/files/index.ts b/client/src/entities/files/index.ts
index e535cc7..9c21d6c 100644
--- a/client/src/entities/files/index.ts
+++ b/client/src/entities/files/index.ts
@@ -1,4 +1,5 @@
-export { FileSearchForm } from "./file_hash_search"
+export { FileSearchForm } from "./file_hash_search";
+export { ArchiveFileOverview } from "./archive-overview";
export type {
IFile,
IFanCard,
diff --git a/client/src/entities/paysites/list.ts b/client/src/entities/paysites/list.ts
index 2d076c4..eca8553 100644
--- a/client/src/entities/paysites/list.ts
+++ b/client/src/entities/paysites/list.ts
@@ -54,7 +54,7 @@ export const paysites: Record = {
title: "Fantia",
color: "#e1097f",
user: {
- profile: (userID) => `user_id: f"https://fantia.jp/fanclubs/${userID}`,
+ profile: (userID) => `https://fantia.jp/fanclubs/${userID}`,
},
post: {},
},
diff --git a/client/src/entities/posts/announcement.module.scss b/client/src/entities/posts/announcement.module.scss
new file mode 100644
index 0000000..d73d175
--- /dev/null
+++ b/client/src/entities/posts/announcement.module.scss
@@ -0,0 +1,33 @@
+@use "../../css/config/variables/sass" as *;
+
+.block {
+ position: relative;
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: stretch;
+ background-color: var(--colour1-tertiary);
+ border-radius: 10px;
+ border: $size-thin solid transparent;
+ overflow: hidden;
+ transition-duration: var(--duration-global);
+ transition-property: border-color, box-shadow;
+
+ & > * {
+ flex: 0 1 auto;
+ padding: $size-small;
+ }
+
+ &:hover,
+ &:focus-within {
+ box-shadow: 0px 0px 3px 5px var(--positive-colour1-secondary);
+ }
+}
+
+.body {
+ flex: 1 1 auto;
+}
+
+.content {
+ font-family: inherit;
+ line-height: 1.5;
+}
diff --git a/client/src/entities/posts/announcement.tsx b/client/src/entities/posts/announcement.tsx
new file mode 100644
index 0000000..00a5f62
--- /dev/null
+++ b/client/src/entities/posts/announcement.tsx
@@ -0,0 +1,32 @@
+import { IAnnouncement } from "./types";
+
+import * as styles from "./announcement.module.scss";
+
+interface IProps {
+ announcement: IAnnouncement;
+}
+
+export function AnnouncementPreview({ announcement }: IProps) {
+ const { content, published, added } = announcement;
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/client/src/entities/posts/discord-server.tsx b/client/src/entities/posts/discord-server.tsx
index 9d5f758..2050134 100644
--- a/client/src/entities/posts/discord-server.tsx
+++ b/client/src/entities/posts/discord-server.tsx
@@ -2,7 +2,7 @@ import clsx from "clsx";
import { createDiscordChannelPageURL, createProfileLinksURL } from "#lib/urls";
import { KemonoLink } from "#components/links";
-import styles from "./discord-server.module.scss";
+import * as styles from "./discord-server.module.scss";
interface IProps {
serverID: string;
diff --git a/client/src/entities/posts/discord.module.scss b/client/src/entities/posts/discord.module.scss
index 4b101f6..70d3e04 100644
--- a/client/src/entities/posts/discord.module.scss
+++ b/client/src/entities/posts/discord.module.scss
@@ -47,12 +47,11 @@
.image {
max-width: 300px;
- border-radius: 4px;
}
.embed {
+ display: block;
max-width: 300px;
- border-radius: 4px;
}
.emoji {
diff --git a/client/src/entities/posts/discord.tsx b/client/src/entities/posts/discord.tsx
index 5cb674b..c41a10c 100644
--- a/client/src/entities/posts/discord.tsx
+++ b/client/src/entities/posts/discord.tsx
@@ -3,10 +3,10 @@ import {
createDiscordChannelPageURL,
createThumbnailURL,
} from "#lib/urls";
-import { KemonoLink } from "#components/links";
+import { FancyLink, KemonoLink } from "#components/links";
import { IDiscordAttachment, IDiscordChannelMessage } from "./types";
-import styles from "./discord.module.scss";
+import * as styles from "./discord.module.scss";
interface IProps {
serverID: string;
@@ -108,13 +108,9 @@ function DiscordMessage({ message }: IDiscordMessageProps) {
))}
{embeds.map(({ url, title, description }) => (
-
- {description ?? title ?? ""}
-
+
+ {description ?? title ?? ""}
+
))}
diff --git a/client/src/entities/posts/index.ts b/client/src/entities/posts/index.ts
index ab380fb..3da1d30 100644
--- a/client/src/entities/posts/index.ts
+++ b/client/src/entities/posts/index.ts
@@ -2,10 +2,10 @@ export { DiscordServer } from "./discord-server";
export { DiscordMessages } from "./discord";
export { isValidPeriod, validatePeriod } from "./period";
export type { IPopularPostsPeriod } from "./period";
-export { PostOverview } from "./overview"
+export { PostOverview } from "./overview/overview";
+export { AnnouncementPreview } from "./announcement";
export type {
IPost,
- IPostWithFavorites,
IPostRevision,
IPostVideo,
IPostAttachment,
diff --git a/client/src/entities/posts/overview.module.scss b/client/src/entities/posts/overview.module.scss
deleted file mode 100644
index 19af712..0000000
--- a/client/src/entities/posts/overview.module.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.expanded {
- max-width: 100%;
-}
diff --git a/client/src/entities/posts/overview.tsx b/client/src/entities/posts/overview.tsx
deleted file mode 100644
index 5b3e55b..0000000
--- a/client/src/entities/posts/overview.tsx
+++ /dev/null
@@ -1,1060 +0,0 @@
-import clsx from "clsx";
-import {
- MouseEvent as ReactMouseEvent,
- Suspense,
- useEffect,
- useRef,
- useState,
-} from "react";
-import { useNavigate, Await } from "react-router-dom";
-import MicroModal from "micromodal";
-import { ICONS_PREPEND, THUMBNAILS_PREPEND, VIDEO_AD } from "#env/env-vars";
-import {
- createAttachmentURL,
- createBannerURL,
- createIconURL,
- createPostRevisionPageURL,
- createPostURL,
- createPreviewURL,
- createProfileTagURL,
- createProfilePageURL,
-} from "#lib/urls";
-import { fetchPost, flagPost } from "#api/posts";
-import { MiddleAd } from "#components/ads";
-import { Image, ImageBackground, ImageLink } from "#components/images";
-import { KemonoLink, LocalLink } from "#components/links";
-import { Timestamp } from "#components/dates";
-import { LoadingIcon } from "#components/loading";
-import { IPaySite } from "#entities/paysites";
-import {
- IComment,
- IPost,
- IPostAttachment,
- IPostPoll,
- IPostPreview,
- IPostVideo,
- IPreviewEmbed,
- IPreviewThumbnail,
-} from "#entities/posts";
-import { IArtistDetails } from "#entities/profiles";
-import {
- addPostToFavourites,
- isFavouritePost,
- isRegisteredAccount,
- removePostFromFavourites,
-} from "#entities/account";
-
-import "fluid-player/src/css/fluidplayer.css";
-import styles from "./overview.module.scss";
-
-interface IPostOverviewProps {
- post: IPost;
-
- profile: IArtistDetails;
- revisions: Awaited>["props"]["revisions"];
-
- /**
- * TODO: wtf
- */
- flagged?: 0;
- videos?: IPostVideo[];
- attachments?: IPostAttachment[];
- previews?: IPostPreview[];
- archives_enabled?: boolean;
- comments: Promise;
- postTitle: string;
- paysite: IPaySite;
-}
-
-interface IPostHeaderProps
- extends Pick<
- IPostOverviewProps,
- "post" | "profile" | "revisions" | "flagged"
- > {
- postTitle: string;
- paysite: IPaySite;
-}
-
-export function PostOverview({
- post,
- profile,
- revisions,
- flagged,
- videos,
- attachments,
- previews,
- archives_enabled,
- comments,
- postTitle,
- paysite,
-}: IPostOverviewProps) {
- useEffect(() => {
- document.addEventListener("DOMContentLoaded", handleShowTagsButton);
- window.addEventListener("resize", handleShowTagsButton);
-
- return () => {
- document.removeEventListener("DOMContentLoaded", handleShowTagsButton);
- window.removeEventListener("resize", handleShowTagsButton);
- };
- }, []);
-
- function handleShowTagsButton() {
- addShowTagsButton();
- }
-
- return (
- <>
-
-
-
-
-
- >
- );
-}
-
-function PostHeader({
- post,
- profile,
- postTitle,
- paysite,
- revisions,
- flagged,
-}: IPostHeaderProps) {
- const navigate = useNavigate();
- const profileURL = String(
- createProfilePageURL({ service: post.service, profileID: post.user })
- );
- const profileIcon = createIconURL(post.service, post.user);
- const bannerURL = createBannerURL(post.service, post.user);
-
- return (
-
-
-
-
-
-
-
- {!profile ? `Profile page` : profile.name}
-
-
-
-
-
-
- {postTitle} ({paysite.title})
-
-
- {!post.published ? undefined : (
-
-
- Published:
-
{" "}
- {post.published.replace("00:00:00", "")}
-
- )}
-
- {!post.edited || post.edited === post.published ? undefined : (
-
-
- Edited:
-
{" "}
- {post.edited.replace("00:00:00", "")}
-
- )}
-
-
- {revisions.length < 2 ? (
-
-
- Imported:{" "}
-
{" "}
- {post.added.slice(0, 7)}
-
- ) : (
- <>
-
- Imported:
-
-
- {
- const revisionID = event.currentTarget.value;
-
- if (revisionID) {
- navigate(
- String(
- createPostRevisionPageURL(
- post.service,
- post.user,
- post.id,
- revisionID
- )
- )
- );
- } else {
- navigate(
- String(createPostURL(post.service, post.user, post.id))
- );
- }
- }}
- >
- {revisions.map(([index, postRevision]) => (
-
- {postRevision.added?.slice(0, 7)} {"<"}
- {index}
- {">"} [{postRevision.revision_id ?? "current"}]
-
- ))}
-
-
- >
- )}
-
-
- {post.tags && post.tags.length !== 0 && (
-
- Tags:
-
- {post.tags.map((tag, index) => (
-
- {tag}
-
- ))}
-
-
- )}
-
-
-
-
- );
-}
-
-interface IPostBodyProps
- extends Pick<
- IPostOverviewProps,
- "post" | "videos" | "attachments" | "previews" | "archives_enabled"
- > {}
-
-const formattedServices = ["fantia", "onlyfans", "fansly", "candfans"];
-
-function PostBody({
- post,
- attachments,
- previews,
- videos,
- archives_enabled,
-}: IPostBodyProps) {
- const { incomplete_rewards, poll, content, service, user, id } = post;
- const postBodyRef = useRef(null);
-
- useEffect(
- () => {
- const bodyElement = postBodyRef.current;
-
- if (!bodyElement) {
- return;
- }
-
- cleanupBody(bodyElement, service);
- },
- // rerun it on post change
- [id, user, service]
- );
-
- return (
-
-
-
- {post.service === "dlsite" && attachments && attachments.length > 1 && (
-
- This DLsite post was received as a split set of multiple files due to
- file size. Download all the files, then open the .exe file to compile
- them into a single one.
-
- )}
-
- {videos && videos.length !== 0 && (
- <>
-
Videos
-
-
- {videos.map((video, index) => (
-
- ))}
-
- >
- )}
-
- {attachments && attachments.length !== 0 && (
- <>
-
Downloads
-
- {attachments.map((attachment, index) => (
-
- ))}
-
- >
- )}
-
- {incomplete_rewards && (
-
- )}
-
- {poll &&
}
-
- {content && (
- <>
-
Content
- {/* TODO: rewrite without this */}
-
- >
- )}
-
- {previews &&
}
-
- );
-}
-
-/**
- * Apply some fixes to the content of the post.
- */
-function cleanupBody(postBody: HTMLElement, service: string) {
- const postContent = postBody.querySelector(".post__content");
- const isNoPostContent =
- !postContent ||
- (!postContent.childElementCount && !postContent.childNodes.length);
-
- // content is empty
- if (isNoPostContent) {
- return;
- }
-
- // pixiv post
- if (service === "fanbox") {
- // its contents is a text node
- if (!postContent.childElementCount && postContent.childNodes.length === 1) {
- // wrap the text node into ``
- const [textNode] = Array.from(postContent.childNodes);
- const pre = document.createElement("pre");
- textNode.after(pre);
- pre.appendChild(textNode);
- }
-
- // remove paragraphs with only ` ` in them
- const paragraphs = postContent.querySelectorAll("p");
- paragraphs.forEach((para) => {
- if (
- para.childElementCount === 1 &&
- para.firstElementChild?.tagName === "BR"
- ) {
- para.remove();
- }
- });
- }
-
- Array.from(document.links).forEach((anchour) => {
- // remove links to fanbox from the post
- const hostname = anchour.hostname;
- if (hostname.includes("downloads.fanbox.cc")) {
- if (anchour.classList.contains("image-link")) {
- anchour.remove();
- } else {
- let el = document.createElement("span");
- el.textContent = anchour.textContent;
- anchour.replaceWith(el);
- }
- } else if (hostname.includes("fanbox.cc")) {
- anchour.href = anchour.href.replace(
- /https?:\/\/(?:[a-zA-Z0-9-]*.)?fanbox\.cc\/(?:(?:manage\/)|(?:@[a-zA-Z\d]+\/)|)posts\/(\d+)/g,
- "/fanbox/post/$1"
- );
- } else if (hostname.includes("patreon.com")) {
- anchour.href = anchour.href.replace(
- /https?:\/\/(?:[\w-]*.)?patreon\.com\/posts\/.*\b(\d+)\b(?:\?.*)?/g,
- "/patreon/post/$1"
- );
- }
- });
-
- // Remove needless spaces and empty paragraphs.
- /**
- * @type {NodeListOf {
- if (
- paragraph.nextElementSibling &&
- paragraph.nextElementSibling.tagName === "BR"
- ) {
- paragraph.nextElementSibling.remove();
- paragraph.remove();
- } else {
- paragraph.remove();
- }
- });
-}
-
-interface IPostVideoProps {
- video: IPostVideo;
-}
-
-function PostVideo({ video }: IPostVideoProps) {
- return (
-
- {video.name}
-
- {!video.caption ? undefined : {video.caption} }
-
-
-
-
-
- );
-}
-
-interface IPostAttachmentProps
- extends Pick {
- attachment: IPostAttachment;
-}
-
-const archiveFileExtension = [".zip", ".rar", ".7z"];
-
-function PostAttachment({
- attachment,
- archives_enabled,
-}: IPostAttachmentProps) {
- const { name, path, server, extension, name_extension, stem } = attachment;
- const isArchiveFile = Boolean(
- archives_enabled &&
- (archiveFileExtension.includes(extension) ||
- archiveFileExtension.includes(name_extension))
- );
-
- return (
-
-
- Download {name}
-
- {isArchiveFile && (
- <>
- {/* TODO: a proper URL function */}(
- browse » )
- >
- )}
-
- );
-}
-
-interface IPostPollProps {
- poll: IPostPoll;
-}
-
-function PostPoll({ poll }: IPostPollProps) {
- const {
- title,
- description,
- choices,
- total_votes,
- created_at,
- closes_at,
- allow_multiple,
- } = poll;
-
- return (
- <>
- Poll
-
-
-
-
{title}
- {!description ? undefined : {description} }
-
-
-
- {choices.map((choice) => {
- const percentage = (choice.votes / (total_votes ?? 1)) * 100;
-
- return (
-
- {choice.text}
- {choice.votes}
-
-
- );
- })}
-
-
-
-
-
- {created_at}
-
- {closes_at && (
-
- —{closes_at}
-
- )}
-
- {allow_multiple && (
- <>
-
- multiple choice
- >
- )}
-
-
- {total_votes} votes
-
-
-
- {String(poll)}
- >
- );
-}
-
-interface IPostPreviewsProps
- extends Pick, "previews"> {}
-
-function PostPreviews({ previews }: IPostPreviewsProps) {
- return (
- <>
- Files
-
- {previews.map((preview, index) =>
- preview.type === "thumbnail" ? (
-
- ) : (
-
- )
- )}
-
- >
- );
-}
-
-interface IPreviewThumbnailProps {
- preview: IPreviewThumbnail;
-}
-
-function PreviewThumbnail({ preview }: IPreviewThumbnailProps) {
- const [isExpanded, switchExpansion] = useState(false);
- const { server, path, name, caption } = preview;
- const url = String(createPreviewURL(path, name, server));
- const downloadName = encodeURIComponent(name);
- const thumbnailRef = useRef(null);
-
- return (
-
- );
-}
-
-interface IPreviewEmbedProps {
- preview: IPreviewEmbed;
-}
-
-function PreviewEmbed({ preview }: IPreviewEmbedProps) {
- const { url, description, subject } = preview;
-
- return (
-
-
-
- {!subject ? "(No title)" : subject}
-
- {description &&
{description}
}
-
-
- );
-}
-
-interface IPostFooterProps extends Pick {
- service: string;
- profileID: string;
- profileName?: string;
-}
-
-function PostFooter({
- comments,
- service,
- profileID,
- profileName,
-}: IPostFooterProps) {
- return (
-
- Comments
- {/* TODO: comment filters */}
- Loading comments... }>
- >}>
- {(comments: IComment[]) => (
-
- {!comments ? (
-
No comments found for this post.
- ) : (
- comments.map((comment) => (
-
- ))
- )}
-
- )}
-
-
-
- );
-}
-
-interface IPostCommentProps {
- comment: IComment;
- postProfileID: string;
- postProfileName?: string;
- service: string;
-}
-
-function PostComment({
- comment,
- postProfileID,
- postProfileName,
- service,
-}: IPostCommentProps) {
- const {
- id,
- commenter,
- commenter_name,
- revisions,
- parent_id,
- content,
- published,
- } = comment;
- const isProfileComment = commenter === postProfileID;
- const modalID = `comment-revisions-${id}`;
-
- return (
-
-
- {!isProfileComment ? (
-
- {commenter_name ?? "Anonymous"}
-
- ) : (
- <>
- {/* TODO: a proper local link */}
-
-
-
-
- {postProfileName ?? "Post's profile"}
-
- >
- )}
-
- {revisions && revisions.length !== 0 && (
- <>
- MicroModal.show(modalID)}
- >
- (
-
- edited
-
- )
-
-
-
-
-
-
-
-
- MicroModal.close(modalID)}
- >
-
-
-
-
-
-
-
- >
- )}
-
-
-
- {parent_id && (
-
- )}
-
-
- {service !== "boosty" ? (
- content
- ) : (
-
- {content.replace(
- '/size/large" title="',
- '/size/small" title="'
- )}
-
- )}
-
-
-
-
-
- );
-}
-
-interface IPostActionsProps extends Pick {
- service: string;
- profileID: string;
- postID: string;
-}
-
-function PostActions({
- service,
- profileID,
- postID,
- flagged,
-}: IPostActionsProps) {
- return (
-
-
-
-
-
- );
-}
-
-interface IFlagButtonProps
- extends Pick<
- IPostActionsProps,
- "flagged" | "service" | "profileID" | "postID"
- > {}
-
-/**
- * TODO: promptless flagging
- */
-function FlagButton({ service, profileID, postID, flagged }: IFlagButtonProps) {
- const [isFlagged, switchFlag] = useState(Boolean(flagged));
- const [isFlagging, switchFlagging] = useState(false);
- const renderKey = `${postID}${profileID}${service}`;
-
- async function handleFlagging() {
- const isConfirmed = confirm(
- "Are you sure you want to flag this post for reimport? Only do this if data in the post is broken/corrupted/incomplete.\nThis is not a deletion button."
- );
-
- if (!isConfirmed) {
- return;
- }
-
- try {
- switchFlagging(true);
-
- await flagPost(service, profileID, postID);
-
- switchFlag(true);
-
- } finally {
- switchFlagging(false);
- }
- }
-
- return !isFlagged ? (
-
-
- {isFlagging ? : <>⚑>}
-
- Flag
-
- ) : (
-
- ⚑
- Flagged
-
- );
-}
-
-interface IFavoriteButtonProps {
- service: string;
- profileID: string;
- postID: string;
-}
-
-function FavoriteButton({ service, profileID, postID }: IFavoriteButtonProps) {
- const [isFavorite, switchFavorite] = useState(false);
- const [isLoading, switchLoading] = useState(true);
- const renderKey = `${postID}${profileID}${service}`;
-
- useEffect(() => {
- (async () => {
- try {
- switchLoading(true);
-
- const isLoggedIn = await isRegisteredAccount();
-
- if (!isLoggedIn) {
- return;
- }
-
- const isFav = await isFavouritePost(service, profileID, postID);
-
- switchFavorite(isFav);
- } catch (error) {
- // TODO: better error handling
- console.error(error);
- } finally {
- switchLoading(false);
- }
- })();
- }, [service, profileID, postID]);
-
- async function handleFavorite() {
- try {
- switchLoading(true);
- await addPostToFavourites(service, profileID, postID);
- switchFavorite(true);
- } catch (error) {
- // TODO: better error handling
- console.error(error);
- } finally {
- switchLoading(false);
- }
- }
- async function handleUnfavorite() {
- try {
- switchLoading(true);
- await removePostFromFavourites(service, profileID, postID);
- switchFavorite(false);
- } catch (error) {
- // TODO: better error handling
- console.error(error);
- } finally {
- switchLoading(false);
- }
- }
-
- return isFavorite ? (
-
- ★
- Unfavorite
-
- ) : (
-
- ☆
- Favorite
-
- );
-}
-
-function addShowTagsButton() {
- let div = document.querySelector("#post-tags > div");
-
- if (document.getElementById("show-tag-overflow-button")) {
- // @ts-expect-error no fucking idea what it does
- document.getElementById("show-tag-overflow-button").remove();
- }
- // @ts-expect-error no fucking idea what it does
-
- if (div && div.offsetWidth < div.scrollWidth) {
- // tags overflow
- let button = document.createElement("a");
- button.href = "javascript:void 0";
- button.id = "show-tag-overflow-button";
- button.textContent = "Show all »";
- button.onclick = (e) => {
- if (div.classList.contains("show-overflow")) {
- div.classList.remove("show-overflow");
- button.textContent = "Show all»";
- } else {
- div.classList.add("show-overflow");
- button.textContent = "« Hide";
- }
- };
- // @ts-expect-error no fucking idea what it does
- div.parentElement.appendChild(button);
- }
-}
diff --git a/client/src/entities/posts/overview/body.module.scss b/client/src/entities/posts/overview/body.module.scss
new file mode 100644
index 0000000..23fd3c2
--- /dev/null
+++ b/client/src/entities/posts/overview/body.module.scss
@@ -0,0 +1,15 @@
+@use "../../../css/config/variables/sass.scss" as *;
+
+.block {
+ border-bottom: solid gray $size-thin;
+ margin-bottom: $size-normal;
+ border-radius: 0 0 10px 10px;
+}
+
+.expanded {
+ max-width: 100%;
+}
+
+.content {
+ font-family: inherit;
+}
diff --git a/client/src/entities/posts/overview/body.tsx b/client/src/entities/posts/overview/body.tsx
new file mode 100644
index 0000000..52ee5a5
--- /dev/null
+++ b/client/src/entities/posts/overview/body.tsx
@@ -0,0 +1,336 @@
+import clsx from "clsx";
+import { useEffect, useRef, useState } from "react";
+import { THUMBNAILS_PREPEND, VIDEO_AD } from "#env/env-vars";
+import { createAttachmentURL, createPreviewURL } from "#lib/urls";
+import { MiddleAd } from "#components/advs";
+import {
+ IPostAttachment,
+ IPostPoll,
+ IPreviewEmbed,
+ IPreviewThumbnail,
+} from "#entities/posts";
+import { cleanupBody } from "./clean-body";
+import { IPostOverviewProps } from "./types";
+import { PostVideo } from "./video";
+import { FlagButton } from "./flag-button";
+
+import * as styles from "./body.module.scss";
+
+interface IPostBodyProps
+ extends Pick<
+ IPostOverviewProps,
+ "post" | "videos" | "attachments" | "previews" | "archives_enabled"
+ > {
+ flagged?: 0;
+}
+
+const formattedServices = ["fantia", "onlyfans", "fansly", "candfans"];
+
+export function PostBody({
+ post,
+ attachments,
+ previews,
+ videos,
+ archives_enabled,
+ flagged,
+}: IPostBodyProps) {
+ const { incomplete_rewards, poll, content, service, user, id } = post;
+ const postBodyRef = useRef(null);
+
+ useEffect(
+ () => {
+ const bodyElement = postBodyRef.current;
+
+ if (!bodyElement) {
+ return;
+ }
+
+ cleanupBody(bodyElement, service);
+ },
+ // rerun it on post change
+ [id, user, service]
+ );
+
+ return (
+
+
+
+ {post.service === "dlsite" && attachments && attachments.length > 1 && (
+
+ This DLsite post was received as a split set of multiple files due to
+ file size. Download all the files, then open the .exe file to compile
+ them into a single one.
+
+ )}
+
+ {videos && videos.length !== 0 && (
+ <>
+
Videos
+
+
+ {videos.map((video) => (
+
+ ))}
+
+ >
+ )}
+
+ {attachments && attachments.length !== 0 && (
+ <>
+
Downloads
+
+ {attachments.map((attachment, index) => (
+
+ ))}
+
+ >
+ )}
+
+ {incomplete_rewards && (
+
+ )}
+
+ {poll &&
}
+
+ {content && (
+ <>
+
Content
+ {/* TODO: rewrite without this */}
+
+ >
+ )}
+
+ {previews &&
}
+
+ );
+}
+
+interface IPostAttachmentProps
+ extends Pick {
+ attachment: IPostAttachment;
+}
+
+const archiveFileExtension = [".zip", ".rar", ".7z"];
+
+function PostAttachment({
+ attachment,
+ archives_enabled,
+}: IPostAttachmentProps) {
+ const { name, path, server, extension, name_extension, stem } = attachment;
+ const isArchiveFile = Boolean(
+ archives_enabled &&
+ (archiveFileExtension.includes(extension) ||
+ archiveFileExtension.includes(name_extension))
+ );
+
+ return (
+
+
+ Download {name}
+
+ {isArchiveFile && (
+ <>
+ {/* TODO: a proper URL function */}(
+ browse » )
+ >
+ )}
+
+ );
+}
+
+interface IPostPollProps {
+ poll: IPostPoll;
+}
+
+function PostPoll({ poll }: IPostPollProps) {
+ const {
+ title,
+ description,
+ choices,
+ total_votes,
+ created_at,
+ closes_at,
+ allow_multiple,
+ } = poll;
+
+ return (
+ <>
+ Poll
+
+
+
+
{title}
+ {!description ? undefined : {description} }
+
+
+
+ {choices.map((choice) => {
+ const percentage = (choice.votes / (total_votes ?? 1)) * 100;
+
+ return (
+
+ {choice.text}
+ {choice.votes}
+
+
+ );
+ })}
+
+
+
+
+
+ {created_at}
+
+ {closes_at && (
+
+ —{closes_at}
+
+ )}
+
+ {allow_multiple && (
+ <>
+
+ multiple choice
+ >
+ )}
+
+
+ {total_votes} votes
+
+
+
+ {String(poll)}
+ >
+ );
+}
+
+interface IPostPreviewsProps
+ extends Pick, "previews"> {}
+
+function PostPreviews({ previews }: IPostPreviewsProps) {
+ return (
+ <>
+ Files
+
+ {previews.map((preview, index) =>
+ preview.type === "thumbnail" ? (
+
+ ) : (
+
+ )
+ )}
+
+ >
+ );
+}
+
+interface IPreviewThumbnailProps {
+ preview: IPreviewThumbnail;
+}
+
+function PreviewThumbnail({ preview }: IPreviewThumbnailProps) {
+ const [isExpanded, switchExpansion] = useState(false);
+ const { server, path, name, caption } = preview;
+ const url = String(createPreviewURL(path, name, server));
+ const downloadName = encodeURIComponent(name);
+ const thumbnailRef = useRef(null);
+
+ return (
+
+ );
+}
+
+interface IPreviewEmbedProps {
+ preview: IPreviewEmbed;
+}
+
+function PreviewEmbed({ preview }: IPreviewEmbedProps) {
+ const { url, description, subject } = preview;
+
+ return (
+
+
+
+ {!subject ? "(No title)" : subject}
+
+ {description &&
{description}
}
+
+
+ );
+}
+
+interface IActionsProps {
+ service: string;
+ profileID: string;
+ postID: string;
+ flagged?: 0;
+}
diff --git a/client/src/entities/posts/overview/clean-body.ts b/client/src/entities/posts/overview/clean-body.ts
new file mode 100644
index 0000000..a4f5775
--- /dev/null
+++ b/client/src/entities/posts/overview/clean-body.ts
@@ -0,0 +1,111 @@
+import { paysites } from "#entities/paysites";
+
+/**
+ * Apply some fixes to the content of the post.
+ */
+export function cleanupBody(postBody: HTMLElement, service: string) {
+ const postContent = postBody.querySelector(
+ ".post__content > pre"
+ );
+ const isNoPostContent =
+ !postContent ||
+ (!postContent.childElementCount && !postContent.childNodes.length);
+
+ // content is empty
+ if (isNoPostContent) {
+ return;
+ }
+
+ // pixiv post
+ if (service === "fanbox") {
+ // its contents is a text node
+ if (!postContent.childElementCount && postContent.childNodes.length === 1) {
+ // wrap the text node into ``
+ const [textNode] = Array.from(postContent.childNodes);
+ const pre = document.createElement("pre");
+ textNode.after(pre);
+ pre.appendChild(textNode);
+ }
+
+ // remove paragraphs with only ` ` in them
+ const paragraphs = postContent.querySelectorAll("p");
+ paragraphs.forEach((para) => {
+ if (
+ para.childElementCount === 1 &&
+ para.firstElementChild?.tagName === "BR"
+ ) {
+ para.remove();
+ }
+ });
+ }
+
+ if (service === "onlyfans") {
+ // replace links to profiles with internal links
+ const links = postContent.querySelectorAll("a");
+
+ Array.from(links).forEach((anchour) => {
+ const literalHref = anchour.getAttribute("href")!;
+
+ // it's not an internal href
+ if (!literalHref.startsWith("/")) {
+ return;
+ }
+
+ const url = new URL(literalHref, anchour.href);
+ const pathname = url.pathname;
+ const pathnameSegments = url.pathname
+ .split("/")
+ .slice(1, pathname.endsWith("/") ? -1 : undefined);
+
+ // url is not a profile
+ if (pathnameSegments.length !== 0) {
+ return;
+ }
+
+ const profileID = pathnameSegments[0];
+ const fixedURL = paysites["onlyfans"].user.profile(profileID);
+ anchour.href = fixedURL;
+ });
+ }
+
+ Array.from(document.links).forEach((anchour) => {
+ // remove links to fanbox from the post
+ const hostname = anchour.hostname;
+ if (hostname.includes("downloads.fanbox.cc")) {
+ if (anchour.classList.contains("image-link")) {
+ anchour.remove();
+ } else {
+ let el = document.createElement("span");
+ el.textContent = anchour.textContent;
+ anchour.replaceWith(el);
+ }
+ } else if (hostname.includes("fanbox.cc")) {
+ anchour.href = anchour.href.replace(
+ /https?:\/\/(?:[a-zA-Z0-9-]*.)?fanbox\.cc\/(?:(?:manage\/)|(?:@[a-zA-Z\d]+\/)|)posts\/(\d+)/g,
+ "/fanbox/post/$1"
+ );
+ } else if (hostname.includes("patreon.com")) {
+ anchour.href = anchour.href.replace(
+ /https?:\/\/(?:[\w-]*.)?patreon\.com\/posts\/.*\b(\d+)\b(?:\?.*)?/g,
+ "/patreon/post/$1"
+ );
+ }
+ });
+
+ // Remove needless spaces and empty paragraphs.
+ /**
+ * @type {NodeListOf {
+ if (
+ paragraph.nextElementSibling &&
+ paragraph.nextElementSibling.tagName === "BR"
+ ) {
+ paragraph.nextElementSibling.remove();
+ paragraph.remove();
+ } else {
+ paragraph.remove();
+ }
+ });
+}
diff --git a/client/src/entities/posts/overview/flag-button.module.scss b/client/src/entities/posts/overview/flag-button.module.scss
new file mode 100644
index 0000000..dcffc45
--- /dev/null
+++ b/client/src/entities/posts/overview/flag-button.module.scss
@@ -0,0 +1,183 @@
+.button {
+ // display: flex;
+ // flex-flow: row nowrap;
+ // gap: 0.5em;
+ // justify-content: center;
+ // align-items: center;
+ // min-width: 6em;
+ color: hsl(0, 0%, 100%);
+ border: transparent;
+ background: transparent;
+ font-weight: bold;
+ text-shadow:
+ hsl(0, 0%, 0%) 0px 0px 3px,
+ hsl(0, 0%, 0%) -1px -1px 0px,
+ hsl(0, 0%, 0%) 1px 1px 0px;
+}
+
+.disabled {
+ color: grey;
+}
+
+.modal {
+ color: var(--colour0-primary);
+ background-color: var(--colour1-primary);
+ padding: 0;
+ font-size: 80%;
+
+ form {
+ div {
+ width: 100%;
+ }
+
+ label {
+ display: block;
+ width: 100%;
+ padding: 2px;
+ }
+
+ input[type="radio"] {
+ display: none;
+ }
+
+ input[type="radio"] ~ label:hover {
+ background-color: var(--colour0-tertirary);
+ }
+
+ input[type="radio"]:checked ~ label {
+ background-color: var(--anchour-internal-colour2-primary);
+ }
+
+ section {
+ &:first-child {
+ div:not(:last-child) {
+ border-bottom: 1px solid var(--colour0-tertirary);
+ }
+ }
+
+ &:last-child div label {
+ color: var(--colour0-secondary);
+ }
+ }
+ }
+
+ @media only screen and (max-width: 720px) {
+ @media (max-width: 400px) {
+ width: 90vw;
+ }
+
+ height: 60vh;
+
+ form {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ section {
+ &:first-child {
+ margin-bottom: 0.25em;
+ border-bottom: 1px solid var(--colour0-tertirary);
+
+ div:not(:last-child) {
+ border-bottom: 1px solid var(--colour0-tertirary);
+ }
+ }
+
+ &:last-child {
+ display: inline-flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ div {
+ // &:not(:last-child)
+ &:first-child {
+ height: 100%;
+
+ label {
+ cursor: default;
+ position: relative;
+ top: 50%;
+ transform: translateY(-50%);
+ }
+ }
+
+ &:last-child {
+ flex-basis: 0;
+
+ button {
+ width: 50%;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @media only screen and (min-width: 721px) {
+ @media (max-width: 1200px) {
+ width: 50vw;
+ }
+ @media (max-width: 1600px) {
+ width: 40vw;
+ }
+ @media (min-width: 1600px) {
+ width: 30vw;
+ }
+
+ form {
+ display: flex;
+
+ section {
+ &:first-child {
+ // Reason selection box
+ padding-right: 0.5em;
+ width: max(30%, 10em);
+
+ div {
+ > label {
+ padding-left: 4px;
+ }
+ &:first-child > label {
+ padding-top: 4px;
+ }
+ &:last-child > label{
+ padding-bottom: 4px;
+ }
+ }
+ }
+
+ &:last-child {
+ // Details/submit
+ display: flex;
+ flex-direction: column;
+ width: 70%;
+ margin-right: 2px;
+
+ :first-child {
+ // Detailed reason box
+ flex-grow: 1;
+ top: 5vh;
+
+ label {
+ cursor: default;
+ position: relative;
+ top: 50%;
+ transform: translateY(-50%);
+ }
+ }
+
+ :last-child {
+ // Buttons' container div
+ text-align: center;
+ margin-bottom: 0.25em;
+
+ :first-child {
+ margin-right: 0.25em;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/client/src/entities/posts/overview/flag-button.tsx b/client/src/entities/posts/overview/flag-button.tsx
new file mode 100644
index 0000000..680b993
--- /dev/null
+++ b/client/src/entities/posts/overview/flag-button.tsx
@@ -0,0 +1,182 @@
+import { FormEvent, MouseEvent, useEffect, useRef, useState } from "react";
+import { flagPost } from "#api/posts";
+import { useClient } from "#hooks";
+import { LoadingIcon } from "#components/loading";
+import { Button } from "#components/buttons";
+import { Modal } from "#components/modal";
+import { IPostActionsProps } from "./types";
+
+import * as styles from "./flag-button.module.scss";
+
+const REASON_MESSAGES: {[reason: string]: string} = {
+ "delete-copyright": `Post contains copyrighted material that should not be shared. We will review this post to ensure legal compliance and protect creators' rights.
+ After submitting the flag to finalize the request please contact us via the contact page. `,
+ "delete-abuse": `Use this flag if the post includes illegal material or content that violates the law in your country.
+ After submitting the flag to finalize the request please contact us via the contact page. `,
+ "missing-password": "Post files or urls requires a password to access content, but no password is provided in the post.",
+ "offsite-expired": "If the post files rewards exist on an external link that no longer works, select this flag.",
+ "post-changed": `Use this option if the original post has been edited at the source with new images or URLs, revised content, or updated index posts.`,
+ "corrupted-files": "Images, videos, or other files that are broken or unreadable.",
+ "missing-files": "The post is missing files that were expected to be included, such as images, attachments, or URLs.",
+ "stale-comments": "The comments on the post are outdated and require reimport to give access to passwords or URLs.",
+ "formatting-error": "Post text has formatting issues, such as text size difference, missing highlighting, incorrect spacing, or broken layout. Reporting this will help development.",
+ "reason-other": "There was some other problem with this post.",
+};
+
+interface IFlagButtonProps
+ extends Pick<
+ IPostActionsProps,
+ "flagged" | "service" | "profileID" | "postID"
+ > {}
+
+export function FlagButton({
+ service,
+ profileID: creatorId,
+ postID: postId,
+ flagged,
+}: IFlagButtonProps) {
+ const client = useClient();
+ const [isFlagged, setFlagged] = useState(Boolean(flagged));
+ const [isFlagging, setFlagging] = useState(false);
+ // const [modalOpen, setModalOpen] = useState(false);
+ // const [reason, setReason] = useState(flagged ?? "");
+ // const [reasonDescription, setReasonDescription] = useState(REASON_MESSAGES[reason] ?? "Select a reason")
+
+ useEffect(() => {
+ setFlagged(Boolean(flagged));
+ }, [service, creatorId, postId, flagged]);
+
+ async function handleFlagging(flagReason: string) {
+ try {
+ setFlagging(true);
+
+ let result = await flagPost({ service, creatorId, postId, reason: flagReason });
+ if (result) {
+ setFlagged(true);
+ // setReason(result);
+ // onModalClose();
+ } else {
+ setFlagged(false);
+ alert("Error flagging");
+ }
+ } catch (e) {
+ alert("Error flagging: " + e);
+ setFlagged(false);
+ } finally {
+ setFlagging(false);
+ }
+ }
+
+ // function showModal() {
+ // setModalOpen(true);
+ // }
+
+ // function onModalClose() {
+ // setModalOpen(false);
+ // }
+
+ // function submitFlag(event: MouseEvent) {
+ // event.preventDefault();
+ // handleFlagging(reason);
+ // }
+
+ // function cancelClicked(event: MouseEvent) {
+ // event.preventDefault();
+ // setModalOpen(false);
+ // }
+
+ // function reasonChanged(event: FormEvent) {
+ // let reasonId = (event.target as HTMLElement).id;
+ // setReason(reasonId);
+ // setReasonDescription(REASON_MESSAGES[reasonId] ?? "Invalid reason selected");
+ // }
+
+ function flagClicked(event: MouseEvent) {
+ event.preventDefault();
+ handleFlagging("reason-other")
+ }
+
+ if (!client) {
+ return (
+ Loading...
+ );
+ } else if (!client.isRegistered) {
+ return (
+ ⚑ Flag
+ );
+ } else if (isFlagging) {
+ return (
+ Flagging...
+ );
+ } else if (isFlagged) {
+ return (
+ ⚑ Flagged
+ );
+ } else {
+ return (
+ <>
+
+
+ {isFlagging ? : <>⚑ >}
+ {!isFlagged ? <>Flag> : <>Flagged>}
+
+
+ {/*
+
+ */}
+ >
+ );
+ }
+}
diff --git a/client/src/entities/posts/overview/footer.module.scss b/client/src/entities/posts/overview/footer.module.scss
new file mode 100644
index 0000000..3855c0e
--- /dev/null
+++ b/client/src/entities/posts/overview/footer.module.scss
@@ -0,0 +1,3 @@
+.content {
+ font-family: inherit;
+}
diff --git a/client/src/entities/posts/overview/footer.tsx b/client/src/entities/posts/overview/footer.tsx
new file mode 100644
index 0000000..eace7c0
--- /dev/null
+++ b/client/src/entities/posts/overview/footer.tsx
@@ -0,0 +1,191 @@
+import clsx from "clsx";
+import { Suspense } from "react";
+import { Await } from "react-router";
+import MicroModal from "micromodal";
+import { ICONS_PREPEND } from "#env/env-vars";
+import { Image } from "#components/images";
+import { KemonoLink, LocalLink } from "#components/links";
+import { Timestamp } from "#components/dates";
+import { Preformatted } from "#components/formatting";
+import { IComment } from "#entities/posts";
+
+import * as styles from "./overview.module.scss";
+import { IPostOverviewProps } from "./types";
+
+interface IPostFooterProps extends Pick {
+ service: string;
+ profileID: string;
+ profileName?: string;
+}
+
+export function PostFooter({
+ comments,
+ service,
+ profileID,
+ profileName,
+}: IPostFooterProps) {
+ return (
+
+ Comments
+ {/* TODO: comment filters */}
+ Loading comments...}>
+ >}>
+ {(comments: IComment[]) => (
+
+ {!comments ? (
+
No comments found for this post.
+ ) : (
+ comments.map((comment) => (
+
+ ))
+ )}
+
+ )}
+
+
+
+ );
+}
+
+interface IPostCommentProps {
+ comment: IComment;
+ postProfileID: string;
+ postProfileName?: string;
+ service: string;
+}
+
+function PostComment({
+ comment,
+ postProfileID,
+ postProfileName,
+ service,
+}: IPostCommentProps) {
+ const {
+ id,
+ commenter,
+ commenter_name,
+ revisions,
+ parent_id,
+ content,
+ published,
+ } = comment;
+ const isProfileComment = commenter === postProfileID;
+ const modalID = `comment-revisions-${id}`;
+
+ return (
+
+
+ {!isProfileComment ? (
+
+ {commenter_name ?? "Anonymous"}
+
+ ) : (
+ <>
+ {/* TODO: a proper local link */}
+
+
+
+
+ {postProfileName ?? "Post's profile"}
+
+ >
+ )}
+
+ {revisions && revisions.length !== 0 && (
+ <>
+ MicroModal.show(modalID)}
+ >
+ (
+
+ edited
+
+ )
+
+
+
+
+
+
+
+
+ MicroModal.close(modalID)}
+ >
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+ {parent_id && (
+
+ )}
+
+
+ {service !== "boosty" ? (
+ content
+ ) : (
+
+ {content.replace(
+ '/size/large" title="',
+ '/size/small" title="'
+ )}
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/entities/posts/overview/header.tsx b/client/src/entities/posts/overview/header.tsx
new file mode 100644
index 0000000..4cd6ebb
--- /dev/null
+++ b/client/src/entities/posts/overview/header.tsx
@@ -0,0 +1,276 @@
+import clsx from "clsx";
+import { useEffect, useState } from "react";
+import { useNavigate } from "react-router";
+import {
+ createBannerURL,
+ createIconURL,
+ createPostRevisionPageURL,
+ createPostURL,
+ createProfileTagURL,
+ createProfilePageURL,
+} from "#lib/urls";
+import { ImageBackground, ImageLink } from "#components/images";
+import { KemonoLink } from "#components/links";
+import { IPaySite } from "#entities/paysites";
+import {
+ addPostToFavourites,
+ isFavouritePost,
+ isRegisteredAccount,
+ removePostFromFavourites,
+} from "#entities/account";
+import { IPostActionsProps, IPostOverviewProps } from "./types";
+import { FlagButton } from "./flag-button";
+import { Timestamp } from "#components/dates";
+
+interface IPostHeaderProps
+ extends Pick<
+ IPostOverviewProps,
+ "post" | "profile" | "revisions" | "flagged"
+ > {
+ postTitle: string;
+ paysite: IPaySite;
+}
+
+export function PostHeader({
+ post,
+ profile,
+ postTitle,
+ paysite,
+ revisions,
+ flagged,
+}: IPostHeaderProps) {
+ const navigate = useNavigate();
+ const profileURL = String(
+ createProfilePageURL({ service: post.service, profileID: post.user })
+ );
+ const profileIcon = createIconURL(post.service, post.user);
+ const bannerURL = createBannerURL(post.service, post.user);
+
+ return (
+
+
+
+
+
+
+
+ {!profile ? `Profile page` : profile.name}
+
+
+
+
+
+
+ {postTitle} ({paysite.title})
+
+
+ {!post.published ? undefined : (
+
+
+ Published:
+
{" "}
+
+
+ )}
+
+ {!post.edited || post.edited === post.published ? undefined : (
+
+ )}
+
+
+ {revisions.length < 2 ? (
+
+
+ Imported:{" "}
+
{" "}
+ {post.added?.slice(0, 7) ?? "Unknown"}
+
+ ) : (
+ <>
+
+ Imported:
+
+
+ {
+ const revisionID = event.currentTarget.value;
+
+ if (revisionID) {
+ navigate(
+ String(
+ createPostRevisionPageURL(
+ post.service,
+ post.user,
+ post.id,
+ revisionID
+ )
+ )
+ );
+ } else {
+ navigate(
+ String(createPostURL(post.service, post.user, post.id))
+ );
+ }
+ }}
+ >
+ {revisions.map(([index, postRevision]) => (
+
+ {postRevision.added?.slice(0, 7) ?? "Unknown"} {"<"}
+ {index}
+ {">"} [{postRevision.revision_id ?? "current"}]
+
+ ))}
+
+
+ >
+ )}
+
+
+ {post.tags && post.tags.length !== 0 && (
+
+ Tags:
+
+ {post.tags.map((tag, index) => (
+
+ {tag}
+
+ ))}
+
+
+ )}
+
+
+
+
+ );
+}
+
+function PostActions({
+ service,
+ profileID,
+ postID,
+ flagged,
+}: IPostActionsProps) {
+ return (
+
+
+
+
+ );
+}
+
+interface IFavoriteButtonProps {
+ service: string;
+ profileID: string;
+ postID: string;
+}
+
+function FavoriteButton({ service, profileID, postID }: IFavoriteButtonProps) {
+ const [isFavorite, switchFavorite] = useState(false);
+ const [isLoading, switchLoading] = useState(true);
+ const renderKey = `${postID}${profileID}${service}`;
+
+ useEffect(() => {
+ (async () => {
+ try {
+ switchLoading(true);
+
+ const isLoggedIn = await isRegisteredAccount();
+
+ if (!isLoggedIn) {
+ return;
+ }
+
+ const isFav = await isFavouritePost(service, profileID, postID);
+
+ switchFavorite(isFav);
+ } catch (error) {
+ // TODO: better error handling
+ console.error(error);
+ } finally {
+ switchLoading(false);
+ }
+ })();
+ }, [service, profileID, postID]);
+
+ async function handleFavorite() {
+ try {
+ switchLoading(true);
+ await addPostToFavourites(service, profileID, postID);
+ switchFavorite(true);
+ } catch (error) {
+ // TODO: better error handling
+ console.error(error);
+ } finally {
+ switchLoading(false);
+ }
+ }
+ async function handleUnfavorite() {
+ try {
+ switchLoading(true);
+ await removePostFromFavourites(service, profileID, postID);
+ switchFavorite(false);
+ } catch (error) {
+ // TODO: better error handling
+ console.error(error);
+ } finally {
+ switchLoading(false);
+ }
+ }
+
+ return isFavorite ? (
+
+ ★
+ Unfavorite
+
+ ) : (
+
+ ☆
+ Favorite
+
+ );
+}
diff --git a/client/src/entities/posts/overview/overview.module.scss b/client/src/entities/posts/overview/overview.module.scss
new file mode 100644
index 0000000..79c6283
--- /dev/null
+++ b/client/src/entities/posts/overview/overview.module.scss
@@ -0,0 +1,7 @@
+@use "../../../css/config/variables/sass.scss" as *;
+
+.list {
+ display: flex;
+ flex-flow: column nowrap;
+ gap: $size-normal;
+}
diff --git a/client/src/entities/posts/overview/overview.tsx b/client/src/entities/posts/overview/overview.tsx
new file mode 100644
index 0000000..80a2375
--- /dev/null
+++ b/client/src/entities/posts/overview/overview.tsx
@@ -0,0 +1,92 @@
+import { useEffect } from "react";
+import { PostHeader } from "./header";
+import { PostBody } from "./body";
+import { PostFooter } from "./footer";
+import { IPostOverviewProps } from "./types";
+
+import "fluid-player/src/css/fluidplayer.css";
+
+export function PostOverview({
+ post,
+ profile,
+ revisions,
+ flagged,
+ videos,
+ attachments,
+ previews,
+ archives_enabled,
+ comments,
+ postTitle,
+ paysite,
+}: IPostOverviewProps) {
+ useEffect(() => {
+ document.addEventListener("DOMContentLoaded", handleShowTagsButton);
+ window.addEventListener("resize", handleShowTagsButton);
+
+ return () => {
+ document.removeEventListener("DOMContentLoaded", handleShowTagsButton);
+ window.removeEventListener("resize", handleShowTagsButton);
+ };
+ }, []);
+
+ function handleShowTagsButton() {
+ addShowTagsButton();
+ }
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
+
+function addShowTagsButton() {
+ let div = document.querySelector("#post-tags > div");
+
+ if (document.getElementById("show-tag-overflow-button")) {
+ // @ts-expect-error no fucking idea what it does
+ document.getElementById("show-tag-overflow-button").remove();
+ }
+ // @ts-expect-error no fucking idea what it does
+
+ if (div && div.offsetWidth < div.scrollWidth) {
+ // tags overflow
+ let button = document.createElement("a");
+ button.href = "javascript:void 0";
+ button.id = "show-tag-overflow-button";
+ button.textContent = "Show all »";
+ button.onclick = (e) => {
+ if (div.classList.contains("show-overflow")) {
+ div.classList.remove("show-overflow");
+ button.textContent = "Show all»";
+ } else {
+ div.classList.add("show-overflow");
+ button.textContent = "« Hide";
+ }
+ };
+ // @ts-expect-error no fucking idea what it does
+ div.parentElement.appendChild(button);
+ }
+}
diff --git a/client/src/entities/posts/overview/types.ts b/client/src/entities/posts/overview/types.ts
new file mode 100644
index 0000000..f1c8885
--- /dev/null
+++ b/client/src/entities/posts/overview/types.ts
@@ -0,0 +1,32 @@
+import { fetchPost } from "#api/posts";
+import { IPaySite } from "#entities/paysites";
+import {
+ IComment,
+ IPost,
+ IPostAttachment,
+ IPostPreview,
+ IPostVideo,
+} from "#entities/posts";
+import { IArtistDetails } from "#entities/profiles";
+
+export interface IPostOverviewProps {
+ post: IPost;
+
+ profile: IArtistDetails;
+ revisions: Awaited>["props"]["revisions"];
+
+ flagged: string | null;
+ videos?: IPostVideo[];
+ attachments?: IPostAttachment[];
+ previews?: IPostPreview[];
+ archives_enabled?: boolean;
+ comments: Promise;
+ postTitle: string;
+ paysite: IPaySite;
+}
+
+export interface IPostActionsProps extends Pick {
+ service: string;
+ profileID: string;
+ postID: string;
+}
diff --git a/client/src/entities/posts/overview/video.tsx b/client/src/entities/posts/overview/video.tsx
new file mode 100644
index 0000000..3b6a396
--- /dev/null
+++ b/client/src/entities/posts/overview/video.tsx
@@ -0,0 +1,96 @@
+import { useEffect, useRef } from "react";
+import { VIDEO_AD } from "#env/env-vars";
+import { IPostVideo } from "#entities/posts";
+
+interface IPostVideoProps {
+ video: IPostVideo;
+}
+
+export function PostVideo({ video }: IPostVideoProps) {
+ const videoRef = useRef(null);
+
+ useEffect(() => {
+ const videoElement = videoRef.current;
+
+ if (!videoElement) {
+ return;
+ }
+
+ let fluidPlayer: FluidPlayerInstance | undefined = undefined;
+
+ console.time(`${video.path}-create`);
+ console.time(`${video.path}-vast`);
+ import("fluid-player")
+ .then(({ default: fluidPlayerModule }) => {
+ fluidPlayer = fluidPlayerModule(videoElement, {
+ layoutControls: {
+ fillToContainer: false,
+ preload: "none",
+ },
+ vastOptions: {
+ adList: JSON.parse(atob(VIDEO_AD)),
+ adTextPosition: "top left",
+ maxAllowedVastTagRedirects: 2,
+ vastAdvanced: {
+ vastLoadedCallback: () => {
+ console.timeLog(`${video.path}-vast`, "Loaded VAST video.");
+ },
+ noVastVideoCallback: () => {
+ console.timeLog(`${video.path}-vast`, "No VAST video loaded.");
+ },
+ vastVideoSkippedCallback: () => {
+ console.timeLog(`${video.path}-vast`, "Skipped VAST video.");
+ },
+ vastVideoEndedCallback: () => {
+ console.timeLog(`${video.path}-vast`, "VAST video ended.");
+ },
+ },
+ },
+ } satisfies Partial);
+ })
+ .then(() => {
+ console.timeEnd(`${video.path}-create`);
+ })
+ .catch((error) => {
+ const message = `Failed to initialize Fluid Player for video "${video.path}".`;
+ console.error(new Error(message, { cause: error }));
+ });
+
+ return () => {
+ const onEndedEvent = new Event("ended")
+ videoRef.current?.dispatchEvent(onEndedEvent)
+ // will not fix the issue of a possible memory leak
+ // but will stop the video from playing
+ videoRef.current?.pause()
+
+ if (fluidPlayer) {
+ console.time(`${video.path}-destroy`);
+ fluidPlayer.destroy();
+ console.timeEnd(`${video.path}-destroy`);
+ console.timeEnd(`${video.path}-vast`);
+ }
+ };
+ }, [video.path]);
+
+ return (
+
+ {video.name}
+
+ {!video.caption ? undefined : {video.caption} }
+
+
+
+
+
+ );
+}
diff --git a/client/src/entities/posts/types.ts b/client/src/entities/posts/types.ts
index 45e76b0..8f578a9 100644
--- a/client/src/entities/posts/types.ts
+++ b/client/src/entities/posts/types.ts
@@ -14,7 +14,7 @@ export interface IPost {
shared_file: boolean;
embed: {};
attachments: IPostAttachment[];
- added: string;
+ added?: string;
published?: string;
edited?: string;
prev?: string;
@@ -23,10 +23,10 @@ export interface IPost {
tags: string[] | null;
incomplete_rewards?: string;
poll?: IPostPoll;
-}
-export interface IPostWithFavorites extends IPost {
- fav_count: number;
+ fav_count?: number;
+ isFavourite?: boolean;
+ isFavouriteProfile?: boolean;
}
export interface IPostRevision {
@@ -99,10 +99,22 @@ export interface ICommentRevision {
export interface IAnnouncement {
service: string;
+ /**
+ * ID of profile.
+ */
user_id: string;
+ /**
+ * SHA-256 hash.
+ */
hash: string;
content: string;
+ /**
+ * ISO datetime without timezone.
+ */
added: string;
+ /**
+ * ISO datetime without timezone.
+ */
published?: string;
}
@@ -135,7 +147,7 @@ export interface IDiscordAttachment {
}
export interface IDiscordEmbed {
- url: string
- title?: string
- description?: string
+ url: string;
+ title?: string;
+ description?: string;
}
diff --git a/client/src/env/env-vars.ts b/client/src/env/env-vars.ts
index adf99fe..b03326c 100644
--- a/client/src/env/env-vars.ts
+++ b/client/src/env/env-vars.ts
@@ -18,8 +18,6 @@ export const BANNERS_PREPEND = BUNDLER_ENV_BANNERS_PREPEND;
export const THUMBNAILS_PREPEND = BUNDLER_ENV_THUMBNAILS_PREPEND;
-export const CREATORS_LOCATION = BUNDLER_ENV_CREATORS_LOCATION;
-
export const ARTISTS_OR_CREATORS = BUNDLER_ENV_ARTISTS_OR_CREATORS;
export const DISABLE_DMS = BUNDLER_ENV_DISABLE_DMS;
@@ -86,6 +84,12 @@ export const API_SERVER_BASE_URL = BUNDLER_ENV_API_SERVER_BASE_URL;
export const API_SERVER_PORT = BUNDLER_ENV_API_SERVER_PORT;
+export const GIT_COMMIT_HASH = BUNDLER_ENV_GIT_COMMIT_HASH;
+
+export const BUILD_DATE = BUNDLER_ENV_BUILD_DATE;
+
+export const IS_FILE_SERVING_ENABLED = BUNDLER_ENV_IS_FILE_SERVING_ENABLED;
+
// stolen from https://stackoverflow.com/a/76844373
declare global {
const BUNDLER_ENV_KEMONO_SITE: string;
@@ -117,6 +121,9 @@ declare global {
const BUNDLER_ENV_IS_ARCHIVER_ENABLED: boolean;
const BUNDLER_ENV_API_SERVER_BASE_URL: string | undefined;
const BUNDLER_ENV_API_SERVER_PORT: number | undefined;
+ const BUNDLER_ENV_GIT_COMMIT_HASH: string | undefined;
+ const BUNDLER_ENV_BUILD_DATE: string | undefined;
+ const BUNDLER_ENV_IS_FILE_SERVING_ENABLED: boolean;
}
interface IAnnouncement {
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 22832a3..79b44e8 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -1,11 +1,12 @@
-import "./index.scss";
// TODO: nuke/inline these styles
import "purecss/build/base-min.css";
import "purecss/build/grids-min.css";
import "purecss/build/grids-responsive-min.css";
+
+import "./index.scss";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
-import { RouterProvider } from "react-router-dom";
+import { RouterProvider } from "react-router/dom";
import { router } from "./router";
const rootElement = document.getElementById("root");
diff --git a/client/src/lib/api/error-v2.ts b/client/src/lib/api/error-v2.ts
new file mode 100644
index 0000000..e092c33
--- /dev/null
+++ b/client/src/lib/api/error-v2.ts
@@ -0,0 +1,42 @@
+import { InvalidErrorType } from "#lib/errors";
+import { IResponseError } from "./types";
+
+interface IAPIV2Error extends Error {
+ pathSpec: string;
+ request: Request;
+ response: Response;
+ error?: IResponseError;
+}
+
+interface IAPIV2ErrorOptions extends ErrorOptions {
+ pathSpec: string;
+ request: Request;
+ response: Response;
+ error?: IResponseError;
+}
+
+export class APIV2Error extends Error implements IAPIV2Error {
+ pathSpec: string;
+ request: Request;
+ response: Response;
+ error?: IResponseError;
+
+ constructor(message: string, options: IAPIV2ErrorOptions) {
+ super(message);
+
+ this.pathSpec = options.pathSpec;
+ this.request = options.request;
+ this.response = options.response;
+ this.error = options.error;
+ }
+}
+
+export function isAPIV2Error(input: unknown): input is APIV2Error {
+ return input instanceof APIV2Error;
+}
+
+export function ensureAPIV2Error(input: unknown): asserts input is APIV2Error {
+ if (!isAPIV2Error(input)) {
+ throw new InvalidErrorType(input);
+ }
+}
diff --git a/client/src/api/fetch.ts b/client/src/lib/api/fetch.ts
similarity index 93%
rename from client/src/api/fetch.ts
rename to client/src/lib/api/fetch.ts
index ff2250d..814e504 100644
--- a/client/src/api/fetch.ts
+++ b/client/src/lib/api/fetch.ts
@@ -1,5 +1,6 @@
import { logoutAccount } from "#entities/account";
-import { HTTP_STATUS } from "#lib/http";
+import { HTTP_STATUS, mergeHeaders } from "#lib/http";
+import { customFetch } from "#lib/fetch";
import { APIError } from "#lib/api";
const urlBase = `/api/v1`;
@@ -12,6 +13,7 @@ jsonHeaders.append("Content-Type", "application/json");
interface IOptions extends Omit {
method: "GET" | "POST" | "DELETE";
body?: any;
+ headers?: Headers;
}
/**
@@ -52,14 +54,16 @@ export async function apiFetch(
const jsonBody = JSON.stringify(options.body);
finalOptions = {
...options,
- headers: jsonHeaders,
+ headers: options.headers
+ ? mergeHeaders(options.headers, jsonHeaders)
+ : jsonHeaders,
body: jsonBody,
credentials: "same-origin",
};
}
}
const request = new Request(apiPath, finalOptions);
- const response = await fetch(request);
+ const response = await customFetch(request);
if (!response.ok) {
// server logged the account out
diff --git a/client/src/lib/api/index.ts b/client/src/lib/api/index.ts
index 65724d6..3e7d77a 100644
--- a/client/src/lib/api/index.ts
+++ b/client/src/lib/api/index.ts
@@ -1 +1,4 @@
+export { apiFetch } from "./fetch";
export { APIError, ensureAPIError, isAPIError } from "./error";
+export { apiV2Fetch } from "./v2";
+export { APIV2Error, ensureAPIV2Error, isAPIV2Error } from "./error-v2";
diff --git a/client/src/lib/api/types.ts b/client/src/lib/api/types.ts
new file mode 100644
index 0000000..a888a98
--- /dev/null
+++ b/client/src/lib/api/types.ts
@@ -0,0 +1,25 @@
+export type IMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
+
+export const requestBodyType = "Sneed's Feed & Seed (formerly Chuck's)";
+export const responseBodyTypeSuccess = "Chuck's Fuck & Suck (formerly Boyle's)";
+export const responseBodyTypeError = "Boyle's Foil & Soil (formerly Sneed's)";
+
+export interface IRequestBody {
+ type: typeof requestBodyType;
+ data?: DataShape;
+}
+
+export interface IResponseBodySuccess {
+ type: typeof responseBodyTypeSuccess;
+ data: DataShape;
+}
+
+export interface IResponseBodyError {
+ type: typeof responseBodyTypeError;
+ error: IResponseError;
+}
+
+export interface IResponseError {
+ type: string;
+ message?: string;
+}
diff --git a/client/src/lib/api/v2.ts b/client/src/lib/api/v2.ts
new file mode 100644
index 0000000..4b62778
--- /dev/null
+++ b/client/src/lib/api/v2.ts
@@ -0,0 +1,145 @@
+import { HTTP_STATUS, mergeHeaders } from "#lib/http";
+import { customFetch } from "#lib/fetch";
+import { logoutAccount } from "#entities/account";
+import { APIV2Error } from "./error-v2";
+import {
+ IMethod,
+ IRequestBody,
+ IResponseBodySuccess,
+ IResponseBodyError,
+ requestBodyType,
+ IResponseError,
+} from "./types";
+
+const urlBase = `/api/v2`;
+const jsonHeaders = new Headers();
+jsonHeaders.append("Content-Type", "application/json");
+
+interface IOptions extends Omit {
+ body?: any;
+ headers?: Headers;
+ searchParams?: URLSearchParams;
+}
+
+/**
+ * Generic request for API V2.
+ * @param pathSpec
+ * @param method
+ * @param path
+ * A path to the endpoint, relative to the base API path.
+ * @param options
+ */
+export async function apiV2Fetch(
+ pathSpec: string,
+ method: IMethod,
+ path: string,
+ options?: IOptions
+): Promise {
+ const searchParams = options?.searchParams;
+ // `URL` constructor requires a full origin
+ // to be present in either of arguments
+ // but the argument for `fetch()` accepts relative paths just fine
+ // so we are doing some gymnastics in order not to depend
+ // on browser context (does not exist on server)
+ // or an env variable (not needed if the origin is the same).
+ const url = new URL(`${urlBase}${path}`, "https://example.com");
+ url.search = !searchParams ? "" : String(searchParams);
+
+ url.searchParams.sort();
+
+ const apiPath = `${url.pathname}${
+ // `URL.search` param includes `?` even with no params
+ // so we include it conditionally
+ searchParams?.size !== 0 ? url.search : ""
+ }`;
+
+ let finalOptions: RequestInit;
+ {
+ if (!options?.body) {
+ finalOptions = {
+ ...options,
+ method,
+ credentials: "same-origin",
+ };
+ } else {
+ const requestBody = {
+ type: requestBodyType,
+ data: options.body,
+ } satisfies IRequestBody;
+ const jsonBody = JSON.stringify(requestBody);
+ finalOptions = {
+ ...options,
+ method,
+ headers: options.headers
+ ? mergeHeaders(options.headers, jsonHeaders)
+ : jsonHeaders,
+ body: jsonBody,
+ credentials: "same-origin",
+ };
+ }
+ }
+
+ const request = new Request(apiPath, finalOptions);
+ const response = await customFetch(request);
+
+ if (!response.ok) {
+ let error: IResponseError | undefined = undefined;
+
+ // doing it this way because response doesn't allow
+ // parsing body several times
+ // and cloning response is a bit too much
+ const text = (await response.text()).trim();
+
+ try {
+ const responseBody: IResponseBodyError = JSON.parse(text);
+ error = responseBody.error;
+ } catch (error) {}
+
+ let message: string;
+
+ switch (response.status) {
+ case HTTP_STATUS.BAD_REQUEST:
+ case HTTP_STATUS.UNPROCESSABLE_CONTENT: {
+ message = "Failed to fetch from API due to client inputs.";
+ break;
+ }
+
+ case HTTP_STATUS.UNAUTHORIZED: {
+ await logoutAccount(true);
+ message = "Failed to fetch from API due to lack of credentials.";
+ break;
+ }
+
+ case HTTP_STATUS.NOT_FOUND: {
+ message = `Failed to fetch from API because path "${response.url} doesn't exist.`;
+ break;
+ }
+
+ case HTTP_STATUS.SERVICE_UNAVAILABLE: {
+ message = "API is in maintenance or not available.";
+ break;
+ }
+
+ default: {
+ message =
+ response.status >= 500
+ ? "Failed to fetch from API due to server error."
+ : "Failed to fetch from API for unknown reasons.";
+ break;
+ }
+ }
+
+ const errorOptions = {
+ pathSpec,
+ request,
+ response,
+ error,
+ } satisfies ConstructorParameters["1"];
+
+ throw new APIV2Error(message, errorOptions);
+ }
+
+ const result: IResponseBodySuccess = await response.json();
+
+ return result.data;
+}
diff --git a/client/src/lib/fetch/errors.ts b/client/src/lib/fetch/errors.ts
new file mode 100644
index 0000000..a16d56e
--- /dev/null
+++ b/client/src/lib/fetch/errors.ts
@@ -0,0 +1,36 @@
+import { InvalidErrorType } from "#lib/errors";
+
+interface IFetchError extends Error {
+ request: Request;
+}
+
+interface IFetchErrorOptions extends ErrorOptions {
+ request: Request;
+}
+
+/**
+ * `fetch()` by itself doesn't throw, it only does so due to some client settings
+ * i.e. improperly formed headers/body/url by the client code
+ * or browser extensions/adblockers terminating it early.
+ *
+ * Since it throws before doing any actual request, the response object is not available to it.
+ */
+export class FetchError extends Error implements IFetchError {
+ request: Request;
+
+ constructor(message: string, options: IFetchErrorOptions) {
+ super(message);
+
+ this.request = options.request;
+ }
+}
+
+export function isFetchError(input: unknown): input is FetchError {
+ return input instanceof FetchError;
+}
+
+export function ensureFetchError(input: unknown): asserts input is FetchError {
+ if (!isFetchError(input)) {
+ throw new InvalidErrorType(input);
+ }
+}
diff --git a/client/src/lib/fetch/fetch.ts b/client/src/lib/fetch/fetch.ts
new file mode 100644
index 0000000..8825fec
--- /dev/null
+++ b/client/src/lib/fetch/fetch.ts
@@ -0,0 +1,18 @@
+import { FetchError } from "./errors";
+
+export async function customFetch(...args: Parameters) {
+ const request = new Request(...args);
+
+
+ try {
+ const response = await fetch(request);
+
+ return response;
+ } catch (error) {
+
+ throw new FetchError("Failed to fetch due to client settings.", {
+ cause: error,
+ request,
+ });
+ }
+}
diff --git a/client/src/lib/fetch/index.ts b/client/src/lib/fetch/index.ts
new file mode 100644
index 0000000..b584930
--- /dev/null
+++ b/client/src/lib/fetch/index.ts
@@ -0,0 +1,2 @@
+export { customFetch } from "./fetch";
+export { FetchError, isFetchError, ensureFetchError } from "./errors";
diff --git a/client/src/lib/http/headers.ts b/client/src/lib/http/headers.ts
new file mode 100644
index 0000000..adeed42
--- /dev/null
+++ b/client/src/lib/http/headers.ts
@@ -0,0 +1,12 @@
+export function mergeHeaders(
+ firstHeaders: Headers,
+ secondHeaders: Headers
+): Headers {
+ const resultHeaders = new Headers(firstHeaders);
+
+ secondHeaders.forEach((value, key) => {
+ resultHeaders.append(key, value);
+ });
+
+ return resultHeaders;
+}
diff --git a/client/src/lib/http/index.ts b/client/src/lib/http/index.ts
index 45525f7..a14dead 100644
--- a/client/src/lib/http/index.ts
+++ b/client/src/lib/http/index.ts
@@ -1 +1,2 @@
export { HTTP_STATUS } from "./status";
+export { mergeHeaders } from "./headers";
diff --git a/client/src/lib/numbers/index.ts b/client/src/lib/numbers/index.ts
new file mode 100644
index 0000000..03ff98a
--- /dev/null
+++ b/client/src/lib/numbers/index.ts
@@ -0,0 +1,3 @@
+export function parseInt(value: string) {
+ return Number.parseInt(value, 10);
+}
diff --git a/client/src/lib/pagination/index.ts b/client/src/lib/pagination/index.ts
index fd45929..592b16c 100644
--- a/client/src/lib/pagination/index.ts
+++ b/client/src/lib/pagination/index.ts
@@ -1,2 +1,7 @@
-export { PAGINATION_LIMIT, parseOffset } from "./lib";
+export {
+ PAGINATION_LIMIT,
+ parseOffset,
+ parsePageNumber,
+ createPagination,
+} from "./lib";
export type { IPagination } from "./types";
diff --git a/client/src/lib/pagination/lib.ts b/client/src/lib/pagination/lib.ts
index f274a1e..dcc1a28 100644
--- a/client/src/lib/pagination/lib.ts
+++ b/client/src/lib/pagination/lib.ts
@@ -1,3 +1,5 @@
+import { IPagination } from "./types";
+
export const PAGINATION_LIMIT = 50;
export function parseOffset(offset: string | number, limit = PAGINATION_LIMIT) {
@@ -10,3 +12,40 @@ export function parseOffset(offset: string | number, limit = PAGINATION_LIMIT) {
return parsedOffset;
}
+
+export function parsePageNumber(page: string | number | undefined): number {
+ if (page === undefined) {
+ throw new Error("Page number is required.");
+ }
+
+ const parsedPage =
+ typeof page === "number" ? page : Number.parseInt(page.trim(), 10);
+
+ if (parsedPage < 1) {
+ throw new Error("Page number must be positive.");
+ }
+
+ return parsedPage;
+}
+
+export function createPagination(
+ totalCount: number,
+ currentPage?: number
+): IPagination {
+ const limit = PAGINATION_LIMIT;
+ const totalPages = Math.ceil(totalCount / limit);
+ const current = currentPage ?? totalPages;
+ const currentMin = Math.min((current - 1) * limit + 1, totalCount);
+ const currentMax = Math.min(currentMin - 1 + limit, totalCount);
+
+ const pagination: IPagination = {
+ total_count: totalCount,
+ limit,
+ total_pages: totalPages,
+ current_page: current,
+ current_min: currentMin,
+ current_max: currentMax,
+ };
+
+ return pagination;
+}
diff --git a/client/src/lib/pagination/types.ts b/client/src/lib/pagination/types.ts
index 7294846..a3837f8 100644
--- a/client/src/lib/pagination/types.ts
+++ b/client/src/lib/pagination/types.ts
@@ -1,9 +1,8 @@
export interface IPagination {
- current_page: number;
+ total_count: number;
limit: number;
- base: unknown;
- offset: number;
- count: number;
- current_count: number;
+ current_page: number;
total_pages: number;
+ current_min: number;
+ current_max: number;
}
diff --git a/client/src/lib/types/index.ts b/client/src/lib/types/index.ts
index f7595db..8164bbd 100644
--- a/client/src/lib/types/index.ts
+++ b/client/src/lib/types/index.ts
@@ -5,3 +5,15 @@ export type ElementType> =
ContainerType extends Iterable ? ElementType : never;
export type StrictOmit = Omit;
+
+/**
+ * Make selected keys optional.
+ */
+export type IPartialSome = Omit &
+ Pick, Key>;
+
+/**
+ * Make selected key required.
+ */
+export type IRequiredSome = Omit &
+ Pick, Key>;
diff --git a/client/src/lib/urls/administrator.ts b/client/src/lib/urls/administrator.ts
index c278eb9..894be06 100644
--- a/client/src/lib/urls/administrator.ts
+++ b/client/src/lib/urls/administrator.ts
@@ -4,16 +4,13 @@ import { InternalURL } from "./internal-url";
export function createAccountsPageURL(
page?: number,
name?: string,
- role?: string,
- limit?: number
+ role?: string
) {
- const path = `/account/administrator/accounts`;
+ const path = !page
+ ? `/account/administrator/accounts`
+ : `/account/administrator/accounts/${page}`;
const params = new URLSearchParams();
- if (page) {
- params.set("page", String(page));
- }
-
if (name) {
params.set("name", name);
}
@@ -22,15 +19,11 @@ export function createAccountsPageURL(
params.set("role", role);
}
- if (limit) {
- params.set("limit", String(limit));
- }
-
- return new InternalURL(path);
+ return new InternalURL(path, params);
}
export function createAccountDetailsPageURL(id: IAccount["id"]) {
- const path = `/account/administrator/accounts/${id}`;
+ const path = `/account/administrator/account/${id}`;
return new InternalURL(path);
}
diff --git a/client/src/lib/urls/files.ts b/client/src/lib/urls/files.ts
index d0afbf8..40a4c27 100644
--- a/client/src/lib/urls/files.ts
+++ b/client/src/lib/urls/files.ts
@@ -12,6 +12,12 @@ export function createThumbnailURL(filePath: string) {
return new InternalURL(path);
}
+export function createFilePageURL(fileHash: string) {
+ const path = `/file/${fileHash}`;
+
+ return new InternalURL(path);
+}
+
export function createArchiveFileURL(
archiveHash: string,
archiveExtension: string,
diff --git a/client/src/lib/urls/index.ts b/client/src/lib/urls/index.ts
index 72abc1b..691e538 100644
--- a/client/src/lib/urls/index.ts
+++ b/client/src/lib/urls/index.ts
@@ -46,6 +46,7 @@ export {
export {
createFileURL,
createThumbnailURL,
+ createFilePageURL,
createArchiveFileURL,
createFileSearchPageURL,
} from "./files";
diff --git a/client/src/pages/_index.scss b/client/src/pages/_index.scss
index e8843d3..cf64db7 100644
--- a/client/src/pages/_index.scss
+++ b/client/src/pages/_index.scss
@@ -3,7 +3,7 @@
@use "profile/index";
@use "profile.scss";
@use "review_dms";
-@use "importer_status";
+@use "importer/importer_status.scss";
@use "posts";
@use "account";
@use "upload";
diff --git a/client/src/pages/account/administrator/account.module.scss b/client/src/pages/account/administrator/account.module.scss
new file mode 100644
index 0000000..81ec887
--- /dev/null
+++ b/client/src/pages/account/administrator/account.module.scss
@@ -0,0 +1,6 @@
+@use "../../../css/config/variables/sass" as *;
+
+// TODO: nuke this declaration once page skeleton is a proper grid
+.overview {
+ margin: 0 auto;
+}
diff --git a/client/src/pages/account/administrator/account.tsx b/client/src/pages/account/administrator/account.tsx
new file mode 100644
index 0000000..62702b8
--- /dev/null
+++ b/client/src/pages/account/administrator/account.tsx
@@ -0,0 +1,102 @@
+import {
+ ActionFunctionArgs,
+ LoaderFunctionArgs,
+ redirect,
+ useLoaderData,
+} from "react-router";
+import { createAccountDetailsPageURL } from "#lib/urls";
+import {
+ apiChangeTargetAccountRole,
+ apiFetchAccount,
+} from "#api/account/administrator";
+import {
+ PageSkeleton,
+ validateAdministratorPageAction,
+ validateAdministratorPageLoader,
+} from "#components/pages";
+import { IAccount, ensureAccountRole } from "#entities/account";
+import { AccountOverview } from "#entities/administrator";
+
+import * as styles from "./account.module.scss";
+
+interface IProps {
+ account: IAccount;
+}
+
+export function AdministratorAccountOverviewPage() {
+ const { account } = useLoaderData() as IProps;
+ const title = "Account overview";
+ const heading = "Account Overview";
+
+ return (
+
+
+
+ );
+}
+
+export async function loader(args: LoaderFunctionArgs) {
+ await validateAdministratorPageLoader(args);
+
+ const { params } = args;
+
+ const accountID = params.account_id?.trim();
+
+ if (!accountID) {
+ throw new Error("Account ID is required.");
+ }
+
+ const parsedAccountID = Number(accountID);
+
+ if (parsedAccountID === 0) {
+ throw new Error("Account ID must be positive.");
+ }
+
+ const account = await apiFetchAccount(parsedAccountID);
+
+ const props: IProps = {
+ account,
+ };
+
+ return props;
+}
+
+export async function action(args: ActionFunctionArgs) {
+ try {
+ await validateAdministratorPageAction(args);
+
+ const { params, request } = args;
+
+ const accountID = params.account_id?.trim();
+
+ if (!accountID) {
+ throw new Error("Account ID is required.");
+ }
+
+ const parsedAccountID = Number(accountID);
+
+ if (parsedAccountID === 0) {
+ throw new Error("Account ID must be positive.");
+ }
+
+ const data = await request.formData();
+
+ const role = (data.get("role") as string | null)?.trim();
+
+ if (!role) {
+ throw new Error("Role is required.");
+ }
+
+ ensureAccountRole(role);
+
+ const targetAccountID = await apiChangeTargetAccountRole(
+ parsedAccountID,
+ role
+ );
+ const url = String(createAccountDetailsPageURL(targetAccountID));
+
+ return redirect(url);
+ } catch (error) {
+ return error;
+ }
+}
diff --git a/client/src/pages/account/administrator/accounts.module.scss b/client/src/pages/account/administrator/accounts.module.scss
new file mode 100644
index 0000000..3359c53
--- /dev/null
+++ b/client/src/pages/account/administrator/accounts.module.scss
@@ -0,0 +1,6 @@
+@use "../../../css/config/variables/sass" as *;
+
+.filter {
+ max-width: 360px;
+ margin: 0 auto;
+}
diff --git a/client/src/pages/account/administrator/accounts.scss b/client/src/pages/account/administrator/accounts.scss
index 4fe69ef..2f1af67 100644
--- a/client/src/pages/account/administrator/accounts.scss
+++ b/client/src/pages/account/administrator/accounts.scss
@@ -1,4 +1,4 @@
-@use "../../../css/config/variables" as *;
+@use "../../../css/config/variables/sass" as *;
.site-section--admin-accounts {
.account {
@@ -54,6 +54,7 @@
transition-duration: var(--duration-global);
transition-property: border-color;
+ // TODO: nuke this declaration after rewriting page-specific styles
& .account-card {
height: 100%;
border-radius: 0;
diff --git a/client/src/pages/account/administrator/accounts.tsx b/client/src/pages/account/administrator/accounts.tsx
index 53647ee..7749d29 100644
--- a/client/src/pages/account/administrator/accounts.tsx
+++ b/client/src/pages/account/administrator/accounts.tsx
@@ -1,243 +1,174 @@
+import { LoaderFunctionArgs, redirect, useLoaderData } from "react-router";
import {
- ActionFunctionArgs,
- LoaderFunctionArgs,
- redirect,
- useLoaderData,
-} from "react-router-dom";
-import clsx from "clsx";
-import { IPagination } from "#lib/pagination";
+ IPagination,
+ createPagination,
+ parsePageNumber,
+} from "#lib/pagination";
import { createAccountsPageURL } from "#lib/urls";
-import {
- fetchAccounts,
- fetchChangeRolesOfAccounts,
-} from "#api/account/administrator";
+import { apiCountAccounts, apiFetchAccounts } from "#api/account/administrator";
import { FormRouter } from "#components/forms";
-import { Pagination, PaginationController } from "#components/pagination";
-import { CardList, AccountCard } from "#components/cards";
-import { PageSkeleton, createAccountPageLoader } from "#components/pages";
-import { IAccontRole, IAccount, accountRoles } from "#entities/account";
+import { Option } from "#components/forms/inputs";
+import { FormSectionSelect, FormSectionText } from "#components/forms/sections";
+import { Pagination, PaginationInfo } from "#components/pagination";
+import { CardList } from "#components/cards";
+import {
+ PageSkeleton,
+ validateAdministratorPageLoader,
+} from "#components/pages";
+import { Details } from "#components/details";
+import {
+ AccountPreview,
+ IAccontRole,
+ IAccount,
+ accountRoles,
+ ensureAccountRole,
+} from "#entities/account";
+
+import * as styles from "./accounts.module.scss";
interface IProps {
name?: string;
- role?: IRole;
- roleList: IAccontRole[];
+ role?: IAccontRole;
pagination: IPagination;
accounts: IAccount[];
- limit?: number;
-}
-
-type IRole = "all" | IAccontRole;
-
-const roleValues = ["all", ...accountRoles] as const satisfies IRole[];
-
-function isRoleValue(input: unknown): input is IRole {
- return roleValues.includes(input as IRole);
}
export function AdministratorAccountsPage() {
- const { name, role, roleList, pagination, limit, accounts } =
- useLoaderData() as IProps;
+ const { name, role, pagination, accounts } = useLoaderData() as IProps;
const title = "Accounts";
const heading = "Accounts";
- const formID = "account-pages";
return (
-
-
-
- Name:
-
-
+ "Search"}
+ >
+
-
-
-
- Roles:
-
-
-
- All
-
- {roleList.map((role) => (
-
- {role.toUpperCase()}
-
- ))}
-
-
-
-
- Search
-
-
-
+ options={
+ <>
+ All
+ {accountRoles.map((role) => (
+
+ {role.toUpperCase()}
+
+ ))}
+ >
+ }
+ />
+
+
-
-
- String(createAccountsPageURL(page, name, role, limit))
- }
- />
+
-
- {accounts.length === 0 ? (
- No accounts found.
- ) : (
- accounts.map((account) =>
- account.role === "moderator" ? (
-
- ) : account.role === "consumer" ? (
-
- ) : undefined
- )
- )}
-
-
- {accounts.length !== 0 && (
-
-
- Submit
-
-
+
+ {accounts.length === 0 ? (
+ No accounts found.
+ ) : (
+ accounts.map((account) => (
+
+ ))
)}
-
+
- String(createAccountsPageURL(page, name, role))}
+ extraValues={{ name, role }}
/>
);
}
-export const loader = createAccountPageLoader(async function loader({
- request,
-}: LoaderFunctionArgs): Promise {
+export async function loader(args: LoaderFunctionArgs): Promise {
+ await validateAdministratorPageLoader(args);
+
+ const { request, params } = args;
const searchParams = new URL(request.url).searchParams;
- let page: number | undefined = undefined;
- {
- const inputValue = searchParams.get("page")?.trim();
- if (inputValue) {
- page = Number.parseInt(inputValue, 10);
- }
- }
-
+ const page = parsePageNumber(params.page?.trim());
const name = searchParams.get("name")?.trim();
- let role: undefined | IRole;
+ let role: undefined | IAccontRole;
{
const inputValue = searchParams.get("role")?.trim();
+
if (inputValue) {
- if (!isRoleValue(inputValue)) {
- throw new Error(`Invalid role value "${inputValue}".`);
- }
+ ensureAccountRole(inputValue);
role = inputValue;
}
}
- let limit: undefined | number = undefined;
- {
- const inputValue = searchParams.get("limit")?.trim();
- if (inputValue) {
- limit = Number.parseInt(inputValue, 10);
- }
+ const totalCount = await apiCountAccounts(name, role);
+
+ if (totalCount === 0) {
+ throw new Error("No accounts found.");
}
- const { accounts, pagination, role_list } = await fetchAccounts(
- page,
- name,
- role,
- limit
- );
+ const pagination = createPagination(totalCount, page);
+ const accounts = await apiFetchAccounts(pagination.current_page, name, role);
return {
accounts,
pagination,
- roleList: role_list,
name,
role,
- limit,
};
-});
-
-export async function action({ request }: ActionFunctionArgs) {
- try {
- if (request.method !== "POST") {
- throw new Error(`Unknown method "${request.method}".`);
- }
-
- const data = await request.formData();
- const moderators = data.getAll("moderator") as string[];
- const consumers = data.getAll("consumer") as string[];
-
- await fetchChangeRolesOfAccounts(moderators, consumers);
-
- return redirect(String(createAccountsPageURL()));
- } catch (error) {
- return error;
- }
+}
+
+export async function baseLoader(args: LoaderFunctionArgs) {
+ await validateAdministratorPageLoader(args);
+
+ const { request } = args;
+ const searchParams = new URL(request.url).searchParams;
+
+ const name = searchParams.get("name")?.trim();
+
+ let page: number | undefined = undefined;
+ {
+ const inputValue = searchParams.get("page")?.trim();
+ if (inputValue) {
+ page = parsePageNumber(inputValue);
+ }
+ }
+
+ let role: undefined | IAccontRole;
+ {
+ const inputValue = searchParams.get("role")?.trim();
+
+ if (inputValue) {
+ ensureAccountRole(inputValue);
+
+ role = inputValue;
+ }
+ }
+
+ const totalCount = await apiCountAccounts(name, role);
+
+ if (totalCount === 0) {
+ throw new Error("No accounts found.");
+ }
+
+ const pagination = createPagination(totalCount, page);
+ const url = String(
+ createAccountsPageURL(pagination.current_page, name, role)
+ );
+
+ return redirect(url);
}
diff --git a/client/src/pages/account/administrator/dashboard.module.scss b/client/src/pages/account/administrator/dashboard.module.scss
new file mode 100644
index 0000000..81ec887
--- /dev/null
+++ b/client/src/pages/account/administrator/dashboard.module.scss
@@ -0,0 +1,6 @@
+@use "../../../css/config/variables/sass" as *;
+
+// TODO: nuke this declaration once page skeleton is a proper grid
+.overview {
+ margin: 0 auto;
+}
diff --git a/client/src/pages/account/administrator/dashboard.tsx b/client/src/pages/account/administrator/dashboard.tsx
index e4008e7..eaee974 100644
--- a/client/src/pages/account/administrator/dashboard.tsx
+++ b/client/src/pages/account/administrator/dashboard.tsx
@@ -1,18 +1,26 @@
+import { createAccountsPageURL } from "#lib/urls";
import { createAccountPageLoader, PageSkeleton } from "#components/pages";
import { KemonoLink } from "#components/links";
+import { Overview, OverviewHeader } from "#components/overviews";
+
+import * as styles from "./dashboard.module.scss";
export function AdministratorDashboardPage() {
return (
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/client/src/pages/account/change_password.tsx b/client/src/pages/account/change_password.tsx
index 4d89073..d50fc21 100644
--- a/client/src/pages/account/change_password.tsx
+++ b/client/src/pages/account/change_password.tsx
@@ -1,4 +1,4 @@
-import { ActionFunctionArgs, redirect } from "react-router-dom";
+import { ActionFunctionArgs, redirect } from "react-router";
import { createAccountPageURL } from "#lib/urls";
import { PageSkeleton, createAccountPageLoader } from "#components/pages";
import { FormRouter } from "#components/forms";
diff --git a/client/src/pages/account/favorites/legacy.tsx b/client/src/pages/account/favorites/legacy.tsx
index bc0193d..dbb7231 100644
--- a/client/src/pages/account/favorites/legacy.tsx
+++ b/client/src/pages/account/favorites/legacy.tsx
@@ -1,4 +1,4 @@
-import { redirect } from "react-router-dom";
+import { redirect } from "react-router";
import { createAccountFavoriteProfilesPageURL } from "#lib/urls";
export async function loader() {
diff --git a/client/src/pages/account/favorites/posts.tsx b/client/src/pages/account/favorites/posts.tsx
index 7744d53..68f8546 100644
--- a/client/src/pages/account/favorites/posts.tsx
+++ b/client/src/pages/account/favorites/posts.tsx
@@ -1,10 +1,10 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import {
createAccountFavoritePostsPageURL,
createAccountFavoriteProfilesPageURL,
} from "#lib/urls";
import { parseOffset } from "#lib/pagination";
-import { HeaderAd, SliderAd } from "#components/ads";
+import { HeaderAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, PostCard } from "#components/cards";
import { FormRouter } from "#components/forms";
@@ -12,7 +12,7 @@ import { PageSkeleton, createAccountPageLoader } from "#components/pages";
import { KemonoLink } from "#components/links";
import { IFavouritePost, getAllFavouritePosts } from "#entities/account";
-import styles from "./posts.module.scss";
+import * as styles from "./posts.module.scss";
type IProps = {
order?: IOrder;
@@ -57,6 +57,7 @@ export function FavoritePostsPage() {
"Filter"}
>
@@ -172,7 +173,7 @@ export const loader = createAccountPageLoader(async function loader({
}
}
- const { count, posts } = await getAllFavouritePosts();
+ const { count, posts } = await getAllFavouritePosts(offset, order, sortBy);
return {
count,
diff --git a/client/src/pages/account/favorites/profiles.tsx b/client/src/pages/account/favorites/profiles.tsx
index f84bda4..240a328 100644
--- a/client/src/pages/account/favorites/profiles.tsx
+++ b/client/src/pages/account/favorites/profiles.tsx
@@ -1,10 +1,10 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import {
createAccountFavoritePostsPageURL,
createAccountFavoriteProfilesPageURL,
} from "#lib/urls";
import { parseOffset } from "#lib/pagination";
-import { HeaderAd, SliderAd } from "#components/ads";
+import { HeaderAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, ArtistCard } from "#components/cards";
import { FormRouter } from "#components/forms";
@@ -12,7 +12,7 @@ import { PageSkeleton, createAccountPageLoader } from "#components/pages";
import { KemonoLink } from "#components/links";
import { IFavouriteArtist, getAllFavouriteProfiles } from "#entities/account";
-import styles from "./profiles.module.scss";
+import * as styles from "./profiles.module.scss";
interface IProps {
order?: IOrder;
@@ -52,6 +52,7 @@ export function FavoriteProfilesPage() {
"Filter"}
>
diff --git a/client/src/pages/account/home.tsx b/client/src/pages/account/home.tsx
index e2c1052..1559bf9 100644
--- a/client/src/pages/account/home.tsx
+++ b/client/src/pages/account/home.tsx
@@ -1,4 +1,4 @@
-import { useLoaderData } from "react-router-dom";
+import { useLoaderData } from "react-router";
import {
createAccountDMsReviewPageURL,
createAccountFavoritePostsPageURL,
@@ -52,7 +52,7 @@ export function AccountPage() {
-
+
Favorites:
@@ -72,7 +72,7 @@ export function AccountPage() {
-
+
Notifications:
diff --git a/client/src/pages/account/keys.scss b/client/src/pages/account/keys.scss
index a6c4813..4ecb233 100644
--- a/client/src/pages/account/keys.scss
+++ b/client/src/pages/account/keys.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section--account-keys {
.key {
diff --git a/client/src/pages/account/keys.tsx b/client/src/pages/account/keys.tsx
index eb0d743..7ade699 100644
--- a/client/src/pages/account/keys.tsx
+++ b/client/src/pages/account/keys.tsx
@@ -1,4 +1,4 @@
-import { ActionFunctionArgs, redirect, useLoaderData } from "react-router-dom";
+import { ActionFunctionArgs, redirect, useLoaderData } from "react-router";
import { createAccountImportKeysPageURL } from "#lib/urls";
import {
fetchAccountAutoImportKeys,
diff --git a/client/src/pages/account/login.tsx b/client/src/pages/account/login.tsx
index acf5846..c532335 100644
--- a/client/src/pages/account/login.tsx
+++ b/client/src/pages/account/login.tsx
@@ -2,7 +2,7 @@ import {
ActionFunctionArgs,
redirect,
useSearchParams,
-} from "react-router-dom";
+} from "react-router";
import { PageSkeleton } from "#components/pages";
import { KemonoLink } from "#components/links";
import { createArtistsPageURL, createRegistrationPageURL } from "#lib/urls";
diff --git a/client/src/pages/account/moderator/_index.scss b/client/src/pages/account/moderator/_index.scss
index bf6869d..8df7a36 100644
--- a/client/src/pages/account/moderator/_index.scss
+++ b/client/src/pages/account/moderator/_index.scss
@@ -1,4 +1,4 @@
-@use "../../../css/config/variables" as *;
+@use "../../../css/config/variables/sass" as *;
.site-section--moderator-dashboard {
margin-left: auto;
diff --git a/client/src/pages/account/moderator/profile_links.tsx b/client/src/pages/account/moderator/profile_links.tsx
index 1c4f557..2771128 100644
--- a/client/src/pages/account/moderator/profile_links.tsx
+++ b/client/src/pages/account/moderator/profile_links.tsx
@@ -2,7 +2,7 @@ import {
LoaderFunctionArgs,
useLoaderData,
useNavigate,
-} from "react-router-dom";
+} from "react-router";
import {
createProfileLinkRequestsPageURL,
createProfilePageURL,
diff --git a/client/src/pages/account/notifications.scss b/client/src/pages/account/notifications.scss
index 6207a3f..31174e6 100644
--- a/client/src/pages/account/notifications.scss
+++ b/client/src/pages/account/notifications.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section--account-notifications {
.notifications {
diff --git a/client/src/pages/account/notifications.tsx b/client/src/pages/account/notifications.tsx
index bdaa2cf..41697b2 100644
--- a/client/src/pages/account/notifications.tsx
+++ b/client/src/pages/account/notifications.tsx
@@ -1,4 +1,4 @@
-import { useLoaderData } from "react-router-dom";
+import { useLoaderData } from "react-router";
import { fetchAccountNotifications } from "#api/account";
import { INotification } from "#entities/account";
import { PageSkeleton, createAccountPageLoader } from "#components/pages";
diff --git a/client/src/pages/account/register.tsx b/client/src/pages/account/register.tsx
index be916d7..86ee5f4 100644
--- a/client/src/pages/account/register.tsx
+++ b/client/src/pages/account/register.tsx
@@ -2,7 +2,7 @@ import {
ActionFunctionArgs,
redirect,
useSearchParams,
-} from "react-router-dom";
+} from "react-router";
import { createArtistsPageURL, createLoginPageURL } from "#lib/urls";
import { getLocalStorageItem } from "#storage/local";
import { KemonoLink } from "#components/links";
diff --git a/client/src/pages/all_dms.scss b/client/src/pages/all_dms.scss
index 2ef8f97..f18a71c 100644
--- a/client/src/pages/all_dms.scss
+++ b/client/src/pages/all_dms.scss
@@ -1,4 +1,4 @@
-@use "../css/config/variables" as *;
+@use "../css/config/variables/sass" as *;
.site-section--all-dms {
.no-results {
diff --git a/client/src/pages/all_dms.tsx b/client/src/pages/all_dms.tsx
index 102db8f..b94aad0 100644
--- a/client/src/pages/all_dms.tsx
+++ b/client/src/pages/all_dms.tsx
@@ -1,9 +1,9 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createDMsPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { fetchDMs } from "#api/dms";
import { PageSkeleton } from "#components/pages";
-import { HeaderAd, SliderAd } from "#components/ads";
+import { HeaderAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, DMCard } from "#components/cards";
import { FormRouter } from "#components/forms";
diff --git a/client/src/pages/authentication/logout.tsx b/client/src/pages/authentication/logout.tsx
index df24c8d..cc32aa2 100644
--- a/client/src/pages/authentication/logout.tsx
+++ b/client/src/pages/authentication/logout.tsx
@@ -1,4 +1,4 @@
-import { redirect } from "react-router-dom";
+import { redirect } from "react-router";
import { createArtistsPageURL } from "#lib/urls";
import { logoutAccount } from "#entities/account";
diff --git a/client/src/pages/contact.tsx b/client/src/pages/contact.tsx
index dadb6ea..99cf163 100644
--- a/client/src/pages/contact.tsx
+++ b/client/src/pages/contact.tsx
@@ -6,15 +6,12 @@ export function ContactPage() {
return (
-
- Questions: contact@kemono.su
-
-
- Legal inquiries: legal@kemono.su
-
-
- Advertising inquiries: ads@kemono.su
-
+
+ Contact email: contact@kemono.ru
+
+
+ Please allow up to 3-5 working days for your request to be processed. You may not receive a response if we are not interested.
+
);
}
diff --git a/client/src/pages/discord-channel.tsx b/client/src/pages/discord-channel.tsx
index 5ef7cd6..18161ce 100644
--- a/client/src/pages/discord-channel.tsx
+++ b/client/src/pages/discord-channel.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { parseOffset } from "#lib/pagination";
import { fetchDiscordChannel, fetchDiscordServer } from "#api/profiles/discord";
import { PageSkeleton } from "#components/pages";
@@ -8,7 +8,7 @@ import {
IDiscordChannelMessage,
} from "#entities/posts";
-import styles from "./discord-channel.module.scss";
+import * as styles from "./discord-channel.module.scss";
interface IProps {
serverID: string;
diff --git a/client/src/pages/discord.tsx b/client/src/pages/discord.tsx
index d442e4a..5ef9a8c 100644
--- a/client/src/pages/discord.tsx
+++ b/client/src/pages/discord.tsx
@@ -1,9 +1,9 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { fetchDiscordServer } from "#api/profiles/discord";
import { PageSkeleton } from "#components/pages";
import { DiscordServer } from "#entities/posts";
-import styles from "./discord.module.scss";
+import * as styles from "./discord.module.scss";
interface IProps {
serverID: string;
diff --git a/client/src/pages/documentation/api.tsx b/client/src/pages/documentation/api.tsx
index d4b65f0..9604c13 100644
--- a/client/src/pages/documentation/api.tsx
+++ b/client/src/pages/documentation/api.tsx
@@ -3,10 +3,10 @@ import SwaggerUI from "swagger-ui-react";
import { PageSkeleton } from "#components/pages";
// TODO: path alias it after moving out of server folder
-import schema from "../../../../src/pages/api/schema.yaml";
+import schema from "../../../../schema/public/api.yaml";
import "swagger-ui-react/swagger-ui.css";
-import styles from "./api.module.scss";
+import * as styles from "./api.module.scss";
export function Component() {
const title = "API documenation";
diff --git a/client/src/pages/favorites.tsx b/client/src/pages/favorites.tsx
index bc0193d..dbb7231 100644
--- a/client/src/pages/favorites.tsx
+++ b/client/src/pages/favorites.tsx
@@ -1,4 +1,4 @@
-import { redirect } from "react-router-dom";
+import { redirect } from "react-router";
import { createAccountFavoriteProfilesPageURL } from "#lib/urls";
export async function loader() {
diff --git a/client/src/pages/file/archive.module.scss b/client/src/pages/file/archive.module.scss
new file mode 100644
index 0000000..772e97c
--- /dev/null
+++ b/client/src/pages/file/archive.module.scss
@@ -0,0 +1,6 @@
+@use "../../css/config/variables/sass.scss" as *;
+
+.article {
+ // TODO: remove once layout is rewritten
+ margin: 0 auto;
+}
diff --git a/client/src/pages/file/archive.tsx b/client/src/pages/file/archive.tsx
new file mode 100644
index 0000000..d483d71
--- /dev/null
+++ b/client/src/pages/file/archive.tsx
@@ -0,0 +1,80 @@
+import {
+ ActionFunctionArgs,
+ LoaderFunctionArgs,
+ redirect,
+ useLoaderData,
+} from "react-router";
+import { createFilePageURL } from "#lib/urls";
+import { apiFetchArchiveFile, apiSetArchiveFilePassword } from "#api/files";
+import { PageSkeleton } from "#components/pages";
+import { ArchiveFileOverview, IArchiveFile } from "#entities/files";
+
+import * as styles from "./archive.module.scss";
+
+interface IProps {
+ archive: IArchiveFile;
+}
+
+export function ArchiveFilePage() {
+ const { archive } = useLoaderData() as IProps;
+ const title = `Archive file "${archive.file.hash}" details`;
+ const heading = "Archive File Details";
+
+ return (
+
+
+
+ );
+}
+
+export async function loader({ params }: LoaderFunctionArgs): Promise {
+ const fileHash = params.file_hash?.trim();
+
+ if (!fileHash) {
+ throw new Error("File hash is required.");
+ }
+
+ const archive = await apiFetchArchiveFile(fileHash);
+
+ if (!archive) {
+ throw new Error("Archive file not found.");
+ }
+
+ return {
+ archive,
+ };
+}
+
+export async function action({ params, request }: ActionFunctionArgs) {
+ try {
+ const method = request.method;
+
+ switch (method) {
+ case "PATCH": {
+ const fileHash = params.file_hash?.trim();
+
+ if (!fileHash) {
+ throw new Error("File hash is required.");
+ }
+
+ const data = await request.formData();
+ const password = data.get("password") as string | null;
+
+ if (!password) {
+ throw new Error("Password is required.");
+ }
+
+ await apiSetArchiveFilePassword(fileHash, password);
+ const url = String(createFilePageURL(fileHash));
+
+ return redirect(url);
+ }
+
+ default: {
+ throw new Error(`Unknown method "${method}".`);
+ }
+ }
+ } catch (error) {
+ return error;
+ }
+}
diff --git a/client/src/pages/file/legacy.tsx b/client/src/pages/file/legacy.tsx
new file mode 100644
index 0000000..6e046a0
--- /dev/null
+++ b/client/src/pages/file/legacy.tsx
@@ -0,0 +1,40 @@
+import {
+ LoaderFunctionArgs,
+ useLoaderData,
+ useNavigate,
+} from "react-router";
+import { createFilePageURL } from "#lib/urls";
+import { useEffect } from "react";
+
+interface IProps {
+ hash: string;
+}
+// doing this roundabout way because `redirect` returned from loaders
+// doesn't overwrite history stack, even if redirect is "permanent"
+
+export function LegacyFilePage() {
+ const { hash } = useLoaderData() as IProps;
+ const navigate = useNavigate();
+
+ const url = String(createFilePageURL(hash));
+
+ useEffect(() => {
+ navigate(url, { replace: true });
+ }, []);
+
+ return <>>;
+}
+
+export async function loader({ params }: LoaderFunctionArgs) {
+ const fileHash = params.file_hash?.trim();
+
+ if (!fileHash) {
+ throw new Error("File hash is required.");
+ }
+
+ const props: IProps = {
+ hash: fileHash,
+ };
+
+ return props;
+}
diff --git a/client/src/pages/home.scss b/client/src/pages/home.scss
index 14f4873..7ba7ef1 100644
--- a/client/src/pages/home.scss
+++ b/client/src/pages/home.scss
@@ -1,9 +1,12 @@
-@use "../css/config/variables" as *;
+@use "../css/config/variables/sass" as *;
-.site-section--home {
-}
// minheights
+div.content-wrapper {
+ display: flex;
+ flex-direction: column;
+}
+
.jumbo-welcome {
overflow-y: hidden;
position: relative;
@@ -13,6 +16,9 @@
min-height: 450px;
background-color: rgba(0, 0, 0, 0.7);
padding: $size-small;
+ border: 5px solid var(--anchour-internal-colour2-primary);
+ border-radius: 10px;
+ margin: 1em;
@media (max-width: $width-tablet) {
background-color: #3b3e44;
@@ -27,6 +33,10 @@
@media (max-width: $width-tablet) {
display: none;
}
+
+ div {
+ max-height: 70vh;
+ }
}
.jumbo-welcome-description {
diff --git a/client/src/pages/importer_list.tsx b/client/src/pages/importer/importer_list.tsx
similarity index 99%
rename from client/src/pages/importer_list.tsx
rename to client/src/pages/importer/importer_list.tsx
index d3c4b8e..26c0d01 100644
--- a/client/src/pages/importer_list.tsx
+++ b/client/src/pages/importer/importer_list.tsx
@@ -1,6 +1,6 @@
import clsx from "clsx";
import { useState } from "react";
-import { ActionFunctionArgs, redirect } from "react-router-dom";
+import { ActionFunctionArgs, redirect } from "react-router";
import { PAYSITE_LIST, SITE_NAME } from "#env/env-vars";
import { createImporterStatusPageURL } from "#lib/urls";
import { fetchCreateImport } from "#api/imports";
diff --git a/client/src/pages/importer_ok.tsx b/client/src/pages/importer/importer_ok.tsx
similarity index 100%
rename from client/src/pages/importer_ok.tsx
rename to client/src/pages/importer/importer_ok.tsx
diff --git a/client/src/pages/importer/importer_status.module.scss b/client/src/pages/importer/importer_status.module.scss
new file mode 100644
index 0000000..ff82227
--- /dev/null
+++ b/client/src/pages/importer/importer_status.module.scss
@@ -0,0 +1,5 @@
+@use "../../css/config/variables/sass" as *;
+
+.importList {
+ padding-left: 48px;
+}
diff --git a/client/src/pages/importer_status.scss b/client/src/pages/importer/importer_status.scss
similarity index 97%
rename from client/src/pages/importer_status.scss
rename to client/src/pages/importer/importer_status.scss
index e016f62..573af18 100644
--- a/client/src/pages/importer_status.scss
+++ b/client/src/pages/importer/importer_status.scss
@@ -1,4 +1,4 @@
-@use "../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section--importer-status {
.import {
diff --git a/client/src/pages/importer/importer_status.tsx b/client/src/pages/importer/importer_status.tsx
new file mode 100644
index 0000000..c401a5b
--- /dev/null
+++ b/client/src/pages/importer/importer_status.tsx
@@ -0,0 +1,138 @@
+import {
+ LoaderFunctionArgs,
+ useLoaderData,
+} from "react-router";
+import { createAccountDMsReviewPageURL } from "#lib/urls";
+import { fetchHasPendingDMs } from "#api/dms";
+import { fetchImportLogs } from "#api/imports";
+import { getLocalStorageItem, setLocalStorageItem } from "#storage/local";
+import { PageSkeleton } from "#components/pages";
+import { LoadingIcon } from "#components/loading";
+
+import * as styles from "./importer_status.module.scss";
+import { KemonoLink } from "#components/links";
+import { useEffect, useState } from "react";
+
+interface IProps {
+ importId: string;
+ isDMS?: boolean;
+}
+
+export function ImporterStatusPage() {
+ const { importId, isDMS } = useLoaderData() as IProps;
+ const title = `Import "${importId}" logs`;
+ const heading = `Importer Logs for ${importId}`;
+ const cooldown = 15_000;
+ const [reverse, setReverse] = useState(false);
+ const [logs, setLogs] = useState | null>(null);
+ const [finished, setFinished] = useState(false);
+
+ useEffect(() => {
+ if (finished) return;
+ async function fetchLogs() {
+ try {
+ let resp = await fetchImportLogs(importId);
+ setLogs(reverse ? [...resp].reverse() : [...resp]);
+ if (resp?.[resp?.length - 1]?.match(/Finished/i)) {
+ setFinished(true);
+ } else {
+ setFinished(false);
+ }
+ } catch (error) {
+ console.log(error)
+ }
+ }
+
+ fetchLogs();
+
+ const id = setInterval(fetchLogs, cooldown);
+
+ return () => clearInterval(id);
+ }, [reverse, finished]);
+
+ function toggleReverse() {
+ setReverse(!reverse);
+ setLogs(logs?.reverse() ?? []);
+ }
+
+ return (
+
+ {!logs ? (
+
+ Wait until logs load...
+
+ ) : logs.length ? (
+ <>
+ {isDMS && (
+
+
Hey!
+
+ You gave the importer permission to access your messages. To protect your anonymity, you must manually approve each one. Wait until after the importer says Done importing DMs
, then go go{" "}
+
+ here
+ {" "}
+ to choose which ones you wish to import. to choose which ones you wish to import.
+
+
+ )}
+
+
+ Status: {finished ? "Completed" : "In Progress"}
+ Total: {logs?.length}
+
+
Reverse order
+
+
+ {logs?.map((message, index) => (
+ {message}
+ ))}
+
+ >
+ ) : (
+ No logs found!
+ )}
+
+ );
+}
+
+async function initPendingReviewDms(
+ forceReload = false,
+ minutesForRecheck = 30
+) {
+ let hasPendingReviewDms = getLocalStorageItem("has_pending_review_dms") === "true";
+ const lastCheckedHasPendingReviewDms = parseInt(
+ getLocalStorageItem("last_checked_has_pending_review_dms") ?? "0",
+ 10
+ );
+
+ if (
+ forceReload ||
+ !lastCheckedHasPendingReviewDms ||
+ lastCheckedHasPendingReviewDms < Date.now() - minutesForRecheck * 60 * 1000
+ ) {
+ hasPendingReviewDms = await fetchHasPendingDMs();
+ setLocalStorageItem("has_pending_review_dms", String(hasPendingReviewDms));
+ localStorage.setItem(
+ "last_checked_has_pending_review_dms",
+ Date.now().toString()
+ );
+ }
+}
+
+export async function loader({
+ params,
+ request,
+}: LoaderFunctionArgs): Promise {
+ const importId = params.import_id?.trim();
+ if (!importId) {
+ throw new Error("Import ID is required.");
+ }
+
+ const searchparams = new URL(request.url).searchParams;
+ let isDMS = Boolean(searchparams.get("dms")?.trim());
+
+ return {
+ importId,
+ isDMS,
+ };
+}
diff --git a/client/src/pages/importer_tutorial.tsx b/client/src/pages/importer/importer_tutorial.tsx
similarity index 100%
rename from client/src/pages/importer_tutorial.tsx
rename to client/src/pages/importer/importer_tutorial.tsx
diff --git a/client/src/pages/importer_tutorial_fanbox.tsx b/client/src/pages/importer/importer_tutorial_fanbox.tsx
similarity index 100%
rename from client/src/pages/importer_tutorial_fanbox.tsx
rename to client/src/pages/importer/importer_tutorial_fanbox.tsx
diff --git a/client/src/pages/importer/index.ts b/client/src/pages/importer/index.ts
new file mode 100644
index 0000000..0fa2339
--- /dev/null
+++ b/client/src/pages/importer/index.ts
@@ -0,0 +1 @@
+export { ImporterStatusPage } from "./importer_status";
diff --git a/client/src/pages/importer_status.tsx b/client/src/pages/importer_status.tsx
deleted file mode 100644
index 66e92ea..0000000
--- a/client/src/pages/importer_status.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import clsx from "clsx";
-import { useState } from "react";
-import {
- LoaderFunctionArgs,
- useLoaderData,
- useNavigate,
-} from "react-router-dom";
-import { createImporterStatusPageURL } from "#lib/urls";
-import { fetchHasPendingDMs } from "#api/dms";
-import { fetchImportLogs } from "#api/imports";
-import { getLocalStorageItem, setLocalStorageItem } from "#storage/local";
-import { useInterval } from "#hooks";
-import { PageSkeleton } from "#components/pages";
-import { LoadingIcon } from "#components/loading";
-import { Button } from "#components/buttons";
-
-interface IProps {
- importID: string;
- isDMS?: boolean;
- logs: string[];
-}
-
-export function ImporterStatusPage() {
- const { importID, isDMS, logs } = useLoaderData() as IProps;
- const navigate = useNavigate();
- const [isReversed, switchReversed] = useState(false);
- const title = `Import ${importID}`;
- const heading = `Importer logs for ${importID}`;
- const status = logs.length === 0 ? "Fetching" : "In Progress";
- const cooldown = 120_000;
-
- useInterval(() => {
- navigate(String(createImporterStatusPageURL(importID)));
- }, cooldown);
-
- return (
-
- {isDMS && (
-
-
Hey!
-
- You gave the importer permission to access your messages. To protect
- your anonymity, you must manually approve each one. Wait until{" "}
- after the importer says Done importing DMs
, then
- go here to choose which ones you
- wish to import.
-
-
- )}
-
-
-
-
-
- Status:
- {status}
-
-
-
- Total:
- {logs.length}
-
-
-
-
- switchReversed((old) => !old)}
- >
- Reverse order
-
-
-
-
-
- Wait until logs load...
-
-
-
- {logs.length !== 0 &&
- logs.map((message, index) => (
-
- {message}
-
- ))}
-
-
-
- );
-}
-
-async function initPendingReviewDms(
- forceReload = false,
- minutesForRecheck = 30
-) {
- let hasPendingReviewDms =
- getLocalStorageItem("has_pending_review_dms") === "true";
- const lastCheckedHasPendingReviewDms = parseInt(
- getLocalStorageItem("last_checked_has_pending_review_dms") ?? "0",
- 10
- );
-
- if (
- forceReload ||
- !lastCheckedHasPendingReviewDms ||
- lastCheckedHasPendingReviewDms < Date.now() - minutesForRecheck * 60 * 1000
- ) {
- /**
- * @type {string}
- */
- hasPendingReviewDms = await fetchHasPendingDMs();
- setLocalStorageItem("has_pending_review_dms", String(hasPendingReviewDms));
- localStorage.setItem(
- "last_checked_has_pending_review_dms",
- Date.now().toString()
- );
- }
-}
-
-export async function loader({
- params,
- request,
-}: LoaderFunctionArgs): Promise {
- const searchparams = new URL(request.url).searchParams;
-
- const importID = params.import_id?.trim();
- if (!importID) {
- throw new Error("Import ID is required.");
- }
-
- let isDMS: boolean | undefined = undefined;
- {
- const inputValue = Boolean(searchparams.get("dms")?.trim());
- if (inputValue) {
- isDMS = inputValue;
- }
- }
-
- const logs = await fetchImportLogs(importID);
-
- if (logs.length !== 0) {
- initPendingReviewDms(true);
- }
-
- return {
- importID,
- isDMS,
- logs,
- };
-}
diff --git a/client/src/pages/post-revision.module.scss b/client/src/pages/post-revision.module.scss
new file mode 100644
index 0000000..88af0d3
--- /dev/null
+++ b/client/src/pages/post-revision.module.scss
@@ -0,0 +1,5 @@
+@use "../css/config/variables/sass.scss" as *;
+
+.article {
+ margin: 0 auto
+}
diff --git a/client/src/pages/post-revision.tsx b/client/src/pages/post-revision.tsx
index b7e6f5d..ec37536 100644
--- a/client/src/pages/post-revision.tsx
+++ b/client/src/pages/post-revision.tsx
@@ -1,22 +1,16 @@
import { useEffect } from "react";
-import {
- LoaderFunctionArgs,
- useLoaderData,
- defer,
- Link,
-} from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData, Link } from "react-router";
import { Helmet } from "react-helmet-async";
import {
ICONS_PREPEND,
IS_ARCHIVER_ENABLED,
KEMONO_SITE,
SITE_NAME,
- VIDEO_AD,
} from "#env/env-vars";
import { fetchArtistProfile } from "#api/profiles";
import { fetchPostRevision, fetchPostComments } from "#api/posts";
import { PageSkeleton } from "#components/pages";
-import { SliderAd } from "#components/ads";
+import { SliderAd } from "#components/advs";
import { paysites, validatePaysite } from "#entities/paysites";
import {
IComment,
@@ -28,17 +22,15 @@ import {
} from "#entities/posts";
import { IArtistDetails } from "#entities/profiles";
+import * as styles from "./post-revision.module.scss";
+
interface IProps {
post: IPost;
profile: IArtistDetails;
revisions: Awaited<
ReturnType
>["props"]["revisions"];
-
- /**
- * TODO: wtf
- */
- flagged?: 0;
+ flagged: string | null;
videos?: IPostVideo[];
attachments?: IPostAttachment[];
previews?: IPostPreview[];
@@ -84,30 +76,6 @@ export function PostRevisionPage() {
useEffect(() => {
document.addEventListener("keydown", handlePrevNextLinks);
- import("fluid-player")
- .then(({ default: fluidPlayer }) => {
- Array.from(document.getElementsByTagName("video")).forEach((_, i) => {
- fluidPlayer(`kemono-player${i}`, {
- layoutControls: {
- fillToContainer: false,
- preload: "none",
- },
- vastOptions: {
- adList: JSON.parse(atob(VIDEO_AD)),
- adTextPosition: "top left",
- maxAllowedVastTagRedirects: 2,
- vastAdvanced: {
- vastLoadedCallback: function () {},
- noVastVideoCallback: function () {},
- vastVideoSkippedCallback: function () {},
- vastVideoEndedCallback: function () {},
- },
- },
- });
- });
- })
- .catch((error) => console.error(error));
-
return () => {
document.removeEventListener("keydown", handlePrevNextLinks);
};
@@ -172,24 +140,21 @@ export function PostRevisionPage() {
);
}
-export async function loader({
- params,
-}: LoaderFunctionArgs): Promise> {
+export async function loader({ params }: LoaderFunctionArgs): Promise {
const service = params.service?.trim();
{
if (!service) {
@@ -239,5 +204,5 @@ export async function loader({
comments,
} satisfies IProps;
- return defer(pageProps);
+ return pageProps;
}
diff --git a/client/src/pages/post.module.scss b/client/src/pages/post.module.scss
new file mode 100644
index 0000000..88af0d3
--- /dev/null
+++ b/client/src/pages/post.module.scss
@@ -0,0 +1,5 @@
+@use "../css/config/variables/sass.scss" as *;
+
+.article {
+ margin: 0 auto
+}
diff --git a/client/src/pages/post.scss b/client/src/pages/post.scss
index aa5d66e..469245f 100644
--- a/client/src/pages/post.scss
+++ b/client/src/pages/post.scss
@@ -1,4 +1,4 @@
-@use "../css/config/variables" as *;
+@use "../css/config/variables/sass" as *;
.post {
&__nav-list {
@@ -74,9 +74,10 @@
&__actions {
font-size: 1.5em;
+ display: flex;
& > * {
- margin-right: 1em;
+ margin-right: 0.5em;
user-select: none;
&:last-child {
@@ -85,40 +86,6 @@
}
}
- &__flag {
- display: inline-block;
- color: hsl(3, 100%, 69%);
- font-weight: bold;
- text-shadow:
- hsl(0, 0%, 0%) 0px 0px 3px,
- hsl(0, 0%, 0%) -1px -1px 0px,
- hsl(0, 0%, 0%) 1px 1px 0px;
- background-color: transparent;
- border: transparent;
-
- // hack to overwrite * selector color
- & span {
- color: hsl(3, 100%, 69%);
- }
-
- &--flagged {
- color: hsl(0, 0%, 45%);
-
- // hack to overwrite * selector color
- & span {
- color: hsl(0, 0%, 45%);
- }
- }
-
- &--loading {
- cursor: progress;
-
- & .post__flag-icon {
- display: none;
- }
- }
- }
-
&__fav {
color: hsl(0, 0%, 100%);
font-weight: bold;
diff --git a/client/src/pages/post.tsx b/client/src/pages/post.tsx
index 5ac6868..e25aba0 100644
--- a/client/src/pages/post.tsx
+++ b/client/src/pages/post.tsx
@@ -1,22 +1,16 @@
import { useEffect } from "react";
-import {
- LoaderFunctionArgs,
- useLoaderData,
- defer,
- Link,
-} from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData, Link } from "react-router";
import { Helmet } from "react-helmet-async";
import {
ICONS_PREPEND,
IS_ARCHIVER_ENABLED,
KEMONO_SITE,
SITE_NAME,
- VIDEO_AD,
} from "#env/env-vars";
import { fetchArtistProfile } from "#api/profiles";
import { fetchPost, fetchPostComments } from "#api/posts";
import { PageSkeleton } from "#components/pages";
-import { SliderAd } from "#components/ads";
+import { SliderAd } from "#components/advs";
import { paysites, validatePaysite } from "#entities/paysites";
import {
IComment,
@@ -28,14 +22,13 @@ import {
} from "#entities/posts";
import { IArtistDetails } from "#entities/profiles";
+import * as styles from "./post.module.scss";
+
interface IProps {
post: IPost;
profile: IArtistDetails;
revisions: Awaited>["props"]["revisions"];
- /**
- * TODO: wtf
- */
- flagged?: 0;
+ flagged: string | null;
videos?: IPostVideo[];
attachments?: IPostAttachment[];
previews?: IPostPreview[];
@@ -81,30 +74,6 @@ export function PostPage() {
useEffect(() => {
document.addEventListener("keydown", handlePrevNextLinks);
- import("fluid-player")
- .then(({ default: fluidPlayer }) => {
- Array.from(document.getElementsByTagName("video")).forEach((_, i) => {
- fluidPlayer(`kemono-player${i}`, {
- layoutControls: {
- fillToContainer: false,
- preload: "none",
- },
- vastOptions: {
- adList: JSON.parse(atob(VIDEO_AD)),
- adTextPosition: "top left",
- maxAllowedVastTagRedirects: 2,
- vastAdvanced: {
- vastLoadedCallback: function () {},
- noVastVideoCallback: function () {},
- vastVideoSkippedCallback: function () {},
- vastVideoEndedCallback: function () {},
- },
- },
- });
- });
- })
- .catch((error) => console.error(error));
-
return () => {
document.removeEventListener("keydown", handlePrevNextLinks);
};
@@ -183,9 +152,7 @@ export function PostPage() {
);
}
-export async function loader({
- params,
-}: LoaderFunctionArgs): Promise> {
+export async function loader({ params }: LoaderFunctionArgs): Promise {
const service = params.service?.trim();
{
if (!service) {
@@ -231,5 +198,5 @@ export async function loader({
comments,
} satisfies IProps;
- return defer(pageProps);
+ return pageProps;
}
diff --git a/client/src/pages/post/data.tsx b/client/src/pages/post/data.tsx
index 57b67c5..a8a623e 100644
--- a/client/src/pages/post/data.tsx
+++ b/client/src/pages/post/data.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, redirect } from "react-router-dom";
+import { LoaderFunctionArgs, redirect } from "react-router";
import { fetchPostData } from "#api/posts";
import { createPostURL } from "#lib/urls";
import { HTTP_STATUS } from "#lib/http";
diff --git a/client/src/pages/posts.tsx b/client/src/pages/posts.tsx
index 2478b14..2699f01 100644
--- a/client/src/pages/posts.tsx
+++ b/client/src/pages/posts.tsx
@@ -1,13 +1,14 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { parseOffset } from "#lib/pagination";
import { createPostsPageURL } from "#lib/urls";
import { fetchPosts } from "#api/posts";
import { PageSkeleton } from "#components/pages";
import { Paginator } from "#components/pagination";
-import { FooterAd, HeaderAd, SliderAd } from "#components/ads";
+import { FooterAd, HeaderAd, SliderAd } from "#components/advs";
import { CardList, PostCard } from "#components/cards";
import { FormRouter, FormSection } from "#components/forms";
import { IPost } from "#entities/posts";
+import { findFavouritePosts, findFavouriteProfiles } from "#entities/account";
interface IProps {
count: number;
@@ -62,7 +63,12 @@ export function PostsPage() {
) : (
posts.map((post) => (
-
+
))
)}
@@ -98,6 +104,51 @@ export async function loader({ request }: LoaderFunctionArgs): Promise {
const query = searchParams.get("q")?.trim();
const tags = searchParams.getAll("tag");
const { count, true_count, posts } = await fetchPosts(offset, query, tags);
+ const postsData = posts.map(({ service, user, id }) => ({
+ service,
+ user,
+ id,
+ }));
+ const profilesData = posts.reduce<{ service: string; id: string }[]>(
+ (profilesData, post) => {
+ const match = profilesData.find(
+ (profileData) =>
+ profileData.id === post.user && profileData.service === post.service
+ );
+
+ if (!match) {
+ profilesData.push({ service: post.service, id: post.user });
+ }
+
+ return profilesData;
+ },
+ []
+ );
+ const favPosts = await findFavouritePosts(postsData);
+ const favProfiles = await findFavouriteProfiles(profilesData);
+ const postsWithFavs = posts.map((post) => {
+ const isFavPost = Boolean(
+ favPosts.find(
+ ({ service, user, id }) =>
+ id === post.id && user === post.user && service === post.service
+ )
+ );
+ const isFavProfile = Boolean(
+ favProfiles.find(
+ ({ service, id }) => id === post.user && service === post.service
+ )
+ );
+
+ if (!isFavPost && !isFavProfile) {
+ return post;
+ }
+
+ return {
+ ...post,
+ isFavourite: isFavPost,
+ isFavouriteProfile: isFavProfile,
+ };
+ });
return {
offset,
@@ -105,6 +156,6 @@ export async function loader({ request }: LoaderFunctionArgs): Promise {
tags,
count,
trueCount: true_count,
- posts,
+ posts: postsWithFavs,
};
}
diff --git a/client/src/pages/posts/archive.tsx b/client/src/pages/posts/archive.tsx
deleted file mode 100644
index 24b7edd..0000000
--- a/client/src/pages/posts/archive.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
-import { createArchiveFileURL } from "#lib/urls";
-import { fetchArchiveFile, fetchSetArchiveFilePassword } from "#api/files";
-import { PageSkeleton } from "#components/pages";
-import { IArchiveFile } from "#entities/files";
-
-interface IProps {
- archive: IArchiveFile;
- isFileServingEnabled: boolean;
-}
-
-export function ArchiveFilePage() {
- const { archive, isFileServingEnabled } = useLoaderData() as IProps;
- const { file, file_list, password } = archive;
- const title = "Archive files";
- const heading = "Archive Files";
-
- return (
-
-
-
- {file_list.length === 0 ? (
- <>Archive is empty or missing password.>
- ) : (
- file_list.map((fileName) =>
- !isFileServingEnabled ? (
- <>
- {fileName}
-
- >
- ) : password ? (
- <>
-
- {fileName}
-
-
- >
- ) : (
- <>
-
- {fileName}
-
-
- >
- )
- )
- )}
-
- );
-}
-
-export async function loader({ params }: LoaderFunctionArgs): Promise {
- const fileHash = params.file_hash?.trim();
- if (!fileHash) {
- throw new Error("File hash is required.");
- }
-
- const { archive, file_serving_enabled } = await fetchArchiveFile(fileHash);
-
- if (!archive) {
- throw new Error("Archive not found.");
- }
-
- return {
- archive,
- isFileServingEnabled: file_serving_enabled,
- };
-}
diff --git a/client/src/pages/posts/popular.tsx b/client/src/pages/posts/popular.tsx
index 4d8c4e5..9e41a49 100644
--- a/client/src/pages/posts/popular.tsx
+++ b/client/src/pages/posts/popular.tsx
@@ -1,31 +1,59 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createPopularPostsPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { fetchPopularPosts } from "#api/posts";
import { PageSkeleton } from "#components/pages";
import { Paginator } from "#components/pagination";
-import { FooterAd, HeaderAd, SliderAd } from "#components/ads";
-import { CardList, PostFavoriteCard } from "#components/cards";
+import { FooterAd, HeaderAd, SliderAd } from "#components/advs";
+import { CardList, PostCard } from "#components/cards";
import {
IPopularPostsPeriod,
- IPostWithFavorites,
+ IPost,
validatePeriod,
} from "#entities/posts";
+import { KemonoLink } from "#components/links";
+import { findFavouritePosts, findFavouriteProfiles } from "#entities/account";
interface IProps {
+ /**
+ * Datetime string.
+ */
minDate: string;
+ /**
+ * Datetime string.
+ */
maxDate: string;
+ /**
+ * Human description of range.
+ */
rangeDescription: string;
+ /**
+ * Date string.
+ */
earliestDateForPopular: string;
- navigationDates: Record;
+ /**
+ * Value is a tuple of date strings.
+ */
+ navigationDates: Record;
scale?: IPopularPostsPeriod;
+ /**
+ * Date string.
+ */
today: string;
count: number;
- posts: IPostWithFavorites[];
+ posts: IPost[];
offset?: number;
+ /**
+ * Datetime string.
+ */
date?: string;
}
+/**
+ * A tuple of date strings.
+ */
+type INavigationDate = [prev: string, next: string, current: string];
+
export function PopularPostsPage() {
const {
minDate,
@@ -56,139 +84,26 @@ export function PopularPostsPage() {
-
-
- {navigationDates.day[0] < earliestDateForPopular ? (
- next »
- ) : (
-
- « prev
-
- )}
- {" "}
+
-
- {scale === "day" ? (
- Day
- ) : (
-
- Day
-
- )}
- {" "}
+
-
- {navigationDates.day[1] > today ? (
- next »
- ) : (
-
- next »
-
- )}
-
-
-
-
-
- {navigationDates.week[0] < earliestDateForPopular ? (
- next »
- ) : (
-
- « prev
-
- )}
- {" "}
-
-
- {scale === "week" ? (
- Week
- ) : (
-
- Week
-
- )}
- {" "}
-
-
- {navigationDates.week[1] > today ? (
- next »
- ) : (
-
- next »
-
- )}
-
-
-
-
-
- {navigationDates.month[0] < earliestDateForPopular ? (
- next »
- ) : (
-
- « prev
-
- )}
- {" "}
-
-
- {scale === "month" ? (
- Month
- ) : (
-
- Month
-
- )}
- {" "}
-
-
-
- {navigationDates.month[1] > today ? (
- next »
- ) : (
-
- next »
-
- )}
-
-
-
+
) : (
posts.map((post) => (
-
))
)}
@@ -234,10 +152,150 @@ export function PopularPostsPage() {
);
}
+interface IDailySelectorProps
+ extends Pick {
+ navigationDate: INavigationDate;
+}
+
+function DailySelector({
+ earliestDateForPopular,
+ scale,
+ today,
+ navigationDate,
+}: IDailySelectorProps) {
+ const [prev, next, current] = navigationDate;
+
+ return (
+
+
+ {prev < earliestDateForPopular ? (
+ next »
+ ) : (
+
+ « prev
+
+ )}
+ {" "}
+
+ {scale === "day" ? (
+ Day
+ ) : (
+
+ Day
+
+ )}
+ {" "}
+
+ {next > today ? (
+ next »
+ ) : (
+
+ next »
+
+ )}
+
+
+ );
+}
+
+interface IWeeklySelectorProps
+ extends Pick {
+ navigationDate: [string, string, string];
+}
+
+function WeeklySelector({
+ earliestDateForPopular,
+ scale,
+ today,
+ navigationDate,
+}: IWeeklySelectorProps) {
+ const [prev, next, current] = navigationDate;
+
+ return (
+
+
+ {prev < earliestDateForPopular ? (
+ next »
+ ) : (
+
+ « prev
+
+ )}
+ {" "}
+
+ {scale === "week" ? (
+ Week
+ ) : (
+
+ Week
+
+ )}
+ {" "}
+
+ {next > today ? (
+ next »
+ ) : (
+
+ next »
+
+ )}
+
+
+ );
+}
+
+interface IMonthlySelectorProps
+ extends Pick {
+ navigationDate: [string, string, string];
+}
+
+function MonthlySelector({
+ earliestDateForPopular,
+ scale,
+ today,
+ navigationDate,
+}: IMonthlySelectorProps) {
+ const [prev, next, current] = navigationDate;
+
+ return (
+
+
+ {prev < earliestDateForPopular ? (
+ next »
+ ) : (
+
+ « prev
+
+ )}
+ {" "}
+
+ {scale === "month" ? (
+ Month
+ ) : (
+
+ Month
+
+ )}
+ {" "}
+
+
+ {next > today ? (
+ next »
+ ) : (
+
+ next »
+
+ )}
+
+
+
+ );
+}
+
export async function loader({ request }: LoaderFunctionArgs): Promise {
const searchParams = new URL(request.url).searchParams;
- const date = searchParams.get("date")?.trim();
+ const inputDate = searchParams.get("date")?.trim();
const scale = searchParams.get("period")?.trim() ?? "recent";
validatePeriod(scale);
@@ -251,16 +309,65 @@ export async function loader({ request }: LoaderFunctionArgs): Promise {
}
}
- const { info, props, results } = await fetchPopularPosts(date, scale, offset);
+ const {
+ info,
+ props,
+ results: posts,
+ } = await fetchPopularPosts(inputDate, scale, offset);
const { count, earliest_date_for_popular, today } = props;
- const { range_desc, min_date, max_date, navigation_dates } = info;
+ const { date, range_desc, min_date, max_date, navigation_dates } = info;
+ const postsData = posts.map(({ service, user, id }) => ({
+ service,
+ user,
+ id,
+ }));
+ const profilesData = posts.reduce<{ service: string; id: string }[]>(
+ (profilesData, post) => {
+ const match = profilesData.find(
+ (profileData) =>
+ profileData.id === post.user && profileData.service === post.service
+ );
+
+ if (!match) {
+ profilesData.push({ service: post.service, id: post.user });
+ }
+
+ return profilesData;
+ },
+ []
+ );
+ const favPosts = await findFavouritePosts(postsData);
+ const favProfiles = await findFavouriteProfiles(profilesData);
+ const postsWithFavs = posts.map((post) => {
+ const isFavPost = Boolean(
+ favPosts.find(
+ ({ service, user, id }) =>
+ id === post.id && user === post.user && service === post.service
+ )
+ );
+ const isFavProfile = Boolean(
+ favProfiles.find(
+ ({ service, id }) => id === post.user && service === post.service
+ )
+ );
+
+ if (!isFavPost && !isFavProfile) {
+ return post;
+ }
+
+ return {
+ ...post,
+ isFavourite: isFavPost,
+ isFavouriteProfile: isFavProfile,
+ };
+ });
return {
date,
count,
scale,
offset,
- posts: results,
+ posts: postsWithFavs,
today,
earliestDateForPopular: earliest_date_for_popular,
rangeDescription: range_desc,
diff --git a/client/src/pages/posts/random.tsx b/client/src/pages/posts/random.tsx
index 2372c96..3959f56 100644
--- a/client/src/pages/posts/random.tsx
+++ b/client/src/pages/posts/random.tsx
@@ -1,4 +1,4 @@
-import { redirect } from "react-router-dom";
+import { redirect } from "react-router";
import { createPostURL } from "#lib/urls";
import { fetchRandomPost } from "#api/posts";
diff --git a/client/src/pages/profile.scss b/client/src/pages/profile.scss
index 3febb0b..8e31111 100644
--- a/client/src/pages/profile.scss
+++ b/client/src/pages/profile.scss
@@ -1,4 +1,4 @@
-@use "../css/config/variables" as *;
+@use "../css/config/variables/sass" as *;
.tabs {
margin: 0 auto;
diff --git a/client/src/pages/profile.tsx b/client/src/pages/profile.tsx
index ff1a173..3de904b 100644
--- a/client/src/pages/profile.tsx
+++ b/client/src/pages/profile.tsx
@@ -1,9 +1,9 @@
-import { LoaderFunctionArgs, redirect, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, redirect, useLoaderData } from "react-router";
import { createDiscordServerPageURL, createProfilePageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { ElementType } from "#lib/types";
import { fetchProfilePosts } from "#api/profiles";
-import { FooterAd, SliderAd } from "#components/ads";
+import { FooterAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, PostCard } from "#components/cards";
import { ProfilePageSkeleton } from "#components/pages";
diff --git a/client/src/pages/profile/announcements.tsx b/client/src/pages/profile/announcements.tsx
index e89616b..a9ececa 100644
--- a/client/src/pages/profile/announcements.tsx
+++ b/client/src/pages/profile/announcements.tsx
@@ -1,13 +1,14 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { Helmet } from "react-helmet-async";
import { ICONS_PREPEND, KEMONO_SITE, SITE_NAME } from "#env/env-vars";
import { fetchAnnouncements } from "#api/posts";
import { fetchArtistProfile } from "#api/profiles";
import { PageSkeleton } from "#components/pages";
-import { CardList, DMCard } from "#components/cards";
+import { CardList } from "#components/cards";
import { ProfileHeader, Tabs, IArtistDetails } from "#entities/profiles";
import { paysites, validatePaysite } from "#entities/paysites";
import { IAnnouncement } from "#entities/posts";
+import { AnnouncementPreview } from "#entities/posts";
interface IProps {
service: string;
@@ -67,11 +68,9 @@ export function AnnouncementsPage() {
) : (
announcements.map((announcement) => (
-
))
)}
diff --git a/client/src/pages/profile/dms.scss b/client/src/pages/profile/dms.scss
index 3a755a4..80f7338 100644
--- a/client/src/pages/profile/dms.scss
+++ b/client/src/pages/profile/dms.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section--dms {
.no-results {
diff --git a/client/src/pages/profile/dms.tsx b/client/src/pages/profile/dms.tsx
index 6632325..d682d51 100644
--- a/client/src/pages/profile/dms.tsx
+++ b/client/src/pages/profile/dms.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { Helmet } from "react-helmet-async";
import { ICONS_PREPEND, KEMONO_SITE, SITE_NAME } from "#env/env-vars";
import { fetchProfileDMs } from "#api/dms";
diff --git a/client/src/pages/profile/fancards.scss b/client/src/pages/profile/fancards.scss
index d634373..bcaac05 100644
--- a/client/src/pages/profile/fancards.scss
+++ b/client/src/pages/profile/fancards.scss
@@ -1,14 +1,15 @@
div#fancard-container {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
- margin-top: 0.5em;
- gap: 0.5em 0.25em;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
article.fancard__file {
width: 400px;
height: 293px;
display: inline-grid;
background-color: var(--colour1-secondary);
+ margin: 0.5em;
+ margin-bottom: 0.25em;
span {
padding-top: 0.5em;
diff --git a/client/src/pages/profile/fancards.tsx b/client/src/pages/profile/fancards.tsx
index 2b02245..35298f8 100644
--- a/client/src/pages/profile/fancards.tsx
+++ b/client/src/pages/profile/fancards.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { Helmet } from "react-helmet-async";
import {
ICONS_PREPEND,
diff --git a/client/src/pages/profile/linked_accounts.tsx b/client/src/pages/profile/linked_accounts.tsx
index 9373755..f31b4ee 100644
--- a/client/src/pages/profile/linked_accounts.tsx
+++ b/client/src/pages/profile/linked_accounts.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createProfileNewLinksPageURL } from "#lib/urls";
import { fetchArtistProfile, fetchProfileLinks } from "#api/profiles";
import { CardList, ArtistCard } from "#components/cards";
diff --git a/client/src/pages/profile/new-linked-profile.module.scss b/client/src/pages/profile/new-linked-profile.module.scss
new file mode 100644
index 0000000..b698d5c
--- /dev/null
+++ b/client/src/pages/profile/new-linked-profile.module.scss
@@ -0,0 +1,3 @@
+.selected {
+ border: 2px solid green;
+}
diff --git a/client/src/pages/profile/new_linked_account.tsx b/client/src/pages/profile/new-linked-profile.tsx
similarity index 91%
rename from client/src/pages/profile/new_linked_account.tsx
rename to client/src/pages/profile/new-linked-profile.tsx
index e61f110..368faaf 100644
--- a/client/src/pages/profile/new_linked_account.tsx
+++ b/client/src/pages/profile/new-linked-profile.tsx
@@ -1,10 +1,11 @@
import { useEffect, useState } from "react";
+import clsx from "clsx";
import {
ActionFunctionArgs,
LoaderFunctionArgs,
useActionData,
useLoaderData,
-} from "react-router-dom";
+} from "react-router";
import { SITE_NAME } from "#env/env-vars";
import { AVAILABLE_PAYSITE_LIST } from "#env/derived-vars";
import { ElementType } from "#lib/types";
@@ -16,6 +17,7 @@ import {
import { FormRouter, FormSection, ButtonSubmit } from "#components/forms";
import { InputHidden } from "#components/forms/inputs";
import { ArtistCard } from "#components/cards";
+import { Button } from "#components/buttons";
import {
ProfileHeader,
Tabs,
@@ -25,6 +27,8 @@ import {
} from "#entities/profiles";
import { validatePaysite } from "#entities/paysites";
+import * as styles from "./new-linked-profile.module.scss";
+
interface IProps {
profile: IArtistDetails;
}
@@ -167,24 +171,25 @@ export function NewProfileLinkPage() {
) : profileSuggestions.count === 0 ? (
<>No results found.>
) : (
- profileSuggestions.artists.slice(0, 20).map((profile, index) => (
+ profileSuggestions.artists.slice(0, 20).map((profile) => (
{
- event.preventDefault();
- event.stopPropagation();
- changeSelectedProfile(profile);
- }}
+ key={`${profile.service}${profile.id}`}
+ className={clsx(
+ profile.service === selectedProfile?.service &&
+ profile.id === selectedProfile?.id &&
+ styles.selected
+ )}
>
-
+
+ onClick={() => changeSelectedProfile(profile)}
+ >
+ Select
+
))
)}
diff --git a/client/src/pages/profile/tags.scss b/client/src/pages/profile/tags.scss
index 6b42120..8160aa1 100644
--- a/client/src/pages/profile/tags.scss
+++ b/client/src/pages/profile/tags.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
h2#all-tags-header {
margin-left: auto;
diff --git a/client/src/pages/profile/tags.tsx b/client/src/pages/profile/tags.tsx
index d24c358..7e642b7 100644
--- a/client/src/pages/profile/tags.tsx
+++ b/client/src/pages/profile/tags.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createProfileTagURL } from "#lib/urls";
import { PageSkeleton } from "#components/pages";
import { getTags } from "#entities/tags";
diff --git a/client/src/pages/profiles.tsx b/client/src/pages/profiles.tsx
index 1a24513..4ee6ab5 100644
--- a/client/src/pages/profiles.tsx
+++ b/client/src/pages/profiles.tsx
@@ -3,10 +3,9 @@ import { Suspense } from "react";
import {
useLoaderData,
LoaderFunctionArgs,
- defer,
Await,
useAsyncError,
-} from "react-router-dom";
+} from "react-router";
import { PAYSITE_LIST } from "#env/env-vars";
import {
ARTISTS_OR_CREATORS_LOWERCASE,
@@ -15,14 +14,14 @@ import {
import { createArtistsPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { PageSkeleton } from "#components/pages";
-import { FooterAd, HeaderAd, SliderAd } from "#components/ads";
+import { FooterAd, HeaderAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, ArtistCard } from "#components/cards";
import { ButtonSubmit, FormRouter, FormSection } from "#components/forms";
import { LoadingIcon } from "#components/loading";
import { getArtists } from "#entities/profiles";
-import styles from "./profiles.module.scss";
+import * as styles from "./profiles.module.scss";
interface IProps {
results: ReturnType
;
@@ -167,9 +166,10 @@ interface ISearchFormProps
function SearchForm({ query, service, sort_by, order }: ISearchFormProps) {
return (
> {
+}: LoaderFunctionArgs): Promise {
const searchParams = new URL(request.url).searchParams;
let offset: IProps["offset"] | undefined = undefined;
@@ -329,5 +329,5 @@ export async function loader({
query,
} satisfies IProps;
- return defer(pageProps);
+ return pageProps;
}
diff --git a/client/src/pages/profiles/random.tsx b/client/src/pages/profiles/random.tsx
index 5774200..575cad7 100644
--- a/client/src/pages/profiles/random.tsx
+++ b/client/src/pages/profiles/random.tsx
@@ -1,4 +1,4 @@
-import { redirect } from "react-router-dom";
+import { redirect } from "react-router";
import { createProfilePageURL } from "#lib/urls";
import { fetchRandomArtist } from "#api/profiles";
diff --git a/client/src/pages/profiles/updated.tsx b/client/src/pages/profiles/updated.tsx
index 0e26de4..857d811 100644
--- a/client/src/pages/profiles/updated.tsx
+++ b/client/src/pages/profiles/updated.tsx
@@ -1,10 +1,10 @@
import clsx from "clsx";
-import { useLoaderData, LoaderFunctionArgs } from "react-router-dom";
+import { useLoaderData, LoaderFunctionArgs } from "react-router";
import { ARTISTS_OR_CREATORS_LOWERCASE } from "#env/derived-vars";
import { createArtistsUpdatedPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { PageSkeleton } from "#components/pages";
-import { FooterAd, HeaderAd, SliderAd } from "#components/ads";
+import { FooterAd, HeaderAd, SliderAd } from "#components/advs";
import { Paginator } from "#components/pagination";
import { CardList, ArtistCard } from "#components/cards";
import { getArtists } from "#entities/profiles";
diff --git a/client/src/pages/review_dms/dms.scss b/client/src/pages/review_dms/dms.scss
index 3309d35..a3d42de 100644
--- a/client/src/pages/review_dms/dms.scss
+++ b/client/src/pages/review_dms/dms.scss
@@ -1,4 +1,4 @@
-@use "../../css/config/variables" as *;
+@use "../../css/config/variables/sass" as *;
.site-section--review-dms {
.dms {
diff --git a/client/src/pages/review_dms/review_dms.tsx b/client/src/pages/review_dms/review_dms.tsx
index 04edeb5..5075b6c 100644
--- a/client/src/pages/review_dms/review_dms.tsx
+++ b/client/src/pages/review_dms/review_dms.tsx
@@ -4,7 +4,7 @@ import {
LoaderFunctionArgs,
redirect,
useLoaderData,
-} from "react-router-dom";
+} from "react-router";
import { createAccountDMsReviewPageURL } from "#lib/urls";
import { fetchApproveDMs, fetchDMsForReview } from "#api/account/dms";
import { PageSkeleton, createAccountPageLoader } from "#components/pages";
@@ -13,7 +13,7 @@ import { FormRouter } from "#components/forms";
import { KemonoLink } from "#components/links";
import { IUnapprovedDM } from "#entities/dms";
-import styles from "./review_dms.module.scss";
+import * as styles from "./review_dms.module.scss";
interface IProps {
status: "pending" | "ignored";
diff --git a/client/src/pages/search_hash.tsx b/client/src/pages/search_hash.tsx
index 2f4daab..2ef6ee3 100644
--- a/client/src/pages/search_hash.tsx
+++ b/client/src/pages/search_hash.tsx
@@ -3,7 +3,7 @@ import {
LoaderFunctionArgs,
redirect,
useLoaderData,
-} from "react-router-dom";
+} from "react-router";
// TODO: https://github.com/Daninet/hash-wasm probably
// since this one wasn't updated in 3 years
import sha256 from "sha256-wasm";
diff --git a/client/src/pages/share.tsx b/client/src/pages/share.tsx
index 11f69a9..6946fbd 100644
--- a/client/src/pages/share.tsx
+++ b/client/src/pages/share.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createFileURL } from "#lib/urls";
import { fetchShare } from "#api/shares";
import { PageSkeleton } from "#components/pages";
diff --git a/client/src/pages/shares-all.tsx b/client/src/pages/shares-all.tsx
index 18362c1..2019774 100644
--- a/client/src/pages/shares-all.tsx
+++ b/client/src/pages/shares-all.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createSharesPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { fetchShares } from "#api/shares";
diff --git a/client/src/pages/shares.tsx b/client/src/pages/shares.tsx
index aa93f00..64d1cf7 100644
--- a/client/src/pages/shares.tsx
+++ b/client/src/pages/shares.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { createProfilesSharesPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { fetchProfileShares } from "#api/shares";
diff --git a/client/src/pages/tags-all.tsx b/client/src/pages/tags-all.tsx
index 47518a3..cccba09 100644
--- a/client/src/pages/tags-all.tsx
+++ b/client/src/pages/tags-all.tsx
@@ -1,4 +1,4 @@
-import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
+import { LoaderFunctionArgs, useLoaderData } from "react-router";
import { PageSkeleton } from "#components/pages";
import { ITag } from "#entities/tags";
import { createTagPageURL } from "#lib/urls";
diff --git a/client/src/pages/upload.tsx b/client/src/pages/upload.tsx
index 0e18861..bac8d70 100644
--- a/client/src/pages/upload.tsx
+++ b/client/src/pages/upload.tsx
@@ -3,7 +3,7 @@ import {
ActionFunctionArgs,
LoaderFunctionArgs,
useLoaderData,
-} from "react-router-dom";
+} from "react-router";
import Uppy from "@uppy/core";
import Dashboard from "@uppy/dashboard";
import Form from "@uppy/form";
@@ -57,8 +57,7 @@ export function Component() {
});
uppy.on("complete", ({ successful }) => {
- const files = successful.map(
- // @ts-expect-error uppy types too generic
+ const files = successful?.map(
(file) => file.meta.name
);
diff --git a/client/src/router.tsx b/client/src/router.tsx
index b5aa56d..34acc26 100644
--- a/client/src/router.tsx
+++ b/client/src/router.tsx
@@ -1,417 +1,17 @@
-import { createBrowserRouter } from "react-router-dom";
-import { Layout } from "#components/layout";
-import { ErrorPage } from "#components/pages";
-import { HomePage } from "#pages/home";
-import { ImporterTutorialPage } from "#pages/importer_tutorial";
-import { ImporterTutorialFanboxPage } from "#pages/importer_tutorial_fanbox";
-import {
- ImporterPage,
- action as importerPageAction,
-} from "#pages/importer_list";
-import {
- SearchFilesPage,
- loader as searchFilesPageLoader,
- action as searchFilesPageAction,
-} from "#pages/search_hash";
-import { ImporterOKPage } from "#pages/importer_ok";
-import {
- AdministratorDashboardPage,
- loader as administratorDashboardPageLoader,
-} from "#pages/account/administrator/dashboard";
-import {
- AccountLoginPage,
- action as accountLoginPageAction,
-} from "#pages/account/login";
-import { ArtistsPage, loader as artistsPageLoader } from "#pages/profiles";
-import {
- ArtistsUpdatedPage,
- loader as artistsUpdatedPageLoader,
-} from "#pages/profiles/updated";
-import { loader as artistRandomPageLoader } from "#pages/profiles/random";
-import { ProfilePage, loader as profilePageLoader } from "#pages/profile";
-import {
- ProfileTagsPage,
- loader as profileTagsPageLoader,
-} from "#pages/profile/tags";
-import {
- FancardsPage,
- loader as fancardsLoader,
-} from "#pages/profile/fancards";
-import {
- ProfileSharesPage,
- loader as profileSharesPageLoader,
-} from "#pages/shares";
-import {
- ProfileDMsPage,
- loader as profileDMsPageLoader,
-} from "#pages/profile/dms";
-import {
- AnnouncementsPage,
- loader as announcementsPageLoader,
-} from "#pages/profile/announcements";
-import {
- ProfileLinksPage,
- loader as profileLinksPageLoader,
-} from "#pages/profile/linked_accounts";
-import {
- NewProfileLinkPage,
- loader as newProfileLinkPageLoader,
- action as newProfileLinkPageAction,
-} from "#pages/profile/new_linked_account";
-import { DMsPage, loader as dmsPageLoader } from "#pages/all_dms";
-import { loader as accountFavoritesPageLoader } from "#pages/favorites";
-import { SharePage, loader as sharePageLoader } from "#pages/share";
-import { SharesPage, loader as sharesPageLoader } from "#pages/shares-all";
-import { PostPage, loader as postPageLoader } from "#pages/post";
-import { loader as postPageDataLoader } from "#pages/post/data";
-import { PostsPage, loader as postsPageLoader } from "#pages/posts";
-import {
- PopularPostsPage,
- loader as popularPostsPageLoader,
-} from "#pages/posts/popular";
-import { TagsPage, loader as tagsPageLoader } from "#pages/tags-all";
-import {
- DiscordServerPage,
- loader as discordServerPageLoader,
-} from "#pages/discord";
-import {
- DiscordChannelPage,
- loader as discordChannelPageLoader,
-} from "#pages/discord-channel";
-import {
- ArchiveFilePage,
- loader as archiveFilePageLoader,
-} from "#pages/posts/archive";
-import { loader as postRandomPageLoader } from "#pages/posts/random";
-import {
- DMsReviewPage,
- loader as dmsReviewPageLoader,
- action as dmsReviewPageAction,
-} from "#pages/review_dms/review_dms";
-import {
- PostRevisionPage,
- loader as postRevisionPageLoader,
-} from "#pages/post-revision";
-import {
- ImporterStatusPage,
- loader as importerStatusPageLoader,
-} from "#pages/importer_status";
-import { AccountPage, loader as accountPageLoader } from "#pages/account/home";
-import {
- AccountNotificationsPage,
- loader as accountNotificationsPageLoader,
-} from "#pages/account/notifications";
-import {
- AccountAutoImportKeysPage,
- loader as accountAutoImportKeysPageLoader,
- action as accountAutoImportKeysPageAction,
-} from "#pages/account/keys";
-import {
- AccountChangePasswordPage,
- loader as accountChangePasswordPageLoader,
-} from "#pages/account/change_password";
-import {
- AdministratorAccountsPage,
- loader as administratorAccountsPageLoader,
-} from "#pages/account/administrator/accounts";
-import {
- ModeratorDashboardPage,
- loader as moderatorDashboardPageLoader,
-} from "#pages/account/moderator/dashboard";
-import {
- ProfileLinkRequestsPage,
- loader as profileLinkRequestsPageLoader,
-} from "#pages/account/moderator/profile_links";
-import {
- RegisterPage,
- action as registerPageAction,
-} from "#pages/account/register";
-import { loader as accountLogoutPageLoader } from "#pages/authentication/logout";
-import { loader as favoritesLegacyPageLoader } from "#pages/account/favorites/legacy";
-import {
- FavoriteProfilesPage,
- loader as favoritesProfilesPageLoader,
-} from "#pages/account/favorites/profiles";
-import {
- FavoritePostsPage,
- loader as favoritesPostsPageLoader,
-} from "#pages/account/favorites/posts";
-import { Compliance2257Page } from "#pages/2257";
-import { ContactPage } from "#pages/contact";
-import { DMCAPage } from "#pages/dmca";
-import { FanboxImportsPage } from "#pages/fanboximports";
-import { GumroadAndCoPage } from "#pages/gumroad-and-co";
-import { MatrixPage } from "#pages/matrix";
+import { createBrowserRouter } from "react-router";
-export const router = createBrowserRouter([
+import { routes } from "./routes";
+
+export const router = createBrowserRouter(
+ routes,
{
- path: "/",
- element: ,
- errorElement: ,
- children: [
- {
- errorElement: ,
- children: [
- { index: true, element: },
- {
- path: "/2257",
- element: ,
- },
- {
- path: "/contact",
- element: ,
- },
- {
- path: "/dmca",
- element: ,
- },
- {
- path: "/fanboximports",
- element: ,
- },
- {
- path: "/gumroad-and-co",
- element: ,
- },
- {
- path: "/matrix",
- element: ,
- },
- {
- path: "/importer",
- element: ,
- action: importerPageAction,
- },
- {
- path: "/importer/ok",
- element: ,
- },
- {
- path: "/importer/tutorial",
- element: ,
- },
- {
- path: "/importer/tutorial_fanbox",
- element: ,
- },
- {
- path: "/importer/status/:import_id",
- element: ,
- loader: importerStatusPageLoader,
- },
- {
- path: "/search_hash",
- element: ,
- loader: searchFilesPageLoader,
- action: searchFilesPageAction,
- },
- {
- path: "/artists",
- element: ,
- loader: artistsPageLoader,
- },
- {
- path: "/artists/updated",
- element: ,
- loader: artistsUpdatedPageLoader,
- },
- {
- path: "/artists/random",
- loader: artistRandomPageLoader,
- },
- {
- path: "/posts",
- element: ,
- loader: postsPageLoader,
- },
- {
- path: "/posts/popular",
- element: ,
- loader: popularPostsPageLoader,
- },
- {
- path: "/posts/tags",
- element: ,
- loader: tagsPageLoader,
- },
- {
- path: "/posts/archives/:file_hash",
- element: ,
- loader: archiveFilePageLoader,
- },
- {
- path: "/posts/random",
- loader: postRandomPageLoader,
- },
- {
- path: "/favorites",
- loader: favoritesLegacyPageLoader,
- },
- {
- path: "/discord/server/:server_id",
- element: ,
- loader: discordServerPageLoader,
- },
- {
- path: "/discord/server/:server_id/:channel_id",
- element: ,
- loader: discordChannelPageLoader,
- },
- {
- path: "/:service/user/:creator_id",
- element: ,
- loader: profilePageLoader,
- },
- {
- path: "/:service/user/:creator_id/tags",
- element: ,
- loader: profileTagsPageLoader,
- },
- {
- path: "/:service/user/:creator_id/fancards",
- element: ,
- loader: fancardsLoader,
- },
- {
- path: "/:service/user/:creator_id/shares",
- element: ,
- loader: profileSharesPageLoader,
- },
- {
- path: "/:service/user/:creator_id/dms",
- element: ,
- loader: profileDMsPageLoader,
- },
- {
- path: "/:service/user/:creator_id/announcements",
- element: ,
- loader: announcementsPageLoader,
- },
- {
- path: "/:service/user/:creator_id/links",
- element: ,
- loader: profileLinksPageLoader,
- },
- {
- path: "/:service/user/:creator_id/post/:post_id",
- element: ,
- loader: postPageLoader,
- },
- {
- path: "/:service/user/:creator_id/post/:post_id/revision/:revision_id",
- element: ,
- loader: postRevisionPageLoader,
- },
- {
- path: "/:service/post/:post_id",
- loader: postPageDataLoader,
- },
- {
- path: "/dms",
- element: ,
- loader: dmsPageLoader,
- },
- {
- path: "/shares",
- element: ,
- loader: sharesPageLoader,
- },
- {
- path: "/share/:share_id",
- element: ,
- loader: sharePageLoader,
- },
- {
- path: "/documentation/api",
- lazy: () => import("#pages/documentation/api"),
- },
- {
- path: "/authentication/register",
- element: ,
- action: registerPageAction,
- },
- {
- path: "/authentication/login",
- element: ,
- action: accountLoginPageAction,
- },
- {
- path: "/authentication/logout",
- loader: accountLogoutPageLoader,
- },
- {
- path: "/account",
- element: ,
- loader: accountPageLoader,
- },
- {
- path: "/account/favorites",
- loader: accountFavoritesPageLoader,
- },
- {
- path: "/account/favorites/artists",
- element: ,
- loader: favoritesProfilesPageLoader,
- },
- {
- path: "/account/favorites/posts",
- element: ,
- loader: favoritesPostsPageLoader,
- },
- {
- path: "/account/notifications",
- element: ,
- loader: accountNotificationsPageLoader,
- },
- {
- path: "/account/keys",
- element: ,
- loader: accountAutoImportKeysPageLoader,
- action: accountAutoImportKeysPageAction,
- },
- {
- path: "/account/change_password",
- element: ,
- loader: accountChangePasswordPageLoader,
- },
- {
- path: "/account/:service/user/:creator_id/links/new",
- element: ,
- loader: newProfileLinkPageLoader,
- action: newProfileLinkPageAction,
- },
- {
- path: "/account/posts/upload",
- lazy: () => import("#pages/upload"),
- },
- {
- path: "/account/review_dms",
- element: ,
- loader: dmsReviewPageLoader,
- action: dmsReviewPageAction,
- },
- {
- path: "/account/moderator",
- element: ,
- loader: moderatorDashboardPageLoader,
- },
- {
- path: "/account/moderator/tasks/creator_links",
- element: ,
- loader: profileLinkRequestsPageLoader,
- },
- {
- path: "/account/administrator",
- element: ,
- loader: administratorDashboardPageLoader,
- },
- {
- path: "/account/administrator/accounts",
- element: ,
- loader: administratorAccountsPageLoader,
- },
- ],
- },
- ],
- },
-]);
+ future: {
+ v7_relativeSplatPath: true,
+ v7_normalizeFormMethod: true,
+ v7_startTransition: true,
+ v7_fetcherPersist: true,
+ v7_partialHydration: true,
+ v7_skipActionErrorRevalidation: true,
+ },
+ }
+);
diff --git a/client/src/routes.tsx b/client/src/routes.tsx
new file mode 100644
index 0000000..27a5f16
--- /dev/null
+++ b/client/src/routes.tsx
@@ -0,0 +1,445 @@
+import { Layout } from "#components/layout";
+import { ErrorPage } from "#components/pages";
+import { HomePage } from "#pages/home";
+import { ImporterTutorialPage } from "#pages/importer/importer_tutorial";
+import { ImporterTutorialFanboxPage } from "#pages/importer/importer_tutorial_fanbox";
+import {
+ ImporterPage,
+ action as importerPageAction,
+} from "#pages/importer/importer_list";
+import {
+ SearchFilesPage,
+ loader as searchFilesPageLoader,
+ action as searchFilesPageAction,
+} from "#pages/search_hash";
+import { ImporterOKPage } from "#pages/importer/importer_ok";
+import {
+ AdministratorDashboardPage,
+ loader as administratorDashboardPageLoader,
+} from "#pages/account/administrator/dashboard";
+import {
+ AccountLoginPage,
+ action as accountLoginPageAction,
+} from "#pages/account/login";
+import { ArtistsPage, loader as artistsPageLoader } from "#pages/profiles";
+import {
+ ArtistsUpdatedPage,
+ loader as artistsUpdatedPageLoader,
+} from "#pages/profiles/updated";
+import { loader as artistRandomPageLoader } from "#pages/profiles/random";
+import { ProfilePage, loader as profilePageLoader } from "#pages/profile";
+import {
+ ProfileTagsPage,
+ loader as profileTagsPageLoader,
+} from "#pages/profile/tags";
+import {
+ FancardsPage,
+ loader as fancardsLoader,
+} from "#pages/profile/fancards";
+import {
+ ProfileSharesPage,
+ loader as profileSharesPageLoader,
+} from "#pages/shares";
+import {
+ ProfileDMsPage,
+ loader as profileDMsPageLoader,
+} from "#pages/profile/dms";
+import {
+ AnnouncementsPage,
+ loader as announcementsPageLoader,
+} from "#pages/profile/announcements";
+import {
+ ProfileLinksPage,
+ loader as profileLinksPageLoader,
+} from "#pages/profile/linked_accounts";
+import {
+ NewProfileLinkPage,
+ loader as newProfileLinkPageLoader,
+ action as newProfileLinkPageAction,
+} from "#pages/profile/new-linked-profile";
+import { DMsPage, loader as dmsPageLoader } from "#pages/all_dms";
+import { loader as accountFavoritesPageLoader } from "#pages/favorites";
+import { SharePage, loader as sharePageLoader } from "#pages/share";
+import { SharesPage, loader as sharesPageLoader } from "#pages/shares-all";
+import { PostPage, loader as postPageLoader } from "#pages/post";
+import { loader as postPageDataLoader } from "#pages/post/data";
+import { PostsPage, loader as postsPageLoader } from "#pages/posts";
+import {
+ PopularPostsPage,
+ loader as popularPostsPageLoader,
+} from "#pages/posts/popular";
+import { TagsPage, loader as tagsPageLoader } from "#pages/tags-all";
+import {
+ DiscordServerPage,
+ loader as discordServerPageLoader,
+} from "#pages/discord";
+import {
+ DiscordChannelPage,
+ loader as discordChannelPageLoader,
+} from "#pages/discord-channel";
+import {
+ ArchiveFilePage,
+ loader as archiveFilePageLoader,
+ action as archiveFilePageAction,
+} from "#pages/file/archive";
+import { loader as postRandomPageLoader } from "#pages/posts/random";
+import {
+ DMsReviewPage,
+ loader as dmsReviewPageLoader,
+ action as dmsReviewPageAction,
+} from "#pages/review_dms/review_dms";
+import {
+ PostRevisionPage,
+ loader as postRevisionPageLoader,
+} from "#pages/post-revision";
+import {
+ ImporterStatusPage,
+ loader as importerStatusPageLoader,
+} from "#pages/importer/importer_status";
+import { AccountPage, loader as accountPageLoader } from "#pages/account/home";
+import {
+ AccountNotificationsPage,
+ loader as accountNotificationsPageLoader,
+} from "#pages/account/notifications";
+import {
+ AccountAutoImportKeysPage,
+ loader as accountAutoImportKeysPageLoader,
+ action as accountAutoImportKeysPageAction,
+} from "#pages/account/keys";
+import {
+ AccountChangePasswordPage,
+ loader as accountChangePasswordPageLoader,
+ action as accountChangePasswordPageAction,
+} from "#pages/account/change_password";
+import {
+ AdministratorAccountsPage,
+ loader as administratorAccountsPageLoader,
+ baseLoader as administratorAccountsPageBaseLoader,
+} from "#pages/account/administrator/accounts";
+import {
+ ModeratorDashboardPage,
+ loader as moderatorDashboardPageLoader,
+} from "#pages/account/moderator/dashboard";
+import {
+ ProfileLinkRequestsPage,
+ loader as profileLinkRequestsPageLoader,
+} from "#pages/account/moderator/profile_links";
+import {
+ RegisterPage,
+ action as registerPageAction,
+} from "#pages/account/register";
+import { loader as accountLogoutPageLoader } from "#pages/authentication/logout";
+import { loader as favoritesLegacyPageLoader } from "#pages/account/favorites/legacy";
+import {
+ FavoriteProfilesPage,
+ loader as favoritesProfilesPageLoader,
+} from "#pages/account/favorites/profiles";
+import {
+ FavoritePostsPage,
+ loader as favoritesPostsPageLoader,
+} from "#pages/account/favorites/posts";
+import { Compliance2257Page } from "#pages/2257";
+import { ContactPage } from "#pages/contact";
+import { DMCAPage } from "#pages/dmca";
+import { FanboxImportsPage } from "#pages/fanboximports";
+import { GumroadAndCoPage } from "#pages/gumroad-and-co";
+import { MatrixPage } from "#pages/matrix";
+import {
+ AdministratorAccountOverviewPage,
+ loader as administratorAccountOverviewPageLoader,
+ action as administratorAccountOverviewPageAction,
+} from "#pages/account/administrator/account";
+import {
+ LegacyFilePage,
+ loader as legacyFilePageLoader,
+} from "#pages/file/legacy";
+
+export const routes = [
+ {
+ path: "/",
+ element: ,
+ errorElement: ,
+ children: [
+ {
+ errorElement: ,
+ children: [
+ { index: true, element: },
+ {
+ path: "/2257",
+ element: ,
+ },
+ {
+ path: "/contact",
+ element: ,
+ },
+ {
+ path: "/dmca",
+ element: ,
+ },
+ {
+ path: "/fanboximports",
+ element: ,
+ },
+ {
+ path: "/gumroad-and-co",
+ element: ,
+ },
+ {
+ path: "/matrix",
+ element: ,
+ },
+ {
+ path: "/importer",
+ element: ,
+ action: importerPageAction,
+ },
+ {
+ path: "/importer/ok",
+ element: ,
+ },
+ {
+ path: "/importer/tutorial",
+ element: ,
+ },
+ {
+ path: "/importer/tutorial_fanbox",
+ element: ,
+ },
+ {
+ path: "/importer/status/:import_id",
+ element: ,
+ loader: importerStatusPageLoader,
+ },
+ {
+ path: "/search_hash",
+ element: ,
+ loader: searchFilesPageLoader,
+ action: searchFilesPageAction,
+ },
+ {
+ path: "/artists",
+ element: ,
+ loader: artistsPageLoader,
+ },
+ {
+ path: "/artists/updated",
+ element: ,
+ loader: artistsUpdatedPageLoader,
+ },
+ {
+ path: "/artists/random",
+ loader: artistRandomPageLoader,
+ },
+ {
+ path: "/posts",
+ element: ,
+ loader: postsPageLoader,
+ },
+ {
+ path: "/posts/popular",
+ element: ,
+ loader: popularPostsPageLoader,
+ },
+ {
+ path: "/posts/tags",
+ element: ,
+ loader: tagsPageLoader,
+ },
+ {
+ path: "/posts/archives/:file_hash",
+ element: ,
+ loader: legacyFilePageLoader,
+ },
+ {
+ path: "/file/:file_hash",
+ element: ,
+ loader: archiveFilePageLoader,
+ action: archiveFilePageAction,
+ },
+ {
+ path: "/posts/random",
+ loader: postRandomPageLoader,
+ },
+ {
+ path: "/favorites",
+ loader: favoritesLegacyPageLoader,
+ },
+ {
+ path: "/discord/server/:server_id",
+ element: ,
+ loader: discordServerPageLoader,
+ },
+ {
+ path: "/discord/server/:server_id/:channel_id",
+ element: ,
+ loader: discordChannelPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id",
+ element: ,
+ loader: profilePageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/tags",
+ element: ,
+ loader: profileTagsPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/fancards",
+ element: ,
+ loader: fancardsLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/shares",
+ element: ,
+ loader: profileSharesPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/dms",
+ element: ,
+ loader: profileDMsPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/announcements",
+ element: ,
+ loader: announcementsPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/links",
+ element: ,
+ loader: profileLinksPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/post/:post_id",
+ element: ,
+ loader: postPageLoader,
+ },
+ {
+ path: "/:service/user/:creator_id/post/:post_id/revision/:revision_id",
+ element: ,
+ loader: postRevisionPageLoader,
+ },
+ {
+ path: "/:service/post/:post_id",
+ loader: postPageDataLoader,
+ },
+ {
+ path: "/dms",
+ element: ,
+ loader: dmsPageLoader,
+ },
+ {
+ path: "/shares",
+ element: ,
+ loader: sharesPageLoader,
+ },
+ {
+ path: "/share/:share_id",
+ element: ,
+ loader: sharePageLoader,
+ },
+ {
+ path: "/documentation/api",
+ lazy: () => import("#pages/documentation/api"),
+ },
+ {
+ path: "/authentication/register",
+ element: ,
+ action: registerPageAction,
+ },
+ {
+ path: "/authentication/login",
+ element: ,
+ action: accountLoginPageAction,
+ },
+ {
+ path: "/authentication/logout",
+ loader: accountLogoutPageLoader,
+ },
+ {
+ path: "/account",
+ element: ,
+ loader: accountPageLoader,
+ },
+ {
+ path: "/account/favorites",
+ loader: accountFavoritesPageLoader,
+ },
+ {
+ path: "/account/favorites/artists",
+ element: ,
+ loader: favoritesProfilesPageLoader,
+ },
+ {
+ path: "/account/favorites/posts",
+ element: ,
+ loader: favoritesPostsPageLoader,
+ },
+ {
+ path: "/account/notifications",
+ element: ,
+ loader: accountNotificationsPageLoader,
+ },
+ {
+ path: "/account/keys",
+ element: ,
+ loader: accountAutoImportKeysPageLoader,
+ action: accountAutoImportKeysPageAction,
+ },
+ {
+ path: "/account/change_password",
+ element: ,
+ loader: accountChangePasswordPageLoader,
+ action: accountChangePasswordPageAction,
+ },
+ {
+ path: "/account/:service/user/:creator_id/links/new",
+ element: ,
+ loader: newProfileLinkPageLoader,
+ action: newProfileLinkPageAction,
+ },
+ {
+ path: "/account/posts/upload",
+ lazy: () => import("#pages/upload"),
+ },
+ {
+ path: "/account/review_dms",
+ element: ,
+ loader: dmsReviewPageLoader,
+ action: dmsReviewPageAction,
+ },
+ {
+ path: "/account/moderator",
+ element: ,
+ loader: moderatorDashboardPageLoader,
+ },
+ {
+ path: "/account/moderator/tasks/creator_links",
+ element: ,
+ loader: profileLinkRequestsPageLoader,
+ },
+ {
+ path: "/account/administrator",
+ element: ,
+ loader: administratorDashboardPageLoader,
+ },
+ {
+ path: "/account/administrator/accounts",
+ loader: administratorAccountsPageBaseLoader,
+ },
+ {
+ path: "/account/administrator/accounts/:page",
+ element: ,
+ loader: administratorAccountsPageLoader,
+ },
+ {
+ path: "/account/administrator/account/:account_id",
+ element: ,
+ loader: administratorAccountOverviewPageLoader,
+ action: administratorAccountOverviewPageAction,
+ },
+ ],
+ },
+ ],
+ },
+];
diff --git a/client/static/small_icons/canfans.png b/client/static/small_icons/candfans.png
similarity index 100%
rename from client/static/small_icons/canfans.png
rename to client/static/small_icons/candfans.png
diff --git a/client/tsconfig.json b/client/tsconfig.json
index 20e1c4a..815731a 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -5,6 +5,7 @@
"outDir": "./dist",
"sourceMap": true,
"lib": ["dom", "esnext"],
+ "types": ["vite/client", "@modyfi/vite-plugin-yaml/modules"],
"allowJs": true,
"checkJs": true,
"skipLibCheck": true,
@@ -13,6 +14,7 @@
"target": "ES2017",
"module": "esnext",
"moduleResolution": "bundler",
+ "noEmit": true,
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
diff --git a/client/vite.config.mjs b/client/vite.config.mjs
new file mode 100644
index 0000000..1b9a4b5
--- /dev/null
+++ b/client/vite.config.mjs
@@ -0,0 +1,176 @@
+// @ts-check
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import legacy from "@vitejs/plugin-legacy";
+import ViteYaml from "@modyfi/vite-plugin-yaml";
+import { viteStaticCopy } from "vite-plugin-static-copy";
+import { createHtmlPlugin } from "vite-plugin-html";
+import { patchCssModules } from 'vite-css-modules'
+import {
+ siteName,
+ analyticsEnabled,
+ analyticsCode,
+ kemonoSite,
+ sentryDSN,
+ iconsPrepend,
+ bannersPrepend,
+ thumbnailsPrepend,
+ artistsOrCreators,
+ disableDMs,
+ disableFAQ,
+ disableFilehaus,
+ sidebarItems,
+ footerItems,
+ bannerGlobal,
+ bannerWelcome,
+ homeBackgroundImage,
+ homeMascotPath,
+ homeLogoPath,
+ homeWelcomeCredits,
+ homeAnnouncements,
+ paysiteList,
+ headerAd,
+ middleAd,
+ footerAd,
+ sliderAd,
+ videoAd,
+ isArchiveServerEnabled,
+ apiServerBaseURL,
+ apiServerPort,
+ gitCommitHash,
+ isFileServingEnabled,
+ buildDate,
+} from "./configs/vars.mjs";
+
+export const baseConfig = defineConfig(async ({ command, mode }) => {
+ /**
+ * @type {import("vite").UserConfig}
+ */
+ const config = {
+ plugins: [
+ legacy({
+ targets: ["defaults", "not IE 11"],
+ }),
+ patchCssModules({ exportMode: "named" }),
+ ViteYaml(),
+ // TODO: remove it after settling the static files situation
+ // by using the vite option of copying public folder instead
+ viteStaticCopy({
+ structured: true,
+ targets: [
+ {
+ src: "static",
+ dest: "./",
+ },
+ ],
+ }),
+ createHtmlPlugin({
+ entry: "./src/index.tsx",
+ inject: {
+ data: {
+ title: siteName,
+ analytics: !analyticsEnabled
+ ? undefined
+ : !analyticsCode
+ ? undefined
+ : atob(analyticsCode),
+ },
+ tags: [
+ {
+ tag: "link",
+ attrs: {
+ rel: "icon",
+ href: "./static/favicon.ico",
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:type",
+ content: "website",
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:site_name",
+ content: siteName,
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:title",
+ content: siteName,
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:image",
+ content: `${kemonoSite}/static/kemono-logo.svg`,
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:image:width",
+ content: "150",
+ },
+ injectTo: "head",
+ },
+ {
+ tag: "meta",
+ attrs: {
+ name: "og:image:height",
+ content: "150",
+ },
+ injectTo: "head",
+ },
+ ],
+ },
+ }),
+ react(),
+ ],
+ define: {
+ BUNDLER_ENV_KEMONO_SITE: JSON.stringify(kemonoSite),
+ BUNDLER_ENV_SENTRY_DSN: JSON.stringify(sentryDSN),
+ BUNDLER_ENV_SITE_NAME: JSON.stringify(siteName),
+ BUNDLER_ENV_ICONS_PREPEND: JSON.stringify(iconsPrepend),
+ BUNDLER_ENV_BANNERS_PREPEND: JSON.stringify(bannersPrepend),
+ BUNDLER_ENV_THUMBNAILS_PREPEND: JSON.stringify(thumbnailsPrepend),
+ BUNDLER_ENV_ARTISTS_OR_CREATORS: JSON.stringify(artistsOrCreators),
+ BUNDLER_ENV_DISABLE_DMS: JSON.stringify(disableDMs),
+ BUNDLER_ENV_DISABLE_FAQ: JSON.stringify(disableFAQ),
+ BUNDLER_ENV_DISABLE_FILEHAUS: JSON.stringify(disableFilehaus),
+ BUNDLER_ENV_SIDEBAR_ITEMS: JSON.stringify(sidebarItems),
+ BUNDLER_ENV_FOOTER_ITEMS: JSON.stringify(footerItems),
+ BUNDLER_ENV_BANNER_GLOBAL: JSON.stringify(bannerGlobal),
+ BUNDLER_ENV_BANNER_WELCOME: JSON.stringify(bannerWelcome),
+ BUNDLER_ENV_HOME_BACKGROUND_IMAGE: JSON.stringify(homeBackgroundImage),
+ BUNDLER_ENV_HOME_MASCOT_PATH: JSON.stringify(homeMascotPath),
+ BUNDLER_ENV_HOME_LOGO_PATH: JSON.stringify(homeLogoPath),
+ BUNDLER_ENV_HOME_WELCOME_CREDITS: JSON.stringify(homeWelcomeCredits),
+ BUNDLER_ENV_HOME_ANNOUNCEMENTS: JSON.stringify(homeAnnouncements),
+ BUNDLER_ENV_PAYSITE_LIST: JSON.stringify(paysiteList),
+ BUNDLER_ENV_HEADER_AD: JSON.stringify(headerAd),
+ BUNDLER_ENV_MIDDLE_AD: JSON.stringify(middleAd),
+ BUNDLER_ENV_FOOTER_AD: JSON.stringify(footerAd),
+ BUNDLER_ENV_SLIDER_AD: JSON.stringify(sliderAd),
+ BUNDLER_ENV_VIDEO_AD: JSON.stringify(videoAd),
+ BUNDLER_ENV_IS_ARCHIVER_ENABLED: JSON.stringify(isArchiveServerEnabled),
+ BUNDLER_ENV_API_SERVER_BASE_URL: JSON.stringify(apiServerBaseURL),
+ BUNDLER_ENV_API_SERVER_PORT: JSON.stringify(apiServerPort),
+ BUNDLER_ENV_GIT_COMMIT_HASH: JSON.stringify(gitCommitHash),
+ BUNDLER_ENV_BUILD_DATE: JSON.stringify(buildDate),
+ BUNDLER_ENV_IS_FILE_SERVING_ENABLED: JSON.stringify(isFileServingEnabled),
+ },
+ };
+
+ return config;
+});
diff --git a/client/vite.dev.mjs b/client/vite.dev.mjs
new file mode 100644
index 0000000..2f72dc1
--- /dev/null
+++ b/client/vite.dev.mjs
@@ -0,0 +1,32 @@
+// @ts-check
+import { defineConfig, mergeConfig } from "vite";
+import { baseConfig } from "./vite.config.mjs";
+import {
+ apiServerBaseURL,
+ apiServerPort,
+} from "./configs/vars.mjs";
+
+const config = defineConfig(async (configEnv) => {
+ /**
+ * @type {import("vite").UserConfig}
+ */
+ const devConfig = {
+ server: {
+ host: "0.0.0.0",
+ port: 3450,
+ strictPort: true,
+ proxy: {
+ "/api": `${apiServerBaseURL}:${apiServerPort}`
+ },
+ allowedHosts: [
+ "web",
+ ],
+ },
+ };
+ const resolvedBase = await baseConfig(configEnv);
+ const finalConfig = mergeConfig(resolvedBase, devConfig);
+
+ return finalConfig;
+});
+
+export default config;
diff --git a/client/vite.prod.mjs b/client/vite.prod.mjs
new file mode 100644
index 0000000..d06f201
--- /dev/null
+++ b/client/vite.prod.mjs
@@ -0,0 +1,32 @@
+// @ts-check
+import { defineConfig, mergeConfig } from "vite";
+import { baseConfig } from "./vite.config.mjs";
+import { apiServerBaseURL, apiServerPort } from "./configs/vars.mjs";
+
+const config = defineConfig(async (configEnv) => {
+ /**
+ * @type {import("vite").UserConfig}
+ */
+ const prodConfig = {
+ preview: {
+ host: "0.0.0.0",
+ port: 5000,
+ strictPort: true,
+ proxy: {
+ "/api": `${apiServerBaseURL}:${apiServerPort}`,
+ },
+ },
+ build: {
+ cssCodeSplit: false,
+ sourcemap: true,
+ outDir: "dist",
+ emptyOutDir: true,
+ },
+ };
+ const resolvedBase = await baseConfig(configEnv);
+ const finalConfig = mergeConfig(resolvedBase, prodConfig);
+
+ return finalConfig;
+});
+
+export default config;
diff --git a/client/webpack.config.js b/client/webpack.config.js
index aa22d23..4c36536 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -9,7 +9,6 @@ const {
iconsPrepend,
bannersPrepend,
thumbnailsPrepend,
- creatorsLocation,
artistsOrCreators,
disableDMs,
disableFAQ,
@@ -34,18 +33,17 @@ const {
apiServerPort,
analyticsEnabled,
analyticsCode,
-} = require("./configs/vars");
+ gitCommitHash,
+ isFileServingEnabled,
+ buildDate,
+} = require("./configs/vars.mjs");
/**
- * TODO: make separate entries for `admin` and `moderator`
* @type import("webpack").Configuration
*/
const webpackConfig = {
entry: {
index: "./src/index.tsx",
- // global: path.join(projectPath, "js", "global.js"),
- // admin: path.join(projectPath, "js", "admin.js"),
- // moderator: path.join(projectPath, "js", "moderator.js"),
},
plugins: [
// ...pagePlugins,
@@ -79,7 +77,6 @@ const webpackConfig = {
BUNDLER_ENV_ICONS_PREPEND: JSON.stringify(iconsPrepend),
BUNDLER_ENV_BANNERS_PREPEND: JSON.stringify(bannersPrepend),
BUNDLER_ENV_THUMBNAILS_PREPEND: JSON.stringify(thumbnailsPrepend),
- BUNDLER_ENV_CREATORS_LOCATION: JSON.stringify(creatorsLocation),
BUNDLER_ENV_ARTISTS_OR_CREATORS: JSON.stringify(artistsOrCreators),
BUNDLER_ENV_DISABLE_DMS: JSON.stringify(disableDMs),
BUNDLER_ENV_DISABLE_FAQ: JSON.stringify(disableFAQ),
@@ -102,6 +99,9 @@ const webpackConfig = {
BUNDLER_ENV_IS_ARCHIVER_ENABLED: JSON.stringify(isArchiveServerEnabled),
BUNDLER_ENV_API_SERVER_BASE_URL: JSON.stringify(apiServerBaseURL),
BUNDLER_ENV_API_SERVER_PORT: JSON.stringify(apiServerPort),
+ BUNDLER_ENV_GIT_COMMIT_HASH: JSON.stringify(gitCommitHash),
+ BUNDLER_ENV_BUILD_DATE: JSON.stringify(buildDate),
+ BUNDLER_ENV_IS_FILE_SERVING_ENABLED: JSON.stringify(isFileServingEnabled),
}),
new CopyWebpackPlugin({
patterns: [
diff --git a/client/webpack.dev.js b/client/webpack.dev.js
index 9ccbdf4..7805591 100644
--- a/client/webpack.dev.js
+++ b/client/webpack.dev.js
@@ -2,8 +2,12 @@
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const { merge } = require("webpack-merge");
-const yaml = require("yaml")
-const { kemonoSite, apiServerBaseURL, apiServerPort } = require("./configs/vars");
+const yaml = require("yaml");
+const {
+ kemonoSite,
+ apiServerBaseURL,
+ apiServerPort,
+} = require("./configs/vars.mjs");
const baseConfig = require("./webpack.config");
const projectPath = path.resolve(__dirname, "src");
@@ -14,10 +18,12 @@ const projectPath = path.resolve(__dirname, "src");
const devServer = {
host: "0.0.0.0",
port: 3450,
- proxy: {
- context: ['/api'],
- target: `${apiServerBaseURL}:${apiServerPort}`,
- },
+ proxy: [
+ {
+ context: ["/api"],
+ target: `${apiServerBaseURL}:${apiServerPort}`,
+ },
+ ],
static: {
directory: path.resolve(__dirname, "static"),
watch: true,
@@ -61,7 +67,7 @@ const webpackConfigDev = {
{
test: /\.s[ac]ss$/i,
use: [
- MiniCssExtractPlugin.loader,
+ "style-loader",
{
loader: "css-loader",
options: {
@@ -96,7 +102,7 @@ const webpackConfigDev = {
},
{
test: /\.yaml$/i,
- type: 'json',
+ type: "json",
parser: {
parse: yaml.parse,
},
@@ -108,7 +114,6 @@ const webpackConfigDev = {
filename: "static/bundle/js/[name].bundle.js",
assetModuleFilename: "static/bundle/assets/[name][ext][query]",
publicPath: "/",
- clean: true,
},
};
diff --git a/db/migrations/20250328_01_KV3ap-add-reason-to-flags.py b/db/migrations/20250328_01_KV3ap-add-reason-to-flags.py
new file mode 100644
index 0000000..75ed32d
--- /dev/null
+++ b/db/migrations/20250328_01_KV3ap-add-reason-to-flags.py
@@ -0,0 +1,31 @@
+"""
+Create new post_flags table.
+"""
+
+from yoyo import step
+
+__depends__ = {"20241110_00_DASAD-add-favorite-counts-table"}
+
+steps = [
+ step("""
+ CREATE TABLE "public"."post_flags" (
+ "post_id" TEXT NOT NULL,
+ "creator_id" TEXT NOT NULL,
+ "service" TEXT NOT NULL,
+ "contributor_id" int4 NOT NULL,
+ "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "reason" int2 NOT NULL,
+ "reason_text" TEXT,
+ "flagger_ip_hash" UUID,
+ CONSTRAINT "post_flags_pk" PRIMARY KEY ("post_id", "creator_id", "service", "contributor_id")
+ );
+ """, 'DROP TABLE "public"."post_flags"'),
+ step(
+ """CREATE INDEX "idx_post_flags_on_contributor_id_and_created_at" ON "post_flags" ("contributor_id", "created_at");""",
+ """DROP INDEX "idx_post_flags_on_contributor_id_and_created_at";"""
+ ),
+ step(
+ """CREATE INDEX "idx_post_flags_on_ip_hash_and_created_at" ON "post_flags" ("flagger_ip_hash", "created_at");""",
+ """DROP INDEX "idx_post_flags_on_ip_hash_and_created_at";"""
+ ),
+]
diff --git a/docs/FAQ.md b/docs/FAQ.md
index ce4c37a..62f7484 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -1,75 +1,5 @@
# Frequently Asked Questions
-## My dump doesn't migrate.
-
-_This assumes a running setup._
-
-1. Enter into database container:
-
- ```sh
- docker exec \
- --interactive \
- --username=nano \
- --tty kemono-db psql \
- kemonodb
- ```
-
-2. Check the contents of the `posts` table.
-
- ```sql
- SELECT * FROM posts;
- ```
-
- _Most likely it has `0` rows._
-
-3. Move contents of `booru_posts` ➞ `posts`
-
- ```sql
- INSERT INTO posts SELECT * FROM booru_posts ON CONFLICT DO NOTHING;
- ```
-
-4. Restart the archiver.
-
- ```sh
- docker restart kemono-archiver
- ```
-
- If you see a bunch of log entries from `kemono-db` ,
- then this indicates that the archiver is doing it's job.
-
-5. In case the frontend still doesn't show
- the artists / posts, clear the redis cache.
-
- ```sh
- docker exec \
- kemono-redis \
- redis-cli \
- FLUSHALL
- ```
-
-## How do I import from db dump?
-
-1. Retrieve a database dump.
-
-2. Run the following in the folder of said dump.
-
- ```sh
- cat db-filename.dump \
- | gunzip \
- | docker exec \
- --interactive kemono-db psql \
- --username=nano kemonodb
- ```
-
-3. Restart the archiver to trigger migrations.
-
- ```sh
- docker restart kemono-archiver
- ```
-
- If that didn't start the migrations, refer
- to [My Dump Doesn't Migrate](#my-dump-doesnt-migrate) section.
-
## How do I put files into nginx container?
1. Retrieve the files in required folder structure.
diff --git a/docs/develop.md b/docs/develop.md
index e3619c1..1976c1f 100644
--- a/docs/develop.md
+++ b/docs/develop.md
@@ -7,7 +7,7 @@ the IDE setup.
## Requirements:
Python: 3.12+
-NodeJS: 18+
+NodeJS: 18.20+
## Installation
diff --git a/docs/features/accounts.md b/docs/features/accounts.md
index 8d0d4fc..9d347b2 100644
--- a/docs/features/accounts.md
+++ b/docs/features/accounts.md
@@ -3,7 +3,6 @@
## Table of contents
- [General Description](#general-description)
-- [Issues](#issues)
## General Description
@@ -26,5 +25,3 @@ The first registered account of the instance gets this role. Administrator can c
#### Session Key Management
Accounts can access the page which lists all keys set up for autoimport and revoke any of them.
-
-## Issues
diff --git a/docs/projects/_index.md b/docs/projects/_index.md
deleted file mode 100644
index d9efcad..0000000
--- a/docs/projects/_index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Projects
-
-- [Moderation system](./moderation-system.md)
diff --git a/docs/projects/favorites1dot5.md b/docs/projects/favorites1dot5.md
deleted file mode 100644
index afea33d..0000000
--- a/docs/projects/favorites1dot5.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Favorites V1.5
-
-## Table of contents
-
-- [General Description](#general-description)
-- [Interfaces](#interfaces)
-- [Technical Description](#technical-description)
-- [Issues](#issues)
-
-## General Description
-
-## Interfaces
-
-### SQL
-
-## Technical Description
-
-## Issues
diff --git a/docs/projects/file-upload.md b/docs/projects/file-upload.md
deleted file mode 100644
index 40119b9..0000000
--- a/docs/projects/file-upload.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# File Upload
-
-## Table of contents
-
-- [Interfaces](#interfaces)
-- [Core information](#core-information)
-- [Process](#process)
-- [Issues](#issues)
-
-## Interfaces
-
-```typescript
-interface ManualUpload {}
-```
-
-## Core information
-
-## Process
-
-1. The account goes to `/posts/upload`.
-2. Uploads the file.
-3. The file gets processed.
-4. The file gets sent for review to a moderator.
-5. The moderator then decides to discard the upload or approve for public view.
-6. ...
-
-## Issues
-
-- What happens when one mod approves a file while the other one discards it?
-- Unlike DMs the file verification can take very variable amount of time, so there should be separate states for a given upload, like `"pending"`,`"approved"`,`"rejected"`.
diff --git a/docs/projects/moderation-system.md b/docs/projects/moderation-system.md
deleted file mode 100644
index 7a23482..0000000
--- a/docs/projects/moderation-system.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Moderation System
-
-## Table of contents
-
-- [General Description](#general-description)
-- [Interfaces](#interfaces)
-- [Technical Description](#technical-description)
-- [Process](#process)
-- [Issues](#issues)
-
-## General Description
-
-The moderation system allows certain users ("moderators") chosen by the administrator user to perform various tasks.
-
-## Interfaces
-
-```typescript
-interface Action {
- id: string;
- account_id: string;
- type: string;
- categories: string[];
- /**
- * A list of resource `id`s affected by the action.
- */
- entity_ids: string[];
- status: "completed" | "failed" | "reverted";
- created_at: Date;
-}
-```
-
-## Technical Description
-
-## Process
-
-### Moderator
-
-1. When the role of an account changes to `moderator`, the account gets notified of this.
-1. The account then can access `/mod` endpoint, which leads to the moderator dashboard. On this page the mod can see various stats, among them is the list of various `tasks`.
-1. Each performed `task` results in an `action`.
-
-## Issues
diff --git a/docs/templates/feature-template.md b/docs/templates/feature-template.md
deleted file mode 100644
index 7ff85ef..0000000
--- a/docs/templates/feature-template.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Title
-
-## Table of contents
-
-- [General Description](#general-description)
-- [Issues](#issues)
-
-## General Description
-
-## Issues
diff --git a/docs/templates/project-template.md b/docs/templates/project-template.md
deleted file mode 100644
index 8cba19d..0000000
--- a/docs/templates/project-template.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Title
-
-## Table of contents
-
-- [General Description](#general-description)
-- [Interfaces](#interfaces)
-- [Technical Description](#technical-description)
-- [Issues](#issues)
-
-## General Description
-
-## Interfaces
-
-## Technical Description
-
-## Issues
diff --git a/docs/todos.md b/docs/todos.md
deleted file mode 100644
index 972d0ca..0000000
--- a/docs/todos.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# TODOs
-
-## Server
-
-## Archiver
-
-- Make dev file import work
-
-## Client
-
-### Webpack
-
-- SASS uses its own module name resolution mechanism which differs from the current webpack setup. Specifically `config.resolve.alias` rules will not apply to filenames in `@use "";` expression.
-- Figure out how to pass env variables to stylesheets.
-- Figure out how to set up source maps for production.
-
-### HTML/Templates
-
-- Find a way to nest macro calls.
-
-#### `user.html`
-
-- AJAX search.
-
-#### `import` pages
-
-- consolidate them into a single page, since most of them are just placeholders for AJAX scripts.
-
-### CSS
-
-### JS
diff --git a/nginx.conf b/nginx.conf
index 2e58f2c..4717115 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -32,18 +32,27 @@ http {
root /storage;
client_max_body_size 100m;
+ location @kemono {
+ proxy_pass http://web:3450;
+ }
+
+ location @api {
+ proxy_pass http://api:3449;
+ }
+
location ~ "^/archive_files/([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{60})\.(.*)" {
proxy_pass http://foobar:5000/extract/data/$1/$2/$1$2$3.$4$is_args$args;
}
+ location /api {
+ try_files /dev/null @api;
+ }
+
location / {
try_files $uri @kemono;
if ($arg_f) {
add_header Content-Disposition "inline; filename=$arg_f";
}
}
- location @kemono {
- proxy_pass http://web;
- }
}
}
diff --git a/requirements.txt b/requirements.txt
index c067f94..edd66eb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,6 +4,7 @@ nh3==0.2.15
cloudscraper==1.2.71
Flask==2.3.2
humanize==4.8.0
+jsonschema==4.23.0
murmurhash2==0.2.10
pre-commit==3.7.0
psycopg[binary,pool]>=3.1.10
@@ -15,6 +16,7 @@ requests==2.31.0
httpx[http2,socks]==0.25.2
retry==0.9.2
sentry-sdk[flask]==1.29.2
+setuptools==75.8.0
orjson==3.9.15
uWSGI==2.0.24; platform_system != "Windows"
pyyaml==6.0.1
diff --git a/schema/config.schema.json b/schema/config.schema.json
new file mode 100644
index 0000000..e94e2f6
--- /dev/null
+++ b/schema/config.schema.json
@@ -0,0 +1,630 @@
+{
+ "$id": "configuration",
+ "title": "Configuration",
+ "description": "Configuration for Kemono.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["site", "development_mode", "automatic_migrations", "webserver"],
+ "properties": {
+ "site": {
+ "description": "Deprecated in favour of `#/webserver/site`.",
+ "$comment": "`$deprecated` keyword was in introduced in draft `2019-09`, so just using `description` field instead.",
+ "type": "string"
+ },
+ "development_mode": {
+ "type": "boolean"
+ },
+ "automatic_migrations": {
+ "type": "boolean"
+ },
+ "sentry_dsn": {
+ "type": "string"
+ },
+ "sentry_dsn_js": {
+ "type": "string"
+ },
+ "open_telemetry_endpoint": {
+ "type": "null"
+ },
+ "ban_url": {
+ "description": "Kemono3 `BAN` URL prefix for cache purging.",
+ "anyOf": [
+ { "type": "string" },
+ { "type": "array", "items": { "type": "string" } }
+ ]
+ },
+ "enable_notifications": {
+ "type": "boolean"
+ },
+ "cache_ttl_for_recent_posts": {
+ "type": "integer"
+ },
+ "webserver": {
+ "$ref": "#/definitions/webserver"
+ },
+ "database": {
+ "$ref": "#/definitions/database"
+ },
+ "redis": {
+ "$ref": "#/definitions/redis"
+ },
+ "archive_server": {
+ "$ref": "#/definitions/archive-server"
+ },
+ "filehaus": {
+ "$ref": "#/definitions/filehaus"
+ }
+ },
+ "definitions": {
+ "webserver": {
+ "description": "Configuration for the frontend server.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["secret", "port", "ui"],
+ "properties": {
+ "secret": {
+ "description": "Secret key used to encrypt sessions.",
+ "type": "string"
+ },
+ "workers": {
+ "description": "Amount of workers to run at once.",
+ "type": "integer"
+ },
+ "harakiri": {
+ "$comment": "This one isn't used by server code.",
+ "type": "integer"
+ },
+ "threads": {
+ "description": "Amount of thread to run at once.",
+ "type": "integer"
+ },
+ "ip_security": {
+ "description": "If you've dealt with how the trust of forwarding IPs works upstream, flip this off.",
+ "type": "boolean"
+ },
+ "country_header_key": {
+ "description": "Header for user country iso, generater by DDOS-GUARD.",
+ "anyOf": [{ "type": "string" }, { "const": "DDG-Connecting-Country" }]
+ },
+ "uwsgi_options": {
+ "$ref": "#/definitions/uwsgi-options"
+ },
+ "logging": {
+ "description": "Logging mode.",
+ "enum": ["DEBUG", "ERROR"]
+ },
+ "site": {
+ "description": "The URL at which the site is publicly accessible.",
+ "type": "string"
+ },
+ "static_folder": {
+ "description": "The location of the resources that will be served.",
+ "type": "string"
+ },
+ "template_folder": {
+ "type": "string"
+ },
+ "jinja_bytecode_cache_path": {
+ "type": "null"
+ },
+ "max_full_text_search_input_len": {
+ "type": "integer"
+ },
+ "table_sample_bernoulli_sample_size": {
+ "type": "number"
+ },
+ "extra_pages_to_load_on_posts": {
+ "type": "integer"
+ },
+ "pages_in_popular": {
+ "type": "integer"
+ },
+ "earliest_date_for_popular": {
+ "type": "string"
+ },
+ "use_redis_by_lock_default_on_queries": {
+ "type": "boolean"
+ },
+ "api": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "creators_location": {
+ "type": "string"
+ }
+ }
+ },
+ "base_url": {
+ "type": "string"
+ },
+ "port": {
+ "description": "The port the site will be served on.",
+ "type": "integer"
+ },
+ "ui": {
+ "$ref": "#/definitions/ui"
+ }
+ }
+ },
+ "ui": {
+ "description": "Interface preferences and customization options.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["home", "config"],
+ "properties": {
+ "home": {
+ "$ref": "#/definitions/ui-home"
+ },
+ "config": {
+ "$ref": "#/definitions/ui-config"
+ },
+ "fileservers": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ { "type": "string" },
+ { "anyOf": [{ "type": "integer" }, { "type": "string" }] }
+ ]
+ }
+ },
+ "sidebar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable_filehaus": {
+ "type": "boolean"
+ },
+ "disable_faq": {
+ "type": "boolean"
+ },
+ "disable_dms": {
+ "type": "boolean"
+ }
+ }
+ },
+ "sidebar_items": {
+ "description": "Add custom links to the bottom of the sidebar.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["text"],
+ "properties": {
+ "header": { "type": "boolean" },
+ "text": { "type": "string" },
+ "class_name": { "type": "string" },
+ "link": { "type": "string" },
+ "is_external": { "type": "boolean" },
+ "color": { "type": "string" }
+ }
+ }
+ },
+ "footer_items": {
+ "description": "Add custom HTML elements to the footer.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "banner": {
+ "description": "Banner HTML. Each entry should be Base64-encoded.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "global": {
+ "description": "B64-encoded html fragment.",
+ "type": "string"
+ },
+ "welcome": {
+ "description": "B64-encoded html fragment.",
+ "type": "string"
+ }
+ }
+ },
+ "ads": {
+ "$ref": "#/definitions/ui-ads"
+ },
+ "matomo": {
+ "$ref": "#/definitions/matomo"
+ },
+ "video_extensions": {
+ "description": "File extensions recognized as (browser-friendly) video. Will automatically be embedded in post pages.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "enum": [".mp4", ".webm", ".m4v", ".3gp", ".mov"]
+ }
+ },
+ "files_url_prepend": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "icons_base_url": {
+ "type": "string"
+ },
+ "banners_base_url": {
+ "type": "string"
+ },
+ "thumbnails_base_url": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "ui-home": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "site_name": { "type": "string" },
+ "welcome_credits": {
+ "description": "B64-encoded html fragment.",
+ "type": "string"
+ },
+ "home_background_image": {
+ "description": "A path to background image on server.",
+ "type": "string"
+ },
+ "logo_path": {
+ "type": "string"
+ },
+ "mascot_path": {
+ "type": "string"
+ },
+ "announcements": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "title": { "type": "string" },
+ "date": { "type": "string" },
+ "content": { "type": "string" }
+ }
+ }
+ }
+ }
+ },
+ "ui-config": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["paysite_list"],
+ "properties": {
+ "paysite_list": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "enum": [
+ "patreon",
+ "fanbox",
+ "afdian",
+ "discord",
+ "fantia",
+ "boosty",
+ "gumroad",
+ "subscribestar",
+ "dlsite",
+ "candfans",
+ "fansly",
+ "onlyfans"
+ ]
+ }
+ },
+ "artists_or_creators": {
+ "type": "string"
+ }
+ }
+ },
+ "ui-ads": {
+ "description": "Ads preferences. Each spot should be Base64-encoded.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "header": {
+ "description": "Base64-encoded html fragment.",
+ "type": "string"
+ },
+ "middle": {
+ "description": "Base64-encoded html fragment.",
+ "type": "string"
+ },
+ "footer": {
+ "description": "Base64-encoded html fragment.",
+ "type": "string"
+ },
+ "slider": {
+ "description": "Base64-encoded html fragment.",
+ "type": "string"
+ },
+ "video": {
+ "description": "Base64-encoded JSON list of objects.\nSee https://docs.fluidplayer.com/docs/configuration/ads/#adlist .",
+ "type": "string"
+ }
+ }
+ },
+ "matomo": {
+ "description": "Matomo preferences.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled": { "type": "boolean" },
+ "tracking_domain": {
+ "type": "string"
+ },
+ "tracking_code": {
+ "type": "string"
+ },
+ "site_id": {
+ "type": "integer"
+ },
+ "plain_code": {
+ "description": "Base64-encoded html fragment.",
+ "type": "string"
+ }
+ }
+ },
+ "database": {
+ "description": "Database configuration.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["host", "user", "password", "database"],
+ "properties": {
+ "host": { "type": "string" },
+ "port": { "type": "integer" },
+ "user": { "type": "string" },
+ "password": { "type": "string" },
+ "database": { "type": "string" },
+ "application_name": { "type": "string" }
+ }
+ },
+ "redis": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["defaults"],
+ "properties": {
+ "defaults": { "$ref": "#/definitions/redis-defaults" },
+ "compression": { "type": "string" },
+ "default_ttl": { "type": "string" },
+ "node_options": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "host": {
+ "type": "string"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "db": {
+ "type": "integer"
+ },
+ "password": {
+ "type": "string"
+ }
+ }
+ },
+ "nodes": {
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": { "type": "string" }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "port": {
+ "type": "integer"
+ },
+ "db": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "keyspaces": {
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/redis-keyspaces"
+ },
+ "additionalProperties": {
+ "type": "integer"
+ }
+ }
+ }
+ },
+ "redis-defaults": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["host"],
+ "properties": {
+ "host": {
+ "type": "string"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "db": {
+ "type": "integer"
+ }
+ }
+ },
+ "redis-keyspaces": {
+ "enum": [
+ "account",
+ "saved_key_import_ids",
+ "saved_keys",
+ "random_artist_keys",
+ "top_artists",
+ "artists_by_update_time",
+ "artists_faved",
+ "artists_faved_count",
+ "artists_recently_faved_count",
+ "top_artists_recently",
+ "non_discord_artist_keys",
+ "non_discord_artists",
+ "artists_by_service",
+ "artist",
+ "artist_post_count",
+ "artist_post_offset",
+ "artist_last_updated",
+ "artist_favorited",
+ "dms",
+ "all_dms",
+ "all_dms_count",
+ "all_dms_by_query",
+ "all_dms_by_query_count",
+ "dms_count",
+ "unapproved_dms",
+ "favorite_artists",
+ "favorite_posts",
+ "notifications_for_account",
+ "random_post_keys",
+ "post",
+ "next_post",
+ "previous_post",
+ "posts_incomplete_rewards",
+ "post_favorited",
+ "posts_by_artist",
+ "posts_by_artists",
+ "posts_by_favorited_artists",
+ "comments",
+ "artist_posts_offset",
+ "is_post_flagged",
+ "importer_logs",
+ "ratelimit",
+ "all_posts",
+ "all_post_keys",
+ "all_shares",
+ "all_shares_count",
+ "all_posts_for_query",
+ "global_post_count",
+ "global_post_count_for_query",
+ "lock",
+ "lock-signal",
+ "imports",
+ "share_files",
+ "account_notifications",
+ "new_notifications",
+ "share",
+ "artist_shares",
+ "post_revisions",
+ "post_revision",
+ "files",
+ "post_by_id",
+ "fancards",
+ "announcements",
+ "announcement_count",
+ "artist_share_count",
+ "discord_channels_for_server",
+ "discord_posts",
+ "popular_posts",
+ "tagged_posts",
+ "tags",
+ "file",
+ "archive_files",
+ "linked_accounts",
+ "running_imports"
+ ]
+ },
+ "archive-server": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "api_url": {
+ "type": "string"
+ },
+ "serve_files": {
+ "type": "boolean"
+ },
+ "file_serving_enabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "filehaus": {
+ "description": "Filehaus configuration.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "requires_account": {
+ "description": "If true, an account will be required for uploading.",
+ "type": "boolean"
+ },
+ "required_roles": {
+ "description": "Required account roles for uploading. If set to an empty list, no permissions will be required.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "enum": ["administrator", "moderator", "uploader"]
+ }
+ },
+ "tus": {
+ "description": "`tusd` configuration.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "manage": {
+ "description": "Automatically manage `tusd` on port 1080. If you intend to store uploads on a different server from Kemono3, set a custom URL instead...",
+ "type": "boolean"
+ },
+ "url": {
+ "description": "...right here. Note that if you do not allow automatic management and did not set a custom URL, uploads will be blackholed to a demo instance and Filehaus sharing will not function correctly.\nDo note that using `tusd` instances to enable Filehaus functionality requires the `post-create` hook to be pointed at Kemono's `/shares/tus` endpoint.\n`tusd --hooks-enabled-events post-create -hooks-http \"http://127.0.0.1:6942/shares/tus\" -upload-dir=./data`",
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "uwsgi-options": {
+ "description": "Set additional uWSGI options if you want. Overrides any of the other options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cheaper-algo": {
+ "enum": ["busyness"]
+ },
+ "cheaper": {
+ "type": "integer"
+ },
+ "cheaper-initial": {
+ "type": "integer"
+ },
+ "cheaper-overload": {
+ "type": "integer"
+ },
+ "cheaper-step": {
+ "type": "integer"
+ },
+ "cheaper-busyness-multiplier": {
+ "type": "integer"
+ },
+ "cheaper-busyness-min": {
+ "type": "integer"
+ },
+ "cheaper-busyness-max": {
+ "type": "integer"
+ },
+ "cheaper-busyness-backlog-alert": {
+ "type": "integer"
+ },
+ "cheaper-busyness-backlog-step": {
+ "type": "integer"
+ },
+ "disable-logging": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+}
diff --git a/schema/config.ts b/schema/config.ts
new file mode 100644
index 0000000..8f92303
--- /dev/null
+++ b/schema/config.ts
@@ -0,0 +1,98 @@
+export interface IConfiguration {
+ site: string;
+ sentry_dsn_js?: string;
+ development_mode: boolean;
+ automatic_migrations: boolean;
+ webserver: IServerConfig;
+ archive_server?: IArchiveServerConfig;
+}
+
+interface IServerConfig {
+ ui: IUIConfig;
+ port: number;
+ base_url?: string;
+}
+
+interface IUIConfig {
+ home: IHomeConfig;
+ config: { paysite_list: string[]; artists_or_creators: string };
+ matomo?: IMatomoConfig;
+ sidebar?: ISidebarConfig;
+ sidebar_items: unknown[];
+ footer_items?: unknown[];
+ banner?: IBannerConfig;
+ ads?: IAdsConfig;
+ files_url_prepend?: {
+ icons_base_url?: string;
+ banners_base_url?: string;
+ thumbnails_base_url?: string;
+ };
+}
+
+interface IMatomoConfig {
+ enabled: boolean;
+ /**
+ * b64-encoded string
+ */
+ plain_code: string;
+ tracking_domain: string;
+ tracking_code: string;
+ site_id: string;
+}
+
+interface ISidebarConfig {
+ disable_dms?: boolean;
+ disable_faq?: boolean;
+ disable_filehaus?: boolean;
+}
+
+interface IBannerConfig {
+ /**
+ * b64-encoded string
+ */
+ global?: string;
+ /**
+ * b64-encoded string
+ */
+ welcome?: string;
+}
+
+interface IHomeConfig {
+ site_name?: string;
+ mascot_path?: string;
+ logo_path?: string;
+ /**
+ * b64-encoded string
+ */
+ welcome_credits?: string;
+ home_background_image?: string;
+ announcements?: { title: string; date: string; content: string }[];
+}
+
+interface IAdsConfig {
+ /**
+ * b64-encoded string
+ */
+ header: string;
+ /**
+ * b64-encoded string
+ */
+ middle: string;
+ /**
+ * b64-encoded string
+ */
+ footer: string;
+ /**
+ * b64-encoded string
+ */
+ slider: string;
+ /**
+ * Base64-encoded JSON list of objects.
+ */
+ video: string;
+}
+
+interface IArchiveServerConfig {
+ enabled?: boolean;
+ file_serving_enabled?: boolean
+}
diff --git a/src/pages/api/schema.yaml b/schema/public/api.yaml
similarity index 86%
rename from src/pages/api/schema.yaml
rename to schema/public/api.yaml
index 5a26b76..87fd959 100644
--- a/src/pages/api/schema.yaml
+++ b/schema/public/api.yaml
@@ -1,12 +1,12 @@
openapi: 3.1.0
info:
title: Kemono API
- version: 1.1.0
+ version: 1.3.0
contact:
email: contact@kemono.party
servers:
- - url: https://kemono.su/api/v1
- - url: https://coomer.su/api/v1
+ - url: https://kemono.su/api
+ - url: https://coomer.su/api
tags:
- name: Posts
description: Version one
@@ -19,7 +19,353 @@ tags:
- name: File Search
- name: Misc
paths:
- /creators.txt:
+ /v2/file/{file_hash}:
+ get:
+ description: Overview of the file.
+ parameters:
+ - name: file_hash
+ in: path
+ description: Hash of the file.
+ required: true
+ schema:
+ $ref: "#/components/schemas/hash-sha256"
+ responses:
+ '200':
+ description: Successfully retrieved file details.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ $ref: "#/components/schemas/archive-info"
+ '400':
+ description: There are errors in parameters.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: File does not exist.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ patch:
+ description: Add password to a file if needed
+ parameters:
+ - name: file_hash
+ in: path
+ description: Hash of the file.
+ required: true
+ schema:
+ $ref: "#/components/schemas/hash-sha256"
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/request-body-with-data"
+ - type: object
+ properties:
+ data:
+ type: object
+ required:
+ - password
+ additionalPropeties: false
+ properties:
+ password:
+ type: string
+ minLength: 1
+ responses:
+ '200':
+ description: Successfully added a correct password.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ description: Hash of the file which got updated.
+ $ref: "#/components/schemas/hash-sha256"
+ '400':
+ description: There are errors in parameters or the body.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ /v2/account/flags/post:
+ put:
+ description: Flag the post for reimport.
+ security:
+ - cookieAuth: [ ]
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/request-body-with-data"
+ - type: object
+ properties:
+ data:
+ type: object
+ required:
+ - service
+ - profile_id
+ - post_id
+ additionalPropeties: false
+ properties:
+ service:
+ type: string
+ profile_id:
+ type: string
+ post_id:
+ type: string
+ responses:
+ '201':
+ description: Successfully flagged the post.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ type: object
+ description: Data of flagged post.
+ required:
+ - service
+ - profile_id
+ - post_id
+ properties:
+ service:
+ type: string
+ profile_id:
+ type: string
+ post_id:
+ type: string
+ '400':
+ description: Request body has errors.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: Post doesn't exist.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '409':
+ description: Post is already flagged.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ /v2/account/administrator/accounts:
+ get:
+ description: Get account count.
+ security:
+ - cookieAuth: [ ]
+ parameters:
+ - name: name
+ in: query
+ description: Filter by name
+ schema:
+ type: string
+ - name: role
+ in: query
+ description: Filter by role
+ schema:
+ type: string
+ responses:
+ '200':
+ description: Successfully counted accounts.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ $ref: "#/components/schemas/non-negative-integer"
+ '401':
+ description: User not logged in.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: User is not administrator.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ /v2/account/administrator/accounts/{page}:
+ get:
+ description: Get accounts at page.
+ security:
+ - cookieAuth: [ ]
+ parameters:
+ - $ref: "#/components/parameters/path-page"
+ - name: name
+ in: query
+ description: Filter by name
+ schema:
+ type: string
+ - name: role
+ in: query
+ description: Filter by role
+ schema:
+ type: string
+ responses:
+ '200':
+ description: Successfully gotten accounts at page.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: "#/components/schemas/account"
+ '400':
+ description: There are errors in parameters.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '401':
+ description: User not logged in.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: User is not administrator.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ /v2/account/administrator/account/{account_id}:
+ get:
+ description: Overview of target account.
+ security:
+ - cookieAuth: [ ]
+ parameters:
+ - name: account_id
+ in: path
+ description: ID of the account.
+ required: true
+ schema:
+ $ref: "#/components/schemas/positive-integer"
+ responses:
+ '200':
+ description: Successfully retrieved target account details.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ $ref: "#/components/schemas/account"
+ '400':
+ description: There are errors in parameters.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '401':
+ description: User not logged in.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: User is not administrator or account doesn't exist.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ patch:
+ description: Change target account details.
+ security:
+ - cookieAuth: [ ]
+ parameters:
+ - name: account_id
+ in: path
+ description: ID of the account.
+ required: true
+ schema:
+ $ref: "#/components/schemas/positive-integer"
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/request-body-with-data"
+ - type: object
+ properties:
+ data:
+ type: object
+ required:
+ - role
+ additionalPropeties: false
+ properties:
+ role:
+ type: string
+ responses:
+ '200':
+ description: Successfully changed target account details.
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/response-body-success"
+ - type: object
+ properties:
+ data:
+ description: ID of account which got updated.
+ $ref: "#/components/schemas/positive-integer"
+ '400':
+ description: There are errors in parameters or in the body.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '401':
+ description: Admin account is not logged in.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '404':
+ description: Admin account is not administrator or target account doesn't exist.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ '409':
+ description: Failed to update target account due to a conflict.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/response-body-error"
+ /v1/creators.txt:
get:
tags:
- Posts
@@ -60,7 +406,7 @@ paths:
name: RAIGYO
service: fanbox
updated: 1672534800
- /posts:
+ /v1/posts:
get:
tags:
- Posts
@@ -174,7 +520,7 @@ paths:
path: /d7/4d/d74d1727f2c3fcf7a7cc2d244d677d93b4cc562a56904765e4e708523b34fb4c.png
- name: ab0e17d7-52e5-42c2-925b-5cfdb451df0c.png
path: /1b/67/1b677a8c0525e386bf2b2f013e36e29e4033feb2308798e4e5e3780da6c0e815.png
- /posts/random:
+ /v1/posts/random:
get:
description: Get a random post
responses:
@@ -197,7 +543,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /posts/popular:
+ /v1/posts/popular:
get:
description: Get popular posts
parameters:
@@ -318,7 +664,7 @@ paths:
type: array
items:
type: boolean
- /posts/tags:
+ /v1/posts/tags:
get:
description: Get tags
responses:
@@ -338,28 +684,7 @@ paths:
type: array
items:
$ref: "#/components/schemas/tag"
- /posts/archives/{file_hash}:
- get:
- description: Get archive file contents
- parameters:
- - name: file_hash
- in: path
- required: true
- schema:
- type: string
- responses:
- '200':
- description: Archive file contents.
- content:
- application/json:
- schema:
- type: object
- properties:
- archive:
- $ref: "#/components/schemas/archive-info"
- file_serving_enabled:
- type: boolean
- /{service}/post/{post_id}:
+ /v1/{service}/post/{post_id}:
get:
description: Get a post by ID
parameters:
@@ -385,7 +710,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /{service}/user/{creator_id}/profile:
+ /v1/{service}/user/{creator_id}/profile:
get:
summary: Get a creator
tags:
@@ -444,7 +769,7 @@ paths:
type: string
description: The error message
enum: ["Creator not found."]
- /{service}/user/{creator_id}:
+ /v1/{service}/user/{creator_id}:
get:
summary: Get a list of creator posts
tags:
@@ -568,7 +893,7 @@ paths:
type: string
description: The error message
enum: ["Creator not found."]
- /{service}/user/{creator_id}/announcements:
+ /v1/{service}/user/{creator_id}/announcements:
get:
summary: Get creator announcements
tags:
@@ -617,7 +942,7 @@ paths:
added: '2023-01-31T05:16:15.462035'
'404':
description: Artist not found
- /{service}/user/{creator_id}/fancards:
+ /v1/{service}/user/{creator_id}/fancards:
get:
summary: Get fancards by creator, fanbox only
tags:
@@ -699,7 +1024,7 @@ paths:
ihash: null
'404':
description: Artist not found
- /{service}/user/{creator_id}/links:
+ /v1/{service}/user/{creator_id}/links:
get:
summary: Get a creator's linked accounts
tags:
@@ -778,7 +1103,7 @@ paths:
plain/text:
schema:
const: ""
- /{service}/user/{creator_id}/links/new:
+ /v1/{service}/user/{creator_id}/links/new:
get:
description: Add links to the artist
parameters:
@@ -886,7 +1211,7 @@ paths:
properties:
error:
type: text
- /{service}/user/{creator_id}/tags:
+ /v1/{service}/user/{creator_id}/tags:
get:
description: Tags of profile
tags:
@@ -931,7 +1256,7 @@ paths:
type: string
artist:
$ref: "#/components/schemas/artist"
- /{service}/user/{creator_id}/shares:
+ /v1/{service}/user/{creator_id}/shares:
get:
description: Shares of the artist
parameters:
@@ -979,7 +1304,7 @@ paths:
type: string
artist_id:
type: string
- /{service}/user/{creator_id}/dms:
+ /v1/{service}/user/{creator_id}/dms:
get:
description: Direct messages of profile
parameters:
@@ -1019,7 +1344,7 @@ paths:
enum:
- ✔️
- "0"
- /{service}/user/{creator_id}/posts-legacy:
+ /v1/{service}/user/{creator_id}/posts-legacy:
get:
description: A duct-tape endpoint which also returns count for pagination component.
parameters:
@@ -1098,7 +1423,7 @@ paths:
type: boolean
disable_service_icons:
const: true
- /{service}/user/{creator_id}/post/{post_id}:
+ /v1/{service}/user/{creator_id}/post/{post_id}:
get:
summary: Get a specific post
tags:
@@ -1213,7 +1538,7 @@ paths:
prev: '1836649'
'404':
description: Post not found
- /{service}/user/{creator_id}/post/{post_id}/revision/{revision_id}:
+ /v1/{service}/user/{creator_id}/post/{post_id}/revision/{revision_id}:
get:
description: Get revision of a post
parameters:
@@ -1269,7 +1594,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /discord/channel/{channel_id}:
+ /v1/discord/channel/{channel_id}:
get:
tags:
- Discord
@@ -1378,7 +1703,7 @@ paths:
path: /3b/4e/3b4ed5aabdd85b26fbbc3ee9b0e5649df69167efe26b5abc24cc2a1159f446d4.png
'404':
description: Discord channel not found
- /discord/channel/lookup/{discord_server}:
+ /v1/discord/channel/lookup/{discord_server}:
get:
tags:
- Discord
@@ -1411,7 +1736,7 @@ paths:
name: nyarla-lewds
'404':
description: Discord server not found
- /authentication/register:
+ /v1/authentication/register:
post:
description: Register an account
requestBody:
@@ -1442,7 +1767,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /authentication/login:
+ /v1/authentication/login:
post:
description: Sign in to account
requestBody:
@@ -1475,7 +1800,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /authentication/logout:
+ /v1/authentication/logout:
post:
description: Logout from account
responses:
@@ -1485,7 +1810,7 @@ paths:
application/json:
schema:
const: true
- /account:
+ /v1/account:
get:
description: Get account data
security:
@@ -1509,7 +1834,7 @@ paths:
$ref: "#/components/schemas/account"
notifications_count:
$ref: "#/components/schemas/non-negative-integer"
- /account/change_password:
+ /v1/account/change_password:
post:
description: Change account password
requestBody:
@@ -1536,7 +1861,7 @@ paths:
application/json:
schema:
const: true
- /account/notifications:
+ /v1/account/notifications:
get:
description: Get account notifications
security:
@@ -1555,7 +1880,7 @@ paths:
type: array
items:
$ref: "#/components/schemas/notification"
- /account/keys:
+ /v1/account/keys:
get:
description: Get account autoimport keys
security:
@@ -1620,7 +1945,7 @@ paths:
const: /account/keys
message:
const: "Success!"
- /account/favorites:
+ /v1/account/favorites:
get:
tags:
- Favorites
@@ -1670,7 +1995,7 @@ paths:
description: Timestamp when the creator was last updated
'401':
$ref: '#/components/schemas/401'
- /account/posts/upload:
+ /v1/account/posts/upload:
get:
description: Upload posts.
security:
@@ -1685,7 +2010,7 @@ paths:
properties:
currentPage:
const: posts
- /account/review_dms:
+ /v1/account/review_dms:
get:
description: Get DMs for review.
security:
@@ -1742,85 +2067,7 @@ paths:
application/json:
schema:
const: true
- /account/administrator/accounts:
- get:
- security:
- - cookieAuth: [ ]
- description: Get a list of accounts
- parameters:
- - name: name
- in: query
- description: Filter by name
- schema:
- type: string
- - name: role
- in: query
- description: Filter by role
- schema:
- type: string
- - name: page
- in: query
- description: Page of the list
- schema:
- $ref: "#/components/schemas/positive-integer"
- - name: limit
- in: query
- description: A limit per page
- schema:
- $ref: "#/components/schemas/positive-integer"
- responses:
- '200':
- description: A list of accounts.
- content:
- application/json:
- schema:
- type: object
- properties:
- accounts:
- type: array
- items:
- $ref: "#/components/schemas/account"
- role_list:
- type: array
- items:
- type: string
- pagination:
- $ref: "#/components/schemas/pagination"
- currentPage:
- const: admin
- post:
- security:
- - cookieAuth: [ ]
- description: Change the roles of accounts
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- minProperties: 1
- properties:
- moderator:
- type: array
- items:
- $ref: "#/components/schemas/positive-integer"
- consumer:
- type: array
- items:
- $ref: "#/components/schemas/positive-integer"
- responses:
- '200':
- description: Successfully changed account roles.
- content:
- application/json:
- schema:
- type: object
- properties:
- currentPage:
- type: string
- redirect:
- type: string
- /account/moderator/tasks/creator_links:
+ /v1/account/moderator/tasks/creator_links:
get:
security:
- cookieAuth: [ ]
@@ -1834,7 +2081,7 @@ paths:
type: array
items:
$ref: "#/components/schemas/unapproved-link"
- /account/moderator/creator_link_requests/{request_id}/approve:
+ /v1/account/moderator/creator_link_requests/{request_id}/approve:
post:
security:
- cookieAuth: [ ]
@@ -1849,7 +2096,7 @@ paths:
properties:
response:
const: approved
- /account/moderator/creator_link_requests/{request_id}/reject:
+ /v1/account/moderator/creator_link_requests/{request_id}/reject:
post:
security:
- cookieAuth: [ ]
@@ -1864,7 +2111,7 @@ paths:
properties:
response:
const: rejected
- /favorites/post/{service}/{creator_id}/{post_id}:
+ /v1/favorites/post/{service}/{creator_id}/{post_id}:
post:
tags:
- Favorites
@@ -1935,7 +2182,7 @@ paths:
content: { }
'401':
$ref: '#/components/schemas/401'
- /favorites/creator/{service}/{creator_id}:
+ /v1/favorites/creator/{service}/{creator_id}:
post:
tags:
- Favorites
@@ -1994,7 +2241,7 @@ paths:
content: { }
'401':
$ref: '#/components/schemas/401'
- /search_hash/{file_hash}:
+ /v1/search_hash/{file_hash}:
get:
tags:
- File Search
@@ -2149,7 +2396,7 @@ paths:
path: /b9/26/b926020cf035af45a1351e0a7e2c983ebcc93b4c751998321a6593a98277cdeb.png
'404':
description: File not found
- /{service}/user/{creator_id}/post/{post}/flag:
+ /v1/{service}/user/{creator_id}/post/{post}/flag:
post:
tags:
- Post Flagging
@@ -2214,7 +2461,7 @@ paths:
'404':
description: The post has no flag
content: { }
- /{service}/user/{creator_id}/post/{post_id}/revisions:
+ /v1/{service}/user/{creator_id}/post/{post_id}/revisions:
get:
tags:
- Posts
@@ -2331,7 +2578,7 @@ paths:
path: /attachments/attachment4.jpg
'404':
description: Post not found
- /{service}/user/{creator_id}/post/{post_id}/comments:
+ /v1/{service}/user/{creator_id}/post/{post_id}/comments:
get:
tags:
- Comments
@@ -2403,7 +2650,7 @@ paths:
added: "2023-11-14T03:09:12.275975"
'404':
description: No comments found.
- /artists/random:
+ /v1/artists/random:
get:
description: Get a random artist
responses:
@@ -2424,7 +2671,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/error"
- /shares:
+ /v1/shares:
get:
description: Get a list of shares
parameters:
@@ -2456,7 +2703,7 @@ paths:
$ref: "#/components/schemas/non-negative-integer"
base:
type: object
- /share/{share_id}:
+ /v1/share/{share_id}:
get:
description: Get details of the share.
parameters:
@@ -2480,7 +2727,7 @@ paths:
$ref: "#/components/schemas/share"
base:
type: object
- /dms:
+ /v1/dms:
get:
description: Get a list of DMs.
parameters:
@@ -2520,17 +2767,17 @@ paths:
properties:
q:
type: string
- /has_pending_dms:
+ /v1/has_pending_dms:
get:
description: Check if there are pending DMs.
responses:
'200':
- description:
+ description: There are pending DMs.
content:
application/json:
schema:
type: boolean
- /app_version:
+ /v1/app_version:
get:
tags:
- Misc
@@ -2548,7 +2795,7 @@ paths:
maxLength: 40
examples:
- 3b9cd5fab1d35316436968fe85c90ff2de0cdca0
- /importer/submit:
+ /v1/importer/submit:
post:
description: Create a site import
requestBody:
@@ -2584,7 +2831,7 @@ paths:
properties:
import_id:
type: string
- /importer/logs/{import_id}:
+ /v1/importer/logs/{import_id}:
get:
responses:
'200':
@@ -2616,6 +2863,13 @@ components:
required: true
schema:
type: string
+ path-page:
+ name: page
+ in: path
+ description: Page of the collection.
+ required: true
+ schema:
+ $ref: "#/components/schemas/positive-integer"
query-q:
name: q
in: query
@@ -2636,6 +2890,61 @@ components:
in: cookie
name: session
schemas:
+ request-body:
+ title: RequestBody
+ description: Body of the request to V2 API. Must always be present on methods which allow a body.
+ type: object
+ additionalProperties: false
+ required:
+ - type
+ properties:
+ type:
+ const: Sneed's Feed & Seed (formerly Chuck's)
+ request-body-with-data:
+ title: RequestBodyWithData
+ description: Body of the request with extra data to V2 API.
+ type: object
+ additionalProperties: false
+ required:
+ - type
+ - data
+ properties:
+ type:
+ const: Sneed's Feed & Seed (formerly Chuck's)
+ data: true
+ response-body-success:
+ title: ResponseBodySuccess
+ description: Body of the successful response from V2 API.
+ type: object
+ additionalProperties: false
+ required:
+ - type
+ - data
+ properties:
+ type:
+ const: Chuck's Fuck & Suck (formerly Boyle's)
+ data: true
+ response-body-error:
+ title: ResponseBodyError
+ description: Body of the error response from V2 API.
+ type: object
+ additionalProperties: false
+ required:
+ - type
+ - data
+ properties:
+ type:
+ const: Boyle's Foil & Soil (formerly Sneed's)
+ error:
+ type: object
+ additionalProperties: false
+ required:
+ - type
+ properties:
+ type:
+ type: string
+ message:
+ type: string
error:
title: Error
description: Error message
@@ -2656,6 +2965,11 @@ components:
description: Integer which is always above zero.
type: integer
minimum: 1
+ hash-sha256:
+ title: HashSHA256
+ type: string
+ minLength: 64
+ maxLength: 64
artist:
title: Artist
type: object
diff --git a/src/__main__.py b/src/__main__.py
index 5746012..dea9e29 100644
--- a/src/__main__.py
+++ b/src/__main__.py
@@ -3,4 +3,4 @@ import sys
from src import cmd
if __name__ == "__main__":
- cmd.main(sys.argv[1:])
\ No newline at end of file
+ cmd.main(sys.argv[1:])
diff --git a/src/cmd/__init__.py b/src/cmd/__init__.py
index 2e72003..a025ec0 100644
--- a/src/cmd/__init__.py
+++ b/src/cmd/__init__.py
@@ -2,7 +2,7 @@ from src.cmd.daemon import run_daemon
from src.cmd.web import run_web
from src.cmd.webpack import run_webpack
-from src.config import Configuration
+from src.config import Configuration, parse_config
from src.internals.tracing.custom_psycopg_instrumentor import instrument_psycopg
@@ -37,5 +37,8 @@ def main(args: list[str]):
instrument_psycopg()
__try(run_daemon())
+ case ["validate"]:
+ __try(Configuration)
+
case _:
print(f"usage: python -m src [run|web|webpack|daemon]")
diff --git a/src/cmd/daemon.py b/src/cmd/daemon.py
index 5404eb9..9c1991e 100644
--- a/src/cmd/daemon.py
+++ b/src/cmd/daemon.py
@@ -9,21 +9,10 @@ from src.internals.database import database
def run_daemon():
- """Bugs to fix at a later time:"""
- """ - Pages can get stuck with an older version of their """
- """ HTML, even after disabling anything and everything """
- """ related to cache. The only resolution as of now is """
- """ a restart of the entire webserver. """
-
environment_vars = {
**os.environ.copy(),
"FLASK_DEBUG": "development" if Configuration().development_mode else "false",
"NODE_ENV": "development" if Configuration().development_mode else "production",
- "KEMONO_SITE": Configuration().webserver["site"],
- "ICONS_PREPEND": Configuration().webserver["ui"]["files_url_prepend"]["icons_base_url"],
- "BANNERS_PREPEND": Configuration().webserver["ui"]["files_url_prepend"]["banners_base_url"],
- "THUMBNAILS_PREPEND": Configuration().webserver["ui"]["files_url_prepend"]["thumbnails_base_url"],
- "CREATORS_LOCATION": Configuration().webserver["api"]["creators_location"],
}
if Configuration().sentry_dsn:
@@ -46,44 +35,6 @@ def run_daemon():
send_default_pii = True,
)
- """ Install client dependencies. """
- if not os.path.isdir("./client/node_modules"):
- subprocess.run(
- ["npm", "ci", "--also=dev", "--legacy-peer-deps"],
- check=True,
- cwd="client",
- env=environment_vars,
- )
-
- """ Build or run client development server depending on config. """
- if Configuration().development_mode:
- subprocess.Popen(
- ["npm", "run", "dev"],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- cwd="client",
- env=environment_vars,
- )
- else:
- subprocess.run(["npm", "run", "build"], check=True, cwd="client", env=environment_vars)
-
- """ Run `tusd`. """
- if Configuration().filehaus["tus"]["manage"]:
- subprocess.Popen(
- [
- "tusd",
- "-upload-dir=./storage/uploads",
- "--hooks-enabled-events",
- "post-create",
- "-hooks-http",
- "http://127.0.0.1:3343"
- # 'http://127.0.0.1:6942/shares/tus'
- ],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- env=environment_vars,
- )
-
database.init()
try:
if Configuration().automatic_migrations:
@@ -98,6 +49,8 @@ def run_daemon():
migrations = read_migrations("./db/migrations")
with backend.lock():
backend.apply_migrations(backend.to_apply(migrations))
+ backend.connection.close()
+ del backend
""" Initialize Pgroonga if needed. """
with database.pool.getconn() as conn:
try:
diff --git a/src/cmd/web.py b/src/cmd/web.py
index 6f77b92..3abd220 100644
--- a/src/cmd/web.py
+++ b/src/cmd/web.py
@@ -37,6 +37,8 @@ def run_web():
migrations = read_migrations("./db/migrations")
with backend.lock():
backend.apply_migrations(backend.to_apply(migrations))
+ backend.connection.close()
+ del backend
""" Initialize Pgroonga if needed. """
with database.pool.getconn() as conn:
# TODO: make it an actual migration file
diff --git a/src/config.py b/src/config.py
index 51b9703..e97cfa1 100644
--- a/src/config.py
+++ b/src/config.py
@@ -5,40 +5,16 @@ import os
import random
import string
from base64 import b64encode
+from os import path
import orjson
-
-
-def merge_dict(dict_base, dict_that_overrides):
- if isinstance(dict_base, dict) and isinstance(dict_that_overrides, dict):
- return {**dict_base, **{k: merge_dict(dict_base.get(k, {}), v) for k, v in dict_that_overrides.items()}}
- else:
- return dict_that_overrides
+from jsonschema import validate, Draft7Validator
+from jsonschema.exceptions import ValidationError
class BuildConfiguration:
def __init__(self):
- config_file = os.environ.get("KEMONO_CONFIG") or "config.json"
- config_location = os.path.join("./", config_file)
- config = {}
-
- if os.path.exists(config_location):
- with open(config_location) as f:
- config.update(orjson.loads(f.read()))
-
- override_config_file = os.environ.get("KEMONO_OVERRIDE_CONFIG") or "config.override.json"
- override_config_location = os.path.join("./", override_config_file)
- override_config = {}
-
- if os.path.exists(config_location):
- with open(config_location) as f:
- config.update(orjson.loads(f.read()))
-
- if os.path.exists(override_config_location):
- with open(override_config_location) as f:
- override_config.update(orjson.loads(f.read()))
-
- config = merge_dict(config, override_config)
+ config = parse_config()
self.sentry_dsn = config.get("sentry_dsn", None)
self.sentry_dsn_js = config.get("sentry_dsn_js", None)
@@ -327,3 +303,64 @@ def Configuration():
return global_config
# todo use watcher to reload config object based on json changes
+
+
+def parse_config() -> dict:
+ config_file_name = os.environ.get("KEMONO_CONFIG") or "config.json"
+ override_config_file_name = os.environ.get("KEMONO_OVERRIDE_CONFIG") or "config.override.json"
+ config_file_path = os.path.join("./", config_file_name)
+ override_config_path = os.path.join("./", override_config_file_name)
+ config_schema_file_path = path.join("./", "schema", "config.schema.json")
+ config_schema = {}
+ config = {}
+ override_config = {}
+
+ if not path.exists(config_schema_file_path):
+ raise Exception(f'''Config schema file does not exist at path "{config_schema_file_path}".''')
+ else:
+ with open(config_schema_file_path) as f:
+ config_schema.update(orjson.loads(f.read()))
+
+ if not path.exists(config_file_path):
+ raise Exception(f'''Config file does not exist at path \"{config_file_path}\".''')
+ else:
+ with open(config_file_path) as f:
+ config.update(orjson.loads(f.read()))
+
+ if path.exists(override_config_path):
+ with open(override_config_path) as f:
+ override_config.update(orjson.loads(f.read()))
+
+ config = merge_dict(config, override_config)
+
+ try:
+ Draft7Validator.check_schema(config_schema)
+ validate(instance=config, schema=config_schema, cls=Draft7Validator)
+ except ValidationError as error:
+ schema_json_path_segments = '/'.join([
+ str(segment)
+ for segment
+ in error.absolute_schema_path
+ ])
+ schema_json_path = f"#/{schema_json_path_segments}"
+ error_message = f"Configuration validation failed as per schema in \"{schema_json_path}\"."
+
+ raise Exception(error_message)
+
+ return config
+
+
+def merge_dict(dict_base, dict_that_overrides):
+ if isinstance(dict_base, dict) and isinstance(dict_that_overrides, dict):
+ value = {
+ **dict_base,
+ **{
+ k: merge_dict(dict_base.get(k, {}), v)
+ for k, v
+ in dict_that_overrides.items()
+ }
+ }
+
+ return value
+ else:
+ return dict_that_overrides
diff --git a/src/internals/database/database.py b/src/internals/database/database.py
index 61e9353..5842ea2 100644
--- a/src/internals/database/database.py
+++ b/src/internals/database/database.py
@@ -269,7 +269,7 @@ def cached_count(
return result
-def query_db(query: Query, params: tuple = ()) -> list[dict]:
+def query_db(query: Query, params: tuple | dict = ()) -> list[dict]:
cursor = get_cursor()
cursor.execute(query, params)
result = cursor.fetchall()
@@ -278,7 +278,7 @@ def query_db(query: Query, params: tuple = ()) -> list[dict]:
def query_one_db(
query: Query,
- params: tuple = (),
+ params: tuple | dict = (),
) -> Optional[dict]:
cursor = get_cursor()
cursor.execute(query, params)
diff --git a/src/internals/serializers/post.py b/src/internals/serializers/post.py
index 9671443..5688dd3 100644
--- a/src/internals/serializers/post.py
+++ b/src/internals/serializers/post.py
@@ -36,7 +36,7 @@ def deserialize_posts_incomplete_rewards(posts_incomplete_rewards_str, loader=un
def rebuild_post_fields(post):
if post is None:
return
- if "added" in post:
+ if post.get("added"):
post["added"] = datetime.datetime.fromisoformat(post["added"])
if post.get("published"):
post["published"] = datetime.datetime.fromisoformat(post["published"])
diff --git a/src/lib/account.py b/src/lib/account.py
index 1badd03..a373a8f 100644
--- a/src/lib/account.py
+++ b/src/lib/account.py
@@ -3,7 +3,7 @@ import hashlib
from typing import Optional, TypedDict
import bcrypt
-from flask import current_app, flash, session
+from flask import current_app, session
from nh3 import nh3
from src.internals.cache.redis import get_conn
@@ -23,18 +23,27 @@ def load_account(account_id: Optional[str] = None, reload: bool = False):
return None
key = f"account:{account_id}"
+ params = dict(account_id=account_id)
query = """
- SELECT id, username, created_at, role
- FROM account
- WHERE id = %s
+ SELECT
+ id,
+ username,
+ created_at,
+ role
+ FROM
+ account
+ WHERE
+ id = %(account_id)s
"""
- account_dict = cached_query(query, key, (account_id,), serialize_account, deserialize_account, reload, True)
+ account_dict = cached_query(query, key, params, serialize_account, deserialize_account, reload, True)
return Account.init_from_dict(account_dict)
+
class TDSessionKeyImportID(TypedDict):
key_id: int
import_id: str
+
def get_saved_key_import_ids(key_id, reload=False) -> list[TDSessionKeyImportID]:
key = f"saved_key_import_ids:{key_id}"
params = dict(key_id=key_id)
diff --git a/src/lib/administrator.py b/src/lib/administrator.py
index 1f7961f..f831790 100644
--- a/src/lib/administrator.py
+++ b/src/lib/administrator.py
@@ -1,9 +1,9 @@
-from typing import Dict, List
+from typing import List
from src.internals.database.database import query_db, query_one_db, query_rowcount_db
-from src.lib.notification import send_notifications
-from src.lib.pagination import Pagination
-from src.types.account import Account, AccountRoleChange, NotificationTypes
+from src.lib.notification import send_notifications, TDNotificationInit
+from src.lib.pagination import TDPagination
+from src.types.account import Account, AccountRoleChange, NotificationTypes, visible_roles
def get_account(account_id: str) -> Account:
@@ -16,61 +16,102 @@ def get_account(account_id: str) -> Account:
(account_id,),
)
account = Account.init_from_dict(account)
+
return account
-def count_accounts(queries: Dict[str, str]) -> int:
- role = queries["role"]
- params: tuple[str, ...]
- if queries.get("name"):
- params = (role, queries["name"])
- else:
- params = (role,)
- result = query_one_db(
- f"""
- SELECT COUNT(*) AS total_number_of_accounts
- FROM account
+def count_accounts(role: str | None = None, name: str | None = None) -> int:
+ roles = [role] if role else visible_roles
+ params = dict(
+ roles=roles,
+ name=f"%%{name}%%" if name else None
+ )
+ query = """
+ SELECT
+ COUNT(*)
+ FROM
+ account
WHERE
- role = ANY(%s)
- {"AND username LIKE %s" if len(params) > 1 else ""}
- """,
+ role = ANY(%(roles)s::varchar[])
+ AND
+ (
+ %(name)s::varchar IS NULL
+ OR
+ username LIKE %(name)s::varchar
+ )
+ """
+ result = query_one_db(
+ query,
params,
)
- return result["total_number_of_accounts"] if result else 0
+ count = result["count"] if result else 0
+
+ return count
-def get_accounts(pagination: Pagination, queries: Dict[str, str]) -> List[Account]:
- params = (queries["role"], pagination.offset, pagination.limit)
- if queries.get("name"):
- params = (queries["role"], f"%%{queries["name"]}%%", pagination.offset, pagination.limit)
-
- accounts = query_db(
- f"""
- SELECT id, username, created_at, role
- FROM account
+def get_accounts(pagination: TDPagination, role: str | None = None, name: str | None = None) -> List[Account]:
+ roles = [role] if role else visible_roles
+ params = dict(
+ roles=roles,
+ name=f"%%{name}%%" if name else None,
+ offset=pagination["offset"],
+ limit=pagination["limit"]
+ )
+ query = """
+ SELECT
+ id,
+ username,
+ created_at,
+ role
+ FROM
+ account
WHERE
- role = ANY(%s)
- {"AND username LIKE %s" if len(params) > 3 else ""}
+ role = ANY(%(roles)s::varchar[])
+ AND
+ (
+ %(name)s::varchar IS NULL
+ OR
+ username LIKE %(name)s::varchar
+ )
ORDER BY
- created_at DESC,
- username
- OFFSET %s
- LIMIT %s
- """,
+ id ASC
+ OFFSET %(offset)s
+ LIMIT %(limit)s
+ """
+ accounts = query_db(
+ query,
params,
)
acc_list = [Account.init_from_dict(acc) for acc in accounts]
- count = count_accounts(queries)
- pagination.add_count(count)
+
return acc_list
def change_account_role(account_ids: List[str], extra_info: AccountRoleChange):
change_role_query = """
- UPDATE account
- SET role = %s
- WHERE id = ANY (%s)
+ UPDATE
+ account
+ SET
+ role = %s
+ WHERE
+ id = ANY (%s)
"""
query_rowcount_db(change_role_query, (extra_info["new_role"], account_ids))
- send_notifications(account_ids, NotificationTypes.ACCOUNT_ROLE_CHANGE, extra_info)
+
+ notification_inits: list[TDNotificationInit] = [
+ TDNotificationInit(
+ account_id=account_id,
+ type=NotificationTypes.ACCOUNT_ROLE_CHANGE,
+ # resort to this retardation because
+ # psycopg chokes json'ing typed dicts
+ extra_info=dict(
+ old_role=extra_info["old_role"],
+ new_role=extra_info["new_role"]
+ )
+ )
+ for account_id
+ in account_ids
+ ]
+ send_notifications(notification_inits)
+
return True
diff --git a/src/lib/api/__init__.py b/src/lib/api/__init__.py
new file mode 100644
index 0000000..114daef
--- /dev/null
+++ b/src/lib/api/__init__.py
@@ -0,0 +1,14 @@
+from .v1 import create_client_error_response, create_not_found_error_response
+from .v2 import (
+ create_api_v2_response,
+ create_api_v2_error_response,
+ create_api_v2_client_error_response,
+ create_api_v2_invalid_body_error_response,
+ create_api_v2_not_found_error_response,
+ get_api_v2_request_data,
+ TDAPIError,
+ TDAPIRequestBody,
+ APIV2_REQUEST_BODY_TYPE,
+ APIV2_RESPONSE_SUCCESS_TYPE,
+ APIV2_RESPONSE_ERROR_TYPE,
+)
diff --git a/src/lib/api.py b/src/lib/api/v1.py
similarity index 100%
rename from src/lib/api.py
rename to src/lib/api/v1.py
diff --git a/src/lib/api/v2.py b/src/lib/api/v2.py
new file mode 100644
index 0000000..5b1b6b8
--- /dev/null
+++ b/src/lib/api/v2.py
@@ -0,0 +1,69 @@
+from flask import make_response, jsonify, Request
+from typing import Any, Literal, NotRequired, TypedDict
+
+APIV2_REQUEST_BODY_TYPE = "Sneed's Feed & Seed (formerly Chuck's)"
+APIV2_RESPONSE_SUCCESS_TYPE = "Chuck's Fuck & Suck (formerly Boyle's)"
+APIV2_RESPONSE_ERROR_TYPE = "Boyle's Foil & Soil (formerly Sneed's)"
+
+
+class TDAPIError(TypedDict):
+ type: str
+ message: NotRequired[str]
+
+
+class TDAPIRequestBody(TypedDict):
+ """
+ Only required for requests with body.
+ """
+
+ type: Literal["Sneed's Feed & Seed (formerly Chuck's)"]
+ data: NotRequired[Any]
+
+
+class TDAPIResponseSuccess(TypedDict):
+ type: Literal["Chuck's Fuck & Suck (formerly Boyle's)"]
+ data: Any
+
+
+class TDAPIResponseError(TypedDict):
+ type: Literal["Boyle's Foil & Soil (formerly Sneed's)"]
+ error: TDAPIError
+
+
+def get_api_v2_request_data(request: Request) -> Any:
+ body: TDAPIRequestBody = request.get_json()
+
+ return body.get("data", None)
+
+
+def create_api_v2_response(data: Any, status_code=200):
+ response_body = TDAPIResponseSuccess(type="Chuck's Fuck & Suck (formerly Boyle's)", data=data)
+
+ response = make_response(jsonify(response_body), status_code)
+
+ return response
+
+
+def create_api_v2_error_response(error: TDAPIError, status_code=500):
+ response_body = TDAPIResponseError(type="Boyle's Foil & Soil (formerly Sneed's)", error=error)
+
+ response = make_response(jsonify(response_body), status_code)
+
+ return response
+
+
+def create_api_v2_client_error_response(error: TDAPIError, status_code=400):
+ return create_api_v2_error_response(error, status_code)
+
+
+def create_api_v2_invalid_body_error_response():
+ return create_api_v2_error_response(TDAPIError(type="api_invalid_body_data", message="Invalid body data."), 400)
+
+
+def create_api_v2_not_found_error_response(cache_age: int | None = None):
+ response = create_api_v2_error_response(TDAPIError(type="api_not_found", message="Not Found."), 404)
+
+ if cache_age:
+ response.headers["Cache-Control"] = f"s-maxage={str(cache_age)}"
+
+ return response
diff --git a/src/lib/files.py b/src/lib/files.py
index f8e5018..9f40337 100644
--- a/src/lib/files.py
+++ b/src/lib/files.py
@@ -36,6 +36,7 @@ class File:
size: int
ihash: Optional[str]
+
class TDPost(TypedDict):
file_id: int
id: str
@@ -47,6 +48,7 @@ class TDPost(TypedDict):
file: dict
attachments: list
+
class TDDiscordPost(TypedDict):
file_id: int
id: str
@@ -58,10 +60,12 @@ class TDDiscordPost(TypedDict):
mentions: list
attachments: list
+
class TDFileRelationships(TypedDict):
posts: list[TDPost]
discord_posts: list[TDDiscordPost]
+
def get_file_relationships(file_hash: str, reload: bool = False) -> TDFileRelationships | None:
key = f"files:by_hash:{file_hash}"
query = """
@@ -153,14 +157,19 @@ archive_server_session = requests.Session()
def get_archive_files(file_hash: str) -> Optional[ArchiveInfo]:
if not Configuration().archive_server["enabled"]:
return None
+
arc_data = get_archive(file_hash)
+
if not arc_data:
return None
+
file, ext = arc_data
key = f"archive_files:{file.hash}"
query = """
SELECT
- *
+ archive_files.file_id,
+ archive_files.files,
+ archive_files.password
FROM
archive_files
LEFT JOIN
@@ -171,6 +180,7 @@ def get_archive_files(file_hash: str) -> Optional[ArchiveInfo]:
files.hash = %s
"""
result = cached_query(query, key, (file.hash,), single=True)
+
if result:
return ArchiveInfo(
file,
@@ -182,6 +192,7 @@ def get_archive_files(file_hash: str) -> Optional[ArchiveInfo]:
files_api_call = archive_server_session.get(
f"{Configuration().archive_server["api_url"]}/list/data/{file_hash[0:2]}/{file_hash[2:4]}/{file_hash}{ext}"
)
+
if files_api_call.status_code == 401:
files: list[str] = []
else:
@@ -191,13 +202,29 @@ def get_archive_files(file_hash: str) -> Optional[ArchiveInfo]:
f"{Configuration().archive_server["api_url"]}/needs_password/data/{file_hash[0:2]}/{file_hash[2:4]}/{file_hash}{ext}"
)
needs_pass_api_call.raise_for_status()
+
assert needs_pass_api_call.text in ("true", "false")
+
needs_pass = needs_pass_api_call.text == "true"
+
except Exception as e:
logging.exception("Failed to call archive server", exc_info=True)
+
return None
+
password = "" if needs_pass else None
- query_rowcount_db("INSERT INTO archive_files (file_id, files, password) VALUES (%s, %s, %s) ON CONFLICT (file_id) DO NOTHING", (file.id, files, password))
+ query_rowcount_db(
+ """
+ INSERT INTO archive_files
+ (file_id, files, password)
+ VALUES
+ (%s, %s, %s)
+ ON CONFLICT
+ (file_id) DO NOTHING
+ """,
+ (file.id, files, password)
+ )
+
return ArchiveInfo(file, files, password)
@@ -234,6 +261,7 @@ def try_set_password(file_hash: str, passwords: list[str]) -> bool:
(password, file_hash),
)
files: list[str] | None = update_result["files"] if update_result else None
+
if not files:
try:
files_api_call = archive_server_session.get(
@@ -251,11 +279,15 @@ def try_set_password(file_hash: str, passwords: list[str]) -> bool:
""",
(files, file_hash),
)
+
except Exception:
logging.exception("Failed to update empty list of archives")
+
get_conn().delete(f"archive_files:{file_hash}")
clear_web_cache_for_archive(file_hash)
+
return True
+
return False
diff --git a/src/lib/notification.py b/src/lib/notification.py
index 07007a0..8a5cdfb 100644
--- a/src/lib/notification.py
+++ b/src/lib/notification.py
@@ -1,4 +1,5 @@
-from typing import List, Optional
+from typing import List, TypedDict
+from psycopg.types.json import Json
import orjson
@@ -97,25 +98,50 @@ def get_account_notifications(account_id: int, reload: bool = False) -> List[Not
return notifications
-def send_notifications(account_ids: List[str], notification_type: int, extra_info: Optional[dict]) -> bool:
+class TDNotificationInit(TypedDict):
+ account_id: str
+ type: int
+ extra_info: dict
+
+
+def send_notifications(notification_inits: list[TDNotificationInit]) -> bool:
cursor = get_cursor()
- if not account_ids:
- return False
- if extra_info is not None:
- extra_info = orjson.dumps(extra_info)
- notification_values = f"(%s, {notification_type}, '{extra_info}')"
- else:
- notification_values = f"(%s, {notification_type}, NULL)"
-
- insert_queries_values_template = ",".join([notification_values] * len(account_ids))
- insert_query = f"""
- INSERT INTO notifications (account_id, type, extra_info)
- VALUES {insert_queries_values_template}
- ;
+ params = dict(
+ notification_inits=Json(notification_inits)
+ )
+ insert_query = """
+ WITH notification_inits AS (
+ SELECT
+ notification_init.account_id,
+ notification_init.type,
+ notification_init.extra_info
+ FROM
+ json_to_recordset(%(notification_inits)s) AS notification_init(
+ account_id int,
+ type smallint,
+ extra_info jsonb
+ )
+ )
+ INSERT INTO notifications
+ (
+ account_id,
+ type,
+ extra_info
+ )
+ SELECT
+ account_id,
+ type,
+ extra_info
+ FROM
+ notification_inits
"""
- cursor.execute(insert_query, account_ids)
-
+ cursor.execute(insert_query, params)
+ account_ids = [
+ init["account_id"]
+ for init
+ in notification_inits
+ ]
for account_id in account_ids:
redis = get_conn()
redis.delete(f"account_notifications:{account_id}")
diff --git a/src/lib/pagination.py b/src/lib/pagination.py
index 5a4b0cd..0a5b62e 100644
--- a/src/lib/pagination.py
+++ b/src/lib/pagination.py
@@ -1,35 +1,26 @@
import math
-from flask import Request, url_for
+from typing import TypedDict
-from src.utils.utils import limit_int, parse_int
+PAGINATION_LIMIT = 50
-class Pagination:
- def __init__(self, request: Request) -> None:
- self.current_page: int = parse_int(request.args.get("page"), 1)
- self.limit: int = limit_int(int(request.args.get("limit") or 25), 25)
- self.offset: int = self.calculate_offset(self.current_page, self.limit)
- self.base: dict[str, str] = request.args.to_dict()
+class TDPagination(TypedDict):
+ total_count: int
+ limit: int
+ total_pages: int
+ current_page: int
+ offset: int
- self.base.pop("page", None)
- self.count: int | None = None
- self.current_count: int | None = None
- self.total_pages: int | None = None
+def create_pagination(total_count: int, current_page: int | None = None) -> TDPagination:
+ limit = PAGINATION_LIMIT
+ total_pages = math.ceil(total_count / limit)
+ current = current_page or total_pages
+ offset = (current - 1) * limit
- def add_count(self, count: int):
- self.count = count
- self.current_count = self.offset + self.limit if self.offset + self.limit < self.count else self.count
- self.total_pages = math.ceil(self.count / self.limit) or 1
+ pagination = TDPagination(
+ total_count=total_count, limit=limit, total_pages=total_pages, current_page=current, offset=offset
+ )
- def calculate_offset(self, current_page: int, limit: int):
- if current_page > 1:
- offset = (current_page - 1) * limit
- else:
- offset = 0
-
- return offset
-
- def create_paged_url(self, request: Request, page_number: int):
- return url_for(request.endpoint, page=page_number, **self.base)
+ return pagination
diff --git a/src/lib/post.py b/src/lib/post.py
index 2b41bd6..8bf0039 100644
--- a/src/lib/post.py
+++ b/src/lib/post.py
@@ -1,7 +1,9 @@
+import hashlib
import itertools
import logging
import random
import re
+import uuid
from typing import TypedDict, Union, Sequence, Any, Literal, Optional
from murmurhash2 import murmurhash2
@@ -19,7 +21,7 @@ from src.internals.serializers.post import (
serialize_post_list,
serialize_posts_incomplete_rewards,
)
-from src.lib.posts import Post
+from src.lib.posts import Post, POST_FLAG_CUT_OFF, POST_FLAG_REASON_NUMBER_TO_SLUG
from src.utils.utils import fixed_size_batches, images_pattern
@@ -50,16 +52,16 @@ def get_random_post_key(table_fraction_percentage: float):
def get_post(service, artist_id, post_id, reload=False):
key = f"post:{service}:{artist_id}:{post_id}"
params = (
- service,
- artist_id,
- post_id,
- service,
- artist_id,
- post_id,
- service,
- artist_id,
- post_id,
- )
+ service,
+ artist_id,
+ post_id,
+ service,
+ artist_id,
+ post_id,
+ service,
+ artist_id,
+ post_id,
+ )
query = """
WITH main_post AS (
SELECT
@@ -70,7 +72,13 @@ def get_post(service, artist_id, post_id, reload=False):
content,
embed,
shared_file,
- added,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
published,
edited,
file,
@@ -135,6 +143,7 @@ class TDPostData(TypedDict):
artist_id: str
post_id: str
+
def get_post_multiple(input_: dict[tuple[str, str, str], TDPostData], reload=False):
if not input_:
return []
@@ -176,12 +185,44 @@ def get_post_multiple(input_: dict[tuple[str, str, str], TDPostData], reload=Fal
SELECT row_to_json(x) as post
FROM (
WITH main_post AS (
- SELECT *
- FROM posts
- WHERE service = iv.service
- AND "user" = iv."user"
- AND id = iv.id
- AND ("user", service) NOT IN (SELECT id, service FROM dnp)
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ content,
+ embed,
+ shared_file,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
+ published,
+ edited,
+ file,
+ attachments,
+ poll,
+ captions,
+ tags
+ FROM
+ posts
+ WHERE
+ service = iv.service
+ AND
+ "user" = iv."user"
+ AND
+ id = iv.id
+ AND
+ ("user", service) NOT IN (
+ SELECT
+ id,
+ service
+ FROM
+ dnp
+ )
)
SELECT
main_post.*,
@@ -259,7 +300,7 @@ def get_post_multiple(input_: dict[tuple[str, str, str], TDPostData], reload=Fal
return full_result
-def get_post_by_id(post_id:str, service:str, reload=True):
+def get_post_by_id(post_id: str, service: str, reload=True):
key = f"post_by_id:{service}:{post_id}"
params = dict(
post_id=post_id,
@@ -281,13 +322,15 @@ def get_post_by_id(post_id:str, service:str, reload=True):
return cached_query(query, key, params, reload=reload, single=True)
-def get_posts_incomplete_rewards(post_id, artist_id, service, reload=False):
- key = f"posts_incomplete_rewards:{service}:{post_id}" # todo add artist if other service needs
+def get_posts_incomplete_rewards(post_id: str, artist_id: str, service: str, reload=False):
+ # todo add artist if other service needs
+ key = f"posts_incomplete_rewards:{service}:{post_id}"
query = """
SELECT *
FROM posts_incomplete_rewards
WHERE id = %s AND service = %s
"""
+
return cached_query(
query,
key,
@@ -311,10 +354,12 @@ class TDComment(TypedDict):
deleted_at: str
commenter_name: str
+
def get_post_comments(post_id, service, reload=False) -> list[TDComment]:
if service not in ("fanbox", "patreon", "boosty"):
return []
key = f"comments:{service}:{post_id}"
+
# we select only used fields to save memory and be faster
if service in ("fanbox", "patreon", "boosty"):
revisions_select = """COALESCE(json_agg(
@@ -344,19 +389,51 @@ def get_post_comments(post_id, service, reload=False) -> list[TDComment]:
WHERE comments.post_id = %s AND comments.service = %s
GROUP BY comments.id, comments.parent_id, comments.commenter, comments.commenter_name, comments."content", comments.published
"""
+
return cached_query(query, key, (post_id, service), serialize_post_list, deserialize_post_list, reload)
def get_all_posts_by_artist(artist_id, service, reload=False):
key = f"posts_by_artist:{service}:{artist_id}"
query = """
- SELECT *
- FROM posts
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ content,
+ embed,
+ shared_file,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
+ published,
+ edited,
+ file,
+ attachments,
+ poll,
+ captions,
+ tags
+ FROM
+ posts
WHERE
"user" = %s
- AND service = %s
- AND ("user", service) NOT IN (SELECT id, service from dnp);
+ AND
+ service = %s
+ AND
+ ("user", service) NOT IN (
+ SELECT
+ id,
+ service
+ FROM
+ dnp
+ );
"""
+
return cached_query(
query, key, (artist_id, service), serialize_post_list, deserialize_post_list, reload, lock_enabled=True
)
@@ -365,15 +442,32 @@ def get_all_posts_by_artist(artist_id, service, reload=False):
def get_artist_posts_summary(artist_id, service, offset, limit, sort="id", reload=False):
"""we need this to render html only so we reduce data size to half redis usage"""
key = f"artist_posts_offset:{service}:{artist_id}:{offset}:{sort}:summary"
- assert sort in ("id", "published DESC NULLS LAST") # extra careful building queries with strings
+
+ # extra careful building queries with strings
+ assert sort in ("id", "published DESC NULLS LAST")
+
query = f"""
- SELECT id, "user", service, title, substring("content", 1, 50), published, file, attachments
- FROM posts
- WHERE "user" = %s AND service = %s
- ORDER BY {sort}
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ substring("content", 1, 50),
+ published,
+ file,
+ attachments
+ FROM
+ posts
+ WHERE
+ "user" = %s
+ AND
+ service = %s
+ ORDER BY
+ {sort}
OFFSET %s
LIMIT %s
"""
+
return cached_query(
query,
key,
@@ -387,15 +481,45 @@ def get_artist_posts_summary(artist_id, service, offset, limit, sort="id", reloa
def get_artist_posts_full(artist_id, service, offset, limit, sort="id", reload=False):
key = f"artist_posts_offset:{service}:{artist_id}:{offset}:{sort}:full"
- assert sort in ("id", "published DESC NULLS LAST") # extra careful building queries with strings
+
+ # extra careful building queries with strings
+ assert sort in ("id", "published DESC NULLS LAST")
+
query = f"""
- SELECT*
- FROM posts
- WHERE "user" = %s AND service = %s
- ORDER BY {sort}
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ content,
+ embed,
+ shared_file,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
+ published,
+ edited,
+ file,
+ attachments,
+ poll,
+ captions,
+ tags
+ FROM
+ posts
+ WHERE
+ "user" = %s
+ AND
+ service = %s
+ ORDER BY
+ {sort}
OFFSET %s
LIMIT %s
"""
+
return cached_query(
query,
key,
@@ -410,13 +534,31 @@ def get_artist_posts_full(artist_id, service, offset, limit, sort="id", reload=F
def get_artist_post_count(service, artist_id, reload=False):
key = f"artist_post_count:{service}:{artist_id}"
query = 'SELECT count(*) as count FROM posts WHERE "user" = %s AND service = %s'
+
return cached_count(query, key, (artist_id, service), reload, lock_enabled=True)
-def is_post_flagged(service, artist_id, post_id, reload=False) -> int:
- key = f"is_post_flagged:{service}:{artist_id}:{post_id}"
- query = 'SELECT COUNT(*) FROM booru_flags WHERE id = %s AND "user" = %s AND service = %s'
- return cached_count(query, key, (post_id, artist_id, service), reload)
+def flag_post(service, creator_id, post_id, reason, flagger_id, flagger_ip) -> str | None:
+ query = """
+ INSERT INTO "post_flags" ("service", "creator_id", "post_id", "reason", "contributor_id", "flagger_ip_hash")
+ VALUES (%s, %s, %s, %s, %s, %s)
+ ON CONFLICT ("service", "creator_id", "post_id", "contributor_id")
+ DO UPDATE SET "reason" = EXCLUDED."reason";
+ """
+
+ flagger_ip_hash = uuid.UUID(hashlib.sha256(flagger_ip.encode()).hexdigest()[:32])
+ params = (service, creator_id, post_id, reason, flagger_id, flagger_ip_hash)
+
+ cur = get_cursor()
+ cur.execute(query, params)
+
+ return is_post_flagged(service, creator_id, post_id, reload=True)
+
+def is_post_flagged(service, creator_id, post_id, reload=False) -> str | None:
+ key = f"is_post_flagged:{service}:{creator_id}:{post_id}"
+ query = 'SELECT MAX(reason) FROM post_flags WHERE post_id = %s AND creator_id = %s AND service = %s'
+ reason_int = cached_query(query, key, (post_id, creator_id, service,), unsafe_dumper, unsafe_loader, reload, lock_enabled=False, single=True)
+ return POST_FLAG_REASON_NUMBER_TO_SLUG.get((reason_int or {}).get("max"))
class TDPostRevision(TypedDict):
revision_id: int
@@ -456,7 +598,13 @@ def get_post_revisions(service: str, artist_id: str, post_id: str, reload=False)
content,
embed,
shared_file,
- added,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
published,
edited,
file,
@@ -508,24 +656,29 @@ def get_fileserver_for_value(value: str) -> str:
return name
return ""
+
type TDPreview = Union[TDPreviewThumbnail, TDPreviewEmbed]
+
class TDPreviewThumbnail(TypedDict):
- type: "thumbnail"
+ type: Literal["thumbnail"]
server: str
name: str
path: str
+
class TDPreviewEmbed(TypedDict):
- type: "embed"
+ type: Literal["embed"]
url: str
subject: str
description: str
+
class TDAttachament(TypedDict):
server: str
name: str
- path:str
+ path: str
+
def get_render_data_for_posts(posts: Sequence[Post]) -> tuple[list[TDPreview], list[TDAttachament], list[bool]]:
result_previews = []
@@ -607,4 +760,5 @@ def replace_img_tags(match):
new_src = Configuration().webserver["ui"]["files_url_prepend"]["thumbnails_base_url"] + "/thumbnail" + src
server = get_fileserver_for_value(src.split("?")[0])
# return match.group(0).replace(src, new_src)
+
return f' '
diff --git a/src/lib/posts.py b/src/lib/posts.py
index 5556be9..c1fb006 100644
--- a/src/lib/posts.py
+++ b/src/lib/posts.py
@@ -2,7 +2,7 @@ import base64
import itertools
from dataclasses import dataclass
from datetime import datetime, timedelta
-from typing import Optional, TypedDict,Any
+from typing import Optional, TypedDict, Any
from src.config import Configuration
from src.internals.cache.redis import get_conn
@@ -35,20 +35,40 @@ class Post(TypedDict):
class PostWithFavCount(Post):
fav_count: int
+POST_FLAG_REASON_NUMBER_TO_SLUG = {
+ -2: "delete-copyright",
+ -1: "delete-abuse",
+ 1: "missing-password",
+ 2: "offsite-expired",
+ 10: "post-changed",
+ 20: "corrupted-files",
+ 21: "missing-files",
+ 11: "stale-comments",
+ 12: "formatting-error",
+ 8: "reason-other",
+}
+
+POST_FLAG_REASON_SLUG_TO_NUMBER = {v:k for k,v in POST_FLAG_REASON_NUMBER_TO_SLUG.items()}
+
+POST_FLAG_CUT_OFF = 0
def count_all_posts(reload=False) -> int:
key = "global_post_count"
query = 'SELECT COUNT(*) FROM posts WHERE ("user", service) NOT IN (SELECT id, service from dnp)'
+
return cached_count(query, key, reload=reload, ex=6000, lock_enabled=True)
def count_all_posts_for_query(q: str, reload=False) -> int:
q = " OR ".join(x.lower() for x in q.strip().split(" OR "))
+
if q == "":
return count_all_posts(reload=reload)
+
key = f"global_post_count_for_query:{base64.b64encode(q.encode()).decode()}"
query = """
- SET random_page_cost = 0.0001;
+ BEGIN;
+ SET LOCAL random_page_cost = 0.0001;
SET LOCAL statement_timeout = 10000;
SELECT COUNT(*)
FROM posts
@@ -57,17 +77,22 @@ def count_all_posts_for_query(q: str, reload=False) -> int:
SELECT id, service
FROM dnp
);
+ COMMIT;
"""
- return cached_count(query, key, (q,), reload, prepare=False, client_bind=True, sets_to_fetch=[2], lock_enabled=True)
+
+ return cached_count(query, key, (q,), reload, prepare=False, client_bind=True, sets_to_fetch=[3], lock_enabled=True)
def count_all_posts_for_tag(tags: list[str], service: Optional[str] = None, artist_id: Optional[str] = None) -> int:
b = base64.b64encode(f"==TAG==\0{tags}".encode()).decode()
key = f"global_post_count_for_query:{b}"
query = """
- SELECT COUNT(*)
- FROM POSTS
- WHERE "tags" @> %s::citext[]
+ SELECT
+ COUNT(*)
+ FROM
+ POSTS
+ WHERE
+ "tags" @> %s::citext[]
"""
params = (tags,)
@@ -105,8 +130,10 @@ def get_all_posts_summary(offset: int, limit=50, reload=False, cache_ttl=None):
LIMIT %s
"""
extra = {}
+
if cache_ttl:
extra["ex"] = cache_ttl
+
return cached_query(
query, key, (offset, limit), serialize_dict_list, deserialize_dict_list, reload, lock_enabled=True, **extra
)
@@ -115,13 +142,44 @@ def get_all_posts_summary(offset: int, limit=50, reload=False, cache_ttl=None):
def get_all_posts_full(offset: int, limit=50, reload=False):
key = f"all_posts:full:{limit}:{offset}"
query = """
- SELECT *
- FROM posts
- WHERE ("user", service) NOT IN (SELECT id, service from dnp)
- ORDER BY added DESC
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ content,
+ embed,
+ shared_file,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
+ published,
+ edited,
+ file,
+ attachments,
+ poll,
+ captions,
+ tags
+ FROM
+ posts
+ WHERE
+ ("user", service) NOT IN (
+ SELECT
+ id,
+ service
+ FROM
+ dnp
+ )
+ ORDER BY
+ added DESC
OFFSET %s
LIMIT %s
"""
+
return cached_query(
query, key, (offset, limit), serialize_dict_list, deserialize_dict_list, reload, lock_enabled=True
)
@@ -129,11 +187,14 @@ def get_all_posts_full(offset: int, limit=50, reload=False):
def get_all_posts_for_query(q: str, offset: int, limit=50, reload=False):
q = " OR ".join(x.lower() for x in q.strip().split(" OR "))
+
if q == "":
return get_all_posts_summary(0, limit, reload, cache_ttl=Configuration().cache_ttl_for_recent_posts)
+
key = f"all_posts_for_query:{base64.b64encode(q.encode()).decode()}:{limit}:{offset}"
query = """
- SET random_page_cost = 0.0001;
+ BEGIN;
+ SET LOCAL random_page_cost = 0.0001;
SET LOCAL statement_timeout = 10000;
SELECT
id,
@@ -157,7 +218,9 @@ def get_all_posts_for_query(q: str, offset: int, limit=50, reload=False):
added DESC
LIMIT %s
OFFSET %s;
+ COMMIT;
"""
+
return cached_query(
query,
key,
@@ -167,7 +230,7 @@ def get_all_posts_for_query(q: str, offset: int, limit=50, reload=False):
reload,
prepare=False,
client_bind=True,
- sets_to_fetch=[2],
+ sets_to_fetch=[3],
lock_enabled=True,
)
@@ -175,6 +238,7 @@ def get_all_posts_for_query(q: str, offset: int, limit=50, reload=False):
def get_all_channels_for_server(discord_server, reload=False):
key = f"discord_channels_for_server:{discord_server}"
query = "SELECT channel_id as id, name FROM discord_channels WHERE server_id = %s"
+
return cached_query(query, key, (discord_server,), reload=reload, ex_on_null=60, lock_enabled=True)
@@ -192,6 +256,7 @@ def get_popular_posts_for_date_range(
redis = get_conn()
result = redis.lindex(key, page)
+
if result:
parsed_result = deserialize_post_list(result)
if parsed_result:
@@ -206,6 +271,7 @@ def get_popular_posts_for_date_range(
params = (start_date, end_date, pages_to_query * per_page)
order_factor = "COUNT(*)"
+
if scale == "recent":
order_factor = 'SUM((EXTRACT(EPOCH FROM ("created_at" - %s )) / EXTRACT(EPOCH FROM ( %s - %s )) ))::float'
params = (start_date, end_date, start_date, *params)
@@ -221,9 +287,24 @@ def get_popular_posts_for_date_range(
ORDER BY fav_count DESC
LIMIT %s
)
- SELECT p.id, p."user", p.service, p.title, substring( p."content", 1, 50), p.published, p.file, p.attachments, tf."fav_count"
- FROM "top_faves" tf
- INNER JOIN "posts" p ON p."id" = tf."post_id" and p."service" = tf."service";
+ SELECT
+ p.id,
+ p."user",
+ p.service,
+ p.title,
+ substring( p."content", 1, 50),
+ p.published,
+ p.file,
+ p.attachments,
+ tf."fav_count"
+ FROM
+ "top_faves" AS tf
+ INNER JOIN
+ "posts" AS p
+ ON
+ p."id" = tf."post_id"
+ AND
+ p."service" = tf."service";
"""
result = cached_query(
@@ -237,6 +318,7 @@ def get_popular_posts_for_date_range(
cache_store_method="rpush",
lock_enabled=True,
)
+
return (result or [])[(page * per_page) : ((page + 1) * per_page)]
@@ -245,11 +327,35 @@ def get_tagged_posts(
) -> list[Post]:
key = f"tagged_posts:{tags}:{service}:{artist_id}:{offset}"
query = """
- SELECT *
- FROM "posts"
- WHERE "tags" @> %s::citext[]
+ SELECT
+ id,
+ "user",
+ service,
+ title,
+ content,
+ embed,
+ shared_file,
+ (
+ CASE service
+ WHEN 'fanbox'
+ THEN NULL
+ ELSE added
+ END
+ ) AS added,
+ published,
+ edited,
+ file,
+ attachments,
+ poll,
+ captions,
+ tags
+ FROM
+ "posts"
+ WHERE
+ "tags" @> %s::citext[]
"""
params: tuple[...] = (tags,)
+
if service and artist_id:
query += """
AND "service" = %s AND "user" = %s ORDER BY published DESC
@@ -273,6 +379,7 @@ class Tag:
def get_all_tags(service: Optional[str] = None, creator_id: Optional[str] = None) -> list[Tag]:
if creator_id and not service:
raise Exception("Must be used with both creator_id and service")
+
key = f"tags:{service or ""}:{creator_id or ""}"
query = f"""
SELECT {"tag" if creator_id else "lower(tag)"} as tag, COUNT(1) AS post_count
@@ -291,4 +398,5 @@ def get_all_tags(service: Optional[str] = None, creator_id: Optional[str] = None
LIMIT 2000
"""
ex = int(timedelta(hours=(6 if creator_id else 24)).total_seconds())
+
return cached_query(query, key, params, ex=ex)
diff --git a/src/pages/api/__init__.py b/src/pages/api/__init__.py
index 0b40361..49f2888 100644
--- a/src/pages/api/__init__.py
+++ b/src/pages/api/__init__.py
@@ -3,10 +3,12 @@ from flask import Blueprint, Response
from src.config import Configuration
from src.pages.api.v1 import v1api_bp
+from src.pages.api.v2 import v2api_bp
api_bp = Blueprint("api", __name__, url_prefix="/api")
api_bp.register_blueprint(v1api_bp)
+api_bp.register_blueprint(v2api_bp)
# set up cors handler for development
if (Configuration().development_mode):
diff --git a/src/pages/api/v1/account.py b/src/pages/api/v1/account.py
index ad3c3e2..d1500dd 100644
--- a/src/pages/api/v1/account.py
+++ b/src/pages/api/v1/account.py
@@ -22,7 +22,6 @@ from src.types.kemono import Unapproved_DM
from . import v1api_bp
-from .administrator import administrator_bp
from .moderator import moderator_bp
account_bp = Blueprint("account", __name__)
@@ -217,11 +216,6 @@ def approve_importer_dms():
def not_authorized_error(error):
return (jsonify(error="Not Authorized"), 401)
-
-# going this roundabout way because the structure expects
-# a flat module list in the folder
-# and I am not going to change it
-account_bp.register_blueprint(administrator_bp, url_prefix="/account")
account_bp.register_blueprint(moderator_bp, url_prefix="/account")
# not sure about resolution order
# so load it in the end
diff --git a/src/pages/api/v1/administrator.py b/src/pages/api/v1/administrator.py
deleted file mode 100644
index 92636f5..0000000
--- a/src/pages/api/v1/administrator.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from typing import TypedDict, Literal
-
-from flask import Blueprint, g, make_response, jsonify, abort, request
-
-from src.lib.pagination import Pagination
-from src.lib.administrator import get_accounts, change_account_role
-from src.types.account import Account, visible_roles, AccountRoleChange
-
-administrator_bp = Blueprint("api_administrator", __name__)
-
-
-@administrator_bp.before_request
-def check_credentials():
- account: Account = g.get("account")
-
- if account.role != "administrator":
- return abort(404)
-
-
-class TDAccountsProps(TypedDict):
- accounts: list[Account]
- role_list: list[str]
- pagination: Pagination
- currentPage: Literal["admin"]
-
-
-@administrator_bp.get("/administrator/accounts")
-def get_accounts_list():
- queries = request.args.to_dict()
- queries["name"] = queries["name"] if queries.get("name") else None
-
- # transform `role` query into a list for db query
- if queries.get("role") and queries["role"] != "all":
- queries["role"] = [queries["role"]]
- else:
- queries["role"] = visible_roles
-
- pagination = Pagination(request)
- accounts = get_accounts(pagination, queries)
- props = TDAccountsProps(accounts=accounts, role_list=visible_roles, pagination=pagination, currentPage="admin")
-
- response = make_response(
- jsonify(props),
- 200,
- )
- response.headers["Cache-Control"] = "s-maxage=60"
-
- return response
-
-
-class TDAccountChangeBody(TypedDict):
- moderator: list[int]
- consumer: list[int]
-
-
-class TDAccountRoleChangeProps(TypedDict):
- redirect: Literal["/account/administrator/accounts"]
- currentPage: Literal["admin"]
-
-
-@administrator_bp.post("/administrator/accounts")
-def change_account_roles():
- body: TDAccountChangeBody = request.get_json()
- # convert ids to `int`
- candidates = dict(
- moderator=[int(id) for id in body.get("moderator")] if body.get("moderator") else [],
- consumer=[int(id) for id in body.get("consumer")] if body.get("consumer") else [],
- )
-
- if candidates["moderator"]:
- change_account_role(
- candidates["moderator"],
- AccountRoleChange(
- old_role="consumer",
- new_role="moderator",
- ),
- )
- if candidates["consumer"]:
- change_account_role(
- candidates["consumer"],
- AccountRoleChange(
- old_role="moderator",
- new_role="consumer",
- ),
- )
-
- props = TDAccountRoleChangeProps(currentPage="admin", redirect="/account/administrator/accounts")
-
- response = make_response(jsonify(props), 200)
- response.headers["Cache-Control"] = "max-age=0, private, must-revalidate"
-
- return response
diff --git a/src/pages/api/v1/creators.py b/src/pages/api/v1/creators.py
index 02739e6..8ddc752 100644
--- a/src/pages/api/v1/creators.py
+++ b/src/pages/api/v1/creators.py
@@ -491,6 +491,7 @@ def make_artist_display_data(artist: dict) -> ArtistDisplayData:
if pay_site:
return ArtistDisplayData(service=pay_site.title, href=pay_site.user.profile(artist))
+
raise Exception("Service not found in Paysites")
diff --git a/src/pages/api/v1/files.py b/src/pages/api/v1/files.py
index d30cf68..ee10e18 100644
--- a/src/pages/api/v1/files.py
+++ b/src/pages/api/v1/files.py
@@ -27,18 +27,6 @@ def lookup_file(file_hash):
return response
-@v1api_bp.get("/set_password")
-def set_password():
- if not Configuration().archive_server["enabled"]:
- return "false"
- q = get_query_parameters_dict(request)
- file_hash = q.get("file_hash")
- passwords = [password for password in request.args.getlist("password") if password]
- if not file_hash or not passwords or not try_set_password(file_hash, passwords):
- return "false"
- return "true"
-
-
@v1api_bp.route("/shares")
def get_shares_data():
base = request.args.to_dict()
diff --git a/src/pages/api/v1/flags.py b/src/pages/api/v1/flags.py
deleted file mode 100644
index 3fe5ba0..0000000
--- a/src/pages/api/v1/flags.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from flask import make_response, jsonify
-
-from src.config import Configuration
-from src.internals.cache.redis import get_conn
-from src.internals.database.database import query_db
-from src.lib.post import is_post_flagged
-from src.pages.api.v1 import v1api_bp
-
-
-@v1api_bp.route("//user//post//flag", methods=["POST"])
-def flag_post_api(service, creator_id, post):
- query = """
- INSERT INTO booru_flags (id, "user", service)
- SELECT %s, %s, %s
- WHERE NOT EXISTS (
- SELECT 1
- FROM booru_flags
- WHERE id = %s AND "user" = %s AND service = %s
- )
- RETURNING id, service
- """
- rows_returned = query_db(query, (post, creator_id, service, post, creator_id, service))
- get_conn().set(
- f"is_post_flagged:{service}:{creator_id}:{post}", len(rows_returned), ex=Configuration().redis["default_ttl"]
- )
- status_code = 201 if len(rows_returned) else 409
- response = make_response(jsonify(True), status_code)
-
- return response
-
-
-@v1api_bp.route("/user//post//flag", methods=["GET"])
-def flag_api(service, creator_id, post):
- is_flagged = is_post_flagged(service, creator_id, post)
- status_code = 200 if is_flagged else 404
- response = make_response(jsonify(True), status_code)
-
- return response
diff --git a/src/pages/api/v1/importer.py b/src/pages/api/v1/importer.py
index 031671f..f875f52 100644
--- a/src/pages/api/v1/importer.py
+++ b/src/pages/api/v1/importer.py
@@ -8,7 +8,7 @@ from flask import make_response, request, session, jsonify
from src.config import Configuration
from src.internals.cache.redis import get_conn
-from src.internals.database.database import query_db, query_one_db
+from src.internals.database.database import query_db, query_one_db, query_rowcount_db
from src.lib.imports import validate_import_key
from src.lib.api import create_client_error_response
from src.pages.api.v1 import v1api_bp
@@ -138,6 +138,16 @@ def importer_submit():
if existing_imports:
existing_import = existing_imports[0]["job_id"]
+
+ _update_count = query_rowcount_db(
+ f"""
+ UPDATE public.jobs
+ SET priority = LEAST(priority, 1) - 1
+ WHERE job_id = %s;
+ """,
+ (str(existing_import),),
+ )
+
response = make_response(jsonify(import_id=existing_import), 200)
return response
diff --git a/src/pages/api/v1/posts.py b/src/pages/api/v1/posts.py
index d3a9ec2..2cdab7e 100644
--- a/src/pages/api/v1/posts.py
+++ b/src/pages/api/v1/posts.py
@@ -6,11 +6,13 @@ from typing import cast, get_args, TypedDict
from pathlib import PurePath
import dateutil.parser
-from flask import jsonify, make_response, request, url_for, redirect
+from datetime import date
+from flask import jsonify, make_response, request, url_for, redirect, session
from src.config import Configuration
from src.lib.artist import get_artist
from src.lib.post import (
+ flag_post,
get_artist_posts_full,
get_post,
get_post_revisions,
@@ -23,7 +25,9 @@ from src.lib.post import (
patch_inline_img,
TDPostRevision
)
-from src.lib.posts import get_all_posts_for_query, get_all_posts_summary, get_popular_posts_for_date_range, get_all_tags, count_all_posts, Post, count_all_posts_for_query, get_tagged_posts, count_all_posts_for_tag
+from src.lib.posts import get_all_posts_for_query, get_all_posts_summary, get_popular_posts_for_date_range, \
+ get_all_tags, count_all_posts, Post, count_all_posts_for_query, get_tagged_posts, count_all_posts_for_tag, \
+ POST_FLAG_REASON_SLUG_TO_NUMBER
from src.lib.files import get_archive_files
from src.lib.api import create_not_found_error_response, create_client_error_response
from src.pages.artists import do_artist_post_search
@@ -33,6 +37,7 @@ from src.utils.utils import get_query_parameters_dict, parse_int, positive_or_no
from src.pages.api.v1 import v1api_bp
+
@v1api_bp.get("//post/")
def get_by_id(service, post_id):
post = get_post_by_id(post_id, service)
@@ -75,8 +80,10 @@ def list_posts_api(service, creator_id):
return response
+
video_extensions = Configuration().webserver["ui"]["video_extensions"]
+
@v1api_bp.get("//user//post/")
def get_post_api(service, creator_id, post_id):
post = get_post(service, creator_id, post_id)
@@ -100,8 +107,6 @@ def get_post_api(service, creator_id, post_id):
return response
-
-
@v1api_bp.get("//user//post//revisions")
def list_post_revision_api(service, creator_id, post_id):
revisions = get_post_revisions(service, creator_id, post_id)
@@ -110,6 +115,7 @@ def list_post_revision_api(service, creator_id, post_id):
return response
+
@v1api_bp.route("//user//post//revision/")
def get_post_revision(service: str, artist_id: str, post_id: str, revision_id: str):
revisions = get_post_revisions(service, artist_id, post_id) if revision_id.isdigit() else []
@@ -143,6 +149,25 @@ def get_post_revision(service: str, artist_id: str, post_id: str, revision_id: s
return response
+@v1api_bp.post("//user//post//flag")
+def flag_post_api(service, user_id, post_id):
+ flagger_id = session.get("account_id")
+ if not flagger_id:
+ return make_response(jsonify(error="Not logged in"), 401)
+
+ body = request.get_json()
+ reason = body.get("reason")
+
+ if not reason:
+ return make_response(jsonify(error="No reason provided"), 400)
+
+ if reason not in POST_FLAG_REASON_SLUG_TO_NUMBER:
+ return make_response(jsonify(error="Invalid reason provided"), 400)
+
+ result = flag_post(service, user_id, post_id, POST_FLAG_REASON_SLUG_TO_NUMBER[reason], flagger_id, request.remote_addr)
+ return make_response(jsonify(result), 200)
+
+
@v1api_bp.get("/posts")
def recent():
limit = 50
@@ -218,6 +243,7 @@ def recent():
@v1api_bp.get("/posts/random")
def random_post():
post = get_random_post_key(Configuration().webserver.get("table_sample_bernoulli_sample_size"))
+
if post is None:
message = "No post found"
response = make_response(jsonify(error=message), 404)
@@ -239,15 +265,16 @@ def random_post():
@v1api_bp.get("/posts/popular")
def popular_posts():
query_params = get_query_parameters_dict(request)
- earliest_date_for_popular = Configuration().webserver.get("earliest_date_for_popular")
+ earliest_date_for_popular: date = Configuration().webserver.get("earliest_date_for_popular")
# checked below but doesn't typecheck without a cast
- scale: PeriodScale = cast(PeriodScale, query_params.get("period", "recent"))
+ scale = cast(PeriodScale, query_params.get("period", "recent"))
if scale not in get_args(PeriodScale):
scale = "recent"
info, valid_date = parse_scale_string(query_params.get("date"), scale)
does_not_match_step_date = scale != "recent" and info.date.date() != info.navigation_dates[scale][2]
+
if (
not valid_date
or does_not_match_step_date
@@ -255,27 +282,37 @@ def popular_posts():
or info.date.date() < earliest_date_for_popular
):
correct_date = info.navigation_dates[scale][2].isoformat()
+
if info.date.date() > datetime.date.today():
correct_date = datetime.date.today()
scale = "day"
+
elif info.date.date() < earliest_date_for_popular:
correct_date = earliest_date_for_popular
scale = "day"
- new_url = set_query_parameter(url_for("posts.popular_posts"), {"date": correct_date, "period": scale})
+
+ new_url = set_query_parameter(url_for("api.v1.popular_posts"), {"date": correct_date, "period": scale})
response = redirect(new_url)
cache_seconds = int(datetime.timedelta(days=7).total_seconds())
+
if info.date.date() > datetime.date.today():
cache_seconds = int(datetime.timedelta(hours=3).total_seconds())
+
response.headers["Cache-Control"] = f"max-age={cache_seconds}"
+
return response
+
expiry = int(datetime.timedelta(days=30).total_seconds())
+
if scale == "recent":
expiry = int(datetime.timedelta(minutes=30 + 1).total_seconds())
elif info.max_date > datetime.datetime.utcnow():
if scale == "day":
expiry = int(datetime.timedelta(hours=3).total_seconds())
+
elif scale == "week":
expiry = int(datetime.timedelta(days=1).total_seconds())
+
elif scale == "month":
if datetime.date.today().day < 7:
expiry = int(datetime.timedelta(days=1).total_seconds())
@@ -285,10 +322,13 @@ def popular_posts():
pages = Configuration().webserver.get("pages_in_popular")
per_page = 50
offset = positive_or_none(step_int(parse_int(query_params.pop("o", 0), 0), per_page))
+
if offset is None:
response = redirect(url_for("posts.popular_posts"))
response.headers["Cache-Control"] = f"max-age={int(datetime.timedelta(days=7).total_seconds())}"
+
return response
+
posts = get_popular_posts_for_date_range(
info.min_date, info.max_date, scale, offset // per_page, per_page, pages, expiry
)
@@ -314,6 +354,7 @@ def popular_posts():
200,
)
response.headers["Cache-Control"] = f"max-age={int(expiry)}"
+
return response
@@ -330,22 +371,13 @@ def list_tags():
return response
-@v1api_bp.route("/posts/archives/")
-def list_archive(file_hash: str):
- archive = get_archive_files(file_hash)
- response = make_response(jsonify(
- archive=archive,
- file_serving_enabled=Configuration().archive_server["file_serving_enabled"],
- ), 200)
- response.headers["Cache-Control"] = "s-maxage=600"
-
- return response
DOWNLOAD_URL_FANBOX_REGEX = re.compile(r" ")
+
class TDPostProps(TypedDict):
- flagged: int
- revisions: list[tuple[int, TDPostRevision]]
+ flagged: str
+ revisions: list[TDPostRevision]
def ready_post_props_light(post: Post):
diff --git a/src/pages/api/v2/__init__.py b/src/pages/api/v2/__init__.py
new file mode 100644
index 0000000..b03aae2
--- /dev/null
+++ b/src/pages/api/v2/__init__.py
@@ -0,0 +1,49 @@
+from flask import Blueprint, abort, request
+
+from src.lib.api import (
+ create_api_v2_invalid_body_error_response,
+ create_api_v2_error_response,
+ TDAPIRequestBody,
+ APIV2_REQUEST_BODY_TYPE,
+ TDAPIError,
+)
+
+from .file import file_bp
+from .account import account_bp
+
+v2api_bp = Blueprint("v2", __name__, url_prefix="/v2")
+
+methods_with_body = ("POST", "PUT", "PATH", "DELETE")
+
+
+# validate body of request for methods which support bodies
+@v2api_bp.before_request
+def check_api_request():
+ method = request.method
+
+ if method not in methods_with_body:
+ return
+
+ body: TDAPIRequestBody = request.get_json()
+
+ if not (isinstance(body, dict)):
+ abort(create_api_v2_invalid_body_error_response())
+
+ type = body.get("type")
+
+ if not type or type != APIV2_REQUEST_BODY_TYPE:
+ abort(create_api_v2_invalid_body_error_response())
+
+
+@v2api_bp.errorhandler(500)
+def handle_server_error(error: Exception):
+ """
+ TODO: proper logging
+ """
+ responseError = TDAPIError(type="server_error", message="Unknown error.")
+
+ return create_api_v2_error_response(responseError, 500)
+
+
+v2api_bp.register_blueprint(file_bp)
+v2api_bp.register_blueprint(account_bp)
diff --git a/src/pages/api/v2/account/__init__.py b/src/pages/api/v2/account/__init__.py
new file mode 100644
index 0000000..834ed81
--- /dev/null
+++ b/src/pages/api/v2/account/__init__.py
@@ -0,0 +1,33 @@
+from flask import Blueprint, abort
+
+from src.lib.account import (
+ is_logged_in,
+ load_account,
+)
+from src.lib.api import create_api_v2_client_error_response, TDAPIError
+
+from .administrator import administrator_bp
+
+account_bp = Blueprint("account", __name__, url_prefix="/account")
+
+
+# check credentials for all requests for this blueprint
+# so the subsequent handlers wouldn't need to check it again
+@account_bp.before_request
+def check_auth():
+ if not is_logged_in():
+ response = create_api_v2_client_error_response(
+ TDAPIError(type="api_account_not_authenticated", message="Account not authenticated."), 401
+ )
+ abort(response)
+
+ account = load_account()
+
+ if not account:
+ response = create_api_v2_client_error_response(
+ TDAPIError(type="api_account_not_authenticated", message="Account not authenticated."), 401
+ )
+ abort(response)
+
+
+account_bp.register_blueprint(administrator_bp)
diff --git a/src/pages/api/v2/account/administrator/__init__.py b/src/pages/api/v2/account/administrator/__init__.py
new file mode 100644
index 0000000..d4d727c
--- /dev/null
+++ b/src/pages/api/v2/account/administrator/__init__.py
@@ -0,0 +1,23 @@
+from flask import Blueprint, g, abort
+
+from src.lib.api import create_api_v2_not_found_error_response
+from src.types.account import Account
+
+from .accounts import get_accounts_count, get_account_list
+from .account import get_target_account_overview, change_target_account_details
+
+administrator_bp = Blueprint("administrator", __name__, url_prefix="/administrator")
+
+
+@administrator_bp.before_request
+def check_credentials():
+ account: Account = g.get("account")
+
+ if account.role != "administrator":
+ return abort(create_api_v2_not_found_error_response())
+
+
+administrator_bp.get("/accounts")(get_accounts_count)
+administrator_bp.get("/accounts/")(get_account_list)
+administrator_bp.get("/account/")(get_target_account_overview)
+administrator_bp.patch("/account/")(change_target_account_details)
diff --git a/src/pages/api/v2/account/administrator/account.py b/src/pages/api/v2/account/administrator/account.py
new file mode 100644
index 0000000..6a47a24
--- /dev/null
+++ b/src/pages/api/v2/account/administrator/account.py
@@ -0,0 +1,81 @@
+from flask import g, request
+from typing import TypedDict
+
+from src.lib.api import (
+ create_api_v2_response,
+ create_api_v2_client_error_response,
+ TDAPIError,
+ create_api_v2_not_found_error_response,
+ create_api_v2_invalid_body_error_response,
+ get_api_v2_request_data,
+)
+from src.lib.account import load_account
+from src.lib.administrator import change_account_role
+from src.types.account import Account, visible_roles, AccountRoleChange
+
+
+def get_target_account_overview(account_id: str):
+ parsed_account_id = int(account_id)
+
+ if parsed_account_id == 0:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="invalid_id", message="Account ID must be positive.")
+ )
+
+ target_account = load_account(account_id)
+
+ if not target_account:
+ return create_api_v2_not_found_error_response()
+
+ response = create_api_v2_response(target_account)
+
+ return response
+
+
+class TDAccountUpdate(TypedDict):
+ role: str
+
+
+def change_target_account_details(account_id: str):
+ parsed_account_id = int(account_id)
+ body: TDAccountUpdate = get_api_v2_request_data(request)
+
+ if parsed_account_id == 0:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="invalid_id", message="Account ID must be positive.")
+ )
+
+ is_valid_body = body is not None and isinstance(body, dict) and (body.get("role") in visible_roles)
+
+ if not is_valid_body:
+ return create_api_v2_invalid_body_error_response()
+
+ role = body["role"]
+ target_account = load_account(account_id)
+
+ if not target_account:
+ return create_api_v2_not_found_error_response()
+
+ if target_account.role == "administrator":
+ return create_api_v2_client_error_response(
+ TDAPIError(type="http_conflict", message="Cannot change the role of another admin."), 409
+ )
+
+ if target_account.role == role:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="http_conflict", message="Target role is the same as old one."), 409
+ )
+
+ admin_account: Account = g.get("account")
+
+ if admin_account.id == target_account.id:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="http_conflict", message="Cannot change the role of yourself."), 409
+ )
+
+ change_data = AccountRoleChange(old_role=target_account.role, new_role=role)
+ change_account_role([str(target_account.id)], change_data)
+
+ response = create_api_v2_response(account_id)
+
+ return response
diff --git a/src/pages/api/v2/account/administrator/accounts.py b/src/pages/api/v2/account/administrator/accounts.py
new file mode 100644
index 0000000..af3eef9
--- /dev/null
+++ b/src/pages/api/v2/account/administrator/accounts.py
@@ -0,0 +1,45 @@
+from flask import request
+
+from src.lib.pagination import create_pagination
+from src.lib.api import create_api_v2_response, create_api_v2_client_error_response, TDAPIError
+from src.lib.administrator import count_accounts, get_accounts
+
+
+def get_accounts_count():
+ name = request.args.get("name")
+ role = request.args.get("role")
+
+ if name:
+ name = name.strip()
+
+ count = count_accounts(role, name)
+ response = create_api_v2_response(count)
+
+ return response
+
+
+def get_account_list(page: str):
+ current_page = int(page)
+ name = request.args.get("name")
+ role = request.args.get("role")
+
+ if name:
+ name = name.strip()
+
+ if current_page < 1:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="invalid_page", message="Page number must be positive.")
+ )
+
+ count = count_accounts(role, name)
+ pagination = create_pagination(count, current_page)
+
+ if current_page > pagination["total_pages"]:
+ return create_api_v2_client_error_response(
+ TDAPIError(type="invalid_page", message="Page number must not be higher than total pages.")
+ )
+
+ accounts = get_accounts(pagination, role, name)
+ response = create_api_v2_response(accounts)
+
+ return response
diff --git a/src/pages/api/v2/file/__init__.py b/src/pages/api/v2/file/__init__.py
new file mode 100644
index 0000000..ab3782d
--- /dev/null
+++ b/src/pages/api/v2/file/__init__.py
@@ -0,0 +1,12 @@
+from flask import Blueprint
+
+from src.config import Configuration
+
+from .overview import get_file_overview, set_file_password
+
+file_bp = Blueprint("file", __name__, url_prefix="/file")
+
+file_bp.get("/")(get_file_overview)
+
+if Configuration().archive_server["enabled"]:
+ file_bp.patch("/")(set_file_password)
diff --git a/src/pages/api/v2/file/overview.py b/src/pages/api/v2/file/overview.py
new file mode 100644
index 0000000..360f717
--- /dev/null
+++ b/src/pages/api/v2/file/overview.py
@@ -0,0 +1,65 @@
+from typing import TypedDict
+
+from flask import request
+
+from src.lib.api import (
+ create_api_v2_response,
+ create_api_v2_not_found_error_response,
+ get_api_v2_request_data,
+ create_api_v2_invalid_body_error_response,
+ create_api_v2_client_error_response,
+ TDAPIError,
+)
+from src.lib.files import get_archive_files, try_set_password
+
+
+def get_file_overview(file_hash: str):
+ archive = get_archive_files(file_hash)
+
+ if not archive:
+ return create_api_v2_not_found_error_response(600)
+
+ response = create_api_v2_response(archive)
+
+ response.headers["Cache-Control"] = "s-maxage=600"
+
+ return response
+
+
+class TDFileUpdate(TypedDict):
+ password: str
+
+
+def set_file_password(file_hash: str):
+ data: TDFileUpdate = get_api_v2_request_data(request)
+
+ if not isinstance(data, dict):
+ return create_api_v2_invalid_body_error_response()
+
+ password = data.get("password")
+
+ if not password:
+ error = TDAPIError(type="api_invalid_body_data", message="Password is required.")
+
+ return create_api_v2_client_error_response(error)
+
+ archive = get_archive_files(file_hash)
+
+ if not archive:
+ return create_api_v2_not_found_error_response()
+
+ if archive.password:
+ error = TDAPIError(type="api_invalid_body_data", message="Password is already set.")
+
+ return create_api_v2_client_error_response(error, 409)
+
+ is_set = try_set_password(file_hash, [password])
+
+ if not is_set:
+ error = TDAPIError(type="api_invalid_body_data", message="Invalid password.")
+
+ return create_api_v2_client_error_response(error)
+
+ response = create_api_v2_response(file_hash)
+
+ return response
diff --git a/src/pages/post.py b/src/pages/post.py
index 5b1650e..da957a4 100644
--- a/src/pages/post.py
+++ b/src/pages/post.py
@@ -16,6 +16,8 @@ from src.lib.post import (
from src.lib.posts import Post
from src.utils.utils import images_pattern, sanitize_html
+from flask import session
+
video_extensions = Configuration().webserver["ui"]["video_extensions"]
diff --git a/src/server.py b/src/server.py
index 69de826..27a07bf 100644
--- a/src/server.py
+++ b/src/server.py
@@ -7,6 +7,7 @@ from flask import Flask, g, make_response, render_template, request, send_from_d
from flask.json.provider import JSONProvider
from src.config import Configuration
+from src.lib.api import create_api_v2_client_error_response, TDAPIError
app = Flask(
__name__,
@@ -257,6 +258,10 @@ def route_not_found(error):
if request.path.startswith('/api/v1'):
return jsonify(error="Not Found"), 404
+ if request.path.startswith('/api/v2'):
+ error = TDAPIError(type="http_error", message="Not Found")
+ return create_api_v2_client_error_response(error, 404)
+
return error, 404
@app.errorhandler(405)
@@ -264,6 +269,10 @@ def method_not_allowed(error):
if request.path.startswith('/api/v1'):
return jsonify(error="Method Not Allowed"), 405
+ if request.path.startswith('/api/v2'):
+ error = TDAPIError(type="http_error", message="Method Not Allowed")
+ return create_api_v2_client_error_response(error, 405)
+
return error, 405
@app.errorhandler(413)
diff --git a/src/types/account/account.py b/src/types/account/account.py
index cdf8c2f..aede2b8 100644
--- a/src/types/account/account.py
+++ b/src/types/account/account.py
@@ -13,38 +13,3 @@ class Account(DatabaseEntry):
username: str
created_at: datetime
role: str
-
-
-# @dataclass
-# class Consumer(Account):
-# pass
-
-# @dataclass
-# class Moderator(Account):
-# pass
-
-# @dataclass
-# class Administrator(Account):
-# pass
-
-# class Agreement:
-# """
-# The user's agreement.
-# """
-# name: str
-# agreed_at: datetime
-# version: str
-# def is_outdated(self, version: str) -> bool:
-# current_version = parse_version(self.version)
-# new_version = parse_version(version)
-# return current_version < new_version
-
-# class __Import:
-# """
-# The user's import.
-# """
-# id: str
-# service: str
-# approved: list[str]
-# rejected: list[str]
-# pending: list[str]
diff --git a/src/types/account/notification.py b/src/types/account/notification.py
index ba03bb2..e3d6be0 100644
--- a/src/types/account/notification.py
+++ b/src/types/account/notification.py
@@ -12,7 +12,7 @@ class Notification(DatabaseEntry):
account_id: int
type: str
created_at: datetime
- extra_info: Optional[TypedDict]
+ extra_info: Optional[dict]
is_seen: bool = False
diff --git a/src/utils/datetime_.py b/src/utils/datetime_.py
index 10af38a..232f0ce 100644
--- a/src/utils/datetime_.py
+++ b/src/utils/datetime_.py
@@ -16,7 +16,7 @@ class TimeRangeInfo:
date: datetime
min_date: datetime
max_date: datetime
- navigation_dates: dict[PeriodScale, tuple[date, date, date]]
+ navigation_dates: dict[PeriodScale, tuple['date', 'date', 'date']]
range_desc: str
scale: PeriodScale
@@ -32,25 +32,33 @@ def get_minmax_ts(
round_factor = int(round_to.total_seconds())
rounded_seconds = round(now_as_timedelta.total_seconds() / round_factor) * round_factor
rdt = today_as_datetime + timedelta(seconds=rounded_seconds)
+
return rdt - timedelta(days=1), rdt
+
case "day":
+
return (
datetime.combine(input_date, time.min),
datetime.combine(input_date, time.max),
)
+
case "week":
input_date = beginning_of_week(input_date)
+
return (
datetime.combine(beginning_of_week(input_date), time.min),
datetime.combine(next_week(input_date), time.min),
)
+
case "month":
input_date = input_date.replace(day=1)
last_day = calendar.monthrange(input_date.year, input_date.month)[1]
+
return (
datetime.combine(input_date.replace(day=1), time.min),
datetime.combine(input_date.replace(day=last_day), time.max),
)
+
case _:
raise Exception("Invalid scale")
@@ -59,16 +67,21 @@ def surrounding_dates_for_scale(input_date: date, scale: PeriodScale) -> tuple[d
match scale:
case "recent": # not meaningful
delta = relativedelta(hours=24)
+
case "day":
delta = relativedelta(days=1)
+
case "week":
input_date = beginning_of_week(input_date)
delta = relativedelta(days=7)
+
case "month":
input_date = input_date.replace(day=1)
delta = relativedelta(months=1)
+
case _:
raise Exception("Invalid scale")
+
return input_date - delta, input_date + delta, input_date
@@ -76,18 +89,23 @@ def date_range_description(input_date: datetime, scale: PeriodScale) -> str:
match scale:
case "recent":
return "the past 24 hours"
+
case "day":
return input_date.strftime("%B %d, %Y")
+
case "week":
min_date = beginning_of_week(input_date)
max_date = next_week(input_date)
+
return f"{min_date.strftime("%B %d, %Y")} - {max_date.strftime("%B %d, %Y")}"
+
case "month":
return input_date.strftime("%B %Y")
def beginning_of_week(input_date: date) -> date:
days_to_monday = input_date.weekday() - 1 if input_date.weekday() != 0 else 6
+
return input_date - timedelta(days=days_to_monday)
@@ -97,6 +115,7 @@ def next_week(input_datetime: date) -> date:
def parse_scale_string(date_string: str | None, scale: PeriodScale = "recent") -> tuple[TimeRangeInfo, bool]:
valid_date = True
+
if date_string is None:
parsed_date = datetime.now()
else:
@@ -107,8 +126,10 @@ def parse_scale_string(date_string: str | None, scale: PeriodScale = "recent") -
valid_date = False
nav: dict[PeriodScale, tuple[date, date, date]] = {}
+
for period in get_args(PeriodScale):
nav[period] = surrounding_dates_for_scale(parsed_date.date(), period)
+
desc = date_range_description(parsed_date, scale)
(min_date, max_date) = get_minmax_ts(parsed_date, scale)