mirror of
https://github.com/TheBinaryNinja/tvapp2.git
synced 2026-06-07 10:05:41 -04:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
0690e1551b
|
|||
|
d1a7460c05
|
|||
|
70e349d7e3
|
|||
|
568c3fc219
|
|||
|
f55ecae8f3
|
|||
|
e4436ad7b7
|
|||
|
67d7019a93
|
|||
|
4b45c0a2a2
|
|||
|
b3aae7b837
|
|||
|
122286bd7b
|
|||
|
6708bb17a3
|
|||
|
5fa7cd9d85
|
|||
|
25ac27dd64
|
|||
|
a659e03512
|
|||
|
4d081adda2
|
|||
|
279d48d8ee
|
|||
|
c017578631
|
|||
|
f4baade73b
|
|||
|
f68053b461
|
|||
|
ec18ceb6db
|
|||
|
68c4778ed8
|
|||
|
cf28156e70
|
|||
|
149fe89f89
|
|||
|
c124d93285
|
|||
|
06e5d42c9c
|
|||
|
c42b60a58c
|
|||
|
1e8bdcddd8
|
|||
|
90c2295bb8
|
|||
|
cca7b48d3b
|
|||
|
2d9dec2d74
|
|||
|
30741f124e
|
|||
|
f256a9db06
|
|||
|
baf850308f
|
|||
|
|
d9174d2a20 |
@@ -452,6 +452,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=amd64
|
ARCH=amd64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
@@ -503,6 +504,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=arm64
|
ARCH=arm64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/deploy-docker-gitea.yml
vendored
2
.github/workflows/deploy-docker-gitea.yml
vendored
@@ -576,6 +576,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=amd64
|
ARCH=amd64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
@@ -627,6 +628,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=arm64
|
ARCH=arm64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/deploy-docker-github.yml
vendored
2
.github/workflows/deploy-docker-github.yml
vendored
@@ -455,6 +455,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=amd64
|
ARCH=amd64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
@@ -511,6 +512,7 @@ jobs:
|
|||||||
sbom: false
|
sbom: false
|
||||||
build-args: |-
|
build-args: |-
|
||||||
ARCH=arm64
|
ARCH=arm64
|
||||||
|
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
|
||||||
VERSION=${{ env.IMAGE_VERSION }}
|
VERSION=${{ env.IMAGE_VERSION }}
|
||||||
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ FROM --platform=linux/${ARCH} ghcr.io/aetherinox/alpine-base:3.21
|
|||||||
ARG ARCH=amd64
|
ARG ARCH=amd64
|
||||||
ARG BUILDDATE
|
ARG BUILDDATE
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
|
ARG RELEASE
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Set Labels
|
# Set Labels
|
||||||
@@ -56,6 +57,7 @@ LABEL org.opencontainers.image.licenses="MIT"
|
|||||||
LABEL org.opencontainers.image.architecture="${ARCH}"
|
LABEL org.opencontainers.image.architecture="${ARCH}"
|
||||||
LABEL org.opencontainers.image.ref.name="main"
|
LABEL org.opencontainers.image.ref.name="main"
|
||||||
LABEL org.opencontainers.image.registry="local"
|
LABEL org.opencontainers.image.registry="local"
|
||||||
|
LABEL org.opencontainers.image.release="${RELEASE}"
|
||||||
LABEL org.tvapp2.image.maintainers="Aetherinox, iFlip721, Optx"
|
LABEL org.tvapp2.image.maintainers="Aetherinox, iFlip721, Optx"
|
||||||
LABEL org.tvapp2.image.build-version="Version:- ${VERSION} Date:- ${BUILDDATE}"
|
LABEL org.tvapp2.image.build-version="Version:- ${VERSION} Date:- ${BUILDDATE}"
|
||||||
|
|
||||||
@@ -65,16 +67,19 @@ LABEL org.tvapp2.image.build-version="Version:- ${VERSION} Date:- ${BUILDDATE}"
|
|||||||
|
|
||||||
ENV NODE_VERSION=22.8.0
|
ENV NODE_VERSION=22.8.0
|
||||||
ENV YARN_VERSION=1.22.22
|
ENV YARN_VERSION=1.22.22
|
||||||
|
ENV RELEASE="${RELEASE}"
|
||||||
ENV DIR_BUILD=/usr/src/app
|
ENV DIR_BUILD=/usr/src/app
|
||||||
ENV DIR_RUN=/usr/bin/app
|
ENV DIR_RUN=/usr/bin/app
|
||||||
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
|
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
|
||||||
ENV WEB_IP="0.0.0.0"
|
ENV WEB_IP="0.0.0.0"
|
||||||
ENV WEB_PORT=4124
|
ENV WEB_PORT=4124
|
||||||
|
ENV WEB_ENCODING="deflate, br"
|
||||||
ENV STREAM_QUALITY="hd"
|
ENV STREAM_QUALITY="hd"
|
||||||
ENV FILE_URL="urls.txt"
|
ENV FILE_URL="urls.txt"
|
||||||
ENV FILE_M3U="playlist.m3u8"
|
ENV FILE_M3U="playlist.m3u8"
|
||||||
ENV FILE_EPG="xmltv.xml"
|
ENV FILE_EPG="xmltv.xml"
|
||||||
ENV FILE_TAR="xmltv.xml.gz"
|
ENV FILE_TAR="xmltv.xml.gz"
|
||||||
|
ENV HEALTH_TIMER=600000
|
||||||
ENV LOG_LEVEL=4
|
ENV LOG_LEVEL=4
|
||||||
ENV TZ="Etc/UTC"
|
ENV TZ="Etc/UTC"
|
||||||
|
|
||||||
|
|||||||
183
README.md
183
README.md
@@ -69,6 +69,7 @@
|
|||||||
- [Docker Compose](#docker-compose-1)
|
- [Docker Compose](#docker-compose-1)
|
||||||
- [Environment Variables](#environment-variables-1)
|
- [Environment Variables](#environment-variables-1)
|
||||||
- [Mountable Volumes](#mountable-volumes-1)
|
- [Mountable Volumes](#mountable-volumes-1)
|
||||||
|
- [Docker health check](#docker-health-check)
|
||||||
- [Traefik Integration](#traefik-integration)
|
- [Traefik Integration](#traefik-integration)
|
||||||
- [Labels](#labels)
|
- [Labels](#labels)
|
||||||
- [Dynamic.yml](#dynamicyml)
|
- [Dynamic.yml](#dynamicyml)
|
||||||
@@ -84,6 +85,7 @@
|
|||||||
- [Run Error: `Error serving playlist: ENOENT: no such file or directory, open /usr/src/app/xmltv.1.xml`](#run-error-error-serving-playlist-enoent-no-such-file-or-directory-open-usrsrcappxmltv1xml)
|
- [Run Error: `Error serving playlist: ENOENT: no such file or directory, open /usr/src/app/xmltv.1.xml`](#run-error-error-serving-playlist-enoent-no-such-file-or-directory-open-usrsrcappxmltv1xml)
|
||||||
- [Build Error: `s6-rc-compile: fatal: invalid /etc/s6-overlay/s6-rc.d/certsync/type: must be oneshot, longrun, or bundle`](#build-error-s6-rc-compile-fatal-invalid-etcs6-overlays6-rcdcertsynctype-must-be-oneshot-longrun-or-bundle)
|
- [Build Error: `s6-rc-compile: fatal: invalid /etc/s6-overlay/s6-rc.d/certsync/type: must be oneshot, longrun, or bundle`](#build-error-s6-rc-compile-fatal-invalid-etcs6-overlays6-rcdcertsynctype-must-be-oneshot-longrun-or-bundle)
|
||||||
- [Build Error: `unable to exec /etc/s6-overlay/s6-rc.d/init-envfile/run: Permission denied`](#build-error-unable-to-exec-etcs6-overlays6-rcdinit-envfilerun-permission-denied)
|
- [Build Error: `unable to exec /etc/s6-overlay/s6-rc.d/init-envfile/run: Permission denied`](#build-error-unable-to-exec-etcs6-overlays6-rcdinit-envfilerun-permission-denied)
|
||||||
|
- [Build Error: `[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.`](#build-error-err-27-jellyfinlivetvguideguidemanager-error-getting-programs-for-channel-xxxxxxxxxxxxxxx-source-2-systemxmlxmlexception--hexadecimal-value-0x1f-is-an-invalid-character-line-1-position-1)
|
||||||
- [Extra Notes](#extra-notes)
|
- [Extra Notes](#extra-notes)
|
||||||
- [Accessing Container Shell](#accessing-container-shell)
|
- [Accessing Container Shell](#accessing-container-shell)
|
||||||
- [ash](#ash)
|
- [ash](#ash)
|
||||||
@@ -112,6 +114,7 @@
|
|||||||
|
|
||||||
This project contains several repositories which all share the same code; use them as backups:
|
This project contains several repositories which all share the same code; use them as backups:
|
||||||
|
|
||||||
|
- [🔀 dockerhub:thebinaryninja/tvapp2](https://hub.docker.com/r/thebinaryninja/tvapp2)
|
||||||
- [🔀 github:thebinaryninja/tvapp2](https://github.com/thebinaryninja/tvapp2)
|
- [🔀 github:thebinaryninja/tvapp2](https://github.com/thebinaryninja/tvapp2)
|
||||||
- [🔀 gitea:git.binaryninja.net/binaryninja/tvapp2](https://git.binaryninja.net/binaryninja/tvapp2)
|
- [🔀 gitea:git.binaryninja.net/binaryninja/tvapp2](https://git.binaryninja.net/binaryninja/tvapp2)
|
||||||
|
|
||||||
@@ -152,11 +155,12 @@ For the [environment variables](#environment-variables), you may specify these i
|
|||||||
| `TZ` | `Etc/UTC` | Timezone for error / log reporting |
|
| `TZ` | `Etc/UTC` | Timezone for error / log reporting |
|
||||||
| `WEB_IP` | `0.0.0.0` | IP to use for webserver |
|
| `WEB_IP` | `0.0.0.0` | IP to use for webserver |
|
||||||
| `WEB_PORT` | `4124` | Port to use for webserver |
|
| `WEB_PORT` | `4124` | Port to use for webserver |
|
||||||
|
| `WEB_ENCODING` | `deflate, br` | Defines the HTTP `Accept-Encoding` request and response header. This value specifies what content encoding the sender can understand<br /><br />Gzip compression can be enabled by specifying `'gzip, deflate, br'` |
|
||||||
| `URL_REPO` | `https://git.binaryninja.net/BinaryNinja/` | Determines where the data files will be downloaded from. Do not change this or you will be unable to get M3U and EPG data. |
|
| `URL_REPO` | `https://git.binaryninja.net/BinaryNinja/` | Determines where the data files will be downloaded from. Do not change this or you will be unable to get M3U and EPG data. |
|
||||||
| `FILE_URL` | `urls.txt` | Filename for url cache file |
|
| `FILE_URL` | `urls.txt` | Filename for `urls.txt` cache file |
|
||||||
| `FILE_M3U` | `playlist.m3u8` | Filename for M3U playlist file |
|
| `FILE_M3U` | `playlist.m3u8` | Filename for M3U playlist file |
|
||||||
| `FILE_EPG` | `xmltv.xml` | Filename for XML guide data file |
|
| `FILE_EPG` | `xmltv.xml` | Filename for XML guide data file |
|
||||||
| `FILE_GZIP` | `xmltv.xml.gz` | Filename for XML compressed as gzip .gz |
|
| `FILE_GZP` | `xmltv.xml.gz` | Filename for XML compressed as gzip .gz |
|
||||||
| `STREAM_QUALITY` | `hd` | Stream quality<br />Can be either `hd` or `sd` |
|
| `STREAM_QUALITY` | `hd` | Stream quality<br />Can be either `hd` or `sd` |
|
||||||
| `DIR_BUILD` | `/usr/src/app` | Path inside container where TVApp2 will be built. <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
| `DIR_BUILD` | `/usr/src/app` | Path inside container where TVApp2 will be built. <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
||||||
| `DIR_RUN` | `/usr/bin/app` | Path inside container where TVApp2 will be placed after it is built <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
| `DIR_RUN` | `/usr/bin/app` | Path inside container where TVApp2 will be placed after it is built <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
||||||
@@ -206,7 +210,7 @@ docker run -d --restart=unless-stopped \
|
|||||||
|
|
||||||
If you want to use a `📄 docker-compose.yml` to bring TVApp2 up; you may use the following example:
|
If you want to use a `📄 docker-compose.yml` to bring TVApp2 up; you may use the following example:
|
||||||
|
|
||||||
```yml ignore
|
```yml
|
||||||
services:
|
services:
|
||||||
tvapp2:
|
tvapp2:
|
||||||
container_name: tvapp2
|
container_name: tvapp2
|
||||||
@@ -356,7 +360,7 @@ This repository offers two types of docker image; `stable` and `development`. Yo
|
|||||||
|
|
||||||
| Build | Tags |
|
| Build | Tags |
|
||||||
| ------------------------- | ----------------------------------------------------------------------------- |
|
| ------------------------- | ----------------------------------------------------------------------------- |
|
||||||
| `Stable` | `🔖 tvapp2:latest` <br /> `🔖 tvapp2:1.1.0` <br /> `🔖 tvapp2:1.1` <br /> `🔖 tvapp2:1` |
|
| `Stable` | `🔖 tvapp2:latest` <br /> `🔖 tvapp2:1.2.0` <br /> `🔖 tvapp2:1.2` <br /> `🔖 tvapp2:1` |
|
||||||
| `Development` | `🔖 tvapp2:development` |
|
| `Development` | `🔖 tvapp2:development` |
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -563,11 +567,11 @@ Creates the TVApp2 `amd64` docker image:
|
|||||||
# Build tvapp2 amd64
|
# Build tvapp2 amd64
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=amd64 \
|
--build-arg ARCH=amd64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1.0 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2.0 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:2 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
--attest type=sbom,disabled=true \
|
--attest type=sbom,disabled=true \
|
||||||
@@ -591,10 +595,10 @@ Creates the TVApp2 `arm64` docker image:
|
|||||||
# Build tvapp2 arm64
|
# Build tvapp2 arm64
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=arm64 \
|
--build-arg ARCH=arm64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1.0 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2.0 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
@@ -723,8 +727,8 @@ docker run --privileged --rm tonistiigi/binfmt --install all
|
|||||||
|
|
||||||
Once the emulator is installed; we will now build two images. When building these two images; we will ensure the `--tag` value is different for each one, by adding the architecture to the end. This ensures we don't overwrite one image with the newer one. We need to have two seperate docker images with two different tags.
|
Once the emulator is installed; we will now build two images. When building these two images; we will ensure the `--tag` value is different for each one, by adding the architecture to the end. This ensures we don't overwrite one image with the newer one. We need to have two seperate docker images with two different tags.
|
||||||
|
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64`
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64`
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -735,10 +739,10 @@ Once the emulator is installed; we will now build two images. When building thes
|
|||||||
>
|
>
|
||||||
> | Registry | Tag |
|
> | Registry | Tag |
|
||||||
> | --- | --- |
|
> | --- | --- |
|
||||||
> | Dockerhub | `--tag thebinaryninja/tvapp2:1.1.0-amd64`<br>`--tag thebinaryninja/tvapp2:1.1.0-arm64` |
|
> | Dockerhub | `--tag thebinaryninja/tvapp2:1.2.0-amd64`<br>`--tag thebinaryninja/tvapp2:1.2.0-arm64` |
|
||||||
> | Github (GHCR) | `--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64`<br>`--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64` |
|
> | Github (GHCR) | `--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64`<br>`--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64` |
|
||||||
> | Registry v2 | `--tag registry.domain.lan/thebinaryninja/tvapp2:1.1.0-amd64`<br>`--tag registry.domain.lan/thebinaryninja/tvapp2:1.1.0-arm64` |
|
> | Registry v2 | `--tag registry.domain.lan/thebinaryninja/tvapp2:1.2.0-amd64`<br>`--tag registry.domain.lan/thebinaryninja/tvapp2:1.2.0-arm64` |
|
||||||
> | Gitea | `--tag git.binaryninja.net/binaryninja/tvapp2:1.1.0-amd64`<br>`--tag git.binaryninja.net/binaryninja/tvapp2:1.1.0-arm64` |
|
> | Gitea | `--tag git.binaryninja.net/binaryninja/tvapp2:1.2.0-amd64`<br>`--tag git.binaryninja.net/binaryninja/tvapp2:1.2.0-arm64` |
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -759,9 +763,9 @@ Creates the TVApp2 **Stable** release `amd64` docker image:
|
|||||||
# Build Tvapp2 amd64 - (stable release)
|
# Build Tvapp2 amd64 - (stable release)
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=amd64 \
|
--build-arg ARCH=amd64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64 \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
--attest type=sbom,disabled=true \
|
--attest type=sbom,disabled=true \
|
||||||
--file Dockerfile \
|
--file Dockerfile \
|
||||||
@@ -785,9 +789,9 @@ Creates the TVApp2 **Stable** release `arm64` docker image:
|
|||||||
# Build Tvapp2 arm64 - (stable release)
|
# Build Tvapp2 arm64 - (stable release)
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=arm64 \
|
--build-arg ARCH=arm64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64 \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
--attest type=sbom,disabled=true \
|
--attest type=sbom,disabled=true \
|
||||||
--file Dockerfile \
|
--file Dockerfile \
|
||||||
@@ -811,8 +815,8 @@ Creates the TVApp2 **Development** release `amd64` docker image:
|
|||||||
# Build Tvapp2 amd64 - (development release)
|
# Build Tvapp2 amd64 - (development release)
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=amd64 \
|
--build-arg ARCH=amd64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:development-amd64 \
|
--tag ghcr.io/thebinaryninja/tvapp2:development-amd64 \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
--attest type=sbom,disabled=true \
|
--attest type=sbom,disabled=true \
|
||||||
@@ -837,8 +841,8 @@ Creates the TVApp2 **Development** release `arm64` docker image:
|
|||||||
# Build Tvapp2 arm64 - (development release)
|
# Build Tvapp2 arm64 - (development release)
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg ARCH=arm64 \
|
--build-arg ARCH=arm64 \
|
||||||
--build-arg VERSION=1.1.0 \
|
--build-arg VERSION=1.2.0 \
|
||||||
--build-arg BUILDDATE=20250325 \
|
--build-arg BUILDDATE=20250407 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:development-arm64 \
|
--tag ghcr.io/thebinaryninja/tvapp2:development-arm64 \
|
||||||
--attest type=provenance,disabled=true \
|
--attest type=provenance,disabled=true \
|
||||||
--attest type=sbom,disabled=true \
|
--attest type=sbom,disabled=true \
|
||||||
@@ -857,8 +861,8 @@ docker buildx build \
|
|||||||
|
|
||||||
After completing the `docker buildx` commands above; you should now have a few new images. Each image should have its own separate docker tags which do not conflict. If you decided to not build the **development** releases below; that is fine.
|
After completing the `docker buildx` commands above; you should now have a few new images. Each image should have its own separate docker tags which do not conflict. If you decided to not build the **development** releases below; that is fine.
|
||||||
|
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64`
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64`
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:development-amd64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:development-amd64`
|
||||||
- `--tag ghcr.io/thebinaryninja/tvapp2:development-arm64`
|
- `--tag ghcr.io/thebinaryninja/tvapp2:development-arm64`
|
||||||
|
|
||||||
@@ -884,15 +888,15 @@ You can also get the hash digests by running the commands:
|
|||||||
<br />
|
<br />
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64
|
$ docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64
|
||||||
|
|
||||||
Name: ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64
|
Name: ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64
|
||||||
MediaType: application/vnd.docker.distribution.manifest.v2+json
|
MediaType: application/vnd.docker.distribution.manifest.v2+json
|
||||||
Digest: sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b
|
Digest: sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b
|
||||||
|
|
||||||
$ docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64
|
$ docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64
|
||||||
|
|
||||||
Name: ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64
|
Name: ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64
|
||||||
MediaType: application/vnd.docker.distribution.manifest.v2+json
|
MediaType: application/vnd.docker.distribution.manifest.v2+json
|
||||||
Digest: sha256:e68b9de8669eac64d4e4d2a8343c56705e05e9a907cf0b542343f9b536d9c473
|
Digest: sha256:e68b9de8669eac64d4e4d2a8343c56705e05e9a907cf0b542343f9b536d9c473
|
||||||
```
|
```
|
||||||
@@ -938,14 +942,14 @@ Digest: sha256:c719ccb034946e3f0625003f25026d001768794e38a1ba8aafc9146291d548
|
|||||||
> ```shell
|
> ```shell
|
||||||
> $ docker images --all --no-trunc | grep thebinaryninja
|
> $ docker images --all --no-trunc | grep thebinaryninja
|
||||||
>
|
>
|
||||||
> ghcr.io/thebinaryninja/tvapp2 1.1.0-arm64 sha256:48520ca15fed6483d2d5b79993126c311f833002345b0e12b8eceb5bf9def966 42 minutes ago 46MB
|
> ghcr.io/thebinaryninja/tvapp2 1.2.0-arm64 sha256:48520ca15fed6483d2d5b79993126c311f833002345b0e12b8eceb5bf9def966 42 minutes ago 46MB
|
||||||
>
|
>
|
||||||
> ghcr.io/thebinaryninja/tvapp2 1.1.0-amd64 sha256:54a9b7d390199532d5667fae67120d77e2f459bd6108b27ce94e0cfec8f3c41f 43 minutes ago 45MB
|
> ghcr.io/thebinaryninja/tvapp2 1.2.0-amd64 sha256:54a9b7d390199532d5667fae67120d77e2f459bd6108b27ce94e0cfec8f3c41f 43 minutes ago 45MB
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> To get the correct sha256 digest, use:
|
> To get the correct sha256 digest, use:
|
||||||
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64`
|
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64`
|
||||||
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64`
|
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64`
|
||||||
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-amd64`
|
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-amd64`
|
||||||
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-arm64`
|
> - `docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-arm64`
|
||||||
>
|
>
|
||||||
@@ -965,8 +969,8 @@ For the **stable** releases, use:
|
|||||||
# #
|
# #
|
||||||
|
|
||||||
docker buildx imagetools create \
|
docker buildx imagetools create \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1.0 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2.0 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1.1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1.2 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:1 \
|
--tag ghcr.io/thebinaryninja/tvapp2:1 \
|
||||||
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
--tag ghcr.io/thebinaryninja/tvapp2:latest \
|
||||||
sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b \
|
sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b \
|
||||||
@@ -974,9 +978,9 @@ docker buildx imagetools create \
|
|||||||
|
|
||||||
[+] Building 0.2s (4/4) FINISHED
|
[+] Building 0.2s (4/4) FINISHED
|
||||||
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:latest 0.2s
|
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:latest 0.2s
|
||||||
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1.1 0.2s
|
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1.2 0.2s
|
||||||
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1 0.2s
|
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1 0.2s
|
||||||
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1.1.0 0.2s
|
=> [internal] pushing ghcr.io/thebinaryninja/tvapp2:1.2.0 0.2s
|
||||||
```
|
```
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -1022,8 +1026,8 @@ In this example, we take the existing two files we created earlier, and merge th
|
|||||||
```shell
|
```shell
|
||||||
# Example 1 (using tag)
|
# Example 1 (using tag)
|
||||||
docker manifest create ghcr.io/thebinaryninja/tvapp2:latest \
|
docker manifest create ghcr.io/thebinaryninja/tvapp2:latest \
|
||||||
--amend ghcr.io/thebinaryninja/tvapp2:1.1.0-amd64 \
|
--amend ghcr.io/thebinaryninja/tvapp2:1.2.0-amd64 \
|
||||||
--amend ghcr.io/thebinaryninja/tvapp2:1.1.0-arm64
|
--amend ghcr.io/thebinaryninja/tvapp2:1.2.0-arm64
|
||||||
|
|
||||||
# Example 2 (using sha256 hash)
|
# Example 2 (using sha256 hash)
|
||||||
docker manifest create ghcr.io/thebinaryninja/tvapp2:latest \
|
docker manifest create ghcr.io/thebinaryninja/tvapp2:latest \
|
||||||
@@ -1064,7 +1068,7 @@ To build the project, `🗔 cd` into the project folder and run the build comman
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
cd /home/docker/tvapp2/
|
cd /home/docker/tvapp2/
|
||||||
npm run docker:build:amd64 --VERSION=1.1.0 --BUILDDATE=20250325
|
npm run docker:build:amd64 --VERSION=1.2.0 --BUILDDATE=20250407
|
||||||
```
|
```
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -1089,7 +1093,7 @@ The run command above has several variables you must specify:
|
|||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `--VERSION=1.X.X` | The version to assign to the docker image |
|
| `--VERSION=1.X.X` | The version to assign to the docker image |
|
||||||
| `--BUILDDATE=20250325` | The date to assign to the docker image. <br /> Date format: `YYYYMMDD` |
|
| `--BUILDDATE=20250407` | The date to assign to the docker image. <br /> Date format: `YYYYMMDD` |
|
||||||
| `--ARCH=amd64` | Architecture for image<br /> <sub><sup>Options:</sup></sub> `amd64`, `arm64` |
|
| `--ARCH=amd64` | Architecture for image<br /> <sub><sup>Options:</sup></sub> `amd64`, `arm64` |
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -1139,7 +1143,7 @@ sudo nano /home/docker/tvapp2/docker-compose.yml
|
|||||||
|
|
||||||
Add the following to your `📄 docker-compose.yml`:
|
Add the following to your `📄 docker-compose.yml`:
|
||||||
|
|
||||||
```yml ignore
|
```yml
|
||||||
services:
|
services:
|
||||||
tvapp2:
|
tvapp2:
|
||||||
container_name: tvapp2
|
container_name: tvapp2
|
||||||
@@ -1188,11 +1192,12 @@ This docker container contains the following env variables:
|
|||||||
| `TZ` | `Etc/UTC` | Timezone for error / log reporting |
|
| `TZ` | `Etc/UTC` | Timezone for error / log reporting |
|
||||||
| `WEB_IP` | `0.0.0.0` | IP to use for webserver |
|
| `WEB_IP` | `0.0.0.0` | IP to use for webserver |
|
||||||
| `WEB_PORT` | `4124` | Port to use for webserver |
|
| `WEB_PORT` | `4124` | Port to use for webserver |
|
||||||
|
| `WEB_ENCODING` | `deflate, br` | Defines the HTTP `Accept-Encoding` request and response header. This value specifies what content encoding the sender can understand<br /><br />Gzip compression can be enabled by specifying `'gzip, deflate, br'` |
|
||||||
| `URL_REPO` | `https://git.binaryninja.net/BinaryNinja/` | Determines where the data files will be downloaded from. Do not change this or you will be unable to get M3U and EPG data. |
|
| `URL_REPO` | `https://git.binaryninja.net/BinaryNinja/` | Determines where the data files will be downloaded from. Do not change this or you will be unable to get M3U and EPG data. |
|
||||||
| `FILE_URL` | `urls.txt` | Filename for `urls.txt` cache file |
|
| `FILE_URL` | `urls.txt` | Filename for `urls.txt` cache file |
|
||||||
| `FILE_M3U` | `playlist.m3u8` | Filename for M3U playlist file |
|
| `FILE_M3U` | `playlist.m3u8` | Filename for M3U playlist file |
|
||||||
| `FILE_EPG` | `xmltv.xml` | Filename for XML guide data file |
|
| `FILE_EPG` | `xmltv.xml` | Filename for XML guide data file |
|
||||||
| `FILE_GZIP` | `xmltv.xml.gz` | Filename for XML compressed as gzip .gz |
|
| `FILE_GZP` | `xmltv.xml.gz` | Filename for XML compressed as gzip .gz |
|
||||||
| `STREAM_QUALITY` | `hd` | Stream quality<br />Can be either `hd` or `sd` |
|
| `STREAM_QUALITY` | `hd` | Stream quality<br />Can be either `hd` or `sd` |
|
||||||
| `DIR_BUILD` | `/usr/src/app` | Path inside container where TVApp2 will be built. <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
| `DIR_BUILD` | `/usr/src/app` | Path inside container where TVApp2 will be built. <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
||||||
| `DIR_RUN` | `/usr/bin/app` | Path inside container where TVApp2 will be placed after it is built <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
| `DIR_RUN` | `/usr/bin/app` | Path inside container where TVApp2 will be placed after it is built <br /><br /> <sup>⚠️ This should not be used unless you know what you're doing</sup> |
|
||||||
@@ -1210,6 +1215,51 @@ These paths can be mounted and shared between the TVApp2 docker container and yo
|
|||||||
| `📁 /usr/bin/app` | <sub>Path where TVApp2 files will be placed once the app has been built. Includes `📄 formatted.dat`, `📄 xmltv.1.xml`, `📄 urls.txt`, `📁 node_modules`, and `📄 package.json`</sub> |
|
| `📁 /usr/bin/app` | <sub>Path where TVApp2 files will be placed once the app has been built. Includes `📄 formatted.dat`, `📄 xmltv.1.xml`, `📄 urls.txt`, `📁 node_modules`, and `📄 package.json`</sub> |
|
||||||
| `📁 /config` | <sub>Where logs will be placed, as well as the web server generated SSH key and cert `🔑 cert.key` and `🪪 cert.crt`</sub> |
|
| `📁 /config` | <sub>Where logs will be placed, as well as the web server generated SSH key and cert `🔑 cert.key` and `🪪 cert.crt`</sub> |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Docker health check
|
||||||
|
|
||||||
|
This image includes a docker health check that you can define in your `📄 docker-compose.yml` file. You can view the health check status by opening your browser and going to your TVApp2 container's `health` path:
|
||||||
|
|
||||||
|
```
|
||||||
|
http://container-ip:4124/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
You should see something similar to the following response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ip": "172.XX.XX.4",
|
||||||
|
"gateway": "172.XX.XX.1",
|
||||||
|
"uptime": 2703.316357306,
|
||||||
|
"message": "Healthy",
|
||||||
|
"timestamp": 1744152471451
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
To apply a health check, open your TVApp2 `docker-compose.yml` and add any of the following options:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
# Example 1 (Using curl)
|
||||||
|
health check:
|
||||||
|
test: "curl --fail --silent http://127.0.0.1:${JELLYFIN_SCRAPER_TVAPP2_PORT_MAIN:-4124}/api/health | grep -i healthy || exit 1"
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
# Example 1 (Using wget)
|
||||||
|
health check:
|
||||||
|
test: "wget -qO- http://127.0.0.1:${JELLYFIN_SCRAPER_TVAPP2_PORT_MAIN:-4124}/api/health | grep -i healthy || exit 1"
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -1245,7 +1295,7 @@ We will be setting up the following:
|
|||||||
|
|
||||||
To add TVApp2 to Traefik, you will need to open your `📄 docker-compose.yml` and apply the following labels to your TVApp2 container. Ensure you change `domain.lan` to your actual domain name.
|
To add TVApp2 to Traefik, you will need to open your `📄 docker-compose.yml` and apply the following labels to your TVApp2 container. Ensure you change `domain.lan` to your actual domain name.
|
||||||
|
|
||||||
```yml ignore
|
```yml
|
||||||
services:
|
services:
|
||||||
tvapp2:
|
tvapp2:
|
||||||
container_name: tvapp2
|
container_name: tvapp2
|
||||||
@@ -1843,6 +1893,39 @@ find ./ -name 'run' -exec sudo chmod +x {} \;
|
|||||||
|
|
||||||
After you have set these permissions, re-build your docker image using `docker build` or `docker buildx`. Then spin the container up.
|
After you have set these permissions, re-build your docker image using `docker build` or `docker buildx`. Then spin the container up.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### Build Error: `[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.`
|
||||||
|
|
||||||
|
This error may be seen if you are attempting to import our EPG guide data directly into Jellyfin. The cause of this is due to you having **GZIP Compression** enabled in your header request and response. See the example below; which is in your TVApp2 `📄 docker-compose.yml` file:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
hostname: tvapp2
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
LOG_LEVEL: 10
|
||||||
|
WEB_ENCODING: 'gzip, deflate, br'
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
To fix the issue, add or change the environment variable `WEB_ENCODING` and ensure `gzip` is not specified in the list like the following:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
hostname: tvapp2
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
LOG_LEVEL: 10
|
||||||
|
WEB_ENCODING: 'deflate, br'
|
||||||
|
```
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
120
docs/docs/config/volumes.md
Normal file
120
docs/docs/config/volumes.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
title: Environment Variables
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mountable Volumes
|
||||||
|
|
||||||
|
Mountable volumes in Docker allow you to share folders within a docker container with your host machine. This allows you to access these specific files without having to bash into the container and using the terminal to navigate around.
|
||||||
|
|
||||||
|
The TVApp2 docker image provides a few different paths that you can mount to your host machine; as outlined below.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 📁 /usr/bin/app
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `Etc/UTC` -->
|
||||||
|
|
||||||
|
The `TZ` environment variable specifies the timezone that your docker container will
|
||||||
|
utilize. This is useful for syncing your local time with console outputs such as
|
||||||
|
our logging system.
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- TZ=Etc/UTC # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this env variable will change the time for anything
|
||||||
|
related to the TVApp2 docker container.
|
||||||
|
|
||||||
|
=== "Timezones"
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
Etc/UTC
|
||||||
|
Africa/Cairo
|
||||||
|
Africa/Johannesburg
|
||||||
|
Africa/Lagos
|
||||||
|
America/Argentina/Buenos_Aires
|
||||||
|
America/Bogota
|
||||||
|
America/Caracas
|
||||||
|
America/Chicago
|
||||||
|
America/El_Salvador
|
||||||
|
America/Juneau
|
||||||
|
America/Lima
|
||||||
|
America/Los_Angeles
|
||||||
|
America/Mexico_City
|
||||||
|
America/New_York
|
||||||
|
America/Phoenix
|
||||||
|
America/Santiago
|
||||||
|
America/Sao_Paulo
|
||||||
|
America/Toronto
|
||||||
|
America/Vancouver
|
||||||
|
Asia/Almaty
|
||||||
|
Asia/Ashkhabad
|
||||||
|
Asia/Bahrain
|
||||||
|
Asia/Bangkok
|
||||||
|
Asia/Chongqing
|
||||||
|
Asia/Dubai
|
||||||
|
Asia/Ho_Chi_Minh
|
||||||
|
Asia/Hong_Kong
|
||||||
|
Asia/Jakarta
|
||||||
|
Asia/Jerusalem
|
||||||
|
Asia/Kathmandu
|
||||||
|
Asia/Kolkata
|
||||||
|
Asia/Kuwait
|
||||||
|
Asia/Muscat
|
||||||
|
Asia/Qatar
|
||||||
|
Asia/Riyadh
|
||||||
|
Asia/Seoul
|
||||||
|
Asia/Shanghai
|
||||||
|
Asia/Singapore
|
||||||
|
Asia/Taipei
|
||||||
|
Asia/Tehran
|
||||||
|
Asia/Tokyo
|
||||||
|
Atlantic/Reykjavik
|
||||||
|
Australia/ACT
|
||||||
|
Australia/Adelaide
|
||||||
|
Australia/Brisbane
|
||||||
|
Australia/Sydney
|
||||||
|
Europe/Athens
|
||||||
|
Europe/Belgrade
|
||||||
|
Europe/Berlin
|
||||||
|
Europe/Copenhagen
|
||||||
|
Europe/Helsinki
|
||||||
|
Europe/Istanbul
|
||||||
|
Europe/London
|
||||||
|
Europe/Luxembourg
|
||||||
|
Europe/Madrid
|
||||||
|
Europe/Moscow
|
||||||
|
Europe/Paris
|
||||||
|
Europe/Riga
|
||||||
|
Europe/Rome
|
||||||
|
Europe/Stockholm
|
||||||
|
Europe/Tallinn
|
||||||
|
Europe/Vilnius
|
||||||
|
Europe/Warsaw
|
||||||
|
Europe/Zurich
|
||||||
|
Pacific/Auckland
|
||||||
|
Pacific/Chatham
|
||||||
|
Pacific/Fakaofo
|
||||||
|
Pacific/Honolulu
|
||||||
|
Pacific/Norfolk
|
||||||
|
US/Mountain
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
13
docs/docs/includes/abbreviations.md
Normal file
13
docs/docs/includes/abbreviations.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[mkdocs]: https://www.mkdocs.org
|
||||||
|
[mkdocs.dotfiles]: https://www.mkdocs.org/dev-guide/themes/#dot-files
|
||||||
|
[mkdocs.metadata]: https://www.mkdocs.org/user-guide/writing-your-docs/#yaml-style-meta-data
|
||||||
|
[mkdocs.env]: https://www.mkdocs.org/user-guide/configuration/#environment-variables
|
||||||
|
[mkdocs.docs_dir]: https://www.mkdocs.org/user-guide/configuration/#docs_dir
|
||||||
|
[mkdocs.extra_templates]: https://www.mkdocs.org/user-guide/configuration/#extra_templates
|
||||||
|
[mkdocs.site_dir]: https://www.mkdocs.org/user-guide/configuration/#site_dir
|
||||||
|
[mkdocs.site_url]: https://www.mkdocs.org/user-guide/configuration/#site_url
|
||||||
|
[mkdocs.site_description]: https://www.mkdocs.org/user-guide/configuration/#site_description
|
||||||
|
[mkdocs.nav]: https://www.mkdocs.org/user-guide/configuration/#nav
|
||||||
|
[mkdocs.plugins]: https://www.mkdocs.org/user-guide/configuration/#plugins
|
||||||
|
[mkdocs.strict]: https://www.mkdocs.org/user-guide/configuration/#strict
|
||||||
|
[mkdocs.use_directory_urls]: https://www.mkdocs.org/user-guide/configuration/#use_directory_urls
|
||||||
@@ -240,6 +240,7 @@ nav:
|
|||||||
- Tags: 'about/tags.md'
|
- Tags: 'about/tags.md'
|
||||||
- Config:
|
- Config:
|
||||||
- Environment Variables: 'config/env.md'
|
- Environment Variables: 'config/env.md'
|
||||||
|
- Volumes: 'config/volumes.md'
|
||||||
- Changelog: 'about/changelog.md'
|
- Changelog: 'about/changelog.md'
|
||||||
- Discord: 'https://discord.gg/gTze6hRe'
|
- Discord: 'https://discord.gg/gTze6hRe'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
#!/usr/bin/with-contenv sh
|
#!/usr/bin/with-contenv sh
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Store env variables in s6
|
||||||
|
# #
|
||||||
|
|
||||||
|
ip_gateway=$(/sbin/ip route|awk '/default/ { print $3 }')
|
||||||
|
ip_container=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
|
||||||
|
|
||||||
|
printf "$ip_gateway" > /var/run/s6/container_environment/IP_GATEWAY
|
||||||
|
printf "$ip_container" > /var/run/s6/container_environment/IP_CONTAINER
|
||||||
|
|
||||||
|
export IP_GATEWAY=$ip_gateway
|
||||||
|
export IP_GATEWAY=$ip_container
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# install and startup for tvapp2
|
# install and startup for tvapp2
|
||||||
# #
|
# #
|
||||||
@@ -9,4 +22,3 @@ rm -rf ${DIR_BUILD}/*
|
|||||||
cd ${DIR_RUN}
|
cd ${DIR_RUN}
|
||||||
npm install --omit=dev
|
npm install --omit=dev
|
||||||
npm start
|
npm start
|
||||||
|
|
||||||
|
|||||||
507
tvapp2/index.js
507
tvapp2/index.js
@@ -54,25 +54,31 @@ chalk.level = 3;
|
|||||||
let FILE_URL;
|
let FILE_URL;
|
||||||
let FILE_M3U;
|
let FILE_M3U;
|
||||||
let FILE_XML;
|
let FILE_XML;
|
||||||
let FILE_TAR;
|
let FILE_GZP;
|
||||||
let FILE_M3U_SIZE = 0;
|
let FILE_M3U_SIZE = 0;
|
||||||
let FILE_XML_SIZE = 0;
|
let FILE_XML_SIZE = 0;
|
||||||
let FILE_TAR_SIZE = 0;
|
let FILE_GZP_SIZE = 0;
|
||||||
let FILE_M3U_MODIFIED = 0;
|
let FILE_M3U_MODIFIED = 0;
|
||||||
let FILE_XML_MODIFIED = 0;
|
let FILE_XML_MODIFIED = 0;
|
||||||
let FILE_TAR_MODIFIED = 0;
|
let FILE_GZP_MODIFIED = 0;
|
||||||
const FOLDER_WWW = 'www';
|
const FOLDER_WWW = 'www';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Define > Environment Variables || Defaults
|
Define > Environment Variables || Defaults
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const envAppRelease = process.env.RELEASE || 'stable';
|
||||||
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
|
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
|
||||||
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
|
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
|
||||||
const envFileURL = process.env.FILE_URL || 'urls.txt';
|
const envFileURL = process.env.FILE_URL || 'urls.txt';
|
||||||
const envFileM3U = process.env.FILE_M3U || 'playlist.m3u8';
|
const envFileM3U = process.env.FILE_M3U || 'playlist.m3u8';
|
||||||
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
|
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
|
||||||
const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
|
const envFileGZP = process.env.FILE_GZP || 'xmltv.xml.gz';
|
||||||
|
const envApiKey = process.env.API_KEY || null;
|
||||||
|
const envWebIP = process.env.WEB_IP || '0.0.0.0';
|
||||||
|
const envWebPort = process.env.WEB_PORT || `4124`;
|
||||||
|
const envWebEncoding = process.env.WEB_ENCODING || 'deflate, br';
|
||||||
|
const envHealthTimer = process.env.HEALTH_TIMER || 600000;
|
||||||
const LOG_LEVEL = process.env.LOG_LEVEL || 10;
|
const LOG_LEVEL = process.env.LOG_LEVEL || 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -101,13 +107,27 @@ const USERAGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
|
|||||||
http://127.0.0.1:4124/playlist
|
http://127.0.0.1:4124/playlist
|
||||||
http://127.0.0.1:4124/key
|
http://127.0.0.1:4124/key
|
||||||
http://127.0.0.1:4124/channel
|
http://127.0.0.1:4124/channel
|
||||||
|
http://127.0.0.1:4124/health
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const subdomainGZ = [ 'gzip', 'gz' ];
|
const subdomainRestart = [ 'restart', 'sync', 'resync' ];
|
||||||
|
const subdomainGZP = [ 'gzip', 'gz' ];
|
||||||
const subdomainM3U = [ 'playlist', 'm3u', 'm3u8' ];
|
const subdomainM3U = [ 'playlist', 'm3u', 'm3u8' ];
|
||||||
const subdomainEPG = [ 'guide', 'epg', 'xml' ];
|
const subdomainEPG = [ 'guide', 'epg', 'xml' ];
|
||||||
const subdomainKey = [ 'key', 'keys' ];
|
const subdomainKey = [ 'key', 'keys' ];
|
||||||
const subdomainChan = [ 'channels', 'channel' ];
|
const subdomainChan = [ 'channels', 'channel', 'chan' ];
|
||||||
|
const subdomainHealth = [ 'api/status', 'api/health' ];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Container Information
|
||||||
|
|
||||||
|
these environment variables are defined from the s6-overlay layer of the docker image
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fileIpGateway = '/var/run/s6/container_environment/IP_GATEWAY';
|
||||||
|
const fileIpContainer = '/var/run/s6/container_environment/IP_CONTAINER';
|
||||||
|
const envIpGateway = fs.existsSync( fileIpGateway ) ? fs.readFileSync( fileIpGateway, 'utf8' ) : `0.0.0.0`;
|
||||||
|
const envIpContainer = fs.existsSync( fileIpContainer ) ? fs.readFileSync( fileIpContainer, 'utf8' ) : `0.0.0.0`;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Define > Logs
|
Define > Logs
|
||||||
@@ -180,13 +200,13 @@ class Log
|
|||||||
static warn( ...msg )
|
static warn( ...msg )
|
||||||
{
|
{
|
||||||
if ( LOG_LEVEL >= 2 )
|
if ( LOG_LEVEL >= 2 )
|
||||||
console.warn( chalk.white.bgYellow.bold( ` ${ name } ` ), chalk.white( `→` ), this.now(), chalk.yellow( msg.join( ' ' ) ) );
|
console.warn( chalk.white.bgYellow.bold( ` ${ name } ` ), chalk.white( `→` ), this.now(), chalk.yellowBright( msg.join( ' ' ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static error( ...msg )
|
static error( ...msg )
|
||||||
{
|
{
|
||||||
if ( LOG_LEVEL >= 1 )
|
if ( LOG_LEVEL >= 1 )
|
||||||
console.error( chalk.white.bgRedBright.bold( ` ${ name } ` ), chalk.white( `→` ), this.now(), chalk.red( msg.join( ' ' ) ) );
|
console.error( chalk.white.bgRedBright.bold( ` ${ name } ` ), chalk.white( `→` ), this.now(), chalk.redBright( msg.join( ' ' ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,23 +216,23 @@ class Log
|
|||||||
|
|
||||||
if ( process.pkg )
|
if ( process.pkg )
|
||||||
{
|
{
|
||||||
Log.info( `Processing Package` );
|
Log.info( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Starting server utilizing process.execPath` ) );
|
||||||
const basePath = path.dirname( process.execPath );
|
const basePath = path.dirname( process.execPath );
|
||||||
|
|
||||||
FILE_URL = path.join( basePath, FOLDER_WWW, `${ envFileURL }` );
|
FILE_URL = path.join( basePath, FOLDER_WWW, `${ envFileURL }` );
|
||||||
FILE_M3U = path.join( basePath, FOLDER_WWW, `${ envFileM3U }` );
|
FILE_M3U = path.join( basePath, FOLDER_WWW, `${ envFileM3U }` );
|
||||||
FILE_XML = path.join( basePath, FOLDER_WWW, `${ envFileXML }` );
|
FILE_XML = path.join( basePath, FOLDER_WWW, `${ envFileXML }` );
|
||||||
FILE_XML.length;
|
FILE_XML.length;
|
||||||
FILE_TAR = path.join( basePath, FOLDER_WWW, `${ envFileTAR }` );
|
FILE_GZP = path.join( basePath, FOLDER_WWW, `${ envFileGZP }` );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.info( `Processing Locals` );
|
Log.info( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Starting server utilizing processed locals` ) );
|
||||||
|
|
||||||
FILE_URL = path.resolve( __dirname, FOLDER_WWW, `${ envFileURL }` );
|
FILE_URL = path.resolve( __dirname, FOLDER_WWW, `${ envFileURL }` );
|
||||||
FILE_M3U = path.resolve( __dirname, FOLDER_WWW, `${ envFileM3U }` );
|
FILE_M3U = path.resolve( __dirname, FOLDER_WWW, `${ envFileM3U }` );
|
||||||
FILE_XML = path.resolve( __dirname, FOLDER_WWW, `${ envFileXML }` );
|
FILE_XML = path.resolve( __dirname, FOLDER_WWW, `${ envFileXML }` );
|
||||||
FILE_TAR = path.resolve( __dirname, FOLDER_WWW, `${ envFileTAR }` );
|
FILE_GZP = path.resolve( __dirname, FOLDER_WWW, `${ envFileGZP }` );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -268,7 +288,7 @@ const semaphore = new Semaphore( 5 );
|
|||||||
|
|
||||||
async function downloadFile( url, filePath )
|
async function downloadFile( url, filePath )
|
||||||
{
|
{
|
||||||
Log.info( `Fetching`, chalk.white( `→` ), chalk.grey( `${ url }` ), chalk.white( `→` ), chalk.grey( `${ filePath }` ) );
|
Log.info( `netw`, chalk.yellow( `[start]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Downloading external file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ) );
|
||||||
|
|
||||||
return new Promise( ( resolve, reject ) =>
|
return new Promise( ( resolve, reject ) =>
|
||||||
{
|
{
|
||||||
@@ -280,19 +300,19 @@ async function downloadFile( url, filePath )
|
|||||||
{
|
{
|
||||||
if ( response.statusCode !== 200 )
|
if ( response.statusCode !== 200 )
|
||||||
{
|
{
|
||||||
Log.error( `Failed to download file: ${ url }`, chalk.white( `→` ), chalk.grey( `Status code: ${ response.statusCode }` ) );
|
Log.error( `netw`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Failed to download source file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ response.statusCode }` ) );
|
||||||
return reject( new Error( `Failed to download file: ${ url }. Status code: ${ response.statusCode }` ) );
|
return reject( new Error( `Failed to download file: ${ url }. Status code: ${ response.statusCode }` ) );
|
||||||
}
|
}
|
||||||
response.pipe( file );
|
response.pipe( file );
|
||||||
file.on( 'finish', () =>
|
file.on( 'finish', () =>
|
||||||
{
|
{
|
||||||
Log.ok( `Received`, chalk.white( `→` ), `${ filePath }` );
|
Log.ok( `netw`, chalk.yellow( `[finish]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Successfully downloaded and wrote new file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ) );
|
||||||
file.close( () => resolve( true ) );
|
file.close( () => resolve( true ) );
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on( 'error', ( err ) =>
|
.on( 'error', ( err ) =>
|
||||||
{
|
{
|
||||||
Log.error( `Error downloading file: ${ url }`, chalk.white( `→` ), chalk.grey( `Status code: ${ err.message }` ) );
|
Log.error( `netw`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Failed to download source file` ), chalk.blueBright( `<error>` ), chalk.gray( `${ err.message }`, chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ) ) );
|
||||||
fs.unlink( filePath, () => reject( err ) );
|
fs.unlink( filePath, () => reject( err ) );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -357,7 +377,7 @@ function getFileSizeHuman( filename, si = true, decimal = 1 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Func > Ensure File Exists
|
Func > Get Files
|
||||||
|
|
||||||
if file exists; start download from external website utilizing url and file path arguments; or
|
if file exists; start download from external website utilizing url and file path arguments; or
|
||||||
throw error to user that file does not exist via the URL.
|
throw error to user that file does not exist via the URL.
|
||||||
@@ -379,59 +399,56 @@ async function getFile( url, filePath )
|
|||||||
{
|
{
|
||||||
if ( fs.existsSync( filePath ) )
|
if ( fs.existsSync( filePath ) )
|
||||||
{
|
{
|
||||||
Log.warn( `Using existing local file ${ filePath }, download failed`, chalk.white( `→` ), chalk.grey( `${ url }` ) );
|
Log.warn( `netw`, chalk.yellow( `[get]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Download failed - Using existing local file ${ filePath }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.error( `Failed to download file, and no local file exists; aborting`, chalk.white( `→` ), chalk.grey( `${ url }` ) );
|
Log.error( `netw`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Download filed and no local backup exists, aborting` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ url }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ filePath }` ) );
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Func > Package GZip
|
Func > Create GZip
|
||||||
|
|
||||||
locates the xmltv.xml and packages it into a xmltv.gz archive
|
locates the xmltv.xml and packages it into a xmltv.gz archive
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function createGzip( )
|
async function createGzip( )
|
||||||
{
|
{
|
||||||
Log.debug( `Preparing to gzip`, chalk.white( `→` ), chalk.grey( `${ envFileXML }` ) );
|
Log.info( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Preparing to create compressed XML gz file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
|
|
||||||
return new Promise( ( resolve, reject ) =>
|
return new Promise( ( resolve, reject ) =>
|
||||||
{
|
{
|
||||||
Log.debug( `createGzip[promise]`, chalk.white( `→` ), chalk.grey( `${ envFileXML }` ) );
|
Log.debug( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Promise to create compressed gz started` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
|
|
||||||
fs.readFile( FILE_XML, ( err, buf ) =>
|
fs.readFile( FILE_XML, ( err, buf ) =>
|
||||||
{
|
{
|
||||||
Log.debug( `createGzip[fs.readFile]`, chalk.white( `→` ), chalk.grey( `${ envFileXML }` ) );
|
Log.debug( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Reading source XML file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
|
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Could not read file ${ envFileXML }. Error: `, chalk.white( `→` ), chalk.grey( `${ err }` ) );
|
Log.error( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Could not read source XML file` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
return reject( new Error( `Could not read file ${ envFileXML }. Error: ${ err }` ) );
|
return reject( new Error( `Could not read file ${ envFileXML }. Error: ${ err }` ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
zlib.gzip( buf, ( err, buf ) =>
|
zlib.gzip( buf, ( err, buf ) =>
|
||||||
{
|
{
|
||||||
Log.debug( `createGzip[zlib.gzip]`, chalk.white( `→` ), chalk.grey( `${ envFileXML }` ), chalk.white( `→` ), chalk.grey( `${ envFileTAR }` ) );
|
Log.debug( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Starting zlib.gzip` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Could not write to archive. Error: `, chalk.white( `→` ), chalk.grey( `${ err }` ) );
|
Log.error( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Could not create gz archive` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
return reject( new Error( `Could not create ${ envFileTAR }. Error: ${ err }` ) );
|
return reject( new Error( `Could not create ${ envFileGZP }. Error: ${ err }` ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.info( `Compressing`, chalk.white( `→` ), `${ envFileXML }`, chalk.white( `→` ), `${ FILE_TAR }` );
|
Log.info( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Started creating gz archive from XML source` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
fs.writeFile( `${ FILE_TAR }`, buf, ( err ) =>
|
fs.writeFile( `${ FILE_GZP }`, buf, ( err ) =>
|
||||||
{
|
{
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Could not write XML file to archive. Error: `, chalk.white( `→` ), chalk.grey( `${ err }` ) );
|
Log.error( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Could not write to and create gz archive` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
return reject( new Error( `Could not write XML file ${ envFileXML } to ${ envFileTAR }. Error: ${ err }` ) );
|
return reject( new Error( `Could not write XML file ${ envFileXML } to ${ envFileGZP }. Error: ${ err }` ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.ok( `Compressed`, chalk.white( `→` ), `${ envFileXML }`, chalk.white( `→` ), `${ FILE_TAR }` );
|
Log.ok( `gzip`, chalk.yellow( `[create]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Successfully created compressed gz archive from XML source file` ), chalk.blueBright( `<source>` ), chalk.gray( `${ envFileXML }` ), chalk.blueBright( `<destination>` ), chalk.gray( `${ envFileGZP }` ) );
|
||||||
resolve( true );
|
resolve( true );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -440,19 +457,12 @@ async function createGzip( )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Func > Ensure File Exists
|
Func > Get Gzip
|
||||||
|
|
||||||
if file exists; start download from external website utilizing url and file path arguments; or
|
try; catch to create a .gz compressed file from the .xml guide data
|
||||||
throw error to user that file does not exist via the URL.
|
|
||||||
|
|
||||||
If file cannot be obtained from external url; use local copy if available
|
|
||||||
|
|
||||||
@arg str url https://git.binaryninja.net/binaryninja/tvapp2-externals/raw/branch/main/urls.txt
|
|
||||||
@arg str filePath H:\Repos\github\BinaryNinja\tvapp2\tvapp2\urls.txt
|
|
||||||
@ret none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function prepareGzip( )
|
async function getGzip( )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -462,16 +472,37 @@ async function prepareGzip( )
|
|||||||
{
|
{
|
||||||
if ( fs.existsSync( FILE_XML ) )
|
if ( fs.existsSync( FILE_XML ) )
|
||||||
{
|
{
|
||||||
Log.warn( `XML file found, but gzip failed to compress XML`, chalk.white( `→` ), chalk.grey( `${ FILE_XML }` ) );
|
Log.warn( `gzip`, chalk.yellow( `[compress]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.yellowBright( `Source xml file found, but gzip failed generate a compressed .gz fileL` ), chalk.blueBright( `<source>` ), chalk.gray( `${ FILE_XML }` ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.error( `XML file not found`, chalk.white( `→` ), chalk.grey( `${ FILE_XML }` ) );
|
Log.error( `gzip`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Source XML file not found; cannot create compressed gzip` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<source>` ), chalk.gray( `${ FILE_XML }` ) );
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
@note Jellyfin Users
|
||||||
|
Originally, this node webserver enabled gzip compression for the value `Accept-Encoding`. Doing this
|
||||||
|
may cause an error to appear in Jellyfin logs / console when attempting to fetch the latest guide data
|
||||||
|
from the tvapp2 xml file.
|
||||||
|
|
||||||
|
[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel XXXXXXXXXXXXXXX (Source 2)
|
||||||
|
System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.
|
||||||
|
|
||||||
|
To fix the error, we create a customizable env variable that allows the user to override the encoding header.
|
||||||
|
We change the following:
|
||||||
|
'Accept-Encoding': 'gzip, deflate, br'
|
||||||
|
to
|
||||||
|
'Accept-Encoding': 'deflate, br'
|
||||||
|
|
||||||
|
This error does not appear if you load the xml guide data into Cabernet, and then use a tuner to fetch the data from
|
||||||
|
cabernet to jellyfin
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
async function fetchRemote( url )
|
async function fetchRemote( url )
|
||||||
{
|
{
|
||||||
return new Promise( ( resolve, reject ) =>
|
return new Promise( ( resolve, reject ) =>
|
||||||
@@ -480,13 +511,13 @@ async function fetchRemote( url )
|
|||||||
mod
|
mod
|
||||||
.get( url, {
|
.get( url, {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept-Encoding': 'gzip, deflate, br'
|
'Accept-Encoding': envWebEncoding
|
||||||
}
|
}
|
||||||
}, ( resp ) =>
|
}, ( resp ) =>
|
||||||
{
|
{
|
||||||
if ( resp.statusCode !== 200 )
|
if ( resp.statusCode !== 200 )
|
||||||
{
|
{
|
||||||
Log.error( `Server returned status code other than 200`, chalk.white( `→` ), chalk.grey( `${ url } - ${ resp.statusCode }` ) );
|
Log.error( `core`, chalk.yellow( `[fetch]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Server returned status code other than 200` ), chalk.blueBright( `<statusCode>` ), chalk.redBright( `${ resp.statusCode }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ url }` ) );
|
||||||
return reject( new Error( `HTTP ${ resp.statusCode } for ${ url }` ) );
|
return reject( new Error( `HTTP ${ resp.statusCode } for ${ url }` ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,13 +570,26 @@ async function serveKey( req, res )
|
|||||||
const uriParam = new URL( req.url, `http://${ req.headers.host }` ).searchParams.get( 'uri' );
|
const uriParam = new URL( req.url, `http://${ req.headers.host }` ).searchParams.get( 'uri' );
|
||||||
if ( !uriParam )
|
if ( !uriParam )
|
||||||
{
|
{
|
||||||
res.writeHead( 400, {
|
const statusCheck =
|
||||||
'Content-Type': 'text/plain'
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: 'Error: Missing "uri" parameter for key download.',
|
||||||
|
status: 'unhealthy',
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 400,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.error( `Missing "uri" parameter for key download`, chalk.white( `→` ), chalk.grey( `${ req.url }` ) );
|
Log.error( `key`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ req.url }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
return res.end( 'Error: Missing "uri" parameter for key download.' );
|
return res.end( JSON.stringify( statusCheck ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyData = await fetchRemote( uriParam );
|
const keyData = await fetchRemote( uriParam );
|
||||||
@@ -557,13 +601,27 @@ async function serveKey( req, res )
|
|||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `ServeKey Error:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `Failed to serve key`,
|
||||||
|
error: `${ err.message }`,
|
||||||
|
status: 'unhealthy',
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 500,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
res.writeHead( 500, {
|
res.writeHead( statusCheck.code, {
|
||||||
'Content-Type': 'text/plain'
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
res.end( 'Error fetching key.' );
|
Log.error( `key`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ statusCheck.error }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ req.url }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,7 +707,7 @@ async function getTokenizedUrl( channelUrl )
|
|||||||
const streamNameMatch = html.match( /id="stream_name" name="([^"]+)"/ );
|
const streamNameMatch = html.match( /id="stream_name" name="([^"]+)"/ );
|
||||||
if ( !streamNameMatch )
|
if ( !streamNameMatch )
|
||||||
{
|
{
|
||||||
Log.error( `Cannot find "stream_name"`, chalk.white( `→` ), chalk.grey( `${ channelUrl }` ) );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Cannot find "stream_name` ), chalk.blueBright( `<url>` ), chalk.grey( `${ channelUrl }` ) );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
streamName = streamNameMatch[1];
|
streamName = streamNameMatch[1];
|
||||||
@@ -669,6 +727,8 @@ async function getTokenizedUrl( channelUrl )
|
|||||||
const tokenResponse = await fetchPage( tokenUrl );
|
const tokenResponse = await fetchPage( tokenUrl );
|
||||||
let finalUrl;
|
let finalUrl;
|
||||||
|
|
||||||
|
Log.debug( `playlist`, chalk.yellow( `[tokenize]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Generating tokenized final stream URL` ), chalk.blueBright( `<streamName>` ), chalk.gray( `${ streamName }` ), chalk.blueBright( `<quality>` ), chalk.gray( `${ envStreamQuality }` ), chalk.blueBright( `<host>` ), chalk.gray( `${ streamHost }` ) );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const json = JSON.parse( tokenResponse );
|
const json = JSON.parse( tokenResponse );
|
||||||
@@ -676,23 +736,22 @@ async function getTokenizedUrl( channelUrl )
|
|||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Failed to parse token JSON for channel`, chalk.white( `→` ), chalk.grey( `${ channelUrl } - ${ err.message }` ) );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Failed to parse token JSON for channel` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ channelUrl }` ) );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !finalUrl )
|
if ( !finalUrl )
|
||||||
{
|
{
|
||||||
Log.error( `No URL found in token JSON for channel`, chalk.white( `→` ), chalk.grey( `${ channelUrl }` ) );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `No URL found in token JSON for channel` ), chalk.blueBright( `<url>` ), chalk.gray( `${ channelUrl }` ) );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.debug( `Tokenized URL:`, chalk.white( `→` ), chalk.grey( `${ finalUrl }` ) );
|
Log.debug( `playlist`, chalk.yellow( `[tokenize]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Completed generated tokenized final stream URL` ), chalk.blueBright( `<streamName>` ), chalk.gray( `${ streamName }` ), chalk.blueBright( `<quality>` ), chalk.gray( `${ envStreamQuality }` ), chalk.blueBright( `<host>` ), chalk.gray( `${ streamHost }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ finalUrl }` ) );
|
||||||
|
|
||||||
return finalUrl;
|
return finalUrl;
|
||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Fatal error fetching token:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Fatal error fetching token` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<url>` ), chalk.grey( `${ channelUrl }` ) );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -705,11 +764,26 @@ async function serveM3UPlaylist( req, res )
|
|||||||
const urlParam = new URL( req.url, `http://${ req.headers.host }` ).searchParams.get( 'url' );
|
const urlParam = new URL( req.url, `http://${ req.headers.host }` ).searchParams.get( 'url' );
|
||||||
if ( !urlParam )
|
if ( !urlParam )
|
||||||
{
|
{
|
||||||
Log.error( `Missing parameter`, chalk.white( `→` ), chalk.grey( `URL` ) );
|
const statusCheck =
|
||||||
res.writeHead( 400, {
|
{
|
||||||
'Content-Type': 'text/plain'
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `Missing ?url= parameter`,
|
||||||
|
status: `unhealthy`,
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 404,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
res.end( 'Error: Missing URL parameter.' );
|
|
||||||
|
Log.error( `channel`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<expected>` ), chalk.grey( `http://${ req.headers.host }/channel?url=XXXX` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,22 +807,38 @@ async function serveM3UPlaylist( req, res )
|
|||||||
'Content-Disposition': 'inline; filename="' + envFileM3U
|
'Content-Disposition': 'inline; filename="' + envFileM3U
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Log.debug( `playlist`, chalk.yellow( `[fetch]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `retrieving cached playlist` ), chalk.blueBright( `<cachedUrl>` ), chalk.gray( `${ cachedUrl }` ), chalk.blueBright( `<stream>` ), chalk.gray( `${ urlParam }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `200` ) );
|
||||||
|
|
||||||
res.end( rewrittenPlaylist );
|
res.end( rewrittenPlaylist );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.info( `Fetching stream:`, chalk.white( `→` ), chalk.grey( `${ urlParam }` ) );
|
Log.info( `playlist`, chalk.yellow( `[fetch]` ), chalk.white( `→` ), chalk.blueBright( `<stream>` ), chalk.gray( `${ urlParam }` ) );
|
||||||
|
|
||||||
const finalUrl = await getTokenizedUrl( decodedUrl );
|
const finalUrl = await getTokenizedUrl( decodedUrl );
|
||||||
if ( !finalUrl )
|
if ( !finalUrl )
|
||||||
{
|
{
|
||||||
Log.error( `Failed to retrieve tokenized URL` );
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `Failed to retrieve tokenized URL.`,
|
||||||
|
status: `unhealthy`,
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 500,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
res.writeHead( 500, {
|
res.writeHead( statusCheck.code, {
|
||||||
'Content-Type': 'text/plain'
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
res.end( 'Error: Failed to retrieve tokenized URL.' );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<stream>` ), chalk.gray( `${ urlParam }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,15 +855,95 @@ async function serveM3UPlaylist( req, res )
|
|||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Error processing request:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
|
||||||
|
|
||||||
if ( !res.headersSent )
|
if ( !res.headersSent )
|
||||||
{
|
{
|
||||||
res.writeHead( 500, {
|
const statusCheck =
|
||||||
'Content-Type': 'text/plain'
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `Cannot process request when fetching channel playlist`,
|
||||||
|
error: `${ err.message }`,
|
||||||
|
status: 'unhealthy',
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 500,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
res.end( 'Error processing request.' );
|
Log.error( `playlist`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function serveHealthCheck( req, res )
|
||||||
|
{
|
||||||
|
await semaphore.acquire();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const urlParam = new URL( req.url, `http://${ req.headers.host }` ).searchParams.get( 'api' );
|
||||||
|
if ( !urlParam )
|
||||||
|
{
|
||||||
|
Log.debug( `health`, chalk.yellow( `[api]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `No API key passed to health check` ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `healthy`,
|
||||||
|
status: `healthy`,
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 200,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.ok( `health`, chalk.yellow( `[api]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `health check returned` ), chalk.greenBright( `${ statusCheck.status }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ), chalk.blueBright( `<uptime>` ), chalk.gray( `${ process.uptime() }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
if ( !res.headersSent )
|
||||||
|
{
|
||||||
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `health check failed`,
|
||||||
|
error: `${ err.message }`,
|
||||||
|
status: `unhealthy`,
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 503,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.error( `health`, chalk.yellow( `[error]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `${ statusCheck.message }; returned` ), chalk.redBright( `${ statusCheck.status }` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ), chalk.blueBright( `<uptime>` ), chalk.gray( `${ process.uptime() }` ) );
|
||||||
|
|
||||||
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -815,7 +985,7 @@ async function rewriteM3U( originalUrl, req )
|
|||||||
Serves IPTV .m3u playlist
|
Serves IPTV .m3u playlist
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function serveM3U( response, req )
|
async function serveM3U( res, req )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -833,22 +1003,36 @@ async function serveM3U( response, req )
|
|||||||
return `${ baseUrl }/channel?url=${ encodeURIComponent( fullUrl ) }`;
|
return `${ baseUrl }/channel?url=${ encodeURIComponent( fullUrl ) }`;
|
||||||
});
|
});
|
||||||
|
|
||||||
response.writeHead( 200, {
|
res.writeHead( 200, {
|
||||||
'Content-Type': 'application/x-mpegURL',
|
'Content-Type': 'application/x-mpegURL',
|
||||||
'Content-Disposition': 'inline; filename="' + envFileM3U
|
'Content-Disposition': 'inline; filename="' + envFileM3U
|
||||||
});
|
});
|
||||||
|
|
||||||
response.end( updatedContent );
|
res.end( updatedContent );
|
||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Error in serveM3U:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: `Fatal error serving playlist`,
|
||||||
|
error: `${ err.message }`,
|
||||||
|
status: 'unhealthy',
|
||||||
|
ref: req.url,
|
||||||
|
method: req.method || 'GET',
|
||||||
|
code: 500,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
response.writeHead( 500, {
|
Log.error( `playlist`, chalk.yellow( `[serve]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ statusCheck.message }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ req.url }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
|
res.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.end( `Error serving playlist: ${ err.message }` );
|
res.end( JSON.stringify( statusCheck ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,13 +1058,13 @@ async function serveXML( response, req )
|
|||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Error in serveM3U:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
Log.error( `playlist`, chalk.yellow( `[serve]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Fatal serving xml / epg guide data` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ req.url }` ) );
|
||||||
|
|
||||||
response.writeHead( 500, {
|
response.writeHead( 500, {
|
||||||
'Content-Type': 'text/plain'
|
'Content-Type': 'text/plain'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.end( `Error serving playlist: ${ err.message }` );
|
response.end( `Error serving xml/epg guide data: ${ err.message }` );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -888,25 +1072,25 @@ async function serveXML( response, req )
|
|||||||
Serves IPTV .gz guide data
|
Serves IPTV .gz guide data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function serveTAR( response, req )
|
async function serveGZP( response, req )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const protocol = req.headers['x-forwarded-proto']?.split( ',' )[0] || ( req.socket.encrypted ? 'https' : 'http' );
|
const protocol = req.headers['x-forwarded-proto']?.split( ',' )[0] || ( req.socket.encrypted ? 'https' : 'http' );
|
||||||
const host = req.headers.host;
|
const host = req.headers.host;
|
||||||
const baseUrl = `${ protocol }://${ host }`;
|
const baseUrl = `${ protocol }://${ host }`;
|
||||||
const formattedContent = fs.readFileSync( FILE_TAR );
|
const formattedContent = fs.readFileSync( FILE_GZP );
|
||||||
|
|
||||||
response.writeHead( 200, {
|
response.writeHead( 200, {
|
||||||
'Content-Type': 'application/gzip',
|
'Content-Type': 'application/gzip',
|
||||||
'Content-Disposition': 'inline; filename="' + envFileTAR
|
'Content-Disposition': 'inline; filename="' + envFileGZP
|
||||||
});
|
});
|
||||||
|
|
||||||
response.end( formattedContent );
|
response.end( formattedContent );
|
||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Error in serveTAR:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
Log.error( `playlist`, chalk.yellow( `[serve]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Fatal serving compressed gzip file` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err.message }` ), chalk.blueBright( `<url>` ), chalk.gray( `${ req.url }` ) );
|
||||||
|
|
||||||
response.writeHead( 500, {
|
response.writeHead( 500, {
|
||||||
'Content-Type': 'text/plain'
|
'Content-Type': 'text/plain'
|
||||||
@@ -924,7 +1108,7 @@ function setCache( key, value, ttl )
|
|||||||
expiry
|
expiry
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.debug( `Cache set for key ${ key } which expires in`, chalk.white( `→` ), chalk.grey( `${ ttl / 1000 } seconds` ) );
|
Log.debug( `cache`, chalk.yellow( `[set]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `new key created` ), chalk.blueBright( `<key>` ), chalk.gray( `${ key }` ), chalk.blueBright( `<expire>` ), chalk.gray( `${ ttl / 1000 } seconds` ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCache( key )
|
function getCache( key )
|
||||||
@@ -937,7 +1121,7 @@ function getCache( key )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( cached )
|
if ( cached )
|
||||||
Log.debug( `Cache expired for key`, chalk.white( `→` ), chalk.grey( `${ key }` ) );
|
Log.debug( `cache`, chalk.yellow( `[get]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `key has expired, marked for deletion` ), chalk.blueBright( `<key>` ), chalk.gray( `${ key }` ) );
|
||||||
|
|
||||||
cache.delete( key );
|
cache.delete( key );
|
||||||
return null;
|
return null;
|
||||||
@@ -954,12 +1138,18 @@ async function initialize()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.info( `Initialization Started` );
|
const start = performance.now();
|
||||||
|
Log.info( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `Starting TVApp2 container. Assigning bound IP to host network adapter` ), chalk.blueBright( `<hostIp>` ), chalk.gray( `${ envWebIP }` ), chalk.blueBright( `<containerIp>` ), chalk.gray( `${ envIpContainer }` ), chalk.blueBright( `<port>` ), chalk.gray( `${ envWebPort }` ) );
|
||||||
|
|
||||||
|
Log.debug( `.env`, chalk.yellow( `[set]` ), chalk.white( `→` ), chalk.blueBright( `<variable>` ), chalk.gray( `FILE_URL` ), chalk.blueBright( `<value>` ), chalk.gray( `${ FILE_URL }` ) );
|
||||||
|
Log.debug( `.env`, chalk.yellow( `[set]` ), chalk.white( `→` ), chalk.blueBright( `<variable>` ), chalk.gray( `FILE_M3U` ), chalk.blueBright( `<value>` ), chalk.gray( `${ FILE_M3U }` ) );
|
||||||
|
Log.debug( `.env`, chalk.yellow( `[set]` ), chalk.white( `→` ), chalk.blueBright( `<variable>` ), chalk.gray( `FILE_XML` ), chalk.blueBright( `<value>` ), chalk.gray( `${ FILE_XML }` ) );
|
||||||
|
Log.debug( `.env`, chalk.yellow( `[set]` ), chalk.white( `→` ), chalk.blueBright( `<variable>` ), chalk.gray( `FILE_GZP` ), chalk.blueBright( `<value>` ), chalk.gray( `${ FILE_GZP }` ) );
|
||||||
|
|
||||||
await getFile( extURL, FILE_URL );
|
await getFile( extURL, FILE_URL );
|
||||||
await getFile( extXML, FILE_XML );
|
await getFile( extXML, FILE_XML );
|
||||||
await getFile( extM3U, FILE_M3U );
|
await getFile( extM3U, FILE_M3U );
|
||||||
await prepareGzip();
|
await getGzip();
|
||||||
|
|
||||||
urls = fs.readFileSync( FILE_URL, 'utf-8' ).split( '\n' ).filter( Boolean );
|
urls = fs.readFileSync( FILE_URL, 'utf-8' ).split( '\n' ).filter( Boolean );
|
||||||
if ( urls.length === 0 )
|
if ( urls.length === 0 )
|
||||||
@@ -971,17 +1161,18 @@ async function initialize()
|
|||||||
|
|
||||||
FILE_M3U_SIZE = getFileSizeHuman( FILE_M3U );
|
FILE_M3U_SIZE = getFileSizeHuman( FILE_M3U );
|
||||||
FILE_XML_SIZE = getFileSizeHuman( FILE_XML );
|
FILE_XML_SIZE = getFileSizeHuman( FILE_XML );
|
||||||
FILE_TAR_SIZE = getFileSizeHuman( FILE_TAR );
|
FILE_GZP_SIZE = getFileSizeHuman( FILE_GZP );
|
||||||
|
|
||||||
FILE_M3U_MODIFIED = getFileModified( FILE_M3U );
|
FILE_M3U_MODIFIED = getFileModified( FILE_M3U );
|
||||||
FILE_XML_MODIFIED = getFileModified( FILE_XML );
|
FILE_XML_MODIFIED = getFileModified( FILE_XML );
|
||||||
FILE_TAR_MODIFIED = getFileModified( FILE_TAR );
|
FILE_GZP_MODIFIED = getFileModified( FILE_GZP );
|
||||||
|
|
||||||
Log.info( `Initialization Complete` );
|
const end = performance.now();
|
||||||
|
Log.info( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `TVApp2 container is ready` ), chalk.blueBright( `took ${ end - start }ms` ), chalk.blueBright( `<message>` ), chalk.gray( `TVApp2 container is ready; took ${ end - start }ms` ), chalk.blueBright( `<ip>` ), chalk.gray( `${ envIpContainer }` ), chalk.blueBright( `<gateway>` ), chalk.gray( `${ envIpGateway }` ), chalk.blueBright( `<port>` ), chalk.gray( `${ envWebPort }` ) );
|
||||||
}
|
}
|
||||||
catch ( err )
|
catch ( err )
|
||||||
{
|
{
|
||||||
Log.error( `Initialization error:`, chalk.white( `→` ), chalk.grey( `${ err.message }` ) );
|
Log.error( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.redBright( `Could not start up TVApp2 container due to error` ), chalk.blueBright( `<error>` ), chalk.redBright( `${ err }` ), chalk.blueBright( `<ip>` ), chalk.gray( `${ envIpContainer }` ), chalk.blueBright( `<gateway>` ), chalk.gray( `${ envIpGateway }` ), chalk.blueBright( `<port>` ), chalk.gray( `${ envWebPort }` ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1023,52 +1214,89 @@ const server = http.createServer( ( request, response ) =>
|
|||||||
|
|
||||||
const loadFile = reqUrl.replace( /^\/+/, '' );
|
const loadFile = reqUrl.replace( /^\/+/, '' );
|
||||||
|
|
||||||
Log.debug( `www`, chalk.yellow( ` [GET] ` ), chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
|
||||||
|
|
||||||
const handleRequest = async() =>
|
const handleRequest = async() =>
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Define the different routes.
|
Define the different routes.
|
||||||
Place the template system last. Getting TVApp data should take priority.
|
Place the template system last. Getting TVApp data should take priority.
|
||||||
|
|
||||||
|
subdomainM3U array []
|
||||||
|
loadFile channel?url=https%3A%2F%2Ftvpass.org%2Fchannel%2Fabc-wabc-new-york-ny%2F
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( subdomainM3U.includes( `${ loadFile }` ) && method === 'GET' )
|
if ( subdomainRestart.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) )
|
||||||
{
|
{
|
||||||
Log.info( `Received request for m3u playlist data`, chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
await initialize();
|
||||||
|
|
||||||
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: 'Restart command received',
|
||||||
|
status: 'ok',
|
||||||
|
ref: request.url,
|
||||||
|
method: method || 'GET',
|
||||||
|
code: 200,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
response.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `api/restart` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
|
response.end( JSON.stringify( statusCheck ) );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( subdomainM3U.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
|
{
|
||||||
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `m3u playlist` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
await serveM3U( response, request );
|
await serveM3U( response, request );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subdomainChan.includes( `${ loadFile }` ) && method === 'GET' )
|
if ( subdomainChan.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
{
|
{
|
||||||
Log.info( `Received request for channel data`, chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `channel` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
await serveM3UPlaylist( request, response );
|
await serveM3UPlaylist( request, response );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subdomainKey.includes( `${ loadFile }` ) && method === 'GET' )
|
if ( subdomainKey.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
{
|
{
|
||||||
Log.info( `Received request for key data`, chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `key` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
await serveKey( request, response );
|
await serveKey( request, response );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subdomainEPG.includes( `${ loadFile }` ) && method === 'GET' )
|
if ( subdomainEPG.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
{
|
{
|
||||||
Log.info( `Received request for raw EPG data`, chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `epg-uncompressed` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
await serveXML( response, request );
|
await serveXML( response, request );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subdomainGZ.includes( `${ loadFile }` ) && method === 'GET' )
|
if ( subdomainGZP.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
{
|
{
|
||||||
Log.info( `Received request for compressed EPG data`, chalk.white( `→` ), chalk.grey( `${ loadFile }` ) );
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `epg-compressed` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
await serveTAR( response, request );
|
await serveGZP( response, request );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( subdomainHealth.some( ( urlKeyword ) => loadFile.startsWith( urlKeyword ) ) && method === 'GET' )
|
||||||
|
{
|
||||||
|
Log.info( `www`, chalk.yellow( `[req]` ), chalk.white( `→` ), chalk.blueBright( `<type>` ), chalk.gray( `api` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<method>` ), chalk.gray( `${ method }` ) );
|
||||||
|
|
||||||
|
await serveHealthCheck( request, response );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,10 +1315,12 @@ const server = http.createServer( ( request, response ) =>
|
|||||||
sizeXML: FILE_XML_SIZE,
|
sizeXML: FILE_XML_SIZE,
|
||||||
dateXML: FILE_XML_MODIFIED,
|
dateXML: FILE_XML_MODIFIED,
|
||||||
|
|
||||||
fileTAR: envFileTAR,
|
fileGZP: envFileGZP,
|
||||||
sizeTAR: FILE_TAR_SIZE,
|
sizeGZP: FILE_GZP_SIZE,
|
||||||
dateTAR: FILE_TAR_MODIFIED,
|
dateGZP: FILE_GZP_MODIFIED,
|
||||||
|
|
||||||
|
healthTimer: envHealthTimer,
|
||||||
|
appRelease: envAppRelease,
|
||||||
appName: name,
|
appName: name,
|
||||||
appVersion: version,
|
appVersion: version,
|
||||||
appUrlGithub: repository.url,
|
appUrlGithub: repository.url,
|
||||||
@@ -1116,6 +1346,7 @@ const server = http.createServer( ( request, response ) =>
|
|||||||
'.png' : 'image/png',
|
'.png' : 'image/png',
|
||||||
'.gif' : 'image/gif',
|
'.gif' : 'image/gif',
|
||||||
'.css' : 'text/css',
|
'.css' : 'text/css',
|
||||||
|
'.scss' : 'text/x-sass',
|
||||||
'.gz' : 'application/gzip',
|
'.gz' : 'application/gzip',
|
||||||
'.js' : 'text/javascript',
|
'.js' : 'text/javascript',
|
||||||
'.txt' : 'text/plain',
|
'.txt' : 'text/plain',
|
||||||
@@ -1134,24 +1365,46 @@ const server = http.createServer( ( request, response ) =>
|
|||||||
response.setHeader( 'Content-type', fileMime );
|
response.setHeader( 'Content-type', fileMime );
|
||||||
response.end( data );
|
response.end( data );
|
||||||
|
|
||||||
Log.debug( `www`, chalk.green( ` [LOAD] ` ), chalk.white( `→` ), chalk.grey( `asset:${ loadFile } mime:${ fileMime }` ) );
|
Log.ok( `www`, chalk.yellow( `[load]` ), chalk.white( `→` ), chalk.blueBright( `<file>` ), chalk.gray( `${ loadFile }` ), chalk.blueBright( `<mime>` ), chalk.gray( `${ fileMime }` ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.error( `www file not found:`, chalk.white( `→` ), chalk.grey( `${ request.url }` ) );
|
if ( loadFile === 'discovery.json' )
|
||||||
response.writeHead( 404, 'Not Found' );
|
{
|
||||||
response.end();
|
Log.notice( `www`, chalk.yellowBright( `[notice]` ), chalk.white( `→` ), chalk.grey( `If you are attempting to load TVApp2 using an HDHomeRun tuner, please switch to the` ), chalk.yellowBright( `M3U Tuner` ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusCheck =
|
||||||
|
{
|
||||||
|
ip: envIpContainer,
|
||||||
|
gateway: envIpGateway,
|
||||||
|
uptime: process.uptime(),
|
||||||
|
message: 'Page not found',
|
||||||
|
status: 'healthy',
|
||||||
|
ref: request.url,
|
||||||
|
method: method || 'GET',
|
||||||
|
code: 404,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
response.writeHead( statusCheck.code, {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.error( `www`, chalk.redBright( `[error]` ), chalk.white( `→` ), chalk.grey( `${ statusCheck.message }` ), chalk.redBright( `${ loadFile }` ), chalk.blueBright( `<statusCode>` ), chalk.gray( `${ statusCheck.code }` ) );
|
||||||
|
|
||||||
|
response.end( JSON.stringify( statusCheck ) );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
handleRequest().catch( ( err ) =>
|
handleRequest().catch( ( err ) =>
|
||||||
{
|
{
|
||||||
Log.error( `Error handling request:`, chalk.white( `→` ), chalk.grey( `${ err }` ) );
|
|
||||||
|
|
||||||
response.writeHead( 500, {
|
response.writeHead( 500, {
|
||||||
'Content-Type': 'text/plain'
|
'Content-Type': 'text/plain'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Log.error( `Error handling request:`, chalk.white( `→` ), chalk.grey( `${ err }` ) );
|
||||||
|
|
||||||
response.end( 'Internal Server Error' );
|
response.end( 'Internal Server Error' );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1162,17 +1415,15 @@ const server = http.createServer( ( request, response ) =>
|
|||||||
|
|
||||||
( async() =>
|
( async() =>
|
||||||
{
|
{
|
||||||
const envWebIP = process.env.WEB_IP || '0.0.0.0';
|
if ( !envApiKey )
|
||||||
const envWebPort = process.env.WEB_PORT || `4124`;
|
{
|
||||||
|
Log.warn( `core`, chalk.yellow( `[api]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `API_KEY environment variable not defined for api, leaving blank` ) );
|
||||||
Log.debug( `Assigned FILE_URL`, chalk.white( `→` ), chalk.grey( `${ FILE_URL }` ) );
|
}
|
||||||
Log.debug( `Assigned FILE_M3U`, chalk.white( `→` ), chalk.grey( `${ FILE_M3U }` ) );
|
|
||||||
Log.debug( `Assigned FILE_XML`, chalk.white( `→` ), chalk.grey( `${ FILE_XML }` ) );
|
|
||||||
Log.debug( `Assigned FILE_TAR`, chalk.white( `→` ), chalk.grey( `${ FILE_TAR }` ) );
|
|
||||||
|
|
||||||
await initialize();
|
await initialize();
|
||||||
|
|
||||||
server.listen( envWebPort, envWebIP, () =>
|
server.listen( envWebPort, envWebIP, () =>
|
||||||
{
|
{
|
||||||
Log.info( `Server is running on ${ envWebIP }:${ envWebPort }` );
|
Log.warn( `core`, chalk.yellow( `[init]` ), chalk.white( `→` ), chalk.blueBright( `<message>` ), chalk.gray( `server is now running on` ), chalk.whiteBright.bgBlack( ` ${ envWebIP }:${ envWebPort } ` ) );
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
578
tvapp2/node_modules/.package-lock.json
generated
vendored
578
tvapp2/node_modules/.package-lock.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tvapp2",
|
"name": "tvapp2",
|
||||||
"version": "1.2.0",
|
"version": "1.4.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
@@ -132,13 +132,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.2.7",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
|
||||||
"integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
|
"integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^0.12.0",
|
"@eslint/core": "^0.13.0",
|
||||||
"levn": "^0.4.1"
|
"levn": "^0.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -146,9 +146,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
||||||
"version": "0.12.0",
|
"version": "0.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
|
||||||
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
|
"integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -276,6 +276,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"negotiator": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.1",
|
"version": "8.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||||
@@ -567,6 +580,38 @@
|
|||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"iconv-lite": "^0.6.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"raw-body": "^3.0.0",
|
||||||
|
"type-is": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -577,6 +622,15 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||||
@@ -600,7 +654,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -614,7 +667,6 @@
|
|||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
@@ -735,6 +787,45 @@
|
|||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -808,7 +899,6 @@
|
|||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
@@ -875,6 +965,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/didyoumean": {
|
"node_modules/didyoumean": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||||
@@ -899,7 +998,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.1",
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
@@ -910,6 +1008,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||||
@@ -932,6 +1036,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.18.1",
|
"version": "5.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
||||||
@@ -1033,7 +1146,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1043,7 +1155,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1053,7 +1164,6 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0"
|
"es-errors": "^1.3.0"
|
||||||
@@ -1109,6 +1219,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@@ -1548,6 +1664,57 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "^2.0.0",
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
|
"content-disposition": "^1.0.0",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cookie": "^0.7.1",
|
||||||
|
"cookie-signature": "^1.2.1",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"finalhandler": "^2.1.0",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"merge-descriptors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"router": "^2.2.0",
|
||||||
|
"send": "^1.1.0",
|
||||||
|
"serve-static": "^2.2.0",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"type-is": "^2.0.1",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/external-editor": {
|
"node_modules/external-editor": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||||
@@ -1653,6 +1820,23 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||||
@@ -1707,11 +1891,28 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
@@ -1762,7 +1963,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
@@ -1787,7 +1987,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dunder-proto": "^1.0.1",
|
"dunder-proto": "^1.0.1",
|
||||||
@@ -1875,7 +2074,6 @@
|
|||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1946,7 +2144,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1975,7 +2172,6 @@
|
|||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"function-bind": "^1.1.2"
|
"function-bind": "^1.1.2"
|
||||||
@@ -1984,6 +2180,22 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"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/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
@@ -2034,6 +2246,12 @@
|
|||||||
"node": ">=0.8.19"
|
"node": ">=0.8.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/inquirer": {
|
"node_modules/inquirer": {
|
||||||
"version": "7.3.3",
|
"version": "7.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||||
@@ -2091,6 +2309,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-array-buffer": {
|
"node_modules/is-array-buffer": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||||
@@ -2324,6 +2551,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-promise": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-regex": {
|
"node_modules/is-regex": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||||
@@ -2658,12 +2891,53 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.54.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||||
|
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mimic-fn": {
|
"node_modules/mimic-fn": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
@@ -2709,7 +2983,6 @@
|
|||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/mute-stream": {
|
"node_modules/mute-stream": {
|
||||||
@@ -2726,6 +2999,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
@@ -2751,7 +3033,6 @@
|
|||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -2844,6 +3125,27 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
@@ -2961,6 +3263,15 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -2988,6 +3299,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pegjs": {
|
"node_modules/pegjs": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz",
|
||||||
@@ -3016,8 +3336,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright": {
|
"node_modules/playwright": {
|
||||||
"version": "1.51.1",
|
"version": "1.51.1",
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz",
|
|
||||||
"integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==",
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.51.1"
|
"playwright-core": "1.51.1"
|
||||||
@@ -3034,8 +3352,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright-core": {
|
"node_modules/playwright-core": {
|
||||||
"version": "1.51.1",
|
"version": "1.51.1",
|
||||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz",
|
|
||||||
"integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==",
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright-core": "cli.js"
|
"playwright-core": "cli.js"
|
||||||
@@ -3081,6 +3397,19 @@
|
|||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
@@ -3091,6 +3420,57 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||||
|
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.6.3",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
@@ -3214,6 +3594,22 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/router": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"is-promise": "^4.0.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"path-to-regexp": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-async": {
|
"node_modules/run-async": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
@@ -3257,6 +3653,26 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/safe-push-apply": {
|
"node_modules/safe-push-apply": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
||||||
@@ -3296,7 +3712,6 @@
|
|||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
@@ -3309,6 +3724,43 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.5",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.1",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"send": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/set-blocking": {
|
"node_modules/set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
@@ -3365,6 +3817,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -3392,7 +3850,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -3412,7 +3869,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||||
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -3429,7 +3885,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -3448,7 +3903,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -3471,6 +3925,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
@@ -3636,6 +4099,15 @@
|
|||||||
"node": ">=0.6.0"
|
"node": ">=0.6.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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tr46": {
|
"node_modules/tr46": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
@@ -3689,6 +4161,20 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typed-array-buffer": {
|
"node_modules/typed-array-buffer": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||||
@@ -3786,6 +4272,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
@@ -3798,8 +4293,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/user-agents": {
|
"node_modules/user-agents": {
|
||||||
"version": "1.1.497",
|
"version": "1.1.497",
|
||||||
"resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.1.497.tgz",
|
|
||||||
"integrity": "sha512-HF4bW97dI25MWBYY6U07OzGICTmtUfz2UK5KfgP/4DLtupQgCDe6WlL2WQfLk4I6hYDcv45/7ngTmJExYRdHiw==",
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash.clonedeep": "^4.5.0"
|
"lodash.clonedeep": "^4.5.0"
|
||||||
@@ -3819,6 +4312,15 @@
|
|||||||
"uuid": "dist/esm/bin/uuid"
|
"uuid": "dist/esm/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
@@ -3974,6 +4476,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
|
|||||||
587
tvapp2/package-lock.json
generated
587
tvapp2/package-lock.json
generated
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "tvapp2",
|
"name": "tvapp2",
|
||||||
"version": "1.2.0",
|
"version": "1.4.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "tvapp2",
|
"name": "tvapp2",
|
||||||
"version": "1.2.0",
|
"version": "1.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
|
"express": "5.1.0",
|
||||||
"moment": "2.30.1",
|
"moment": "2.30.1",
|
||||||
"playwright": "^1.51.0",
|
"playwright": "^1.51.0",
|
||||||
"user-agents": "^1.1.480"
|
"user-agents": "^1.1.480"
|
||||||
@@ -159,13 +160,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.2.7",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
|
||||||
"integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
|
"integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^0.12.0",
|
"@eslint/core": "^0.13.0",
|
||||||
"levn": "^0.4.1"
|
"levn": "^0.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -173,9 +174,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
||||||
"version": "0.12.0",
|
"version": "0.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
|
||||||
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
|
"integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -303,6 +304,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"negotiator": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.1",
|
"version": "8.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||||
@@ -594,6 +608,38 @@
|
|||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"iconv-lite": "^0.6.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"raw-body": "^3.0.0",
|
||||||
|
"type-is": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -604,6 +650,15 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||||
@@ -627,7 +682,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -641,7 +695,6 @@
|
|||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
@@ -762,6 +815,45 @@
|
|||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -835,7 +927,6 @@
|
|||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
@@ -902,6 +993,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/didyoumean": {
|
"node_modules/didyoumean": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||||
@@ -926,7 +1026,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.1",
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
@@ -937,6 +1036,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||||
@@ -959,6 +1064,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.18.1",
|
"version": "5.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
||||||
@@ -1060,7 +1174,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1070,7 +1183,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1080,7 +1192,6 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0"
|
"es-errors": "^1.3.0"
|
||||||
@@ -1136,6 +1247,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@@ -1575,6 +1692,57 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "^2.0.0",
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
|
"content-disposition": "^1.0.0",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cookie": "^0.7.1",
|
||||||
|
"cookie-signature": "^1.2.1",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"finalhandler": "^2.1.0",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"merge-descriptors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"router": "^2.2.0",
|
||||||
|
"send": "^1.1.0",
|
||||||
|
"serve-static": "^2.2.0",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"type-is": "^2.0.1",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/external-editor": {
|
"node_modules/external-editor": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||||
@@ -1680,6 +1848,23 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||||
@@ -1734,25 +1919,28 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/forwarded": {
|
||||||
"version": "2.3.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
@@ -1803,7 +1991,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
@@ -1828,7 +2015,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dunder-proto": "^1.0.1",
|
"dunder-proto": "^1.0.1",
|
||||||
@@ -1916,7 +2102,6 @@
|
|||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -1987,7 +2172,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -2016,7 +2200,6 @@
|
|||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"function-bind": "^1.1.2"
|
"function-bind": "^1.1.2"
|
||||||
@@ -2025,6 +2208,22 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"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/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
@@ -2075,6 +2274,12 @@
|
|||||||
"node": ">=0.8.19"
|
"node": ">=0.8.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/inquirer": {
|
"node_modules/inquirer": {
|
||||||
"version": "7.3.3",
|
"version": "7.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||||
@@ -2132,6 +2337,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-array-buffer": {
|
"node_modules/is-array-buffer": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||||
@@ -2365,6 +2579,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-promise": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-regex": {
|
"node_modules/is-regex": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||||
@@ -2699,12 +2919,53 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.54.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||||
|
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mimic-fn": {
|
"node_modules/mimic-fn": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
@@ -2750,7 +3011,6 @@
|
|||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/mute-stream": {
|
"node_modules/mute-stream": {
|
||||||
@@ -2767,6 +3027,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
@@ -2792,7 +3061,6 @@
|
|||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -2885,6 +3153,27 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
@@ -3002,6 +3291,15 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -3029,6 +3327,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pegjs": {
|
"node_modules/pegjs": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz",
|
||||||
@@ -3057,8 +3364,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright": {
|
"node_modules/playwright": {
|
||||||
"version": "1.51.1",
|
"version": "1.51.1",
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz",
|
|
||||||
"integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==",
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.51.1"
|
"playwright-core": "1.51.1"
|
||||||
@@ -3075,8 +3380,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright-core": {
|
"node_modules/playwright-core": {
|
||||||
"version": "1.51.1",
|
"version": "1.51.1",
|
||||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz",
|
|
||||||
"integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==",
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright-core": "cli.js"
|
"playwright-core": "cli.js"
|
||||||
@@ -3122,6 +3425,19 @@
|
|||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
@@ -3132,6 +3448,57 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||||
|
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.6.3",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
@@ -3255,6 +3622,22 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/router": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"is-promise": "^4.0.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"path-to-regexp": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-async": {
|
"node_modules/run-async": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
@@ -3298,6 +3681,26 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/safe-push-apply": {
|
"node_modules/safe-push-apply": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
|
||||||
@@ -3337,7 +3740,6 @@
|
|||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
@@ -3350,6 +3752,43 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.5",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.1",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"send": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/set-blocking": {
|
"node_modules/set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
@@ -3406,6 +3845,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -3433,7 +3878,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -3453,7 +3897,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||||
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -3470,7 +3913,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -3489,7 +3931,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -3512,6 +3953,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
@@ -3677,6 +4127,15 @@
|
|||||||
"node": ">=0.6.0"
|
"node": ">=0.6.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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tr46": {
|
"node_modules/tr46": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
@@ -3730,6 +4189,20 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typed-array-buffer": {
|
"node_modules/typed-array-buffer": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||||
@@ -3827,6 +4300,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
@@ -3839,8 +4321,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/user-agents": {
|
"node_modules/user-agents": {
|
||||||
"version": "1.1.497",
|
"version": "1.1.497",
|
||||||
"resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.1.497.tgz",
|
|
||||||
"integrity": "sha512-HF4bW97dI25MWBYY6U07OzGICTmtUfz2UK5KfgP/4DLtupQgCDe6WlL2WQfLk4I6hYDcv45/7ngTmJExYRdHiw==",
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash.clonedeep": "^4.5.0"
|
"lodash.clonedeep": "^4.5.0"
|
||||||
@@ -3860,6 +4340,15 @@
|
|||||||
"uuid": "dist/esm/bin/uuid"
|
"uuid": "dist/esm/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
@@ -4015,6 +4504,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tvapp2",
|
"name": "tvapp2",
|
||||||
"version": "1.2.0",
|
"version": "1.4.0",
|
||||||
"description": "This package allows you to generate M3U playlists and EPG guides from various online IPTV services.",
|
"description": "This package allows you to generate M3U playlists and EPG guides from various online IPTV services.",
|
||||||
"author": "BinaryNinja",
|
"author": "BinaryNinja",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -76,7 +76,8 @@
|
|||||||
"user-agents": "^1.1.480",
|
"user-agents": "^1.1.480",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
"moment": "2.30.1"
|
"moment": "2.30.1",
|
||||||
|
"express": "5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
|
|||||||
335
tvapp2/www/css/tvapp2.min.css
vendored
335
tvapp2/www/css/tvapp2.min.css
vendored
@@ -1,3 +1,50 @@
|
|||||||
|
/*
|
||||||
|
Boostrap 5 > Table
|
||||||
|
*/
|
||||||
|
|
||||||
|
.table
|
||||||
|
{
|
||||||
|
--bs-table-bg: #1b1b1b;
|
||||||
|
--bs-table-border-color: #313131;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-striped > tbody > tr:nth-of-type(2n+1) > *
|
||||||
|
{
|
||||||
|
--bs-table-bg-type: #242424;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Boostrap 5 > Tooltips
|
||||||
|
*/
|
||||||
|
|
||||||
|
.tooltip-inner
|
||||||
|
{
|
||||||
|
background-color: #3061a1;
|
||||||
|
box-shadow: 0px 0px 4px black;
|
||||||
|
opacity: 1;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip.bs-tooltip-right .tooltip-arrow::before
|
||||||
|
{
|
||||||
|
border-right-color: #3061a1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip.bs-tooltip-left .tooltip-arrow::before
|
||||||
|
{
|
||||||
|
border-left-color: #3061a1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip.bs-tooltip-bottom .tooltip-arrow::before
|
||||||
|
{
|
||||||
|
border-bottom-color: #3061a1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip.bs-tooltip-top .tooltip-arrow::before
|
||||||
|
{
|
||||||
|
border-top-color: #3061a1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
background-color: #f8f9fa;
|
background-color: #f8f9fa;
|
||||||
@@ -32,13 +79,45 @@ body
|
|||||||
to { opacity: 1; }
|
to { opacity: 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-dimmer
|
||||||
|
{
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 0.90; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-dimmer-repeat
|
||||||
|
{
|
||||||
|
from { opacity: 0.90; }
|
||||||
|
to { opacity: 0.7; }
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes scale-in
|
@keyframes scale-in
|
||||||
{
|
{
|
||||||
from {
|
from {
|
||||||
transform: scale(1, 1);
|
transform: scale(1, 1);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
transform: scale(1.1, 1.1);
|
transform: scale(1.5, 1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin-scale
|
||||||
|
{
|
||||||
|
to {
|
||||||
|
transform: rotate(0deg) scale(1, 1);
|
||||||
|
}
|
||||||
|
from {
|
||||||
|
transform: rotate(360deg) scale(1.5, 1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin
|
||||||
|
{
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,18 +184,6 @@ p
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .logo
|
|
||||||
{
|
|
||||||
animation-name: fade-in, scale-in;
|
|
||||||
animation-duration: 1s, 0.5s;
|
|
||||||
animation-timing-function: ease-in, linear;
|
|
||||||
animation-direction: alternate, alternate;
|
|
||||||
animation-iteration-count: infinite, 1;
|
|
||||||
transition: all 0.3s;
|
|
||||||
opacity: 0.5;
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
{
|
{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -129,8 +196,8 @@ p
|
|||||||
.footer-inner
|
.footer-inner
|
||||||
{
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 10px;
|
||||||
padding-top: 20px;
|
padding-top: 10px;
|
||||||
background-color: #151515;
|
background-color: #151515;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +222,6 @@ p
|
|||||||
{
|
{
|
||||||
background-color: #a82147;
|
background-color: #a82147;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
height: 55px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .navbar-brand
|
.header .navbar-brand
|
||||||
@@ -173,6 +239,12 @@ p
|
|||||||
padding-left: 7px;
|
padding-left: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header .health
|
||||||
|
{
|
||||||
|
color: #ff7575;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
#breadcrumbs::before
|
#breadcrumbs::before
|
||||||
{
|
{
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
@@ -275,12 +347,11 @@ p
|
|||||||
|
|
||||||
.navbar-social svg
|
.navbar-social svg
|
||||||
{
|
{
|
||||||
font-size: clamp(0.7em, 2vw, 1.1em);
|
font-size: clamp(0.7em, 2vw, 1.0em);
|
||||||
padding-top: 2px;
|
margin-left: 10px;
|
||||||
padding-left: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-social svg:hover
|
.logo
|
||||||
{
|
{
|
||||||
animation-name: fade-in, scale-in;
|
animation-name: fade-in, scale-in;
|
||||||
animation-duration: 1s, 0.5s;
|
animation-duration: 1s, 0.5s;
|
||||||
@@ -288,19 +359,68 @@ p
|
|||||||
animation-direction: alternate, alternate;
|
animation-direction: alternate, alternate;
|
||||||
animation-iteration-count: infinite, 1;
|
animation-iteration-count: infinite, 1;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo:hover
|
||||||
|
{
|
||||||
|
animation-name: scale-in, spin;
|
||||||
|
animation-duration: 1s, 0.5s;
|
||||||
|
animation-timing-function: ease-in, linear;
|
||||||
|
animation-direction: alternate, alternate;
|
||||||
|
animation-iteration-count: infinite, 1;
|
||||||
|
transition: all 0.3s;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1.8);
|
transform: scale(1.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.restart
|
||||||
|
{
|
||||||
|
animation-name: fade-in, scale-in;
|
||||||
|
animation-duration: 1s, 0.5s;
|
||||||
|
animation-timing-function: linear, linear;
|
||||||
|
animation-direction: alternate, alternate;
|
||||||
|
animation-iteration-count: infinite, 1;
|
||||||
|
transition: all 0.3s;
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.restart:hover
|
||||||
|
{
|
||||||
|
animation-name: spin-scale;
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-direction: alternate;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
transition: all 0.3s;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spin
|
||||||
|
{
|
||||||
|
transition-property: transform;
|
||||||
|
transition-duration: 0.5s;
|
||||||
|
animation-name: spin;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
.table thead th a
|
.table thead th a
|
||||||
{
|
{
|
||||||
color: #9b9b9b !important;
|
color: #9b9b9b !important;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.table td, .table th
|
.table td, .table th
|
||||||
{
|
{
|
||||||
padding: .75rem;
|
padding: .35rem;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
border-top: 0px solid #dee2e6;
|
border-top: 0px solid #dee2e6;
|
||||||
font-size: clamp(0.5em, 1vw, 0.8em);
|
font-size: clamp(0.5em, 1vw, 0.8em);
|
||||||
@@ -309,17 +429,13 @@ p
|
|||||||
|
|
||||||
.table thead tr
|
.table thead tr
|
||||||
{
|
{
|
||||||
border-bottom: 2px solid #575757;
|
border-bottom: 2px solid #325eb3;
|
||||||
background-color: #181818;
|
|
||||||
color: #717171;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table thead th
|
.table thead th
|
||||||
{
|
{
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
border-bottom: 0px solid #575757;
|
border-bottom: 0px solid #325eb3;
|
||||||
font-size: clamp(0.5em, 1vw, 0.8em);
|
|
||||||
line-height: 2.5vmin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-hover tbody tr:hover
|
.table-hover tbody tr:hover
|
||||||
@@ -333,27 +449,63 @@ p
|
|||||||
color: #d0c273;
|
color: #d0c273;
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning-firewall
|
.ntfy
|
||||||
|
{
|
||||||
|
padding-top: 1.5vh;
|
||||||
|
padding-bottom: 1.5vh;
|
||||||
|
padding-left: 2vh;
|
||||||
|
padding-right: 2vh;
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
line-height: 25px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ntfy-restart
|
||||||
|
{
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
font-size: clamp(0.5em, 1vw, 0.8em);
|
||||||
|
font-weight: 100;
|
||||||
|
border: 1px dashed #9e973a;
|
||||||
|
display: none;
|
||||||
|
z-index: 5000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ntfy-firewall
|
||||||
{
|
{
|
||||||
background-color: #1A1A1A;
|
background-color: #1A1A1A;
|
||||||
padding: 2vh;
|
|
||||||
margin-bottom: 1vh;
|
|
||||||
font-size: clamp(0.5em, 1vw, 0.8em);
|
font-size: clamp(0.5em, 1vw, 0.8em);
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
border: 1px dashed #FF6C00;
|
border: 1px dashed #FF6C00;
|
||||||
width: 100%;
|
display: none;
|
||||||
line-height: 25px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning-localhost
|
#ntfy-localhost
|
||||||
{
|
{
|
||||||
background-color: #1A1A1A;
|
background-color: #1A1A1A;
|
||||||
padding: 2vh;
|
|
||||||
font-size: clamp(0.5em, 1vw, 0.8em);
|
font-size: clamp(0.5em, 1vw, 0.8em);
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
border: 1px dashed #FF0048;
|
border: 1px dashed #FF0048;
|
||||||
width: 100%;
|
display: none;
|
||||||
line-height: 25px;
|
}
|
||||||
|
|
||||||
|
span.success
|
||||||
|
{
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #97950A;
|
||||||
|
padding-left: 7px;
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
||||||
|
margin-right: 8px;
|
||||||
|
animation-name: fade-in, scale-in;
|
||||||
|
animation-duration: 1s, 0.5s;
|
||||||
|
animation-timing-function: ease-in, linear;
|
||||||
|
animation-direction: alternate, alternate;
|
||||||
|
animation-iteration-count: infinite, 1;
|
||||||
|
transition: all 0.3s;
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
span.notice
|
span.notice
|
||||||
@@ -399,8 +551,8 @@ span.warning
|
|||||||
code
|
code
|
||||||
{
|
{
|
||||||
font-size: 96%;
|
font-size: 96%;
|
||||||
color: #ff4985;
|
color: #ff4985 !important;
|
||||||
word-break: break-word;
|
word-break: break-word !important;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
}
|
}
|
||||||
@@ -428,7 +580,7 @@ code
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 999;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-bottom
|
.fixed-bottom
|
||||||
@@ -437,7 +589,7 @@ code
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 999;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sticky-top
|
.sticky-top
|
||||||
@@ -446,16 +598,115 @@ code
|
|||||||
{
|
{
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 999;
|
z-index: 99999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sticky-bottom
|
||||||
|
{
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: relative !important;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.sticky-bottom
|
.sticky-bottom
|
||||||
{
|
{
|
||||||
@supports (position: sticky)
|
@supports (position: sticky)
|
||||||
{
|
{
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 999;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aboveDimmer
|
||||||
|
{
|
||||||
|
z-index: 301;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes heartbeat
|
||||||
|
{
|
||||||
|
0%
|
||||||
|
{
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
20%
|
||||||
|
{
|
||||||
|
transform: scale(1.5);
|
||||||
|
}
|
||||||
|
40%
|
||||||
|
{
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
60%
|
||||||
|
{
|
||||||
|
transform: scale(1.5);
|
||||||
|
}
|
||||||
|
80%
|
||||||
|
{
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
100%
|
||||||
|
{
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart
|
||||||
|
{
|
||||||
|
position: relative;
|
||||||
|
animation: heartbeat 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dimmer-out
|
||||||
|
{
|
||||||
|
transition: opacity 1s ease-in-out !important;
|
||||||
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dimmer-in
|
||||||
|
{
|
||||||
|
opacity: 0.7;
|
||||||
|
animation-name: fade-in-dimmer, fade-in-dimmer-repeat;
|
||||||
|
animation-delay: 0s, 0.7s;
|
||||||
|
animation-duration: 0.7s, 1s;
|
||||||
|
animation-timing-function: ease-in, linear;
|
||||||
|
animation-direction: alternate, alternate;
|
||||||
|
animation-iteration-count: 1, infinite;
|
||||||
|
transition: opacity 250ms ease-in, visibility 0ms ease-in 250ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dimmer
|
||||||
|
{
|
||||||
|
z-index: 200;
|
||||||
|
position: fixed;
|
||||||
|
background-color: #000000;
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
height: 100%;
|
||||||
|
visibility: hidden;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,40 +1,48 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" data-bs-theme="dark">
|
||||||
<head>
|
<head>
|
||||||
|
<title><%= appName %> - v<%= appVersion %></title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title><%= appName %> - v<%= appVersion %></title>
|
|
||||||
<meta name="robots" content="noindex, nofollow">
|
<meta name="robots" content="noindex, nofollow">
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="css/tvapp2.min.css">
|
<link rel="stylesheet" href="css/tvapp2.min.css">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<script src='https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/js/bootstrap.bundle.min.js' integrity='sha384-k6d4wzSIapyDyv1kpU366/PK5hCdSbCRGRCMv+eplOQJWyd1fbcAu9OCUj5zNLiq' crossorigin='anonymous'></script>
|
||||||
|
<script src=' https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js '></script>
|
||||||
|
<script src='js/tvapp2.min.js'></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Header -->
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<nav class="navbar sticky-top container">
|
<nav class="navbar sticky-top container">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<i class="logo fa-sharp-duotone fa-regular fa-tv" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i>
|
<i data-bs-toggle="tooltip" title="v<%= appVersion %>" class="logo fa-sharp-duotone fa-regular fa-tv" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i>
|
||||||
<a class="header-name" href="<%= appUrlGithub %>">TVApp2 for Docker</a>
|
<a class="header-name" href="<%= appUrlGithub %>">TVApp2 for Docker</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-social">
|
<div class="navbar-social">
|
||||||
<a href="<%= appUrlDocs %>"><i class="logo fa-duotone fa-solid fa-book-open-cover" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
<a href=""><i id="action-health" data-bs-toggle="tooltip" title="Health" class="heart logo health fa-duotone fa-solid fa-heart" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
||||||
<a href="<%= appUrlGithub %>"><i class="logo fa-logos fa-github" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
<a href="javascript:runResync();"><i id="action-resync" data-bs-toggle="tooltip" title="Resync" class="restart fa-solid fa-rotate" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
||||||
<a href="<%= appUrlDiscord %>"><i class="logo fa-logos fa-discord" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
<a href="<%= appUrlDocs %>"><i data-bs-toggle="tooltip" title="Documentation" class="logo fa-duotone fa-solid fa-book-open-cover" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
||||||
|
<a href="<%= appUrlGithub %>"><i data-bs-toggle="tooltip" title="Github" class="logo fa-logos fa-github" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
||||||
|
<a href="<%= appUrlDiscord %>"><i data-bs-toggle="tooltip" title="Discord" class="logo fa-logos fa-discord" style="--fa-primary-color: rgb(255, 255, 255); --fa-secondary-color: rgb(255, 255, 255);" aria-hidden="true"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Header Notification: description -->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container header-container">
|
<div class="container header-container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="about">This page displays your most recent copies of the <code><%= fileM3U %></code> playlist and <code><%= fileXML %></code> EPG guide data. Right-click each file, select <span class="text-accent">Copy Link</span> and paste the URLs within an IPTV app such as Jellyfin. The <code><%= fileXML %></code> and <code><%= fileTAR %></code> have identical guide data, however the <code><%= fileTAR %></code> is compressed and will import into your IPTV application much faster.</div>
|
<div class="about">This page displays your most recent copies of the <code><%= fileM3U %></code> playlist and <code><%= fileXML %></code> EPG guide data. Right-click each file, select <span class="text-accent">Copy Link</span> and paste the URLs within an IPTV app such as Jellyfin. The <code><%= fileXML %></code> and <code><%= fileGZP %></code> have identical guide data, however the <code><%= fileGZP %></code> is compressed and will import into your IPTV application much faster.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Header Fontawesome Icons -->
|
||||||
<div class="container main-container">
|
<div class="container main-container">
|
||||||
<table id="list" class="table table-sm table-hover">
|
<table id="list" class="table table-dark table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="d-none d-md-table-row">
|
<tr class="d-none d-md-table-row">
|
||||||
<td class="icon cell-icon"></td>
|
<td class="icon cell-icon"></td>
|
||||||
@@ -64,7 +72,7 @@
|
|||||||
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
||||||
</td>
|
</td>
|
||||||
<td class="file cell-file">
|
<td class="file cell-file">
|
||||||
<a id="m3u-name" target="_blank"></a>
|
<a id="m3u-name" target="_blank" data-bs-toggle="tooltip" title="IPTV channel list"></a>
|
||||||
</td>
|
</td>
|
||||||
<td class="link cell-link"><a id="m3u-link" target="_blank"></a></td>
|
<td class="link cell-link"><a id="m3u-link" target="_blank"></a></td>
|
||||||
<td class="size cell-size"><span id="m3u-size"></span></td>
|
<td class="size cell-size"><span id="m3u-size"></span></td>
|
||||||
@@ -79,7 +87,7 @@
|
|||||||
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
||||||
</td>
|
</td>
|
||||||
<td class="file cell-file">
|
<td class="file cell-file">
|
||||||
<a id="xml-name" target="_blank"></a>
|
<a id="xml-name" target="_blank" data-bs-toggle="tooltip" title="Uncompressed TV guide data"></a>
|
||||||
</td>
|
</td>
|
||||||
<td class="link cell-link"><a id="xml-link" target="_blank"></a></td>
|
<td class="link cell-link"><a id="xml-link" target="_blank"></a></td>
|
||||||
<td class="size cell-size"><span id="xml-size"></span></td>
|
<td class="size cell-size"><span id="xml-size"></span></td>
|
||||||
@@ -93,12 +101,12 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
<!-- <i class="fa fa-fw fa-solid fa-file-lines" aria-hidden="true"></i> -->
|
||||||
</td>
|
</td>
|
||||||
<td class="file cell-tar">
|
<td class="file cell-gzp">
|
||||||
<a id="tar-name" target="_blank"></a>
|
<a id="gzp-name" target="_blank" data-bs-toggle="tooltip" title="Compressed TV guide data"></a>
|
||||||
</td>
|
</td>
|
||||||
<td class="link cell-link"><a id="tar-link" target="_blank"></a></td>
|
<td class="link cell-link"><a id="gzp-link" target="_blank"></a></td>
|
||||||
<td class="size cell-size"><span id="tar-size"></span></td>
|
<td class="size cell-size"><span id="gzp-size"></span></td>
|
||||||
<td class="date cell-date"><span id="tar-date"></span></td>
|
<td class="date cell-date"><span id="gzp-date"></span></td>
|
||||||
<td class="desc cell-desc">XML / EPG guide data <code>(compressed)</code></td>
|
<td class="desc cell-desc">XML / EPG guide data <code>(compressed)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -106,78 +114,394 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container" style="padding-bottom:20px;">
|
<div class="container" style="padding-bottom:20px;">
|
||||||
<div id="warning-firewall" class="sticky-bottom"></div>
|
<div id="ntfy-restart" class="ntfy ntfy-success sticky-bottom"></div>
|
||||||
<div id="warning-localhost" class="sticky-bottom"></div>
|
<div id="ntfy-firewall" class="ntfy ntfy-warning sticky-bottom"></div>
|
||||||
|
<div id="ntfy-localhost" class="ntfy ntfy-danger sticky-bottom"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-inner">
|
<div class="footer-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="col text-center text-muted text-small text-nowrap">
|
<div class="col text-center text-muted text-small text-nowrap">
|
||||||
<small>Developed by BinaryNinja - <a href="<%= appUrlGithub %>"><%= appName %></a> - v<%= appVersion %></small><br />
|
<small>Developed by BinaryNinja - <a data-bs-toggle="tooltip" title="<%= appRelease %> build" href="<%= appUrlGithub %>"><%= appName %> (<%= appRelease %>)</a> - v<%= appVersion %></small><br />
|
||||||
<small>This utility is for educational purposes only</small>
|
<small>This utility is for educational purposes only</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- Toast Notifications -->
|
||||||
|
<!-- <button type="button" class="btn btn-primary" id="btnTestToasts">Show toast</button> -->
|
||||||
|
<div style="z-index: 9999;" class="toast position-fixed bottom-0 end-0 p-8 m-3" id="tvapp2Toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="true" data-bs-delay="4000">
|
||||||
|
<div class="toast-body">
|
||||||
|
<div class="d-flex gap-4">
|
||||||
|
<span><i class="fa-solid fa-circle-check fa-lg icon-success"></i></span>
|
||||||
|
<div class="d-flex flex-column flex-grow-1 gap-2">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span id="toast-title" class="fw-semibold">Toast Title</span>
|
||||||
|
<button type="button" class="btn-close btn-close-sm ms-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<span id="toast-message">Dismiss in 6 seconds</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="modal fade" id="modalTvapp2" tabindex="-1" data-bs-backdrop="static" aria-labelledby="modalTvapp2Label" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="modalTvapp2Label">Modal title</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
...
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" id="btn-secondary" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" id="btn-primary" class="btn btn-primary">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/*
|
||||||
|
this is test code. enable the "Show Toast" button and then uncomment this code.
|
||||||
|
|
||||||
|
document.getElementById("btnTestToasts").onclick = function()
|
||||||
|
{
|
||||||
|
var toastElList = [].slice.call(document.querySelectorAll('.toast'))
|
||||||
|
var toastList = toastElList.map(function(toastEl)
|
||||||
|
{
|
||||||
|
return new bootstrap.Toast(toastEl)
|
||||||
|
});
|
||||||
|
|
||||||
|
toastList.forEach(toast => toast.show());
|
||||||
|
console.log(toastList);
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||||
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||||
|
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||||
|
})
|
||||||
|
|
||||||
const urlBase = window.location.origin;
|
const urlBase = window.location.origin;
|
||||||
const urlM3U = urlBase + "/playlist";
|
const urlM3U = urlBase + '/playlist';
|
||||||
const urlXML = urlBase + "/epg";
|
const urlXML = urlBase + '/epg';
|
||||||
const urlTAR = urlBase + "/gzip";
|
const urlGZP = urlBase + '/gzip';
|
||||||
|
|
||||||
document.getElementById("m3u-name").textContent = "<%= fileM3U %>";
|
document.getElementById('m3u-name').textContent = '<%= fileM3U %>';
|
||||||
document.getElementById("m3u-name").href = urlM3U;
|
document.getElementById('m3u-name').href = urlM3U;
|
||||||
document.getElementById("m3u-link").textContent = urlM3U;
|
document.getElementById('m3u-link').textContent = urlM3U;
|
||||||
document.getElementById("m3u-link").href = urlM3U;
|
document.getElementById('m3u-link').href = urlM3U;
|
||||||
document.getElementById("m3u-size").textContent = "<%= sizeM3U %>";
|
document.getElementById('m3u-size').textContent = '<%= sizeM3U %>';
|
||||||
document.getElementById("m3u-date").textContent = "<%= dateM3U %>";
|
document.getElementById('m3u-date').textContent = '<%= dateM3U %>';
|
||||||
|
|
||||||
document.getElementById("xml-name").textContent = "<%= fileXML %>";
|
document.getElementById('xml-name').textContent = '<%= fileXML %>';
|
||||||
document.getElementById("xml-name").href = urlXML;
|
document.getElementById('xml-name').href = urlXML;
|
||||||
document.getElementById("xml-link").textContent = urlXML;
|
document.getElementById('xml-link').textContent = urlXML;
|
||||||
document.getElementById("xml-link").href = urlXML;
|
document.getElementById('xml-link').href = urlXML;
|
||||||
document.getElementById("xml-size").textContent = "<%= sizeXML %>";
|
document.getElementById('xml-size').textContent = '<%= sizeXML %>';
|
||||||
document.getElementById("xml-date").textContent = "<%= dateXML %>";
|
document.getElementById('xml-date').textContent = '<%= dateXML %>';
|
||||||
|
|
||||||
document.getElementById("tar-name").textContent = "<%= fileTAR %>";
|
document.getElementById('gzp-name').textContent = '<%= fileGZP %>';
|
||||||
document.getElementById("tar-name").href = urlTAR;
|
document.getElementById('gzp-name').href = urlGZP;
|
||||||
document.getElementById("tar-link").textContent = urlTAR;
|
document.getElementById('gzp-link').textContent = urlGZP;
|
||||||
document.getElementById("tar-link").href = urlTAR;
|
document.getElementById('gzp-link').href = urlGZP;
|
||||||
document.getElementById("tar-size").textContent = "<%= sizeTAR %>";
|
document.getElementById('gzp-size').textContent = '<%= sizeGZP %>';
|
||||||
document.getElementById("tar-date").textContent = "<%= dateTAR %>";
|
document.getElementById('gzp-date').textContent = '<%= dateGZP %>';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function()
|
|
||||||
{
|
/*
|
||||||
|
Document Ready
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$("[data-bs-toggle=tooltip]").tooltip({ placement: 'bottom'});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action > DOM Status
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentReady", function() {
|
||||||
|
$("#tvapp2Toast").toast();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
$('#tvapp2Toast').toast("show");
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Notify > Localhost
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const host = window.location.hostname;
|
const host = window.location.hostname;
|
||||||
if (host === "localhost" || host === "127.0.0.1")
|
const port = window.location.port || (window.location.protocol === 'https:' ? '443' : '80');
|
||||||
|
if (host === 'localhost' || host === '127.0.0.1')
|
||||||
{
|
{
|
||||||
const warning = document.createElement("div");
|
const msg = "<p><span class='warning'>Warning</span> If you are accessing this page via 127.0.0.1 or localhost, proxying will not work on other devices.Please load \
|
||||||
warning.innerHTML = "<p><span class='warning'>Warning</span> If you are accessing this page via 127.0.0.1 or localhost, proxying will not work on other devices.Please load \
|
|
||||||
this page using your computer's IP address (e.g., 192.168.x.x) and port in order to access the playlist from other devices on your network.</p> \
|
this page using your computer's IP address (e.g., 192.168.x.x) and port in order to access the playlist from other devices on your network.</p> \
|
||||||
<br> \
|
<br> \
|
||||||
<p> Learn how to locate your IP address on <a href='https://youtube.com/watch?v=UAhDHXN2c6E' target = '_blank' > Windows</a> or \
|
<p> Learn how to locate your IP address on <a href='https://youtube.com/watch?v=UAhDHXN2c6E' target = '_blank' > Windows</a> or \
|
||||||
<a href='https://youtube.com/watch?v=gaIYP4TZfHI' target = '_blank' > Linux</a>.</p>";
|
<a href='https://youtube.com/watch?v=gaIYP4TZfHI' target = '_blank' > Linux</a>.</p>";
|
||||||
|
|
||||||
document.getElementById("warning-localhost").appendChild(warning);
|
document.getElementById('ntfy-localhost').innerHTML = msg;
|
||||||
|
document.getElementById('ntfy-localhost').style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("warning-localhost").style.display = "none";
|
document.getElementById('ntfy-localhost').style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function()
|
/*
|
||||||
{
|
Notify > Firewall
|
||||||
const port = window.location.port || (window.location.protocol === "https:" ? "443" : "80");
|
*/
|
||||||
const warningMessage = "<p><span class='notice'>Notice</span> Port <strong> " + port + " </strong> must be open and allowed through your <a href='https://youtu.be/zOZWlTplrcA?si=nGXrHKU4sAQsy18e&t=18 target='_blank'>Windows</a> \
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const port = window.location.port || (window.location.protocol === 'https:' ? '443' : '80');
|
||||||
|
const msg = "<p><span class='notice'>Notice</span> Port <strong> " + port + " </strong> must be open and allowed through your <a href='https://youtu.be/zOZWlTplrcA?si=nGXrHKU4sAQsy18e&t=18 target='_blank'>Windows</a> \
|
||||||
or <a href='https://youtu.be/7c_V_3nWWbA?si=Hkd_II9myn-AkNnS&t=12' target='_blank'>Linux</a> OS firewall settings \
|
or <a href='https://youtu.be/7c_V_3nWWbA?si=Hkd_II9myn-AkNnS&t=12' target='_blank'>Linux</a> OS firewall settings \
|
||||||
This action enables devices such as Firestick or Android to connect to the server and request the playlist through the proxy.</p>";
|
This action enables devices such as Firestick or Android to connect to the server and request the playlist through the proxy.</p>";
|
||||||
|
|
||||||
document.getElementById("warning-firewall").innerHTML = warningMessage;
|
document.getElementById('ntfy-firewall').innerHTML = msg;
|
||||||
|
document.getElementById('ntfy-firewall').style.display = 'block';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Notify > Restart / Resync
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const port = window.location.port || (window.location.protocol === 'https:' ? '443' : '80');
|
||||||
|
const msg = "<p><span class='success'>Success</span> Your IPTV m3u channels and xml guide data has been successfully re-synced. \
|
||||||
|
Please refresh this window to see new data</p>";
|
||||||
|
|
||||||
|
document.getElementById('ntfy-restart').innerHTML = msg;
|
||||||
|
document.getElementById('ntfy-restart').style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set initial health check sync time
|
||||||
|
|
||||||
|
first health check runs after 10 seconds
|
||||||
|
all future health checks run after <%= healthTimer %>
|
||||||
|
*/
|
||||||
|
|
||||||
|
let timerDelayMS = 10000;
|
||||||
|
let timerStartMS = Date.now(); // returns milliseconds
|
||||||
|
const timerHealthRun = '<%= healthTimer %>'; // time in milliseconds until health check ran AFTER initial run
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action > Healthcheck
|
||||||
|
*/
|
||||||
|
|
||||||
|
function runHealthCheck()
|
||||||
|
{
|
||||||
|
const toastTypeClass = [];
|
||||||
|
toastTypeClass[ 'DEFAULT' ] = 'text-bg-primary';
|
||||||
|
toastTypeClass[ 'UNHEALTHY' ] = 'text-bg-warning';
|
||||||
|
toastTypeClass[ 'HEALTHY' ] = 'text-bg-success';
|
||||||
|
toastTypeClass[ 'ERROR' ] = 'text-bg-danger';
|
||||||
|
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
url: 'api/health',
|
||||||
|
type: 'GET',
|
||||||
|
data: {
|
||||||
|
internal: 1
|
||||||
|
},
|
||||||
|
beforeSend: function( data )
|
||||||
|
{
|
||||||
|
console.log('Sending health check ...')
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
const status = data.message;
|
||||||
|
const code = data.code;
|
||||||
|
if ( status )
|
||||||
|
{
|
||||||
|
const toastClass = toastTypeClass[status.toUpperCase()];
|
||||||
|
const toastElm = document.getElementById('tvapp2Toast');
|
||||||
|
toastElm.classList.add(toastClass);
|
||||||
|
|
||||||
|
$('.toast #toast-title').html(`<%= appName %> is ${ status }`);
|
||||||
|
$('.toast #toast-message').html(`Health check returned ${ status } (${ code })`);
|
||||||
|
$('#tvapp2Toast').toast('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function( data )
|
||||||
|
{
|
||||||
|
const toastClass = toastTypeClass['ERROR'];
|
||||||
|
const toastElm = document.getElementById('tvapp2Toast');
|
||||||
|
toastElm.classList.add(toastClass);
|
||||||
|
|
||||||
|
$('.toast #toast-title').html(`Could not connect to health check api`);
|
||||||
|
$('.toast #toast-message').html(`Failed to communicate with health check api. Try restarting the docker container to restore connection.`);
|
||||||
|
$('#tvapp2Toast').toast('show');
|
||||||
|
|
||||||
|
}
|
||||||
|
}).always(function()
|
||||||
|
{
|
||||||
|
timerDelayMS = parseInt(timerHealthRun);
|
||||||
|
timerStartMS = Date.now();
|
||||||
|
|
||||||
|
setTimeout(function()
|
||||||
|
{
|
||||||
|
runHealthCheck();
|
||||||
|
}, parseInt(timerHealthRun));
|
||||||
|
}).responseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action > Do Resync
|
||||||
|
*/
|
||||||
|
|
||||||
|
function runResync()
|
||||||
|
{
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
url: 'restart',
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
internal: 1
|
||||||
|
},
|
||||||
|
beforeSend: function( data )
|
||||||
|
{
|
||||||
|
const dimmer = document.createElement('div');
|
||||||
|
dimmer.setAttribute('id', 'dimmer');
|
||||||
|
dimmer.style.visibility = 'visible';
|
||||||
|
dimmer.classList.add('dimmer-in');
|
||||||
|
document.getElementsByTagName('body')[0].appendChild(dimmer);
|
||||||
|
document.getElementById('ntfy-firewall').style.display = 'none';
|
||||||
|
document.getElementById('ntfy-localhost').style.display = 'none';
|
||||||
|
document.getElementById('ntfy-restart').style.display = 'none';
|
||||||
|
|
||||||
|
const iconResync = document.getElementsByClassName('fa-rotate');
|
||||||
|
iconResync[0].classList.remove('restart');
|
||||||
|
iconResync[0].classList.add('spin');
|
||||||
|
|
||||||
|
$('.modal-content .modal-body').html('<small>The M3U and EPG data will now be re-downloaded and synced with your TVApp2 container. Afterward, this page will be refreshed automatically.</small><br /><br /><small>Please wait...</small>')
|
||||||
|
$('.modal-content .modal-title').html('Resyncing Data')
|
||||||
|
$('#modalTvapp2').modal('show');
|
||||||
|
|
||||||
|
const modalBtnPrimary = document.querySelector('#btn-primary');
|
||||||
|
modalBtnPrimary.style.display = 'none';
|
||||||
|
modalBtnPrimary.style.visibility= 'hidden';
|
||||||
|
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
On successful restart, wait 1 second, remove dimmer, reload page in 5 seconds
|
||||||
|
*/
|
||||||
|
|
||||||
|
setTimeout( () =>
|
||||||
|
{
|
||||||
|
document.getElementById('ntfy-restart').style.display = 'block'
|
||||||
|
const dimmer = document.getElementById('dimmer');
|
||||||
|
dimmer.classList.remove('dimmer-in');
|
||||||
|
dimmer.classList.add('dimmer-out');
|
||||||
|
dimmer.remove();
|
||||||
|
|
||||||
|
setTimeout( function()
|
||||||
|
{
|
||||||
|
const iconResync = document.getElementsByClassName('fa-rotate'); // resync favicon
|
||||||
|
iconResync[0].classList.remove('spin'); // stop spinning
|
||||||
|
iconResync[0].classList.add('restart'); // normal spinner class
|
||||||
|
document.location.reload() // reload page
|
||||||
|
}, 5000 ); // how long until refresh page
|
||||||
|
}, 1000 ); // how long until dimmer is removed / reload page activated (also on delay)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Health check > Show time remaining as tooltip
|
||||||
|
*/
|
||||||
|
|
||||||
|
function runTooltipCountdown( )
|
||||||
|
{
|
||||||
|
let timerHours, timerMins, timerRemainsLS;
|
||||||
|
|
||||||
|
function twoDigits( n )
|
||||||
|
{
|
||||||
|
return (n <= 9 ? "0" + n : n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update Tooltip Countdown
|
||||||
|
|
||||||
|
MS = milliseconds
|
||||||
|
LS = long string (Wed Dec 31 1969 10:01:42 (Coordinated Universal Time))
|
||||||
|
*/
|
||||||
|
|
||||||
|
function updateTooltipCountdown()
|
||||||
|
{
|
||||||
|
const timerElapsedMS = Date.now() - timerStartMS; // ( 2091 )
|
||||||
|
const timerRemainsMS = timerDelayMS - timerElapsedMS; // ( 7909 ) divide by 1000 for seconds
|
||||||
|
|
||||||
|
timerRemainsLS = new Date( timerRemainsMS ); // (Wed Dec 31 1969 10:01:42 (Coordinated Universal Time))
|
||||||
|
timerHours = timerRemainsLS.getUTCHours(); // ( 0 )
|
||||||
|
timerMins = timerRemainsLS.getUTCMinutes(); // ( 9 )
|
||||||
|
const timeLeft = (timerHours ? timerHours + ':' + twoDigits( timerMins ) : timerMins) + ':' + twoDigits( timerRemainsLS.getUTCSeconds() );
|
||||||
|
|
||||||
|
jQuery(function($)
|
||||||
|
{
|
||||||
|
$(document.body).tooltip({ selector: "[title]" });
|
||||||
|
$('#action-health')
|
||||||
|
.attr('data-original-title', `Health check in ${ timeLeft }`)
|
||||||
|
.attr('aria-label', `Health check in ${ timeLeft }`)
|
||||||
|
.attr('data-bs-original-title', `Health check in ${ timeLeft }`)
|
||||||
|
});
|
||||||
|
|
||||||
|
const Heart = document.getElementsByClassName('fa-heart');
|
||||||
|
Heart[0].style.color = '#FFF';
|
||||||
|
|
||||||
|
setTimeout( function()
|
||||||
|
{
|
||||||
|
const Heart = document.getElementsByClassName('fa-heart');
|
||||||
|
Heart[0].style.color = '#FFF';
|
||||||
|
|
||||||
|
setTimeout( function()
|
||||||
|
{
|
||||||
|
Heart[0].style.color = '#FF6593';
|
||||||
|
}, timerRemainsLS.getUTCMilliseconds() + 100 );
|
||||||
|
|
||||||
|
}, timerRemainsLS.getUTCMilliseconds() + 500 );
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout( function()
|
||||||
|
{
|
||||||
|
updateTooltipCountdown();
|
||||||
|
}, timerRemainsLS.getUTCMilliseconds() + 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTooltipCountdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action > Healthcheck > Initialize
|
||||||
|
*/
|
||||||
|
|
||||||
|
setTimeout( function() { runHealthCheck(); }, timerDelayMS );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Action > Tooltip Resync Timers
|
||||||
|
*/
|
||||||
|
|
||||||
|
runTooltipCountdown( );
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script src="js/tvapp2.min.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user