Compare commits
108
Commits
2.0.3.0030
...
f558a855ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f558a855ae | ||
|
|
125b0bb35f | ||
|
|
32c3d779c0 | ||
|
|
ce5b12d8b8 | ||
|
|
76183bfaa2 | ||
|
|
c577d354e7 | ||
|
|
e48a061ca0 | ||
|
|
ffd43d5217 | ||
|
|
9bd2b32003 | ||
|
|
8698983bbf | ||
|
|
60af423335 | ||
|
|
57b6be74e2 | ||
|
|
c5545cbf08 | ||
|
|
339d2d0aa5 | ||
|
|
a04b0ede50 | ||
|
|
84de46a2f2 | ||
|
|
5eaf5efdb6 | ||
|
|
fb62353de4 | ||
|
|
fa9d41e10c | ||
|
|
e07d4dd878 | ||
|
|
6053207034 | ||
|
|
6a8b4bed28 | ||
|
|
45685ce592 | ||
|
|
43a9cf5a7e | ||
|
|
a23cc7a183 | ||
|
|
b069d5bee8 | ||
|
|
8cb9e43a72 | ||
|
|
0e999b85b9 | ||
|
|
e4b3667fe0 | ||
|
|
e44eff0645 | ||
|
|
884b427754 | ||
|
|
25bad13800 | ||
|
|
d2456b0506 | ||
|
|
19b9a259b1 | ||
|
|
441cefa3a4 | ||
|
|
014f5b7218 | ||
|
|
0310b7e738 | ||
|
|
6d890cfd33 | ||
|
|
410cc3648f | ||
|
|
07f9cac3c5 | ||
|
|
f43ce0f7c5 | ||
|
|
db59f7ef37 | ||
|
|
b407ec5bf0 | ||
|
|
d8fc1aea97 | ||
|
|
38333d65cb | ||
|
|
a6a9b90937 | ||
|
|
2b3fe6a09d | ||
|
|
a09eca59a7 | ||
|
|
0df3b4d755 | ||
|
|
5552514a1f | ||
|
|
5fceb1d34f | ||
|
|
fb5d0a3904 | ||
|
|
28fe4dcf1c | ||
|
|
bc307a7cd4 | ||
|
|
fd3024d7ff | ||
|
|
d3f6725ba6 | ||
|
|
c266012db3 | ||
|
|
d602b60710 | ||
|
|
67b7ba6df9 | ||
|
|
71dfe91272 | ||
|
|
534510a4ec | ||
|
|
2d10fc9313 | ||
|
|
a63a9c0d8f | ||
|
|
dd911d6e5d | ||
|
|
c1970a8393 | ||
|
|
493d612d52 | ||
|
|
4fc4330a94 | ||
|
|
a683533824 | ||
|
|
4b9f5826cf | ||
|
|
ca49d70910 | ||
|
|
1b425018d4 | ||
|
|
87b36c283b | ||
|
|
6da26ff4fb | ||
|
|
cd08985e79 | ||
|
|
dc04519229 | ||
|
|
c4ad96b715 | ||
|
|
45b5e602bb | ||
|
|
1cefbf022d | ||
|
|
d5328f6b1a | ||
|
|
91b80bc8bb | ||
|
|
aa763726a3 | ||
|
|
66c01dd1fb | ||
|
|
03e1abbe90 | ||
|
|
469581e280 | ||
|
|
019c98996a | ||
|
|
36db927794 | ||
|
|
f0a49788cc | ||
|
|
72767d7dbd | ||
|
|
8eecbf2b78 | ||
|
|
1a1e37fe15 | ||
|
|
08f6fb60e3 | ||
|
|
eded490ac7 | ||
|
|
ed770b9dbc | ||
|
|
6129b4911a | ||
|
|
477c5f30c1 | ||
|
|
65ddc6f301 | ||
|
|
3ef95c1950 | ||
|
|
3a3798cd2d | ||
|
|
72eb7fb599 | ||
|
|
4b969b8cee | ||
|
|
3d9266dabe | ||
|
|
48218cda50 | ||
|
|
dc42afcd05 | ||
|
|
20e5e1b545 | ||
|
|
11dd830110 | ||
|
|
7c87d1d5bd | ||
|
|
6cdd44357b | ||
|
|
ad992eb615 |
No files matched your search
@@ -0,0 +1,10 @@
|
||||
.git
|
||||
.github
|
||||
.DS_Store
|
||||
|
||||
docker-data
|
||||
|
||||
README-DEV.md
|
||||
|
||||
*.log
|
||||
*.tmp
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: go-test
|
||||
image: cache.coadcorp.com/library/golang
|
||||
commands:
|
||||
- go mod download
|
||||
- go test ./...
|
||||
|
||||
- name: go-build
|
||||
image: cache.coadcorp.com/library/golang
|
||||
commands:
|
||||
- XTEVE_VERSION="$(grep -m1 '^#### ' changelog-beta.md | cut -d' ' -f2 | sed 's/-beta$//')"
|
||||
- test -n "$XTEVE_VERSION" || (echo "Could not parse version from changelog-beta.md" && exit 1)
|
||||
- echo "Building xTeVe version $XTEVE_VERSION from changelog-beta.md"
|
||||
- go build -v -ldflags "-X main.Version=$XTEVE_VERSION" ./...
|
||||
|
||||
- name: dockerfile-lint
|
||||
image: cache.coadcorp.com/hadolint/hadolint:v2.12.0-alpine
|
||||
commands:
|
||||
- hadolint -t error Dockerfile
|
||||
|
||||
- name: compose-validate
|
||||
image: cache.coadcorp.com/library/docker:27-cli
|
||||
commands:
|
||||
- apk add --no-cache docker-cli-compose
|
||||
- docker compose -f docker-compose.yml config -q
|
||||
- docker compose -f docker-compose.host.yml config -q
|
||||
|
||||
- name: docker-build-validate
|
||||
image: gcr.io/kaniko-project/executor:v1.23.2-debug
|
||||
commands:
|
||||
- /kaniko/executor --context "${DRONE_WORKSPACE}" --dockerfile "${DRONE_WORKSPACE}/Dockerfile" --no-push --destination xteve:validate --build-arg TARGETOS=linux --build-arg TARGETARCH=amd64 --build-arg XTEVE_UID=1000 --build-arg XTEVE_GID=1000
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- name: docker-publish
|
||||
image: plugins/docker
|
||||
environment:
|
||||
XTEVE_UID: "1000"
|
||||
XTEVE_GID: "1000"
|
||||
settings:
|
||||
registry: registry.coadcorp.com
|
||||
repo: registry.coadcorp.com/nathan/xteve
|
||||
dockerfile: Dockerfile
|
||||
username: nathan
|
||||
password:
|
||||
from_secret: registry_password
|
||||
tags:
|
||||
- latest
|
||||
- ${DRONE_COMMIT_SHA}
|
||||
build_args:
|
||||
- TARGETOS=linux
|
||||
- TARGETARCH=amd64
|
||||
build_args_from_env:
|
||||
- XTEVE_UID
|
||||
- XTEVE_GID
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
demo
|
||||
dev
|
||||
compiler
|
||||
files
|
||||
update_xteve*.sh
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
FROM golang:1.26-alpine AS builder
|
||||
WORKDIR /src
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go run ./cmd/webui-gen
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
RUN XTEVE_VERSION="$(grep -m1 '^#### ' changelog-beta.md | cut -d' ' -f2 | sed 's/-beta$//')" \
|
||||
&& test -n "$XTEVE_VERSION" \
|
||||
&& CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
|
||||
go build -trimpath -ldflags="-s -w -X main.Version=$XTEVE_VERSION" -o /out/xteve ./xteve.go
|
||||
|
||||
FROM mwader/static-ffmpeg:latest AS ffmpeg
|
||||
|
||||
FROM alpine:3.23
|
||||
|
||||
ARG XTEVE_UID=1000
|
||||
ARG XTEVE_GID=1000
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& addgroup -S -g "${XTEVE_GID}" xteve \
|
||||
&& adduser -S -D -H -u "${XTEVE_UID}" -G xteve xteve \
|
||||
&& mkdir -p /xteve/config \
|
||||
&& chown -R xteve:xteve /xteve
|
||||
|
||||
WORKDIR /xteve
|
||||
|
||||
COPY --from=builder /out/xteve /usr/local/bin/xteve
|
||||
COPY --from=ffmpeg /ffmpeg /usr/local/bin/ffmpeg
|
||||
COPY --from=ffmpeg /ffprobe /usr/local/bin/ffprobe
|
||||
COPY docker/entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
USER xteve
|
||||
|
||||
EXPOSE 34400/tcp
|
||||
|
||||
ENV XTEVE_CONFIG=/xteve/config
|
||||
ENV XTEVE_PORT=34400
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD wget -qO- "http://127.0.0.1:${XTEVE_PORT}/lineup_status.json" > /dev/null || exit 1
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
@@ -31,7 +31,7 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
|
||||
* Merge external M3U files
|
||||
* Merge external XMLTV files
|
||||
* Automatic M3U and XMLTV update
|
||||
* M3U und XMLTV export
|
||||
* M3U and XMLTV export
|
||||
|
||||
#### Channel management
|
||||
* Filtering streams
|
||||
@@ -48,6 +48,59 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
|
||||
|
||||
---
|
||||
|
||||
## Project Analysis (UI + Operations)
|
||||
|
||||
The core architecture is strong: a Go backend with websocket-driven UI updates, filesystem-based state, and very low runtime overhead.
|
||||
The weakest points are mostly operational and UX-focused:
|
||||
|
||||
* UI was historically utility-first and desktop-biased, with limited responsive behavior and visual hierarchy.
|
||||
* Container usage was documented externally but there was no first-party Dockerfile/compose setup in this repository.
|
||||
* Static web assets are generated into `src/webUI.go`, which works, but creates large diffs and a heavier edit/build cycle.
|
||||
|
||||
### Recommended next technical improvements
|
||||
|
||||
1. Replace generated `src/webUI.go` with Go `embed` for simpler static asset management and cleaner PR diffs.
|
||||
2. Add CI checks (`go test ./...`, build on Linux/arm64/amd64, docker build smoke test).
|
||||
3. Add a dedicated health endpoint (for example `/healthz`) to decouple health checks from HDHomeRun endpoints.
|
||||
4. Add integration tests around websocket commands that mutate settings/files to reduce regression risk.
|
||||
|
||||
---
|
||||
|
||||
## Container-First Run (Included In This Repo)
|
||||
|
||||
### Build image
|
||||
```bash
|
||||
docker build -t xteve:local .
|
||||
```
|
||||
|
||||
### Run with Docker Compose (bridge mode)
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Compose file: `docker-compose.yml`
|
||||
Persistent config volume: `./docker-data/config:/xteve/config`
|
||||
|
||||
### Run with Docker Compose (host networking, Linux recommended for discovery)
|
||||
```bash
|
||||
docker compose -f docker-compose.host.yml up -d
|
||||
```
|
||||
|
||||
Host networking improves LAN discovery behavior (SSDP/DLNA) for Plex/Emby in many setups.
|
||||
|
||||
### Container environment variables
|
||||
|
||||
* `XTEVE_CONFIG` (default: `/xteve/config`)
|
||||
* `XTEVE_PORT` (default: `34400`)
|
||||
|
||||
### Image details
|
||||
|
||||
* Multi-stage build (Go builder + minimal Alpine runtime)
|
||||
* Runs as non-root user (`xteve`)
|
||||
* Built-in healthcheck against `http://127.0.0.1:${XTEVE_PORT}/lineup_status.json`
|
||||
|
||||
---
|
||||
|
||||
## Downloads v2 | 64 Bit only
|
||||
#### 64 Bit Intel / AMD
|
||||
|
||||
@@ -84,7 +137,7 @@ Including:
|
||||
---
|
||||
|
||||
### xTeVe Beta branch
|
||||
New features and bug fixes are only available in beta brunch. Only after successful testing, they are merged into the master branch.
|
||||
New features and bug fixes are only available in beta branch. Only after successful testing are they are merged into the master branch.
|
||||
|
||||
**It is not recommended to use the beta version in a production system.**
|
||||
|
||||
@@ -117,7 +170,7 @@ When the branch is changed, an update is only performed if there is a new versio
|
||||
## Build from source code [Go / Golang]
|
||||
|
||||
#### Requirements
|
||||
* [Go](https://golang.org) (go1.12.4 or newer)
|
||||
* [Go](https://golang.org) (go1.16.2 or newer)
|
||||
|
||||
#### Dependencies
|
||||
* [go-ssdp](https://github.com/koron/go-ssdp)
|
||||
@@ -156,4 +209,3 @@ var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-
|
||||
|
||||
```
|
||||
|
||||
|
||||
+58
-1
@@ -1,3 +1,60 @@
|
||||
#### 2.2.0.0201-beta
|
||||
Add UI enhancement for range selecting checkboxes
|
||||
|
||||
#### 2.2.0.0200-beta
|
||||
```diff
|
||||
+ Major web UI redesign focused on cleaner layout, better information hierarchy, and faster daily workflows.
|
||||
+ Large mobile UX overhaul: responsive navigation, improved spacing, touch-friendly controls, and better small-screen mapping/config flows.
|
||||
+ Accessibility pass across auth, configuration, and main app screens (focus visibility, keyboard flow, ARIA/announcer updates, contrast and status feedback improvements).
|
||||
+ Settings UX improvements and additional polish in frontend behavior for menu, configuration, and authentication interactions.
|
||||
+ Added optional Plex API refresh integration with new settings: use_plexAPI, plex.url, plex.token.
|
||||
+ Added debounced/queued Plex DVR guide reload workflow after lineup and XEPG updates to reduce manual refresh work in Plex.
|
||||
+ Container/runtime improvements and validation updates for easier, safer container usage.
|
||||
+ Added Drone CI pipeline for tests/build checks, Docker/Compose validation, and Docker image publishing to registry.coadcorp.com via plugins/docker.
|
||||
+ Pipeline build version is now derived from changelog-beta.md and validated against source version to prevent release/version drift.
|
||||
```
|
||||
|
||||
#### 2.1.1.0116-beta
|
||||
If no user agent is specified, the default FFmpeg or VLC user agent is used.
|
||||
|
||||
#### 2.1.1.0115-beta
|
||||
```diff
|
||||
+ GZIP compression for xteve.xml file. (http://xteve.ip:34400/xmltv/xteve.xml.gz)
|
||||
- Removed protocol setting for reverse proxy. HTTPS can also be configured in the proxy, where it makes more sense.
|
||||
```
|
||||
|
||||
#### 2.1.0.0106-beta
|
||||
```diff
|
||||
+ User-Agent is now also used by VLC and FFmpeg.
|
||||
```
|
||||
|
||||
#### 2.1.0.0105-beta
|
||||
```diff
|
||||
+ Fixed wrong buffer value in log
|
||||
+ New setting: URL protocol for M3U and XML file
|
||||
+ Add xml tag premiere to xteve.xml
|
||||
```
|
||||
|
||||
#### 2.1.0.0101-beta
|
||||
```diff
|
||||
+ Reverse proxy fix
|
||||
```
|
||||
|
||||
#### 2.0.3.0042-beta
|
||||
**Version 2.0.3.0042 changes the settings.json.**
|
||||
Settings from the current beta can not be used for the current master version 2.0.3
|
||||
- New default options for VLC and FFmpeg
|
||||
- VLC and FFmpeg log entries in the xTeVe log
|
||||
- Less CPU load with VLC and FFmpeg
|
||||
|
||||
#### 2.0.3.0035-beta
|
||||
```diff
|
||||
+ FFmpeg support
|
||||
+ VLC support
|
||||
```
|
||||
**Version 2.0.3.0035 changes the settings.json.**
|
||||
Settings from the current beta can not be used for the current master version 2.0.3
|
||||
|
||||
#### 2.0.2.0024-beta
|
||||
```diff
|
||||
+ Improved monitoring of the buffer process
|
||||
@@ -44,4 +101,4 @@
|
||||
+ Wizard: Add HTML input placeholder (M3U, XMLTV)
|
||||
+ Wizard: Alert by empty value (M3U, XMLTV)
|
||||
+ Image caching: Ignore invalid image URLs
|
||||
```
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"xteve/src"
|
||||
)
|
||||
|
||||
func main() {
|
||||
src.HTMLInit("webUI", "src", "html"+string(os.PathSeparator), "src"+string(os.PathSeparator)+"webUI.go")
|
||||
if err := src.BuildGoFile(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
xteve:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
XTEVE_UID: ${XTEVE_UID:-1000}
|
||||
XTEVE_GID: ${XTEVE_GID:-1000}
|
||||
container_name: xteve
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
environment:
|
||||
XTEVE_CONFIG: /xteve/config
|
||||
XTEVE_PORT: "34400"
|
||||
XTEVE_UID: ${XTEVE_UID:-1000}
|
||||
XTEVE_GID: ${XTEVE_GID:-1000}
|
||||
volumes:
|
||||
- ./docker-data/config:/xteve/config
|
||||
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
xteve:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
XTEVE_UID: ${XTEVE_UID:-1000}
|
||||
XTEVE_GID: ${XTEVE_GID:-1000}
|
||||
container_name: xteve
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
XTEVE_CONFIG: /xteve/config
|
||||
XTEVE_PORT: "34400"
|
||||
XTEVE_UID: ${XTEVE_UID:-1000}
|
||||
XTEVE_GID: ${XTEVE_GID:-1000}
|
||||
ports:
|
||||
- "34400:34400/tcp"
|
||||
- "1900:1900/udp"
|
||||
volumes:
|
||||
- ./docker-data/config:/xteve/config
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
DEFAULT_CONFIG_DIR="/xteve/config"
|
||||
LEGACY_CONFIG_DIRS="/config /xteve /home/xteve/.xteve"
|
||||
|
||||
resolve_config_dir() {
|
||||
if [ -n "${XTEVE_CONFIG:-}" ] && [ "${XTEVE_CONFIG}" != "${DEFAULT_CONFIG_DIR}" ]; then
|
||||
printf "%s" "${XTEVE_CONFIG}"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f "${DEFAULT_CONFIG_DIR}/settings.json" ]; then
|
||||
printf "%s" "${DEFAULT_CONFIG_DIR}"
|
||||
return
|
||||
fi
|
||||
|
||||
for dir in ${LEGACY_CONFIG_DIRS}; do
|
||||
if [ -f "${dir}/settings.json" ]; then
|
||||
printf "%s" "${dir}"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
printf "%s" "${DEFAULT_CONFIG_DIR}"
|
||||
}
|
||||
|
||||
copy_if_missing() {
|
||||
src="$1"
|
||||
dst="$2"
|
||||
|
||||
if [ -e "${src}" ] && [ ! -e "${dst}" ]; then
|
||||
cp -R "${src}" "${dst}"
|
||||
fi
|
||||
}
|
||||
|
||||
settings_initialized() {
|
||||
file="$1"
|
||||
|
||||
if [ ! -s "${file}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if grep -q '"uuid"' "${file}" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
CONFIG_DIR="$(resolve_config_dir)"
|
||||
PORT="${XTEVE_PORT:-34400}"
|
||||
|
||||
mkdir -p "${CONFIG_DIR}"
|
||||
|
||||
if ! settings_initialized "${CONFIG_DIR}/settings.json"; then
|
||||
for legacy_dir in ${LEGACY_CONFIG_DIRS}; do
|
||||
if [ "${legacy_dir}" = "${CONFIG_DIR}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if settings_initialized "${legacy_dir}/settings.json"; then
|
||||
echo "[entrypoint] Migrating existing configuration from ${legacy_dir} to ${CONFIG_DIR}"
|
||||
|
||||
for file in authentication.json pms.json settings.json xepg.json urls.json; do
|
||||
if [ "${file}" = "settings.json" ] || [ "${file}" = "xepg.json" ] || [ "${file}" = "urls.json" ]; then
|
||||
cp -f "${legacy_dir}/${file}" "${CONFIG_DIR}/${file}" 2>/dev/null || true
|
||||
else
|
||||
copy_if_missing "${legacy_dir}/${file}" "${CONFIG_DIR}/${file}"
|
||||
fi
|
||||
done
|
||||
|
||||
for dir_name in data cache backup tmp; do
|
||||
copy_if_missing "${legacy_dir}/${dir_name}" "${CONFIG_DIR}/${dir_name}"
|
||||
done
|
||||
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if ! touch "${CONFIG_DIR}/.xteve-write-test" 2>/dev/null; then
|
||||
echo "[entrypoint] ERROR: Config directory is not writable: ${CONFIG_DIR}" >&2
|
||||
echo "[entrypoint] Running as UID:GID $(id -u):$(id -g)" >&2
|
||||
ls -ld "${CONFIG_DIR}" >&2 || true
|
||||
echo "[entrypoint] Hint: ensure host path ownership/permissions allow this UID:GID to write, or set matching container UID/GID at build time." >&2
|
||||
exit 1
|
||||
fi
|
||||
rm -f "${CONFIG_DIR}/.xteve-write-test"
|
||||
|
||||
echo "[entrypoint] Using config directory: ${CONFIG_DIR}"
|
||||
echo "[entrypoint] Running as UID:GID $(id -u):$(id -g)"
|
||||
if [ -f "${CONFIG_DIR}/settings.json" ]; then
|
||||
echo "[entrypoint] settings.json details: $(ls -l "${CONFIG_DIR}/settings.json" | awk '{print $1, $3, $4, $5, $9}')"
|
||||
fi
|
||||
|
||||
exec /usr/local/bin/xteve -config "${CONFIG_DIR}" -port "${PORT}" "$@"
|
||||
@@ -0,0 +1,14 @@
|
||||
module xteve
|
||||
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||
github.com/koron/go-ssdp v0.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/koron/go-ssdp v0.0.2 h1:fL3wAoyT6hXHQlORyXUW4Q23kkQpJRgEAYcZB5BR71o=
|
||||
github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs=
|
||||
github.com/koron/go-ssdp v0.1.0 h1:ckl5x5H6qSNFmi+wCuROvvGUu2FQnMbQrU95IHCcv3Y=
|
||||
github.com/koron/go-ssdp v0.1.0/go.mod h1:GltaDBjtK1kemZOusWYLGotV0kBeEf59Bp0wtSB0uyU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
+10
-9
@@ -13,16 +13,16 @@
|
||||
<script language="javascript" type="text/javascript" src="js/base_ts.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="javascript: readyForConfiguration(0);">
|
||||
<body class="auth-screen wizard-screen" onload="javascript: readyForConfiguration(0);">
|
||||
|
||||
<div id="loading" class="block">
|
||||
<div id="loading" class="block" role="status" aria-live="polite" aria-label="Loading" aria-hidden="false">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
|
||||
<div id="header" class="imgCenter"></div>
|
||||
<div id="box">
|
||||
<main id="box" role="main" aria-labelledby="head-text">
|
||||
|
||||
<table id="clientInfo" class="visible">
|
||||
<table id="clientInfo" class="visible" aria-label="Server information">
|
||||
<tr>
|
||||
<td class="tdKey">Version:</td>
|
||||
<td id="version" class="tdVal"> </td>
|
||||
@@ -46,13 +46,14 @@
|
||||
<div id="headline">
|
||||
<h1 id="head-text" class="center">Configuration</h1>
|
||||
</div>
|
||||
<p id="err" class="errorMsg center"></p>
|
||||
<div id="content">
|
||||
<p id="err" class="errorMsg center" role="alert" aria-live="assertive" aria-atomic="true"></p>
|
||||
<div id="content" role="region" aria-live="polite" aria-busy="false" tabindex="-1" aria-label="Configuration step">
|
||||
|
||||
</div>
|
||||
<p id="sr-announcer" class="sr-only" aria-live="polite" aria-atomic="true"></p>
|
||||
<div id="box-footer">
|
||||
<input id="next" class="" type="button" name="next" value="Next" onclick="javascript: saveWizard();">
|
||||
<input id="next" class="" type="button" name="next" value="Next" aria-controls="content" onclick="javascript: saveWizard();">
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
+13
-13
@@ -10,38 +10,38 @@
|
||||
<script language="javascript" type="text/javascript" src="js/authentication_ts.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="auth-screen">
|
||||
|
||||
<div id="header" class="imgCenter"></div>
|
||||
|
||||
<div id="box">
|
||||
<main id="box" role="main" aria-labelledby="head-text">
|
||||
|
||||
<div id="headline">
|
||||
<h1 id="head-text" class="center">{{.account.headline}}</h1>
|
||||
</div>
|
||||
|
||||
<p id="err" class="errorMsg center"></p>
|
||||
<p id="err" class="errorMsg center" role="alert" aria-live="assertive" aria-atomic="true"></p>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<form id="authentication" action="/web/" method="post">
|
||||
<form id="authentication" action="" method="post" aria-describedby="err" novalidate>
|
||||
|
||||
<h5>{{.account.username.title}}:</h5>
|
||||
<input id="username" type="text" name="username" placeholder="Username" value="">
|
||||
<h5>{{.account.password.title}}:</h5>
|
||||
<input id="password" type="password" name="password" placeholder="Password" value="">
|
||||
<h5>{{.account.confirm.title}}:</h5>
|
||||
<input id="confirm" type="password" name="confirm" placeholder="Confirm" value="">
|
||||
<label for="username">{{.account.username.title}}:</label>
|
||||
<input id="username" type="text" name="username" placeholder="Username" value="" autocomplete="username">
|
||||
<label for="password">{{.account.password.title}}:</label>
|
||||
<input id="password" type="password" name="password" placeholder="Password" value="" autocomplete="new-password">
|
||||
<label for="confirm">{{.account.confirm.title}}:</label>
|
||||
<input id="confirm" type="password" name="confirm" placeholder="Confirm" value="" autocomplete="new-password">
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="box-footer">
|
||||
<input id="submit" class="" type="button" value="{{.button.craeteAccount}}" onclick="javascript: login();">
|
||||
<input id="submit" class="" type="button" value="{{.button.craeteAccount}}" aria-label="{{.button.craeteAccount}}" onclick="javascript: login();">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
+618
-268
File diff suppressed because it is too large.
Load diff
+878
-446
File diff suppressed because it is too large.
Load diff
+37
-28
@@ -2,9 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!---
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>xTeVe</title>
|
||||
<link rel="stylesheet" href="css/screen.css" type="text/css">
|
||||
<link rel="stylesheet" href="css/base.css" type="text/css">
|
||||
@@ -17,16 +15,19 @@
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="javascript: PageReady();">
|
||||
<body class="app-shell" onload="javascript: PageReady();">
|
||||
|
||||
<div id="loading" class="none">
|
||||
<a class="skip-link" href="#content">Skip to main content</a>
|
||||
|
||||
<div id="loading" class="none" role="status" aria-live="polite" aria-label="Loading" aria-hidden="true">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
|
||||
<div id="popup" class="none">
|
||||
<div id="popup-custom"></div>
|
||||
<div id="popup" class="none" role="dialog" aria-modal="true" aria-hidden="true" tabindex="-1">
|
||||
<div id="popup-custom" role="document" tabindex="-1"></div>
|
||||
</div>
|
||||
|
||||
<div id="layout-overlay" aria-hidden="true" tabindex="-1"></div>
|
||||
<div id="layout">
|
||||
|
||||
<!--
|
||||
@@ -40,55 +41,62 @@
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div id="menu-wrapper" class="layout-left">
|
||||
<aside id="menu-wrapper" class="layout-left" aria-label="Sidebar menu">
|
||||
<div id= "branch"></div>
|
||||
<div id="logo"></div>
|
||||
<nav id="main-menu"></nav>
|
||||
</div>
|
||||
<nav id="main-menu" role="menubar" aria-label="Main navigation"></nav>
|
||||
</aside>
|
||||
|
||||
<div class="layout-right">
|
||||
<main id="shell-main" class="layout-right">
|
||||
<header id="shell-header">
|
||||
<button id="menu-toggle" type="button" aria-expanded="false" aria-controls="menu-wrapper" aria-label="Toggle navigation menu">Menu</button>
|
||||
<h2 id="shell-title">xTeVe Control Panel</h2>
|
||||
<p id="connection-indicator" class="status-idle" role="status" aria-live="polite" aria-atomic="true">Connecting...</p>
|
||||
</header>
|
||||
|
||||
<table id="clientInfo" class="">
|
||||
<table id="clientInfo" class="" aria-label="Server information">
|
||||
|
||||
<tr>
|
||||
<td class="tdKey">xTeVe:</td>
|
||||
<td id="version" class="tdVal"> </td>
|
||||
<td id="version" class="tdVal" data-label="xTeVe"> </td>
|
||||
<td class="tdKey">OS:</td>
|
||||
<td id="os" class="tdVal"> </td>
|
||||
<td id="os" class="tdVal" data-label="OS"> </td>
|
||||
<td class="tdKey phone">DVR IP:</td>
|
||||
<td id="DVR" class="tdVal phone"> </td>
|
||||
<td id="DVR" class="tdVal phone" data-label="DVR IP"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tdKey">UUID:</td>
|
||||
<td id="uuid" class="tdVal"> </td>
|
||||
<td id="uuid" class="tdVal" data-label="UUID"> </td>
|
||||
<td class="tdKey">Arch:</td>
|
||||
<td id="arch" class="tdVal"> </td>
|
||||
<td id="arch" class="tdVal" data-label="Arch"> </td>
|
||||
<td class="tdKey phone">M3U URL:</td>
|
||||
<td id="m3u-url" class="tdVal phone"> </td>
|
||||
<td id="m3u-url" class="tdVal phone" data-label="M3U URL"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tdKey">Available Streams:</td>
|
||||
<td id="streams" class="tdVal"> </td>
|
||||
<td id="streams" class="tdVal" data-label="Available Streams"> </td>
|
||||
<td class="tdKey">EPG Source:</td>
|
||||
<td id="epgSource" class="tdVal"> </td>
|
||||
<td id="epgSource" class="tdVal" data-label="EPG Source"> </td>
|
||||
<td class="tdKey phone">XEPG URL:</td>
|
||||
<td id="xepg-url" class="tdVal phone"> </td>
|
||||
<td id="xepg-url" class="tdVal phone" data-label="XEPG URL"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tdKey">XEPG Channels:</td>
|
||||
<td id="xepg" class="tdVal"> </td>
|
||||
<td id="xepg" class="tdVal" data-label="XEPG Channels"> </td>
|
||||
<td class="tdKey">Errors:</td>
|
||||
<td id="errors" class="tdVal"> </td>
|
||||
<td id="errors" class="tdVal" data-label="Errors"> </td>
|
||||
<td class="tdKey">Warnings:</td>
|
||||
<td id="warnings" class="tdVal"> </td>
|
||||
<td id="warnings" class="tdVal" data-label="Warnings"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div id="status-cards" class="dashboard-cards" role="list" aria-live="polite" aria-label="System summary"></div>
|
||||
|
||||
<div id="myStreamsBox" class="notVisible">
|
||||
<div id="myStreamsBox" class="notVisible" aria-live="polite" aria-label="Stream details">
|
||||
|
||||
<div id="allStreams">
|
||||
<table id="activeStreams"></table>
|
||||
@@ -97,12 +105,13 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content" class=""></div>
|
||||
<div id="content" class="" role="region" aria-live="polite" aria-busy="false" tabindex="-1" aria-label="Main content"></div>
|
||||
<p id="sr-announcer" class="sr-only" aria-live="polite" aria-atomic="true"></p>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,8 +1,13 @@
|
||||
function login() {
|
||||
var err = false;
|
||||
var firstInvalid = null;
|
||||
var data = new Object();
|
||||
var div = document.getElementById("content");
|
||||
var form = document.getElementById("authentication");
|
||||
var errElement = document.getElementById("err");
|
||||
if (errElement != null) {
|
||||
errElement.innerHTML = "";
|
||||
}
|
||||
var inputs = div.getElementsByTagName("INPUT");
|
||||
console.log(inputs);
|
||||
for (var i = inputs.length - 1; i >= 0; i--) {
|
||||
@@ -10,23 +15,54 @@ function login() {
|
||||
var value = inputs[i].value;
|
||||
if (value.length == 0) {
|
||||
inputs[i].style.borderColor = "red";
|
||||
inputs[i].setAttribute("aria-invalid", "true");
|
||||
if (firstInvalid == null) {
|
||||
firstInvalid = inputs[i];
|
||||
}
|
||||
err = true;
|
||||
}
|
||||
else {
|
||||
inputs[i].style.borderColor = "";
|
||||
inputs[i].setAttribute("aria-invalid", "false");
|
||||
}
|
||||
data[key] = value;
|
||||
}
|
||||
if (err == true) {
|
||||
if (firstInvalid != null) {
|
||||
firstInvalid.focus();
|
||||
}
|
||||
data = new Object();
|
||||
return;
|
||||
}
|
||||
if (data.hasOwnProperty("confirm")) {
|
||||
if (data["confirm"] != data["password"]) {
|
||||
alert("sdafsd");
|
||||
document.getElementById('password').style.borderColor = "red";
|
||||
document.getElementById('confirm').style.borderColor = "red";
|
||||
document.getElementById('password').setAttribute("aria-invalid", "true");
|
||||
document.getElementById('confirm').setAttribute("aria-invalid", "true");
|
||||
document.getElementById("err").innerHTML = "{{.account.failed}}";
|
||||
document.getElementById('password').focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(data);
|
||||
form.submit();
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
var form = document.getElementById("authentication");
|
||||
if (form == null) {
|
||||
return;
|
||||
}
|
||||
var inputs = form.getElementsByTagName("INPUT");
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
inputs[i].addEventListener("keydown", function (event) {
|
||||
if (event.key == "Enter") {
|
||||
event.preventDefault();
|
||||
login();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (inputs.length > 0) {
|
||||
inputs[0].focus();
|
||||
}
|
||||
});
|
||||
+158
-16
@@ -5,7 +5,10 @@ var SEARCH_MAPPING = new Object();
|
||||
var UNDO = new Object();
|
||||
var SERVER_CONNECTION = false;
|
||||
var WS_AVAILABLE = false;
|
||||
// Menü
|
||||
var ACTIVE_MENU_ID = "";
|
||||
var LAST_FOCUSED_ELEMENT = null;
|
||||
var LAST_BULK_CHECKBOX = null;
|
||||
// Menu
|
||||
var menuItems = new Array();
|
||||
menuItems.push(new MainMenuItem("playlist", "{{.mainMenu.item.playlist}}", "m3u.png", "{{.mainMenu.headline.playlist}}"));
|
||||
//menuItems.push(new MainMenuItem("pmsID", "{{.mainMenu.item.pmsID}}", "number.png", "{{.mainMenu.headline.pmsID}}"))
|
||||
@@ -18,9 +21,9 @@ menuItems.push(new MainMenuItem("log", "{{.mainMenu.item.log}}", "log.png", "{{.
|
||||
menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}"));
|
||||
// Kategorien für die Einstellungen
|
||||
var settingsCategory = new Array();
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api,use_plexAPI,plex.url,plex.token"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.missing.epg.mode,xepg.replace.missing.images"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"));
|
||||
function showPopUpElement(elm) {
|
||||
@@ -44,7 +47,74 @@ function showElement(elmID, type) {
|
||||
cssClass = "none";
|
||||
break;
|
||||
}
|
||||
document.getElementById(elmID).className = cssClass;
|
||||
var element = document.getElementById(elmID);
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
element.className = cssClass;
|
||||
element.setAttribute("aria-hidden", type == true ? "false" : "true");
|
||||
if (elmID == "loading" && document.body != null) {
|
||||
document.body.setAttribute("aria-busy", type == true ? "true" : "false");
|
||||
}
|
||||
if (elmID == "popup") {
|
||||
var popupContent_1 = document.getElementById("popup-custom");
|
||||
if (type == true) {
|
||||
LAST_FOCUSED_ELEMENT = document.activeElement;
|
||||
if (popupContent_1 != null) {
|
||||
setTimeout(function () {
|
||||
popupContent_1.focus();
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LAST_FOCUSED_ELEMENT != null && LAST_FOCUSED_ELEMENT.focus != undefined) {
|
||||
setTimeout(function () {
|
||||
LAST_FOCUSED_ELEMENT.focus();
|
||||
}, 20);
|
||||
}
|
||||
LAST_FOCUSED_ELEMENT = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
function announceToScreenReader(message) {
|
||||
if (message == undefined || message.length == 0) {
|
||||
return;
|
||||
}
|
||||
var region = document.getElementById("sr-announcer");
|
||||
if (region == null) {
|
||||
return;
|
||||
}
|
||||
region.innerText = "";
|
||||
setTimeout(function () {
|
||||
region.innerText = message;
|
||||
}, 20);
|
||||
}
|
||||
function setConnectionState(state, text) {
|
||||
var label = text;
|
||||
if (label == undefined || label.length == 0) {
|
||||
switch (state) {
|
||||
case "online":
|
||||
label = "Connected";
|
||||
break;
|
||||
case "busy":
|
||||
label = "Syncing";
|
||||
break;
|
||||
case "offline":
|
||||
label = "Offline";
|
||||
break;
|
||||
default:
|
||||
label = "Connecting";
|
||||
break;
|
||||
}
|
||||
}
|
||||
var indicator = document.getElementById("connection-indicator");
|
||||
if (indicator == null) {
|
||||
return;
|
||||
}
|
||||
indicator.className = "status-" + state;
|
||||
indicator.innerText = label;
|
||||
indicator.setAttribute("aria-label", "Connection status: " + label);
|
||||
announceToScreenReader("Connection status " + label);
|
||||
}
|
||||
function changeButtonAction(element, buttonID, attribute) {
|
||||
var value = element.options[element.selectedIndex].value;
|
||||
@@ -114,6 +184,48 @@ function getAllSelectedChannels() {
|
||||
}
|
||||
return channels;
|
||||
}
|
||||
function scheduleChannelRangeSelection(checkbox, event) {
|
||||
var shiftPressed = false;
|
||||
if (event != undefined && event.shiftKey == true) {
|
||||
shiftPressed = true;
|
||||
}
|
||||
// Run after the native checkbox toggle so we copy the final checked state.
|
||||
setTimeout(function () {
|
||||
selectChannelRange(checkbox, shiftPressed);
|
||||
}, 0);
|
||||
}
|
||||
function selectChannelRange(checkbox, shiftPressed) {
|
||||
if (BULK_EDIT == false || checkbox == undefined || checkbox == null) {
|
||||
return;
|
||||
}
|
||||
var table = document.getElementById("content_table");
|
||||
if (table == null) {
|
||||
return;
|
||||
}
|
||||
var trs = table.getElementsByTagName("TR");
|
||||
var visibleCheckboxes = new Array();
|
||||
for (var i = 1; i < trs.length; i++) {
|
||||
if (trs[i].style.display != "none") {
|
||||
var bulkCheckbox = trs[i].querySelector("input.bulk");
|
||||
if (bulkCheckbox != null) {
|
||||
visibleCheckboxes.push(bulkCheckbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
var currentIndex = visibleCheckboxes.indexOf(checkbox);
|
||||
var previousIndex = -1;
|
||||
if (LAST_BULK_CHECKBOX != null) {
|
||||
previousIndex = visibleCheckboxes.indexOf(LAST_BULK_CHECKBOX);
|
||||
}
|
||||
if (shiftPressed == true && previousIndex > -1 && currentIndex > -1) {
|
||||
var start = Math.min(previousIndex, currentIndex);
|
||||
var end = Math.max(previousIndex, currentIndex);
|
||||
for (var i = start; i <= end; i++) {
|
||||
visibleCheckboxes[i].checked = checkbox.checked;
|
||||
}
|
||||
}
|
||||
LAST_BULK_CHECKBOX = checkbox;
|
||||
}
|
||||
function selectAllChannels() {
|
||||
var bulk = false;
|
||||
var trs = document.getElementById("content_table").getElementsByTagName("TR");
|
||||
@@ -132,6 +244,7 @@ function selectAllChannels() {
|
||||
}
|
||||
}
|
||||
}
|
||||
LAST_BULK_CHECKBOX = null;
|
||||
return;
|
||||
}
|
||||
function bulkEdit() {
|
||||
@@ -150,6 +263,7 @@ function bulkEdit() {
|
||||
rows[i].className = className;
|
||||
rows[i].checked = false;
|
||||
}
|
||||
LAST_BULK_CHECKBOX = null;
|
||||
return;
|
||||
}
|
||||
function sortTable(column) {
|
||||
@@ -160,15 +274,29 @@ function sortTable(column) {
|
||||
var table = document.getElementById("content_table");
|
||||
var tableHead = table.getElementsByTagName("TR")[0];
|
||||
var tableItems = tableHead.getElementsByTagName("TD");
|
||||
for (var h = 0; h < tableItems.length; h++) {
|
||||
if (tableItems[h].getAttribute("role") == "columnheader") {
|
||||
tableItems[h].setAttribute("aria-sort", "none");
|
||||
}
|
||||
}
|
||||
var sortObj = new Object();
|
||||
var x, xValue;
|
||||
var tableHeader;
|
||||
var sortByString = false;
|
||||
if (column > 0 && COLUMN_TO_SORT > 0) {
|
||||
tableItems[COLUMN_TO_SORT].className = "pointer";
|
||||
tableItems[column].className = "sortThis";
|
||||
tableItems[COLUMN_TO_SORT].classList.remove("sortThis");
|
||||
tableItems[COLUMN_TO_SORT].classList.add("pointer");
|
||||
tableItems[column].classList.remove("pointer");
|
||||
tableItems[column].classList.add("sortThis");
|
||||
}
|
||||
COLUMN_TO_SORT = column;
|
||||
var mobileSort = document.getElementById("mapping-sort-mobile");
|
||||
if (mobileSort != null && (column == 1 || column == 3 || column == 4 || column == 5)) {
|
||||
mobileSort.value = column.toString();
|
||||
}
|
||||
if (tableItems[column] != undefined && tableItems[column].getAttribute("role") == "columnheader") {
|
||||
tableItems[column].setAttribute("aria-sort", "ascending");
|
||||
}
|
||||
var rows = table.rows;
|
||||
if (rows[1] != undefined) {
|
||||
tableHeader = rows[0];
|
||||
@@ -226,8 +354,9 @@ function createSearchObj() {
|
||||
SEARCH_MAPPING = new Object();
|
||||
var data = SERVER["xepg"]["epgMapping"];
|
||||
var channels = getObjKeys(data);
|
||||
var channelKeys = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title"];
|
||||
var channelKeys = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"];
|
||||
channels.forEach(function (id) {
|
||||
SEARCH_MAPPING[id] = "";
|
||||
channelKeys.forEach(function (key) {
|
||||
if (key == "x-active") {
|
||||
switch (data[id][key]) {
|
||||
@@ -240,7 +369,15 @@ function createSearchObj() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " ";
|
||||
if (key == "x-xmltv-file") {
|
||||
var xmltvFile = getValueFromProviderFile(data[id][key], "xmltv", "name");
|
||||
if (xmltvFile != undefined) {
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + xmltvFile + " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " ";
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -252,6 +389,9 @@ function searchInMapping() {
|
||||
for (var i = 1; i < trs.length; ++i) {
|
||||
var id = trs[i].getAttribute("id");
|
||||
var element = SEARCH_MAPPING[id];
|
||||
if (element == undefined) {
|
||||
continue;
|
||||
}
|
||||
switch (element.toLowerCase().includes(searchValue.toLowerCase())) {
|
||||
case true:
|
||||
document.getElementById(id).style.display = "";
|
||||
@@ -261,17 +401,19 @@ function searchInMapping() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
announceToScreenReader("Search updated");
|
||||
return;
|
||||
}
|
||||
function calculateWrapperHeight() {
|
||||
if (document.getElementById("box-wrapper")) {
|
||||
var elm = document.getElementById("box-wrapper");
|
||||
var divs = new Array("myStreamsBox", "clientInfo", "content");
|
||||
var elementsHeight = 0 - elm.offsetHeight;
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
elementsHeight = elementsHeight + document.getElementById(divs[i]).offsetHeight;
|
||||
var elm = document.getElementById("box-wrapper");
|
||||
var content = document.getElementById("content");
|
||||
if (elm != null && content != null) {
|
||||
var contentTop = content.getBoundingClientRect().top;
|
||||
var freeSpace = window.innerHeight - contentTop - 26;
|
||||
if (freeSpace < 180) {
|
||||
freeSpace = 180;
|
||||
}
|
||||
elm.style.height = window.innerHeight - elementsHeight + "px";
|
||||
elm.style.height = freeSpace + "px";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
@@ -35,7 +35,9 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
var key = this.key;
|
||||
var content = new PopupContent();
|
||||
var description;
|
||||
var wizardField = null;
|
||||
var doc = document.getElementById(this.DocumentID);
|
||||
doc.setAttribute("aria-busy", "true");
|
||||
doc.innerHTML = "";
|
||||
doc.appendChild(headline);
|
||||
switch (key) {
|
||||
@@ -50,6 +52,7 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
select.setAttribute("class", "wizard");
|
||||
select.id = key;
|
||||
doc.appendChild(select);
|
||||
wizardField = select;
|
||||
description = "{{.wizard.tuner.description}}";
|
||||
break;
|
||||
case "epgSource":
|
||||
@@ -59,6 +62,7 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
select.setAttribute("class", "wizard");
|
||||
select.id = key;
|
||||
doc.appendChild(select);
|
||||
wizardField = select;
|
||||
description = "{{.wizard.epgSource.description}}";
|
||||
break;
|
||||
case "m3u":
|
||||
@@ -67,6 +71,7 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
input.setAttribute("class", "wizard");
|
||||
input.id = key;
|
||||
doc.appendChild(input);
|
||||
wizardField = input;
|
||||
description = "{{.wizard.m3u.description}}";
|
||||
break;
|
||||
case "xmltv":
|
||||
@@ -75,6 +80,7 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
input.setAttribute("class", "wizard");
|
||||
input.id = key;
|
||||
doc.appendChild(input);
|
||||
wizardField = input;
|
||||
description = "{{.wizard.xmltv.description}}";
|
||||
break;
|
||||
default:
|
||||
@@ -82,8 +88,20 @@ var WizardItem = /** @class */ (function (_super) {
|
||||
break;
|
||||
}
|
||||
var pre = document.createElement("PRE");
|
||||
pre.id = "wizard-description-" + key;
|
||||
pre.innerHTML = description;
|
||||
doc.appendChild(pre);
|
||||
if (wizardField != null) {
|
||||
wizardField.setAttribute("aria-label", this.headline);
|
||||
wizardField.setAttribute("aria-describedby", pre.id);
|
||||
setTimeout(function () {
|
||||
wizardField.focus();
|
||||
}, 20);
|
||||
}
|
||||
doc.setAttribute("aria-busy", "false");
|
||||
if (typeof announceToScreenReader == "function") {
|
||||
announceToScreenReader(this.headline + " step");
|
||||
}
|
||||
console.log(headline, key);
|
||||
};
|
||||
return WizardItem;
|
||||
@@ -145,3 +163,20 @@ configurationWizard.push(new WizardItem("tuner", "{{.wizard.tuner.title}}"));
|
||||
configurationWizard.push(new WizardItem("epgSource", "{{.wizard.epgSource.title}}"));
|
||||
configurationWizard.push(new WizardItem("m3u", "{{.wizard.m3u.title}}"));
|
||||
configurationWizard.push(new WizardItem("xmltv", "{{.wizard.xmltv.title}}"));
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
var container = document.getElementById("content");
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
container.addEventListener("keydown", function (event) {
|
||||
if (event.key != "Enter") {
|
||||
return;
|
||||
}
|
||||
var target = event.target;
|
||||
if (target == null || target.tagName != "INPUT") {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
saveWizard();
|
||||
});
|
||||
});
|
||||
+9
-2
@@ -21,15 +21,22 @@ function showLogs(bottom) {
|
||||
var log = new Log();
|
||||
var logs = SERVER["log"]["log"];
|
||||
var div = document.getElementById("content_log");
|
||||
var wrapper = document.getElementById("box-wrapper");
|
||||
var shouldStickToBottom = bottom;
|
||||
div.innerHTML = "";
|
||||
if (wrapper != null && shouldStickToBottom == false) {
|
||||
var distanceToBottom = wrapper.scrollHeight - wrapper.scrollTop - wrapper.clientHeight;
|
||||
if (distanceToBottom < 80) {
|
||||
shouldStickToBottom = true;
|
||||
}
|
||||
}
|
||||
var keys = getObjKeys(logs);
|
||||
keys.forEach(function (logID) {
|
||||
var entry = log.createLog(logs[logID]);
|
||||
div.append(entry);
|
||||
});
|
||||
setTimeout(function () {
|
||||
if (bottom == true) {
|
||||
var wrapper = document.getElementById("box-wrapper");
|
||||
if (shouldStickToBottom == true && wrapper != null) {
|
||||
wrapper.scrollTop = wrapper.scrollHeight;
|
||||
}
|
||||
}, 10);
|
||||
|
||||
+487
-38
@@ -2,7 +2,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
@@ -43,7 +43,14 @@ var MainMenuItem = /** @class */ (function (_super) {
|
||||
var item = document.createElement("LI");
|
||||
item.setAttribute("onclick", "javascript: openThisMenu(this)");
|
||||
item.setAttribute("id", this.id);
|
||||
item.setAttribute("data-menu", this.menuKey);
|
||||
item.setAttribute("role", "menuitem");
|
||||
item.setAttribute("tabindex", "0");
|
||||
item.setAttribute("aria-controls", "content");
|
||||
item.setAttribute("aria-label", this.value);
|
||||
item.setAttribute("onkeydown", "if(event.key==='Enter' || event.key===' '){event.preventDefault();openThisMenu(this);}");
|
||||
var img = this.createIMG(this.imgSrc);
|
||||
img.setAttribute("alt", "");
|
||||
var value = this.createValue(this.value);
|
||||
item.appendChild(img);
|
||||
item.appendChild(value);
|
||||
@@ -63,7 +70,7 @@ var MainMenuItem = /** @class */ (function (_super) {
|
||||
this.tableHeader = ["{{.users.table.username}}", "{{.users.table.password}}", "{{.users.table.web}}", "{{.users.table.pms}}", "{{.users.table.m3u}}", "{{.users.table.xml}}", "{{.users.table.api}}"];
|
||||
break;
|
||||
case "mapping":
|
||||
this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}"];
|
||||
this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}", "{{.mapping.table.edit}}"];
|
||||
break;
|
||||
}
|
||||
//console.log(this.menuKey, this.tableHeader);
|
||||
@@ -127,7 +134,7 @@ var Content = /** @class */ (function () {
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
cell.childType = "P";
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
cell.value = data[key]["tuner"];
|
||||
}
|
||||
else {
|
||||
@@ -356,39 +363,27 @@ var Content = /** @class */ (function () {
|
||||
cell.child = true;
|
||||
cell.childType = "IMG";
|
||||
cell.imageURL = data[key]["tvg-logo"];
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
// Kanalname
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
cell.childType = "P";
|
||||
cell.className = data[key]["x-category"];
|
||||
cell.value = data[key]["x-name"];
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
// Playlist
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
cell.childType = "P";
|
||||
//cell.value = data[key]["_file.m3u.name"]
|
||||
cell.value = getValueFromProviderFile(data[key]["_file.m3u.id"], "m3u", "name");
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
// Gruppe (group-title)
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
cell.childType = "P";
|
||||
cell.value = data[key]["x-group-title"];
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
// XMLTV Datei
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
@@ -399,10 +394,7 @@ var Content = /** @class */ (function () {
|
||||
else {
|
||||
cell.value = data[key]["x-xmltv-file"];
|
||||
}
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
// XMLTV Kanal
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
@@ -413,10 +405,17 @@ var Content = /** @class */ (function () {
|
||||
value = data[key]["x-mapping"].substring(0, 20) + "...";
|
||||
}
|
||||
cell.value = value;
|
||||
var td = cell.createCell();
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
td.id = key;
|
||||
tr.appendChild(td);
|
||||
tr.appendChild(cell.createCell());
|
||||
var cell = new Cell();
|
||||
cell.child = true;
|
||||
cell.childType = "EDIT";
|
||||
cell.value = "{{.button.edit}}";
|
||||
var editTd = cell.createCell();
|
||||
var editButton = editTd.firstChild;
|
||||
editButton.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
|
||||
editButton.setAttribute("id", key);
|
||||
editButton.setAttribute("aria-label", "Edit " + data[key]["x-name"]);
|
||||
tr.appendChild(editTd);
|
||||
rows.push(tr);
|
||||
});
|
||||
break;
|
||||
@@ -451,7 +450,7 @@ var Cell = /** @class */ (function () {
|
||||
break;
|
||||
case "INPUTCHANNEL":
|
||||
element = document.createElement("INPUT");
|
||||
element.setAttribute("onchange", "javscript: changeChannelNumber(this)");
|
||||
element.setAttribute("onchange", "javascript: changeChannelNumber(this)");
|
||||
element.value = this.value;
|
||||
element.type = "text";
|
||||
break;
|
||||
@@ -460,6 +459,9 @@ var Cell = /** @class */ (function () {
|
||||
element.checked = this.value;
|
||||
element.type = "checkbox";
|
||||
element.className = "bulk hideBulk";
|
||||
element.addEventListener("click", function (event) {
|
||||
scheduleChannelRangeSelection(element, event);
|
||||
});
|
||||
break;
|
||||
case "BULK_HEAD":
|
||||
element = document.createElement("INPUT");
|
||||
@@ -475,6 +477,12 @@ var Cell = /** @class */ (function () {
|
||||
element.setAttribute("onerror", "javascript: this.onerror=null;this.src=''");
|
||||
//onerror="this.onerror=null;this.src='missing.gif';"
|
||||
}
|
||||
break;
|
||||
case "EDIT":
|
||||
element = document.createElement("INPUT");
|
||||
element.type = "button";
|
||||
element.value = this.value;
|
||||
element.className = "mapping-edit-button";
|
||||
}
|
||||
td.appendChild(element);
|
||||
}
|
||||
@@ -483,10 +491,18 @@ var Cell = /** @class */ (function () {
|
||||
}
|
||||
if (this.onclick == true) {
|
||||
td.setAttribute("onclick", this.onclickFunktion);
|
||||
td.className = "pointer";
|
||||
td.className = "pointer keyboard-clickable";
|
||||
td.setAttribute("tabindex", "0");
|
||||
td.setAttribute("role", "button");
|
||||
td.setAttribute("onkeydown", "if(event.key==='Enter' || event.key===' '){event.preventDefault();this.click();}");
|
||||
}
|
||||
if (this.tdClassName != undefined) {
|
||||
td.className = this.tdClassName;
|
||||
if (td.className.length > 0) {
|
||||
td.className = td.className + " " + this.tdClassName;
|
||||
}
|
||||
else {
|
||||
td.className = this.tdClassName;
|
||||
}
|
||||
}
|
||||
return td;
|
||||
};
|
||||
@@ -510,6 +526,7 @@ var ShowContent = /** @class */ (function (_super) {
|
||||
COLUMN_TO_SORT = -1;
|
||||
// Alten Inhalt löschen
|
||||
var doc = document.getElementById(this.DocumentID);
|
||||
doc.setAttribute("aria-busy", "true");
|
||||
doc.innerHTML = "";
|
||||
showPreview(false);
|
||||
// Überschrift
|
||||
@@ -556,11 +573,33 @@ var ShowContent = /** @class */ (function (_super) {
|
||||
var input = this.createInput("button", menuKey, "{{.button.bulkEdit}}");
|
||||
input.setAttribute("onclick", 'javascript: bulkEdit()');
|
||||
interaction.appendChild(input);
|
||||
var sortSelect = document.createElement("SELECT");
|
||||
sortSelect.setAttribute("id", "mapping-sort-mobile");
|
||||
sortSelect.className = "mobile-only-control";
|
||||
sortSelect.setAttribute("aria-label", "Sort mapping");
|
||||
var sortOptions = [
|
||||
{ label: "{{.mapping.table.chNo}}", value: "1" },
|
||||
{ label: "{{.mapping.table.channelName}}", value: "3" },
|
||||
{ label: "{{.mapping.table.playlist}}", value: "4" },
|
||||
{ label: "{{.mapping.table.groupTitle}}", value: "5" }
|
||||
];
|
||||
sortOptions.forEach(function (optionData) {
|
||||
var option = document.createElement("OPTION");
|
||||
option.innerText = optionData.label;
|
||||
option.value = optionData.value;
|
||||
sortSelect.appendChild(option);
|
||||
});
|
||||
sortSelect.value = "1";
|
||||
sortSelect.onchange = function () {
|
||||
sortTable(parseInt(this.value, 10));
|
||||
};
|
||||
interaction.appendChild(sortSelect);
|
||||
var input = this.createInput("search", "search", "");
|
||||
input.setAttribute("id", "searchMapping");
|
||||
input.setAttribute("placeholder", "{{.button.search}}");
|
||||
input.setAttribute("aria-label", "{{.button.search}}");
|
||||
input.className = "search";
|
||||
input.setAttribute("onchange", 'javascript: searchInMapping()');
|
||||
input.setAttribute("oninput", 'javascript: searchInMapping()');
|
||||
interaction.appendChild(input);
|
||||
break;
|
||||
case "settings":
|
||||
@@ -580,6 +619,7 @@ var ShowContent = /** @class */ (function (_super) {
|
||||
var settings = this.createDIV();
|
||||
wrapper.appendChild(settings);
|
||||
showSettings();
|
||||
finalizeContentAccessibility(headline);
|
||||
return;
|
||||
break;
|
||||
case "log":
|
||||
@@ -593,6 +633,7 @@ var ShowContent = /** @class */ (function (_super) {
|
||||
var logs = this.createDIV();
|
||||
wrapper.appendChild(logs);
|
||||
showLogs(true);
|
||||
finalizeContentAccessibility(headline);
|
||||
return;
|
||||
break;
|
||||
case "logout":
|
||||
@@ -665,30 +706,392 @@ var ShowContent = /** @class */ (function (_super) {
|
||||
break;
|
||||
}
|
||||
showElement("loading", false);
|
||||
finalizeContentAccessibility(headline);
|
||||
};
|
||||
return ShowContent;
|
||||
}(Content));
|
||||
var SHELL_LAYOUT_READY = false;
|
||||
function isKeyboardActivationKey(event) {
|
||||
return event.key == "Enter" || event.key == " ";
|
||||
}
|
||||
function makeKeyboardClickable(element, label) {
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
if (element.getAttribute("data-keyboard-ready") == "true") {
|
||||
return;
|
||||
}
|
||||
var tagName = element.tagName.toUpperCase();
|
||||
if (tagName == "INPUT" || tagName == "BUTTON" || tagName == "SELECT" || tagName == "TEXTAREA" || tagName == "A") {
|
||||
return;
|
||||
}
|
||||
element.setAttribute("data-keyboard-ready", "true");
|
||||
if (element.getAttribute("tabindex") == null) {
|
||||
element.setAttribute("tabindex", "0");
|
||||
}
|
||||
if (element.getAttribute("role") == null) {
|
||||
element.setAttribute("role", "button");
|
||||
}
|
||||
element.classList.add("keyboard-clickable");
|
||||
if (label != undefined && label.length > 0) {
|
||||
if (element.getAttribute("aria-label") == null || element.getAttribute("aria-label").length == 0) {
|
||||
element.setAttribute("aria-label", label);
|
||||
}
|
||||
}
|
||||
element.addEventListener("keydown", function (event) {
|
||||
if (isKeyboardActivationKey(event) == false) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
this.click();
|
||||
});
|
||||
}
|
||||
function applyTableAccessibility(table, sectionName) {
|
||||
if (table == null) {
|
||||
return;
|
||||
}
|
||||
table.setAttribute("role", "table");
|
||||
var rows = table.getElementsByTagName("TR");
|
||||
var headerLabels = [];
|
||||
if (rows.length > 0) {
|
||||
var headerCells = rows[0].getElementsByTagName("TD");
|
||||
for (var h = 0; h < headerCells.length; h++) {
|
||||
var headerLabel = headerCells[h].innerText;
|
||||
if (headerLabel == undefined || headerLabel.length == 0) {
|
||||
headerLabel = "Value";
|
||||
}
|
||||
if (headerLabel == "BULK") {
|
||||
headerLabel = "Select";
|
||||
}
|
||||
headerLabels.push(headerLabel);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
rows[i].setAttribute("role", "row");
|
||||
if (rows[i].getAttribute("onclick") != null) {
|
||||
var rowLabel = rows[i].innerText;
|
||||
if (rowLabel == undefined || rowLabel.length == 0) {
|
||||
rowLabel = sectionName + " row";
|
||||
}
|
||||
makeKeyboardClickable(rows[i], rowLabel);
|
||||
}
|
||||
var cells = rows[i].getElementsByTagName("TD");
|
||||
for (var c = 0; c < cells.length; c++) {
|
||||
if (i == 0) {
|
||||
cells[c].setAttribute("role", "columnheader");
|
||||
}
|
||||
else {
|
||||
cells[c].setAttribute("role", "cell");
|
||||
}
|
||||
var dataLabel = headerLabels[c];
|
||||
if (dataLabel == undefined || dataLabel.length == 0) {
|
||||
dataLabel = "Value";
|
||||
}
|
||||
cells[c].setAttribute("data-label", dataLabel);
|
||||
var checkbox = cells[c].querySelector('input[type="checkbox"]');
|
||||
if (checkbox != null) {
|
||||
cells[c].setAttribute("data-cell-type", "checkbox");
|
||||
}
|
||||
else {
|
||||
var image = cells[c].querySelector("img");
|
||||
if (image != null) {
|
||||
cells[c].setAttribute("data-cell-type", "image");
|
||||
}
|
||||
else {
|
||||
var actionButton = cells[c].querySelector("input.mapping-edit-button, button.mapping-edit-button");
|
||||
if (actionButton != null) {
|
||||
cells[c].setAttribute("data-cell-type", "action");
|
||||
}
|
||||
else {
|
||||
cells[c].removeAttribute("data-cell-type");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cells[c].getAttribute("onclick") != null) {
|
||||
var cellLabel = cells[c].innerText;
|
||||
if (cellLabel == undefined || cellLabel.length == 0) {
|
||||
cellLabel = sectionName + " details";
|
||||
}
|
||||
makeKeyboardClickable(cells[c], cellLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function finalizeContentAccessibility(sectionName) {
|
||||
var content = document.getElementById("content");
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
content.setAttribute("aria-busy", "false");
|
||||
var heading = content.getElementsByTagName("H3")[0];
|
||||
if (heading != null) {
|
||||
heading.setAttribute("tabindex", "-1");
|
||||
setTimeout(function () {
|
||||
heading.focus();
|
||||
}, 20);
|
||||
}
|
||||
applyTableAccessibility(document.getElementById("content_table"), sectionName);
|
||||
if (sectionName != undefined && sectionName.length > 0) {
|
||||
announceToScreenReader(sectionName + " loaded");
|
||||
}
|
||||
}
|
||||
function setLayoutMenuState(open) {
|
||||
if (document.body == null) {
|
||||
return;
|
||||
}
|
||||
if (open == true) {
|
||||
document.body.classList.add("menu-open");
|
||||
}
|
||||
else {
|
||||
document.body.classList.remove("menu-open");
|
||||
}
|
||||
var toggle = document.getElementById("menu-toggle");
|
||||
if (toggle != null) {
|
||||
toggle.setAttribute("aria-expanded", open == true ? "true" : "false");
|
||||
toggle.setAttribute("aria-label", open == true ? "Close navigation menu" : "Open navigation menu");
|
||||
}
|
||||
var overlay = document.getElementById("layout-overlay");
|
||||
if (overlay != null) {
|
||||
overlay.setAttribute("aria-hidden", open == true ? "false" : "true");
|
||||
}
|
||||
var wrapper = document.getElementById("menu-wrapper");
|
||||
if (wrapper != null) {
|
||||
if (window.innerWidth <= 900) {
|
||||
wrapper.setAttribute("aria-hidden", open == true ? "false" : "true");
|
||||
}
|
||||
else {
|
||||
wrapper.setAttribute("aria-hidden", "false");
|
||||
}
|
||||
}
|
||||
if (window.innerWidth <= 900 && open == false && toggle != null && wrapper != null && wrapper.contains(document.activeElement)) {
|
||||
toggle.focus();
|
||||
}
|
||||
if (window.innerWidth <= 900 && open == true && wrapper != null) {
|
||||
var firstMenuItem = wrapper.querySelector("#main-menu li");
|
||||
if (firstMenuItem != null) {
|
||||
setTimeout(function () {
|
||||
firstMenuItem.focus();
|
||||
}, 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
function toggleLayoutMenu() {
|
||||
if (document.body == null) {
|
||||
return;
|
||||
}
|
||||
var isOpen = document.body.classList.contains("menu-open");
|
||||
setLayoutMenuState(!isOpen);
|
||||
}
|
||||
function closeLayoutMenuIfMobile() {
|
||||
if (window.innerWidth <= 900) {
|
||||
setLayoutMenuState(false);
|
||||
}
|
||||
}
|
||||
function setActiveMenu(menuID) {
|
||||
ACTIVE_MENU_ID = menuID.toString();
|
||||
var menu = document.getElementById("main-menu");
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
var items = menu.getElementsByTagName("LI");
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].classList.remove("menu-active");
|
||||
items[i].removeAttribute("aria-current");
|
||||
}
|
||||
var activeItem = document.getElementById(ACTIVE_MENU_ID);
|
||||
var activeMenuKey = "";
|
||||
if (activeItem != null) {
|
||||
activeItem.classList.add("menu-active");
|
||||
activeItem.setAttribute("aria-current", "page");
|
||||
var menuKeyValue = activeItem.getAttribute("data-menu");
|
||||
if (menuKeyValue != null) {
|
||||
activeMenuKey = menuKeyValue;
|
||||
}
|
||||
}
|
||||
if (document.body != null) {
|
||||
if (activeMenuKey.length > 0) {
|
||||
document.body.setAttribute("data-active-menu", activeMenuKey);
|
||||
}
|
||||
else {
|
||||
document.body.removeAttribute("data-active-menu");
|
||||
}
|
||||
if (activeMenuKey == "log") {
|
||||
document.body.classList.add("menu-log-focus");
|
||||
}
|
||||
else {
|
||||
document.body.classList.remove("menu-log-focus");
|
||||
}
|
||||
}
|
||||
}
|
||||
function renderStatusCards() {
|
||||
var wrapper = document.getElementById("status-cards");
|
||||
if (wrapper == null || SERVER.hasOwnProperty("clientInfo") == false) {
|
||||
return;
|
||||
}
|
||||
var info = SERVER["clientInfo"];
|
||||
var errors = parseInt(info["errors"], 10);
|
||||
var warnings = parseInt(info["warnings"], 10);
|
||||
var cards = [
|
||||
{ label: "Streams", value: info["streams"], tone: "ok" },
|
||||
{ label: "EPG Source", value: info["epgSource"], tone: "neutral" },
|
||||
{ label: "XEPG Channels", value: info["xepg"], tone: "ok" },
|
||||
{ label: "Errors", value: info["errors"], tone: errors > 0 ? "error" : "ok" },
|
||||
{ label: "Warnings", value: info["warnings"], tone: warnings > 0 ? "warn" : "ok" },
|
||||
{ label: "DVR", value: info["DVR"], tone: "neutral" }
|
||||
];
|
||||
wrapper.innerHTML = "";
|
||||
cards.forEach(function (card) {
|
||||
var box = document.createElement("DIV");
|
||||
box.className = "status-card status-card-" + card.tone;
|
||||
box.setAttribute("role", "listitem");
|
||||
var label = document.createElement("P");
|
||||
label.className = "status-card-label";
|
||||
label.innerText = card.label;
|
||||
var value = document.createElement("P");
|
||||
value.className = "status-card-value";
|
||||
if (card.value == undefined || card.value == "") {
|
||||
value.innerText = "-";
|
||||
}
|
||||
else {
|
||||
value.innerText = card.value;
|
||||
}
|
||||
box.appendChild(label);
|
||||
box.appendChild(value);
|
||||
box.setAttribute("aria-label", card.label + ": " + value.innerText);
|
||||
wrapper.appendChild(box);
|
||||
});
|
||||
}
|
||||
function initShellLayout() {
|
||||
if (SHELL_LAYOUT_READY == true) {
|
||||
return;
|
||||
}
|
||||
var toggle = document.getElementById("menu-toggle");
|
||||
if (toggle != null) {
|
||||
toggle.onclick = function () {
|
||||
toggleLayoutMenu();
|
||||
};
|
||||
}
|
||||
var overlay = document.getElementById("layout-overlay");
|
||||
if (overlay != null) {
|
||||
overlay.onclick = function () {
|
||||
setLayoutMenuState(false);
|
||||
};
|
||||
}
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.key == "Escape") {
|
||||
setLayoutMenuState(false);
|
||||
showElement("popup", false);
|
||||
return;
|
||||
}
|
||||
if (event.key == "/") {
|
||||
var target = event.target;
|
||||
var tagName = target != null && target.tagName != undefined ? target.tagName : "";
|
||||
var onInput = tagName == "INPUT" || tagName == "TEXTAREA" || tagName == "SELECT";
|
||||
if (onInput == true) {
|
||||
return;
|
||||
}
|
||||
var search = document.getElementById("searchMapping");
|
||||
if (search != null) {
|
||||
event.preventDefault();
|
||||
search.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
setLayoutMenuState(false);
|
||||
setConnectionState("idle");
|
||||
SHELL_LAYOUT_READY = true;
|
||||
}
|
||||
function shouldPollLogs() {
|
||||
if (document.hidden == true) {
|
||||
return false;
|
||||
}
|
||||
if (document.getElementById("content_log") == null) {
|
||||
return false;
|
||||
}
|
||||
if (ACTIVE_MENU_ID.length < 1) {
|
||||
return false;
|
||||
}
|
||||
var activeItem = document.getElementById(ACTIVE_MENU_ID);
|
||||
if (activeItem == null) {
|
||||
return false;
|
||||
}
|
||||
return activeItem.getAttribute("data-menu") == "log";
|
||||
}
|
||||
function PageReady() {
|
||||
initShellLayout();
|
||||
var server = new Server("getServerConfig");
|
||||
server.request(new Object());
|
||||
var bootstrapAttempts = 0;
|
||||
var maxBootstrapAttempts = 5;
|
||||
var bootstrapTimer = window.setInterval(function () {
|
||||
if (SERVER.hasOwnProperty("clientInfo") == true) {
|
||||
window.clearInterval(bootstrapTimer);
|
||||
return;
|
||||
}
|
||||
if (SERVER_CONNECTION == true) {
|
||||
return;
|
||||
}
|
||||
bootstrapAttempts++;
|
||||
var retryServer = new Server("getServerConfig");
|
||||
retryServer.request(new Object());
|
||||
if (bootstrapAttempts >= maxBootstrapAttempts) {
|
||||
window.clearInterval(bootstrapTimer);
|
||||
}
|
||||
}, 3000);
|
||||
window.addEventListener("resize", function () {
|
||||
if (window.innerWidth > 900) {
|
||||
setLayoutMenuState(false);
|
||||
}
|
||||
calculateWrapperHeight();
|
||||
}, true);
|
||||
setInterval(function () {
|
||||
if (shouldPollLogs() == false) {
|
||||
return;
|
||||
}
|
||||
updateLog();
|
||||
}, 10000);
|
||||
return;
|
||||
}
|
||||
function isClientInfoHttpURL(value) {
|
||||
return /^https?:\/\//i.test(value);
|
||||
}
|
||||
function setClientInfoValue(key, value) {
|
||||
var element = document.getElementById(key);
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
var textValue = "";
|
||||
if (value != undefined && value != null) {
|
||||
textValue = String(value);
|
||||
}
|
||||
if ((key == "m3u-url" || key == "xepg-url") && isClientInfoHttpURL(textValue)) {
|
||||
element.innerHTML = "";
|
||||
var anchor = document.createElement("A");
|
||||
anchor.href = textValue;
|
||||
anchor.target = "_blank";
|
||||
anchor.rel = "noopener noreferrer";
|
||||
anchor.textContent = textValue;
|
||||
element.appendChild(anchor);
|
||||
return;
|
||||
}
|
||||
element.innerHTML = textValue;
|
||||
}
|
||||
function createLayout() {
|
||||
var contentRegion = document.getElementById("content");
|
||||
if (contentRegion != null) {
|
||||
contentRegion.setAttribute("aria-busy", "true");
|
||||
}
|
||||
// Client Info
|
||||
var obj = SERVER["clientInfo"];
|
||||
var keys = getObjKeys(obj);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (document.getElementById(keys[i])) {
|
||||
document.getElementById(keys[i]).innerHTML = obj[keys[i]];
|
||||
}
|
||||
setClientInfoValue(keys[i], obj[keys[i]]);
|
||||
}
|
||||
renderStatusCards();
|
||||
if (!document.getElementById("main-menu")) {
|
||||
if (contentRegion != null) {
|
||||
contentRegion.setAttribute("aria-busy", "false");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Menü erstellen
|
||||
@@ -713,12 +1116,35 @@ function createLayout() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ACTIVE_MENU_ID.length > 0 && document.getElementById(ACTIVE_MENU_ID)) {
|
||||
setActiveMenu(ACTIVE_MENU_ID);
|
||||
}
|
||||
setLayoutMenuState(document.body.classList.contains("menu-open"));
|
||||
var content = document.getElementById("content");
|
||||
var menu = document.getElementById("main-menu");
|
||||
if (ACTIVE_MENU_ID.length == 0 && content != null && menu != null) {
|
||||
if (content.innerHTML.replace(/\\s/g, "").length == 0) {
|
||||
var firstItem = menu.getElementsByTagName("LI")[0];
|
||||
if (firstItem != undefined) {
|
||||
firstItem.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contentRegion != null) {
|
||||
contentRegion.setAttribute("aria-busy", "false");
|
||||
}
|
||||
return;
|
||||
}
|
||||
function openThisMenu(element) {
|
||||
var id = element.id;
|
||||
var content = new ShowContent(id);
|
||||
setActiveMenu(id);
|
||||
content.show();
|
||||
var contentArea = document.getElementById("content");
|
||||
if (contentArea != null) {
|
||||
contentArea.scrollTop = 0;
|
||||
}
|
||||
closeLayoutMenuIfMobile();
|
||||
calculateWrapperHeight();
|
||||
return;
|
||||
}
|
||||
@@ -756,9 +1182,26 @@ var PopupContent = /** @class */ (function (_super) {
|
||||
}
|
||||
PopupContent.prototype.createHeadline = function (headline) {
|
||||
this.doc.innerHTML = "";
|
||||
var titleBar = document.createElement("DIV");
|
||||
titleBar.className = "popup-title";
|
||||
var element = document.createElement("H3");
|
||||
element.id = "popup-title-text";
|
||||
element.innerHTML = headline.toUpperCase();
|
||||
this.doc.appendChild(element);
|
||||
titleBar.appendChild(element);
|
||||
var closeButton = document.createElement("BUTTON");
|
||||
closeButton.setAttribute("type", "button");
|
||||
closeButton.className = "popup-close";
|
||||
closeButton.setAttribute("aria-label", "Close dialog");
|
||||
closeButton.innerHTML = "×";
|
||||
closeButton.onclick = function () {
|
||||
showElement("popup", false);
|
||||
};
|
||||
titleBar.appendChild(closeButton);
|
||||
this.doc.appendChild(titleBar);
|
||||
var popup = document.getElementById("popup");
|
||||
if (popup != null) {
|
||||
popup.setAttribute("aria-labelledby", "popup-title-text");
|
||||
}
|
||||
// Tabelle erstellen
|
||||
this.table = document.createElement("TABLE");
|
||||
this.doc.appendChild(this.table);
|
||||
@@ -901,7 +1344,7 @@ function openPopUp(dataType, element) {
|
||||
input.setAttribute("placeholder", "{{.playlist.fileM3U.placeholder}}");
|
||||
content.appendRow("{{.playlist.fileM3U.title}}", input);
|
||||
// Tuner
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
var text = new Array();
|
||||
var values = new Array();
|
||||
for (var i = 1; i <= 100; i++) {
|
||||
@@ -971,7 +1414,7 @@ function openPopUp(dataType, element) {
|
||||
input.setAttribute("placeholder", "{{.playlist.fileHDHR.placeholder}}");
|
||||
content.appendRow("{{.playlist.fileHDHR.title}}", input);
|
||||
// Tuner
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
var text = new Array();
|
||||
var values = new Array();
|
||||
for (var i = 1; i <= 100; i++) {
|
||||
@@ -1253,6 +1696,12 @@ function openPopUp(dataType, element) {
|
||||
}
|
||||
content.appendRow("{{.mapping.channelName.title}}", input);
|
||||
content.description(data["name"]);
|
||||
// Beschreibung
|
||||
var dbKey = "x-description";
|
||||
var input = content.createInput("text", dbKey, data[dbKey]);
|
||||
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
content.appendRow("{{.mapping.description.title}}", input);
|
||||
// Aktualisierung des Kanalnamens
|
||||
if (data.hasOwnProperty("_uuid.key")) {
|
||||
if (data["_uuid.key"] != "") {
|
||||
@@ -1279,7 +1728,7 @@ function openPopUp(dataType, element) {
|
||||
// Erweitern der EPG Kategorie
|
||||
var dbKey = "x-category";
|
||||
var text = ["-", "Kids (Emby only)", "News", "Movie", "Series", "Sports"];
|
||||
var values = ["-", "Kids", "News", "Movie", "Series", "Sports"];
|
||||
var values = ["", "Kids", "News", "Movie", "Series", "Sports"];
|
||||
var select = content.createSelect(text, values, data[dbKey], dbKey);
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
content.appendRow("{{.mapping.epgCategory.title}}", select);
|
||||
|
||||
+72
-5
@@ -11,6 +11,7 @@ var Server = /** @class */ (function () {
|
||||
if (this.cmd != "updateLog") {
|
||||
showElement("loading", true);
|
||||
UNDO = new Object();
|
||||
setConnectionState("busy");
|
||||
}
|
||||
switch (window.location.protocol) {
|
||||
case "http:":
|
||||
@@ -20,11 +21,61 @@ var Server = /** @class */ (function () {
|
||||
this.protocol = "wss://";
|
||||
break;
|
||||
}
|
||||
var url = this.protocol + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token");
|
||||
var wsHost = window.location.host;
|
||||
if (wsHost == undefined || wsHost.length < 1) {
|
||||
wsHost = window.location.hostname;
|
||||
}
|
||||
var url = this.protocol + wsHost + "/data/" + "?Token=" + getCookie("Token");
|
||||
data["cmd"] = this.cmd;
|
||||
var requestCmd = data["cmd"];
|
||||
var ws = new WebSocket(url);
|
||||
var isLogUpdate = data["cmd"] == "updateLog";
|
||||
var responseReceived = false;
|
||||
var requestFinished = false;
|
||||
var timeoutMs = 12000;
|
||||
var requestTimeout;
|
||||
var finishRequest = function (state, responseSuccess) {
|
||||
if (responseSuccess === void 0) { responseSuccess = false; }
|
||||
if (requestFinished == true) {
|
||||
return;
|
||||
}
|
||||
requestFinished = true;
|
||||
SERVER_CONNECTION = false;
|
||||
window.clearTimeout(requestTimeout);
|
||||
if (responseSuccess == true) {
|
||||
if (state == "online") {
|
||||
WS_FAILURE_COUNT = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
WS_FAILURE_COUNT++;
|
||||
}
|
||||
if (isLogUpdate == false) {
|
||||
showElement("loading", false);
|
||||
}
|
||||
if (state != "") {
|
||||
setConnectionState(state);
|
||||
}
|
||||
};
|
||||
requestTimeout = window.setTimeout(function () {
|
||||
console.log("Websocket request timed out.");
|
||||
var timeoutState = "offline";
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
timeoutState = "idle";
|
||||
}
|
||||
finishRequest(timeoutState, false);
|
||||
try {
|
||||
ws.close();
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}, timeoutMs);
|
||||
ws.onopen = function () {
|
||||
WS_AVAILABLE = true;
|
||||
if (data["cmd"] != "updateLog") {
|
||||
setConnectionState("busy");
|
||||
}
|
||||
console.log("REQUEST (JS):");
|
||||
console.log(data);
|
||||
console.log("REQUEST: (JSON)");
|
||||
@@ -33,14 +84,18 @@ var Server = /** @class */ (function () {
|
||||
};
|
||||
ws.onerror = function (e) {
|
||||
console.log("No websocket connection to xTeVe could be established. Check your network configuration.");
|
||||
SERVER_CONNECTION = false;
|
||||
if (WS_AVAILABLE == false) {
|
||||
var errorState = "offline";
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
errorState = "idle";
|
||||
}
|
||||
finishRequest(errorState, false);
|
||||
if (WS_AVAILABLE == false && isLogUpdate == false && requestCmd != "getServerConfig") {
|
||||
alert("No websocket connection to xTeVe could be established. Check your network configuration.");
|
||||
}
|
||||
};
|
||||
ws.onmessage = function (e) {
|
||||
SERVER_CONNECTION = false;
|
||||
showElement("loading", false);
|
||||
responseReceived = true;
|
||||
finishRequest("online", true);
|
||||
console.log("RESPONSE:");
|
||||
var response = JSON.parse(e.data);
|
||||
console.log(response);
|
||||
@@ -48,6 +103,7 @@ var Server = /** @class */ (function () {
|
||||
document.cookie = "Token=" + response["token"];
|
||||
}
|
||||
if (response["status"] == false) {
|
||||
setConnectionState("offline");
|
||||
alert(response["err"]);
|
||||
if (response.hasOwnProperty("reload")) {
|
||||
location.reload();
|
||||
@@ -94,9 +150,20 @@ var Server = /** @class */ (function () {
|
||||
}
|
||||
createLayout();
|
||||
};
|
||||
ws.onclose = function () {
|
||||
if (responseReceived == true) {
|
||||
return;
|
||||
}
|
||||
var closeState = "offline";
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
closeState = "idle";
|
||||
}
|
||||
finishRequest(closeState, false);
|
||||
};
|
||||
};
|
||||
return Server;
|
||||
}());
|
||||
var WS_FAILURE_COUNT = 0;
|
||||
function getCookie(name) {
|
||||
var value = "; " + document.cookie;
|
||||
var parts = value.split("; " + name + "=");
|
||||
|
||||
+141
-12
@@ -2,7 +2,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
@@ -74,6 +74,29 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "plex.url":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.plexURL.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "plex.url", data);
|
||||
input.setAttribute("placeholder", "{{.settings.plexURL.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "plex.token":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.plexToken.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("password", "plex.token", data);
|
||||
input.setAttribute("placeholder", "{{.settings.plexToken.placeholder}}");
|
||||
input.setAttribute("autocomplete", "off");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "buffer.timeout":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.bufferTimeout.title}}" + ":";
|
||||
@@ -85,6 +108,50 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "ffmpeg.path":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.ffmpegPath.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "ffmpeg.path", data);
|
||||
input.setAttribute("placeholder", "{{.settings.ffmpegPath.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "ffmpeg.options":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.ffmpegOptions.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "ffmpeg.options", data);
|
||||
input.setAttribute("placeholder", "{{.settings.ffmpegOptions.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "vlc.path":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.vlcPath.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "vlc.path", data);
|
||||
input.setAttribute("placeholder", "{{.settings.vlcPath.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "vlc.options":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.vlcOptions.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "vlc.options", data);
|
||||
input.setAttribute("placeholder", "{{.settings.vlcOptions.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
// Checkboxen
|
||||
case "authentication.web":
|
||||
var tdLeft = document.createElement("TD");
|
||||
@@ -185,17 +252,6 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "buffer":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.streamBuffering.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createCheckbox(settingsKey);
|
||||
input.checked = data;
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "api":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.api.title}}" + ":";
|
||||
@@ -207,7 +263,30 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "use_plexAPI":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.usePlexAPI.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createCheckbox(settingsKey);
|
||||
input.checked = data;
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
// Select
|
||||
case "xepg.missing.epg.mode":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.xepgMissingEPGMode.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var text = ["{{.settings.xepgMissingEPGMode.info_strict}}", "{{.settings.xepgMissingEPGMode.info_relaxed}}"];
|
||||
var values = ["strict", "relaxed"];
|
||||
var select = content.createSelect(text, values, data, settingsKey);
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(select);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "tuner":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.tuner.title}}" + ":";
|
||||
@@ -260,6 +339,29 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "buffer":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.streamBuffering.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var text = ["{{.settings.streamBuffering.info_false}}", "xTeVe: ({{.settings.streamBuffering.info_xteve}})", "FFmpeg: ({{.settings.streamBuffering.info_ffmpeg}})", "VLC: ({{.settings.streamBuffering.info_vlc}})"];
|
||||
var values = ["-", "xteve", "ffmpeg", "vlc"];
|
||||
var select = content.createSelect(text, values, data, settingsKey);
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(select);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "udpxy":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.udpxy.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "udpxy", data);
|
||||
input.setAttribute("placeholder", "{{.settings.udpxy.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
}
|
||||
return setting;
|
||||
};
|
||||
@@ -308,6 +410,24 @@ var SettingsCategory = /** @class */ (function () {
|
||||
case "user.agent":
|
||||
text = "{{.settings.userAgent.description}}";
|
||||
break;
|
||||
case "plex.url":
|
||||
text = "{{.settings.plexURL.description}}";
|
||||
break;
|
||||
case "plex.token":
|
||||
text = "{{.settings.plexToken.description}}";
|
||||
break;
|
||||
case "ffmpeg.path":
|
||||
text = "{{.settings.ffmpegPath.description}}";
|
||||
break;
|
||||
case "ffmpeg.options":
|
||||
text = "{{.settings.ffmpegOptions.description}}";
|
||||
break;
|
||||
case "vlc.path":
|
||||
text = "{{.settings.vlcPath.description}}";
|
||||
break;
|
||||
case "vlc.options":
|
||||
text = "{{.settings.vlcOptions.description}}";
|
||||
break;
|
||||
case "epgSource":
|
||||
text = "{{.settings.epgSource.description}}";
|
||||
break;
|
||||
@@ -320,6 +440,9 @@ var SettingsCategory = /** @class */ (function () {
|
||||
case "api":
|
||||
text = "{{.settings.api.description}}";
|
||||
break;
|
||||
case "use_plexAPI":
|
||||
text = "{{.settings.usePlexAPI.description}}";
|
||||
break;
|
||||
case "files.update":
|
||||
text = "{{.settings.filesUpdate.description}}";
|
||||
break;
|
||||
@@ -329,6 +452,12 @@ var SettingsCategory = /** @class */ (function () {
|
||||
case "xepg.replace.missing.images":
|
||||
text = "{{.settings.replaceEmptyImages.description}}";
|
||||
break;
|
||||
case "xepg.missing.epg.mode":
|
||||
text = "{{.settings.xepgMissingEPGMode.description}}";
|
||||
break;
|
||||
case "udpxy":
|
||||
text = "{{.settings.udpxy.description}}";
|
||||
break;
|
||||
default:
|
||||
text = "";
|
||||
break;
|
||||
|
||||
+252
-100
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"mainMenu": {
|
||||
"item":{
|
||||
"mainMenu":
|
||||
{
|
||||
"item":
|
||||
{
|
||||
"playlist": "Playlist",
|
||||
"pmsID": "PMS ID",
|
||||
"filter": "Filter",
|
||||
@@ -11,7 +13,8 @@
|
||||
"log": "Log",
|
||||
"logout": "Logout"
|
||||
},
|
||||
"headline": {
|
||||
"headline":
|
||||
{
|
||||
"playlist": "Local or remote playlists",
|
||||
"filter": "Filter playlist",
|
||||
"xmltv": "Local or remote XMLTV files",
|
||||
@@ -22,19 +25,23 @@
|
||||
"logout": "Logout"
|
||||
}
|
||||
},
|
||||
"confirm":{
|
||||
"confirm":
|
||||
{
|
||||
"restore": "All data will be replaced with those from the backup. Should the files be restored?"
|
||||
},
|
||||
"alert": {
|
||||
"alert":
|
||||
{
|
||||
"fileLoadingError": "File couldn't be loaded",
|
||||
"invalidChannelNumber": "Invalid channel number",
|
||||
"missingInput": "Missing input"
|
||||
},
|
||||
"button":{
|
||||
"button":
|
||||
{
|
||||
"back": "Back",
|
||||
"backup": "Backup",
|
||||
"bulkEdit": "Bulk Edit",
|
||||
"cancel": "Cancel",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"done": "Done",
|
||||
"login": "Login",
|
||||
@@ -48,58 +55,70 @@
|
||||
"resetLogs": "Reset Logs",
|
||||
"uploadLogo": "Upload Logo"
|
||||
},
|
||||
"filter": {
|
||||
"table": {
|
||||
"filter":
|
||||
{
|
||||
"table":
|
||||
{
|
||||
"name": "Filter Name",
|
||||
"type": "Filter Type",
|
||||
"filter": "Filter"
|
||||
},
|
||||
"custom": "Custom",
|
||||
"group": "Group",
|
||||
"name": {
|
||||
"name":
|
||||
{
|
||||
"title": "Filter Name",
|
||||
"placeholder": "Filter name",
|
||||
"description": ""
|
||||
},
|
||||
"description": {
|
||||
"description":
|
||||
{
|
||||
"title": "Description",
|
||||
"placeholder": "Description",
|
||||
"description": ""
|
||||
},
|
||||
"type": {
|
||||
"type":
|
||||
{
|
||||
"title": "Type",
|
||||
"groupTitle": "Group Title",
|
||||
"customFilter": "Custom Filter"
|
||||
},
|
||||
"caseSensitive": {
|
||||
"caseSensitive":
|
||||
{
|
||||
"title": "Case Sensitive",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"filterRule": {
|
||||
"filterRule":
|
||||
{
|
||||
"title": "Filter Rule",
|
||||
"placeholder": "Sport {HD} !{ES,IT}",
|
||||
"description": ""
|
||||
},
|
||||
"filterGroup": {
|
||||
"filterGroup":
|
||||
{
|
||||
"title": "Group Title",
|
||||
"placeholder": "",
|
||||
"description": "Select a M3U group. (Counter)<br>Changing the group title in the M3U invalidates the filter."
|
||||
},
|
||||
"include": {
|
||||
"include":
|
||||
{
|
||||
"title": "Include",
|
||||
"placeholder": "FHD,UHD",
|
||||
"description": "Channel name must include.<br>(Comma separated) Comma means or"
|
||||
},
|
||||
"exclude": {
|
||||
"exclude":
|
||||
{
|
||||
"title": "Exclude",
|
||||
"placeholder": "ES,IT",
|
||||
"description": "Channel name must not contain.<br>(Comma separated) Comma means or"
|
||||
}
|
||||
|
||||
},
|
||||
"playlist": {
|
||||
"table": {
|
||||
"playlist":
|
||||
{
|
||||
"table":
|
||||
{
|
||||
"playlist": "Playlist",
|
||||
"tuner": "Tuner",
|
||||
"lastUpdate": "Last Update",
|
||||
@@ -110,124 +129,156 @@
|
||||
"tvgID": "tvg-id",
|
||||
"uniqueID": "Unique ID"
|
||||
},
|
||||
"playlistType": {
|
||||
"playlistType":
|
||||
{
|
||||
"title": "Playlist type",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"type": {
|
||||
"type":
|
||||
{
|
||||
"title": "Type",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"name": {
|
||||
"name":
|
||||
{
|
||||
"title": "Name",
|
||||
"placeholder": "Playlist name",
|
||||
"description": ""
|
||||
},
|
||||
"description": {
|
||||
"description":
|
||||
{
|
||||
"title": "Description",
|
||||
"placeholder": "Description",
|
||||
"description": ""
|
||||
},
|
||||
"fileM3U": {
|
||||
"fileM3U":
|
||||
{
|
||||
"title": "M3U File",
|
||||
"placeholder": "File path or URL of the M3U",
|
||||
"description": ""
|
||||
},
|
||||
"fileHDHR": {
|
||||
"fileHDHR":
|
||||
{
|
||||
"title": "HDHomeRun IP",
|
||||
"placeholder": "IP address and port (192.168.1.10:5004)",
|
||||
"description": ""
|
||||
},
|
||||
"tuner": {
|
||||
"tuner":
|
||||
{
|
||||
"title": "Tuner / Streams",
|
||||
"placeholder": "",
|
||||
"description": "Number of parallel connections that can be established to the provider. <br>Only available with activated buffer.<br>New settings will only be applied after quitting all streams."
|
||||
}
|
||||
},
|
||||
"xmltv": {
|
||||
"table": {
|
||||
"xmltv":
|
||||
{
|
||||
"table":
|
||||
{
|
||||
"guide": "Guide",
|
||||
"lastUpdate": "Last Update",
|
||||
"availability": "Availability",
|
||||
"channels": "Channels",
|
||||
"programs": "Programs"
|
||||
},
|
||||
"name": {
|
||||
"name":
|
||||
{
|
||||
"title": "Name",
|
||||
"placeholder": "Guide name",
|
||||
"description": ""
|
||||
},
|
||||
"description": {
|
||||
"description":
|
||||
{
|
||||
"title": "Description",
|
||||
"placeholder": "Description",
|
||||
"description": ""
|
||||
},
|
||||
"fileXMLTV": {
|
||||
"fileXMLTV":
|
||||
{
|
||||
"title": "XMLTV File",
|
||||
"placeholder": "File path or URL of the XMLTV",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"mapping": {
|
||||
"table": {
|
||||
"mapping":
|
||||
{
|
||||
"table":
|
||||
{
|
||||
"chNo": "Ch. No.",
|
||||
"logo": "Logo",
|
||||
"channelName": "Channel Name",
|
||||
"playlist": "Playlist",
|
||||
"groupTitle": "Group Title",
|
||||
"xmltvFile": "XMLTV File",
|
||||
"xmltvID": "XMLTV ID"
|
||||
"xmltvID": "XMLTV ID",
|
||||
"edit": "Edit"
|
||||
},
|
||||
"active": {
|
||||
"active":
|
||||
{
|
||||
"title": "Active",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"channelName": {
|
||||
"channelName":
|
||||
{
|
||||
"title": "Channel Name",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"updateChannelName": {
|
||||
"description":
|
||||
{
|
||||
"title": "Channel Description",
|
||||
"placeholder": "Used by the Dummy as an XML description",
|
||||
"description": ""
|
||||
},
|
||||
"updateChannelName":
|
||||
{
|
||||
"title": "Update Channel Name",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"channelLogo": {
|
||||
"channelLogo":
|
||||
{
|
||||
"title": "Logo URL",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"updateChannelLogo": {
|
||||
"updateChannelLogo":
|
||||
{
|
||||
"title": "Update Channel Logo",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"epgCategory": {
|
||||
"epgCategory":
|
||||
{
|
||||
"title": "EPG Category",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"m3uGroupTitle": {
|
||||
"m3uGroupTitle":
|
||||
{
|
||||
"title": "Group Title (xteve.m3u)",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"xmltvFile": {
|
||||
"xmltvFile":
|
||||
{
|
||||
"title": "XMLTV File",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"xmltvChannel": {
|
||||
"xmltvChannel":
|
||||
{
|
||||
"title": "XMLTV Channel",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"table": {
|
||||
"users":
|
||||
{
|
||||
"table":
|
||||
{
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"web": "WEB",
|
||||
@@ -236,185 +287,286 @@
|
||||
"xml": "XML",
|
||||
"api": "API"
|
||||
},
|
||||
"username": {
|
||||
"username":
|
||||
{
|
||||
"title": "Username",
|
||||
"placeholder": "Username",
|
||||
"description": ""
|
||||
},
|
||||
"password": {
|
||||
"password":
|
||||
{
|
||||
"title": "Password",
|
||||
"placeholder": "Password",
|
||||
"description": ""
|
||||
},
|
||||
"confirm": {
|
||||
"confirm":
|
||||
{
|
||||
"title": "Confirm",
|
||||
"placeholder": "Password confirm",
|
||||
"description": ""
|
||||
},
|
||||
"web": {
|
||||
"web":
|
||||
{
|
||||
"title": "Web Access",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"pms": {
|
||||
"pms":
|
||||
{
|
||||
"title": "PMS Access",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"m3u": {
|
||||
"m3u":
|
||||
{
|
||||
"title": "M3U Access",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"xml": {
|
||||
"xml":
|
||||
{
|
||||
"title": "XML Access",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
},
|
||||
"api": {
|
||||
"api":
|
||||
{
|
||||
"title": "API Access",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"category": {
|
||||
"settings":
|
||||
{
|
||||
"category":
|
||||
{
|
||||
"general": "General",
|
||||
"files": "Files",
|
||||
"streaming": "Streaming",
|
||||
"backup": "Backup",
|
||||
"authentication": "Authentication"
|
||||
},
|
||||
"update": {
|
||||
"update":
|
||||
{
|
||||
"title": "Schedule for updating (Playlist, XMLTV, Backup)",
|
||||
"placeholder": "0000,1000,2000",
|
||||
"description": "Time in 24 hour format (0800 = 8:00 am). More times can be entered comma separated."
|
||||
"description": "Time in 24 hour format (0800 = 8:00 am). More times can be entered comma separated. Leave this field empty if no updates are to be carried out."
|
||||
},
|
||||
"api": {
|
||||
"api":
|
||||
{
|
||||
"title": "API Interface",
|
||||
"description": "Via API interface it is possible to send commands to xTeVe. API documentation is <a href='https://github.com/xteve-project/xTeVe-Documentation/blob/master/en/configuration.md#api'>here</a>"
|
||||
},
|
||||
"epgSource": {
|
||||
"usePlexAPI":
|
||||
{
|
||||
"title": "Use Plex API Refresh",
|
||||
"description": "When enabled, xTeVe calls Plex directly to refresh DVR guide data after lineup or XEPG updates."
|
||||
},
|
||||
"plexURL":
|
||||
{
|
||||
"title": "Plex Server URL",
|
||||
"description": "Base URL of your Plex server. Example: http://192.168.1.10:32400",
|
||||
"placeholder": "http://plex-host:32400"
|
||||
},
|
||||
"plexToken":
|
||||
{
|
||||
"title": "Plex API Token",
|
||||
"description": "Plex token used for authenticated API calls to refresh your DVR guide.",
|
||||
"placeholder": "Plex X-Plex-Token"
|
||||
},
|
||||
"epgSource":
|
||||
{
|
||||
"title": "EPG Source",
|
||||
"description": "PMS:<br>- Use EPG data from Plex or Emby <br><br>XEPG:<br>- Use of one or more XMLTV files<br>- Channel management<br>- M3U / XMLTV export (HTTP link for IPTV apps)"
|
||||
},
|
||||
"tuner":{
|
||||
"tuner":
|
||||
{
|
||||
"title": "Number of Tuners",
|
||||
"description": "Number of parallel connections that can be established to the provider.<br>Available for: Plex, Emby (HDHR), M3U (with active buffer).<br>After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again."
|
||||
},
|
||||
"filesUpdate": {
|
||||
"filesUpdate":
|
||||
{
|
||||
"title": "Updates all files at startup",
|
||||
"description": "Updates all playlists, tuner and XMLTV files at startup."
|
||||
},
|
||||
"cacheImages": {
|
||||
"title": "Image caching",
|
||||
"cacheImages":
|
||||
{
|
||||
"title": "Image Caching",
|
||||
"description": "All images from the XMLTV file are cached, allowing faster rendering of the grid in the client.<br>Downloading the images may take a while and will be done in the background."
|
||||
},
|
||||
"replaceEmptyImages": {
|
||||
"replaceEmptyImages":
|
||||
{
|
||||
"title": "Replace missing program images",
|
||||
"description": "If the poster in the XMLTV program is missing, the channel logo will be used."
|
||||
},
|
||||
"xteveAutoUpdate": {
|
||||
"xepgMissingEPGMode":
|
||||
{
|
||||
"title": "Missing EPG Handling",
|
||||
"description": "Strict: channels are deactivated when XMLTV mappings disappear.<br>Relaxed: channels stay active with last-known mappings and fall back to a dummy guide whenever guide data cannot be resolved.",
|
||||
"info_strict": "Strict (deactivate channels)",
|
||||
"info_relaxed": "Relaxed (keep active / dummy guide)"
|
||||
},
|
||||
"xteveAutoUpdate":
|
||||
{
|
||||
"title": "Automatic update of xTeVe",
|
||||
"description": "If a new version of xTeVe is available, it will be automatically installed. The updates are downloaded from GitHub."
|
||||
},
|
||||
"streamBuffering": {
|
||||
"streamBuffering":
|
||||
{
|
||||
"title": "Stream Buffer",
|
||||
"description": "- The stream is passed from xTeVe to Plex / Emby / M3U Player<br>- Small jerking of the streams can be compensated<br>- HLS / M3U8 support<br>- Re-streaming<br>- Separate tuner limit for each playlist"
|
||||
"description": "Functions of the buffer:<br>- The stream is passed from xTeVe, FFmpeg or VLC to Plex, Emby or M3U Player<br>- Small jerking of the streams can be compensated<br>- HLS / M3U8 support<br>- RTP / RTPS support (only FFmpeg or VLC)<br>- Re-streaming<br>- Separate tuner limit for each playlist",
|
||||
"info_false": "No Buffer (Client connects to the streaming server)",
|
||||
"info_xteve": "xTeVe connects to the streaming server",
|
||||
"info_ffmpeg": "FFmpeg connects to the streaming server",
|
||||
"info_vlc": "VLC connects to the streaming server"
|
||||
|
||||
},
|
||||
"bufferSize": {
|
||||
"udpxy":
|
||||
{
|
||||
"title": "UDPxy address",
|
||||
"description": "The address of your UDPxy server. If set, and the channel URLs in the m3u is multicast, xTeVe will rewrite it so that it is accessed via the UDPxy service.",
|
||||
"placeholder": "host:port"
|
||||
},
|
||||
"ffmpegPath":
|
||||
{
|
||||
"title": "FFmpeg Binary Path",
|
||||
"description": "Path to FFmpeg binary.",
|
||||
"placeholder": "/path/to/ffmpeg"
|
||||
},
|
||||
"ffmpegOptions":
|
||||
{
|
||||
"title": "FFmpeg Options",
|
||||
"description": "FFmpeg options.<br>Only change if you know what you are doing.<br>Leave blank to set default settings.",
|
||||
"placeholder": "Leave blank to set default settings"
|
||||
},
|
||||
"vlcPath":
|
||||
{
|
||||
"title": "VLC / CVLC Binary Path",
|
||||
"description": "Path to VLC / CVLC binary.",
|
||||
"placeholder": "/path/to/cvlc"
|
||||
},
|
||||
"vlcOptions":
|
||||
{
|
||||
"title": "VLC / CVLC Options",
|
||||
"description": "VLC / CVLC options.<br>Only change if you know what you are doing.<br>Leave blank to set default settings.",
|
||||
"placeholder": "Leave blank to set default settings"
|
||||
},
|
||||
"bufferSize":
|
||||
{
|
||||
"title": "Buffer Size",
|
||||
"description": "Buffer size in MB.<br>M3U8: If the TS segment smaller then the buffer size, the file size of the segment is used."
|
||||
},
|
||||
"bufferTimeout": {
|
||||
"bufferTimeout":
|
||||
{
|
||||
"title": "Timeout for new client connections",
|
||||
"description": "The xTeVe buffer waits until new client connections are established. Helpful for fast channel switching. Value in milliseconds.",
|
||||
"placeholder": "100"
|
||||
},
|
||||
"userAgent": {
|
||||
"title": "User agent",
|
||||
"description": "User Agent for HTTP requests",
|
||||
"userAgent":
|
||||
{
|
||||
"title": "User Agent",
|
||||
"description": "User Agent for HTTP requests. For every HTTP connection, this value is used for the user agent. Should only be changed if xTeVe is blocked.",
|
||||
"placeholder": "xTeVe"
|
||||
},
|
||||
"backupPath": {
|
||||
"backupPath":
|
||||
{
|
||||
"title": "Location for automatic backups",
|
||||
"placeholder": "/mnt/data/backup/xteve/",
|
||||
"description": "Before any update of the provider data by the schedule, xTeVe creates a backup. The path for the automatic backups can be changed. xTeVe requires write permission for this folder."
|
||||
},
|
||||
"tempPath": {
|
||||
"tempPath":
|
||||
{
|
||||
"title": "Location for the temporary files",
|
||||
"placeholder": "/tmp/xteve/",
|
||||
"description": "Location for the buffer files."
|
||||
},
|
||||
"backupKeep": {
|
||||
"backupKeep":
|
||||
{
|
||||
"title": "Number of backups to keep",
|
||||
"description": "Number of backups to keep. Older backups are automatically deleted."
|
||||
},
|
||||
"authenticationWEB": {
|
||||
"authenticationWEB":
|
||||
{
|
||||
"title": "WEB Authentication",
|
||||
"description": "Access to the web interface only possible with credentials."
|
||||
},
|
||||
"authenticationPMS": {
|
||||
"authenticationPMS":
|
||||
{
|
||||
"title": "PMS Authentication",
|
||||
"description": "Plex requests are only possible with authentication. <br><b>Warning!!!</b> After activating this function xTeVe must be delete in the PMS DVR settings and set up again."
|
||||
},
|
||||
"authenticationM3U": {
|
||||
"authenticationM3U":
|
||||
{
|
||||
"title": "M3U Authentication",
|
||||
"description": "Downloading the xteve.m3u file via an HTTP request is only possible with authentication."
|
||||
},
|
||||
"authenticationXML": {
|
||||
"authenticationXML":
|
||||
{
|
||||
"title": "XML Authentication",
|
||||
"description": "Downloading the xteve.xml file via an HTTP request is only possible with authentication"
|
||||
},
|
||||
"authenticationAPI": {
|
||||
"authenticationAPI":
|
||||
{
|
||||
"title": "API Authentication",
|
||||
"description": "Access to the API interface is only possible with authentication."
|
||||
}
|
||||
},
|
||||
"wizard": {
|
||||
"epgSource": {
|
||||
"wizard":
|
||||
{
|
||||
"epgSource":
|
||||
{
|
||||
"title": "EPG Source",
|
||||
"description": "PMS:<br>- Use EPG data from Plex or Emby <br><br>XEPG:<br>- Use of one or more XMLTV files<br>- Channel management<br>- M3U / XMLTV export (HTTP link for IPTV apps)"
|
||||
},
|
||||
"tuner":{
|
||||
"tuner":
|
||||
{
|
||||
"title": "Number of tuners",
|
||||
"description": "Number of parallel connections that can be established to the provider.<br>Available for: Plex, Emby (HDHR), M3U (with active buffer).<br>After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again."
|
||||
},
|
||||
"m3u": {
|
||||
"m3u":
|
||||
{
|
||||
"title": "M3U Playlist",
|
||||
"placeholder": "File path or URL of the M3U",
|
||||
"description": "Local or remote playlists"
|
||||
},
|
||||
"xmltv": {
|
||||
"xmltv":
|
||||
{
|
||||
"title": "XMLTV File",
|
||||
"placeholder": "File path or URL of the XMLTV",
|
||||
"description": "Local or remote XMLTV file"
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"login":
|
||||
{
|
||||
"failed": "User authentication failed",
|
||||
"headline": "Login",
|
||||
"username": {
|
||||
"username":
|
||||
{
|
||||
"title": "Username",
|
||||
"placeholder": "Username"
|
||||
},
|
||||
"password": {
|
||||
"password":
|
||||
{
|
||||
"title": "Password",
|
||||
"placeholder": "Password"
|
||||
}
|
||||
},
|
||||
"account": {
|
||||
"account":
|
||||
{
|
||||
"failed": "Password does not match",
|
||||
"headline": "Create user account",
|
||||
"username": {
|
||||
"username":
|
||||
{
|
||||
"title": "Username",
|
||||
"placeholder": "Username"
|
||||
},
|
||||
"password": {
|
||||
"password":
|
||||
{
|
||||
"title": "Password",
|
||||
"placeholder": "Password"
|
||||
},
|
||||
"confirm": {
|
||||
"confirm":
|
||||
{
|
||||
"title": "Confirm",
|
||||
"placeholder": "Confirm"
|
||||
}
|
||||
|
||||
+11
-11
@@ -10,37 +10,37 @@
|
||||
<script language="javascript" type="text/javascript" src="js/authentication_ts.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="auth-screen">
|
||||
|
||||
<div id="header" class="imgCenter"></div>
|
||||
|
||||
<div id="box">
|
||||
<main id="box" role="main" aria-labelledby="head-text">
|
||||
|
||||
<div id="headline">
|
||||
<h1 id="head-text" class="center">{{.login.headline}}</h1>
|
||||
</div>
|
||||
|
||||
<p id="err" class="errorMsg center">{{.authenticationErr}}</p>
|
||||
<p id="err" class="errorMsg center" role="alert" aria-live="assertive" aria-atomic="true">{{.authenticationErr}}</p>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<form id="authentication" action="/web/" method="post">
|
||||
<form id="authentication" action="" method="post" aria-describedby="err" novalidate>
|
||||
|
||||
<h5>{{.login.username.title}}:</h5>
|
||||
<input id="username" type="text" name="username" placeholder="Username" value="">
|
||||
<h5>{{.login.password.title}}:</h5>
|
||||
<input id="password" type="password" name="password" placeholder="Password" value="">
|
||||
<label for="username">{{.login.username.title}}:</label>
|
||||
<input id="username" type="text" name="username" placeholder="Username" value="" autocomplete="username">
|
||||
<label for="password">{{.login.password.title}}:</label>
|
||||
<input id="password" type="password" name="password" placeholder="Password" value="" autocomplete="current-password">
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="box-footer">
|
||||
<input id="submit" class="" type="button" value="{{.button.login}}" onclick="javascript: login();">
|
||||
<input id="submit" class="" type="button" value="{{.button.login}}" aria-label="{{.button.login}}" onclick="javascript: login();">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -8,7 +8,7 @@
|
||||
<link rel="stylesheet" href="css/base.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="auth-screen">
|
||||
|
||||
<div id="header" class="imgCenter"></div>
|
||||
|
||||
@@ -27,4 +27,4 @@
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"../src/internal/authentication"
|
||||
"xteve/src/internal/authentication"
|
||||
)
|
||||
|
||||
func activatedSystemAuthentication() (err error) {
|
||||
@@ -16,7 +16,7 @@ func activatedSystemAuthentication() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var defaults = make(map[string]interface{})
|
||||
var defaults = make(map[string]any)
|
||||
defaults["authentication.web"] = false
|
||||
defaults["authentication.pms"] = false
|
||||
defaults["authentication.xml"] = false
|
||||
@@ -43,7 +43,7 @@ func createFirstUserForAuthentication(username, password string) (token string,
|
||||
token, err = authentication.CheckTheValidityOfTheToken(token)
|
||||
authenticationErr(err)
|
||||
|
||||
var userData = make(map[string]interface{})
|
||||
var userData = make(map[string]any)
|
||||
userData["username"] = username
|
||||
userData["authentication.web"] = true
|
||||
userData["authentication.pms"] = true
|
||||
|
||||
+343
-22
@@ -1,11 +1,13 @@
|
||||
package src
|
||||
|
||||
/*
|
||||
Tuner-Limit Bild als Video rendern [ffmpeg]
|
||||
-loop 1 -i stream-limit.jpg -c:v libx264 -t 1 -pix_fmt yuv420p -vf scale=1920:1080 stream-limit.ts
|
||||
Tuner-Limit Bild als Video rendern [ffmpeg]
|
||||
-loop 1 -i stream-limit.jpg -c:v libx264 -t 1 -pix_fmt yuv420p -vf scale=1920:1080 stream-limit.ts
|
||||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -205,7 +208,17 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
|
||||
playlist.Streams[streamID] = stream
|
||||
BufferInformation.Store(playlistID, playlist)
|
||||
|
||||
go connectToStreamingServer(streamID, playlistID)
|
||||
switch Settings.Buffer {
|
||||
|
||||
case "xteve":
|
||||
go connectToStreamingServer(streamID, playlistID)
|
||||
case "ffmpeg", "vlc":
|
||||
go thirdPartyBuffer(streamID, playlistID)
|
||||
|
||||
default:
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
showInfo(fmt.Sprintf("Streaming Status:Playlist: %s - Tuner: %d / %d", playlist.PlaylistName, len(playlist.Streams), playlist.Tuner))
|
||||
|
||||
@@ -248,7 +261,9 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
|
||||
var oldSegments []string
|
||||
|
||||
for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden
|
||||
|
||||
// HTTP Clientverbindung überwachen
|
||||
|
||||
cn, ok := w.(http.CloseNotifier)
|
||||
if ok {
|
||||
|
||||
@@ -327,10 +342,10 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
|
||||
}
|
||||
|
||||
/*
|
||||
// HDHR Header
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("transferMode.dlna.org", "Streaming")
|
||||
// HDHR Header
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("transferMode.dlna.org", "Streaming")
|
||||
*/
|
||||
|
||||
_, err := w.Write(buffer)
|
||||
@@ -400,7 +415,7 @@ func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(files) > 1 {
|
||||
if len(files) > 2 {
|
||||
|
||||
for _, file := range files {
|
||||
|
||||
@@ -436,6 +451,9 @@ func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
|
||||
|
||||
func killClientConnection(streamID int, playlistID string, force bool) {
|
||||
|
||||
Lock.Lock()
|
||||
defer Lock.Unlock()
|
||||
|
||||
if p, ok := BufferInformation.Load(playlistID); ok {
|
||||
|
||||
var playlist = p.(Playlist)
|
||||
@@ -460,6 +478,7 @@ func killClientConnection(streamID int, playlistID string, force bool) {
|
||||
if clients.Connection <= 0 {
|
||||
BufferClients.Delete(playlistID + stream.MD5)
|
||||
delete(playlist.Streams, streamID)
|
||||
delete(playlist.Clients, streamID)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -479,6 +498,8 @@ func killClientConnection(streamID int, playlistID string, force bool) {
|
||||
func clientConnection(stream ThisStream) (status bool) {
|
||||
|
||||
status = true
|
||||
Lock.Lock()
|
||||
defer Lock.Unlock()
|
||||
|
||||
if _, ok := BufferClients.Load(stream.PlaylistID + stream.MD5); !ok {
|
||||
|
||||
@@ -526,6 +547,9 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
var m3u8Segments []string
|
||||
var bandwidth BandwidthCalculation
|
||||
var networkBandwidth = Settings.M3U8AdaptiveBandwidthMBPS * 1e+6
|
||||
// Größe des Buffers
|
||||
var bufferSize = Settings.BufferSize
|
||||
var buffer = make([]byte, 1024*bufferSize*2)
|
||||
|
||||
var defaultSegment = func() {
|
||||
|
||||
@@ -633,7 +657,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
Redirect:
|
||||
|
||||
req, err := http.NewRequest("GET", currentURL, nil)
|
||||
req.Header.Set("User-Agent", Settings.UserAgent)
|
||||
req.Header.Set("User-Agent", getUserAgent())
|
||||
req.Header.Set("Connection", "close")
|
||||
//req.Header.Set("Range", "bytes=0-")
|
||||
req.Header.Set("Accept", "*/*")
|
||||
@@ -782,7 +806,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
switch contentType {
|
||||
|
||||
// M3U8 Playlist
|
||||
case "application/x-mpegurl", "application/vnd.apple.mpegurl", "audio/mpegurl":
|
||||
case "application/x-mpegurl", "application/vnd.apple.mpegurl", "audio/mpegurl", "audio/x-mpegurl":
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
@@ -800,13 +824,13 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
}
|
||||
|
||||
// Video Stream (TS)
|
||||
case "video/mpeg", "video/mp4", "video/mp2t", "video/m2ts", "application/octet-stream", "binary/octet-stream", "application/mp2t":
|
||||
case "video/mpeg", "video/mp4", "video/mp2t", "video/m2ts", "application/octet-stream", "binary/octet-stream", "application/mp2t", "video/x-matroska":
|
||||
|
||||
var fileSize int
|
||||
|
||||
// Größe des Buffers
|
||||
buffer := make([]byte, 1024*Settings.BufferSize*2)
|
||||
var tmpFileSize = 1024 * Settings.BufferSize * 1
|
||||
buffer = make([]byte, 1024*bufferSize*2)
|
||||
var tmpFileSize = 1024 * bufferSize * 1
|
||||
|
||||
debug = fmt.Sprintf("Buffer Size:%d KB [SERVER CONNECTION]", len(buffer)/1024)
|
||||
showDebug(debug, 3)
|
||||
@@ -882,7 +906,9 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
}
|
||||
|
||||
// Buffer auf die Festplatte speichern
|
||||
if fileSize >= tmpFileSize || n == 0 {
|
||||
if fileSize >= tmpFileSize/2 || n == 0 {
|
||||
|
||||
Lock.Lock()
|
||||
|
||||
bandwidth.Stop = time.Now()
|
||||
bandwidth.Size += fileSize
|
||||
@@ -902,6 +928,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
stream.Status = true
|
||||
playlist.Streams[streamID] = stream
|
||||
BufferInformation.Store(playlistID, playlist)
|
||||
Lock.Unlock()
|
||||
|
||||
tmpSegment++
|
||||
|
||||
@@ -928,6 +955,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
|
||||
}
|
||||
|
||||
fileSize = 0
|
||||
buffer = make([]byte, 1024*bufferSize*2)
|
||||
|
||||
if n == 0 {
|
||||
bufferFile.Close()
|
||||
@@ -1255,12 +1283,6 @@ func parseM3U8(stream *ThisStream) (err error) {
|
||||
break
|
||||
}
|
||||
|
||||
err := checkFile(stream.Folder + "remove")
|
||||
if err == nil {
|
||||
os.RemoveAll(stream.Folder)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1319,14 +1341,313 @@ func switchBandwidth(stream *ThisStream) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Buffer mit FFMPEG
|
||||
func thirdPartyBuffer(streamID int, playlistID string) {
|
||||
|
||||
if p, ok := BufferInformation.Load(playlistID); ok {
|
||||
|
||||
var playlist = p.(Playlist)
|
||||
var debug, path, options, bufferType string
|
||||
var tmpSegment = 1
|
||||
var bufferSize = Settings.BufferSize * 1024
|
||||
var stream = playlist.Streams[streamID]
|
||||
var buf bytes.Buffer
|
||||
var fileSize = 0
|
||||
var streamStatus = make(chan bool)
|
||||
|
||||
var tmpFolder = playlist.Streams[streamID].Folder
|
||||
var url = playlist.Streams[streamID].URL
|
||||
|
||||
stream.Status = false
|
||||
|
||||
bufferType = strings.ToUpper(Settings.Buffer)
|
||||
|
||||
switch Settings.Buffer {
|
||||
|
||||
case "ffmpeg":
|
||||
path = Settings.FFmpegPath
|
||||
options = Settings.FFmpegOptions
|
||||
|
||||
case "vlc":
|
||||
path = Settings.VLCPath
|
||||
options = Settings.VLCOptions
|
||||
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
var addErrorToStream = func(err error) {
|
||||
|
||||
var stream = playlist.Streams[streamID]
|
||||
|
||||
if c, ok := BufferClients.Load(playlistID + stream.MD5); ok {
|
||||
|
||||
var clients = c.(ClientConnection)
|
||||
clients.Error = err
|
||||
BufferClients.Store(playlistID+stream.MD5, clients)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
os.RemoveAll(getPlatformPath(tmpFolder))
|
||||
|
||||
err := checkFolder(tmpFolder)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = checkFile(path)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
return
|
||||
}
|
||||
|
||||
showInfo(fmt.Sprintf("%s path:%s", bufferType, path))
|
||||
showInfo("Streaming URL:" + stream.URL)
|
||||
|
||||
var tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
|
||||
|
||||
f, err := os.Create(tmpFile)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
addErrorToStream(err)
|
||||
return
|
||||
}
|
||||
|
||||
//args = strings.Replace(args, "[USER-AGENT]", Settings.UserAgent, -1)
|
||||
|
||||
// User-Agent setzen
|
||||
var args []string
|
||||
|
||||
var userAgent = getUserAgent()
|
||||
|
||||
for i, a := range strings.Split(options, " ") {
|
||||
|
||||
switch bufferType {
|
||||
case "FFMPEG":
|
||||
a = strings.Replace(a, "[URL]", url, -1)
|
||||
if i == 0 {
|
||||
if len(userAgent) != 0 {
|
||||
args = []string{"-user_agent", userAgent}
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, a)
|
||||
|
||||
case "VLC":
|
||||
if a == "[URL]" {
|
||||
a = strings.Replace(a, "[URL]", url, -1)
|
||||
args = append(args, a)
|
||||
|
||||
if len(userAgent) != 0 {
|
||||
args = append(args, fmt.Sprintf(":http-user-agent=%s", userAgent))
|
||||
}
|
||||
|
||||
} else {
|
||||
args = append(args, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var cmd = exec.Command(path, args...)
|
||||
|
||||
debug = fmt.Sprintf("%s:%s %s", bufferType, path, args)
|
||||
showDebug(debug, 1)
|
||||
|
||||
// Byte-Daten vom Prozess
|
||||
stdOut, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
addErrorToStream(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Log-Daten vom Prozess
|
||||
logOut, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
addErrorToStream(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(buf.Bytes()) == 0 && stream.Status == false {
|
||||
showInfo(bufferType + ":Processing data")
|
||||
}
|
||||
|
||||
cmd.Start()
|
||||
defer cmd.Wait()
|
||||
|
||||
go func() {
|
||||
|
||||
// Log Daten vom Prozess im Dubug Mode 1 anzeigen.
|
||||
scanner := bufio.NewScanner(logOut)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
|
||||
for scanner.Scan() {
|
||||
|
||||
debug = fmt.Sprintf("%s log:%s", bufferType, strings.TrimSpace(scanner.Text()))
|
||||
|
||||
select {
|
||||
case <-streamStatus:
|
||||
showDebug(debug, 1)
|
||||
default:
|
||||
showInfo(debug)
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(10) * time.Millisecond)
|
||||
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
f, err = os.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
buffer := make([]byte, 1024*4)
|
||||
|
||||
reader := bufio.NewReader(stdOut)
|
||||
|
||||
t := make(chan int)
|
||||
|
||||
go func() {
|
||||
|
||||
var timeout = 0
|
||||
for {
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond)
|
||||
timeout++
|
||||
|
||||
select {
|
||||
case <-t:
|
||||
return
|
||||
default:
|
||||
t <- timeout
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
for {
|
||||
|
||||
select {
|
||||
case timeout := <-t:
|
||||
if timeout >= 20 && tmpSegment == 1 {
|
||||
cmd.Process.Kill()
|
||||
err = errors.New("Timout")
|
||||
ShowError(err, 4006)
|
||||
addErrorToStream(err)
|
||||
cmd.Wait()
|
||||
f.Close()
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
if fileSize == 0 && stream.Status == false {
|
||||
showInfo("Streaming Status:Receive data from " + bufferType)
|
||||
}
|
||||
|
||||
if clientConnection(stream) == false {
|
||||
cmd.Process.Kill()
|
||||
f.Close()
|
||||
cmd.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
n, err := reader.Read(buffer)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
fileSize = fileSize + len(buffer[:n])
|
||||
|
||||
if _, err := f.Write(buffer[:n]); err != nil {
|
||||
cmd.Process.Kill()
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
cmd.Wait()
|
||||
f.Close()
|
||||
return
|
||||
}
|
||||
|
||||
if fileSize >= bufferSize/2 {
|
||||
|
||||
if tmpSegment == 1 && stream.Status == false {
|
||||
close(t)
|
||||
close(streamStatus)
|
||||
showInfo(fmt.Sprintf("Streaming Status:Buffering data from %s", bufferType))
|
||||
}
|
||||
|
||||
f.Close()
|
||||
tmpSegment++
|
||||
|
||||
if stream.Status == false {
|
||||
Lock.Lock()
|
||||
stream.Status = true
|
||||
playlist.Streams[streamID] = stream
|
||||
BufferInformation.Store(playlistID, playlist)
|
||||
Lock.Unlock()
|
||||
}
|
||||
|
||||
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
|
||||
|
||||
fileSize = 0
|
||||
|
||||
var errCreate, errOpen error
|
||||
f, errCreate = os.Create(tmpFile)
|
||||
f, errOpen = os.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
|
||||
if errCreate != nil || errOpen != nil {
|
||||
cmd.Process.Kill()
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
cmd.Wait()
|
||||
f.Close()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
|
||||
err = errors.New(bufferType + " error")
|
||||
addErrorToStream(err)
|
||||
ShowError(err, 1204)
|
||||
|
||||
time.Sleep(time.Duration(500) * time.Millisecond)
|
||||
clientConnection(stream)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getTuner(id, playlistType string) (tuner int) {
|
||||
|
||||
switch Settings.Buffer {
|
||||
|
||||
case false:
|
||||
case "-":
|
||||
tuner = Settings.Tuner
|
||||
|
||||
case true:
|
||||
case "xteve", "ffmpeg", "vlc":
|
||||
|
||||
i, err := strconv.Atoi(getProviderParameter(id, playlistType, "tuner"))
|
||||
if err == nil {
|
||||
|
||||
@@ -146,3 +146,20 @@ func extractGZIP(gzipBody []byte, fileSource string) (body []byte, err error) {
|
||||
body = resB.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
func compressGZIP(data *[]byte, file string) (err error) {
|
||||
|
||||
if len(file) != 0 {
|
||||
|
||||
f, err := os.Create(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w := gzip.NewWriter(f)
|
||||
w.Write(*data)
|
||||
w.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+14
-4
@@ -15,7 +15,7 @@ var System SystemStruct
|
||||
var WebScreenLog WebScreenLogStruct
|
||||
|
||||
// Settings : Inhalt der settings.json
|
||||
var Settings SettingsStrcut
|
||||
var Settings SettingsStruct
|
||||
|
||||
// Data : Alle Daten werden hier abgelegt. (Lineup, XMLTV)
|
||||
var Data DataStruct
|
||||
@@ -29,6 +29,9 @@ var BufferInformation sync.Map
|
||||
// BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen
|
||||
var BufferClients sync.Map
|
||||
|
||||
// Lock : Lock Map
|
||||
var Lock = sync.RWMutex{}
|
||||
|
||||
// Init : Systeminitialisierung
|
||||
func Init() (err error) {
|
||||
|
||||
@@ -43,9 +46,14 @@ func Init() (err error) {
|
||||
System.ServerProtocol.M3U = "http"
|
||||
System.ServerProtocol.WEB = "http"
|
||||
System.ServerProtocol.XML = "http"
|
||||
System.DVRLimit = 480
|
||||
System.PlexChannelLimit = 480
|
||||
System.UnfilteredChannelLimit = 480
|
||||
System.Compatibility = "1.4.4"
|
||||
|
||||
// FFmpeg Default Einstellungen
|
||||
System.FFmpeg.DefaultOptions = "-hide_banner -loglevel error -i [URL] -c copy -f mpegts pipe:1"
|
||||
System.VLC.DefaultOptions = "-I dummy [URL] --sout #std{mux=ts,access=file,dst=-}"
|
||||
|
||||
// Default Logeinträge, wird später von denen aus der settings.json überschrieben. Muss gemacht werden, damit die ersten Einträge auch im Log (webUI aangezeigt werden)
|
||||
Settings.LogEntriesRAM = 500
|
||||
|
||||
@@ -91,6 +99,8 @@ func Init() (err error) {
|
||||
System.File.XML = getPlatformFile(fmt.Sprintf("%s%s.xml", System.Folder.Data, System.AppName))
|
||||
System.File.M3U = getPlatformFile(fmt.Sprintf("%s%s.m3u", System.Folder.Data, System.AppName))
|
||||
|
||||
System.Compressed.GZxml = getPlatformFile(fmt.Sprintf("%s%s.xml.gz", System.Folder.Data, System.AppName))
|
||||
|
||||
err = activatedSystemAuthentication()
|
||||
if err != nil {
|
||||
return
|
||||
@@ -133,7 +143,6 @@ func Init() (err error) {
|
||||
// Bedingte Update Änderungen durchführen
|
||||
err = conditionalUpdateChanges()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -221,7 +230,8 @@ func StartSystem(updateProviderFiles bool) (err error) {
|
||||
showInfo(fmt.Sprintf("UUID:%s", Settings.UUID))
|
||||
showInfo(fmt.Sprintf("Tuner (Plex / Emby):%d", Settings.Tuner))
|
||||
showInfo(fmt.Sprintf("EPG Source:%s", Settings.EpgSource))
|
||||
showInfo(fmt.Sprintf("Plex Channel Limit:%d", System.DVRLimit))
|
||||
showInfo(fmt.Sprintf("Plex Channel Limit:%d", System.PlexChannelLimit))
|
||||
showInfo(fmt.Sprintf("Unfiltered Chan. Limit:%d", System.UnfilteredChannelLimit))
|
||||
|
||||
// Providerdaten aktualisieren
|
||||
if len(Settings.Files.M3U) > 0 && Settings.FilesUpdate == true || updateProviderFiles == true {
|
||||
|
||||
+178
-65
@@ -11,19 +11,23 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"../src/internal/authentication"
|
||||
"xteve/src/internal/authentication"
|
||||
"xteve/src/internal/imgcache"
|
||||
)
|
||||
|
||||
// Einstellungen ändern (WebUI)
|
||||
func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
func updateServerSettings(request RequestStruct) (settings SettingsStruct, err error) {
|
||||
|
||||
var oldSettings = jsonToMap(mapToJSON(Settings))
|
||||
var newSettings = jsonToMap(mapToJSON(request.Settings))
|
||||
var reloadData = false
|
||||
var cacheImages = false
|
||||
var createXEPGFiles = false
|
||||
var triggerPlexGuideReload = false
|
||||
var debug string
|
||||
|
||||
// -vvv [URL] --sout '#transcode{vcodec=mp4v, acodec=mpga} :standard{access=http, mux=ogg}'
|
||||
|
||||
for key, value := range newSettings {
|
||||
|
||||
if _, ok := oldSettings[key]; ok {
|
||||
@@ -33,14 +37,29 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
case "tuner":
|
||||
showWarning(2105)
|
||||
|
||||
case "use_plexAPI":
|
||||
triggerPlexGuideReload = true
|
||||
|
||||
case "plex.url":
|
||||
if v, ok := value.(string); ok {
|
||||
value = strings.TrimRight(strings.TrimSpace(v), "/")
|
||||
}
|
||||
triggerPlexGuideReload = true
|
||||
|
||||
case "plex.token":
|
||||
if v, ok := value.(string); ok {
|
||||
value = strings.TrimSpace(v)
|
||||
}
|
||||
triggerPlexGuideReload = true
|
||||
|
||||
case "epgSource":
|
||||
reloadData = true
|
||||
|
||||
case "update":
|
||||
// Leerzeichen aus den Werten entfernen und Formatierung der Uhrzeit überprüfen (0000 - 2359)
|
||||
var newUpdateTimes []string
|
||||
var newUpdateTimes = make([]string, 0)
|
||||
|
||||
for _, v := range value.([]interface{}) {
|
||||
for _, v := range value.([]any) {
|
||||
|
||||
v = strings.Replace(v.(string), " ", "", -1)
|
||||
|
||||
@@ -54,6 +73,10 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
|
||||
}
|
||||
|
||||
if len(newUpdateTimes) == 0 {
|
||||
//newUpdateTimes = append(newUpdateTimes, "0000")
|
||||
}
|
||||
|
||||
value = newUpdateTimes
|
||||
|
||||
case "cache.images":
|
||||
@@ -62,6 +85,16 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
case "xepg.replace.missing.images":
|
||||
createXEPGFiles = true
|
||||
|
||||
case "xepg.missing.epg.mode":
|
||||
if v, ok := value.(string); ok {
|
||||
mode := strings.ToLower(strings.TrimSpace(v))
|
||||
if mode != "relaxed" {
|
||||
mode = "strict"
|
||||
}
|
||||
value = mode
|
||||
}
|
||||
reloadData = true
|
||||
|
||||
case "backup.path":
|
||||
value = strings.TrimRight(value.(string), string(os.PathSeparator)) + string(os.PathSeparator)
|
||||
err = checkFolder(value.(string))
|
||||
@@ -94,26 +127,44 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
return
|
||||
}
|
||||
|
||||
case "ffmpeg.path", "vlc.path":
|
||||
var path = value.(string)
|
||||
if len(path) > 0 {
|
||||
|
||||
err = checkFile(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case "scheme.m3u", "scheme.xml":
|
||||
createXEPGFiles = true
|
||||
|
||||
}
|
||||
|
||||
oldSettings[key] = value
|
||||
|
||||
switch fmt.Sprintf("%T", value) {
|
||||
if key == "plex.token" {
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: ******** (%T)", key, value)
|
||||
} else {
|
||||
switch fmt.Sprintf("%T", value) {
|
||||
|
||||
case "bool":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %t (%T)", key, value, value)
|
||||
case "bool":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %t (%T)", key, value, value)
|
||||
|
||||
case "string":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %s (%T)", key, value, value)
|
||||
case "string":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %s (%T)", key, value, value)
|
||||
|
||||
case "[]interface {}":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %v (%T)", key, value, value)
|
||||
case "[]interface {}":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %v (%T)", key, value, value)
|
||||
|
||||
case "float64":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %d (%T)", key, int(value.(float64)), value)
|
||||
case "float64":
|
||||
debug = fmt.Sprintf("Save Setting:Key: %s | Value: %d (%T)", key, int(value.(float64)), value)
|
||||
|
||||
default:
|
||||
debug = fmt.Sprintf("%T", value)
|
||||
default:
|
||||
debug = fmt.Sprintf("%T", value)
|
||||
}
|
||||
}
|
||||
|
||||
showDebug(debug, 1)
|
||||
@@ -138,6 +189,33 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
|
||||
}
|
||||
|
||||
// Buffer Einstellungen überprüfen
|
||||
if len(Settings.FFmpegOptions) == 0 {
|
||||
Settings.FFmpegOptions = System.FFmpeg.DefaultOptions
|
||||
}
|
||||
|
||||
if len(Settings.VLCOptions) == 0 {
|
||||
Settings.VLCOptions = System.VLC.DefaultOptions
|
||||
}
|
||||
|
||||
switch Settings.Buffer {
|
||||
|
||||
case "ffmpeg":
|
||||
|
||||
if len(Settings.FFmpegPath) == 0 {
|
||||
err = errors.New(getErrMsg(2020))
|
||||
return
|
||||
}
|
||||
|
||||
case "vlc":
|
||||
|
||||
if len(Settings.VLCPath) == 0 {
|
||||
err = errors.New(getErrMsg(2021))
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err == nil {
|
||||
|
||||
@@ -156,25 +234,38 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
|
||||
if cacheImages == true {
|
||||
|
||||
if Settings.EpgSource == "XEPG" {
|
||||
if Settings.EpgSource == "XEPG" && System.ImageCachingInProgress == 0 {
|
||||
|
||||
go func() {
|
||||
Data.Cache.Images, err = imgcache.New(System.Folder.ImagesCache, fmt.Sprintf("%s://%s/images/", System.ServerProtocol.WEB, System.Domain), Settings.CacheImages)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
}
|
||||
|
||||
if Settings.CacheImages == true {
|
||||
switch Settings.CacheImages {
|
||||
|
||||
createXMLTVFile()
|
||||
cachingImages()
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
case false:
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
|
||||
} else {
|
||||
case true:
|
||||
go func() {
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
|
||||
}
|
||||
System.ImageCachingInProgress = 1
|
||||
showInfo("Image Caching:Images are cached")
|
||||
|
||||
}()
|
||||
Data.Cache.Images.Image.Caching()
|
||||
showInfo("Image Caching:Done")
|
||||
|
||||
System.ImageCachingInProgress = 0
|
||||
|
||||
buildXEPG(false)
|
||||
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -189,6 +280,10 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
|
||||
}
|
||||
|
||||
if triggerPlexGuideReload == true {
|
||||
queuePlexGuideRefresh("settings change")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
@@ -197,8 +292,8 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
|
||||
// Providerdaten speichern (WebUI)
|
||||
func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
var filesMap = make(map[string]interface{})
|
||||
var newData = make(map[string]interface{})
|
||||
var filesMap = make(map[string]any)
|
||||
var newData = make(map[string]any)
|
||||
var indicator string
|
||||
var reloadData = false
|
||||
|
||||
@@ -220,7 +315,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
}
|
||||
|
||||
if len(filesMap) == 0 {
|
||||
filesMap = make(map[string]interface{})
|
||||
filesMap = make(map[string]any)
|
||||
}
|
||||
|
||||
for dataID, data := range newData {
|
||||
@@ -229,15 +324,15 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
// Neue Providerdatei
|
||||
dataID = indicator + randomString(19)
|
||||
data.(map[string]interface{})["new"] = true
|
||||
data.(map[string]any)["new"] = true
|
||||
filesMap[dataID] = data
|
||||
|
||||
} else {
|
||||
|
||||
// Bereits vorhandene Providerdatei
|
||||
for key, value := range data.(map[string]interface{}) {
|
||||
for key, value := range data.(map[string]any) {
|
||||
|
||||
var oldData = filesMap[dataID].(map[string]interface{})
|
||||
var oldData = filesMap[dataID].(map[string]any)
|
||||
oldData[key] = value
|
||||
|
||||
}
|
||||
@@ -258,11 +353,11 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
}
|
||||
|
||||
// Neue Providerdatei
|
||||
if _, ok := data.(map[string]interface{})["new"]; ok {
|
||||
if _, ok := data.(map[string]any)["new"]; ok {
|
||||
|
||||
reloadData = true
|
||||
err = getProviderData(fileType, dataID)
|
||||
delete(data.(map[string]interface{}), "new")
|
||||
delete(data.(map[string]any), "new")
|
||||
|
||||
if err != nil {
|
||||
delete(filesMap, dataID)
|
||||
@@ -271,7 +366,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
}
|
||||
|
||||
if _, ok := data.(map[string]interface{})["delete"]; ok {
|
||||
if _, ok := data.(map[string]any)["delete"]; ok {
|
||||
|
||||
deleteLocalProviderFiles(dataID, fileType)
|
||||
reloadData = true
|
||||
@@ -304,7 +399,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
|
||||
// Providerdaten manuell aktualisieren (WebUI)
|
||||
func updateFile(request RequestStruct, fileType string) (err error) {
|
||||
|
||||
var updateData = make(map[string]interface{})
|
||||
var updateData = make(map[string]any)
|
||||
|
||||
switch fileType {
|
||||
|
||||
@@ -334,7 +429,7 @@ func updateFile(request RequestStruct, fileType string) (err error) {
|
||||
// Providerdaten löschen (WebUI)
|
||||
func deleteLocalProviderFiles(dataID, fileType string) {
|
||||
|
||||
var removeData = make(map[string]interface{})
|
||||
var removeData = make(map[string]any)
|
||||
var fileExtension string
|
||||
|
||||
switch fileType {
|
||||
@@ -361,10 +456,10 @@ func deleteLocalProviderFiles(dataID, fileType string) {
|
||||
}
|
||||
|
||||
// Filtereinstellungen speichern (WebUI)
|
||||
func saveFilter(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
|
||||
|
||||
var filterMap = make(map[int64]interface{})
|
||||
var newData = make(map[int64]interface{})
|
||||
var filterMap = make(map[int64]any)
|
||||
var newData = make(map[int64]any)
|
||||
var defaultFilter FilterStruct
|
||||
var newFilter = false
|
||||
|
||||
@@ -397,15 +492,15 @@ func saveFilter(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
}
|
||||
|
||||
// Filter aktualisieren / löschen
|
||||
for key, value := range data.(map[string]interface{}) {
|
||||
for key, value := range data.(map[string]any) {
|
||||
|
||||
// Filter löschen
|
||||
if _, ok := data.(map[string]interface{})["delete"]; ok {
|
||||
if _, ok := data.(map[string]any)["delete"]; ok {
|
||||
delete(filterMap, dataID)
|
||||
break
|
||||
}
|
||||
|
||||
if filter, ok := data.(map[string]interface{})["filter"].(string); ok {
|
||||
if filter, ok := data.(map[string]any)["filter"].(string); ok {
|
||||
|
||||
if len(filter) == 0 {
|
||||
|
||||
@@ -419,7 +514,7 @@ func saveFilter(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
|
||||
}
|
||||
|
||||
if oldData, ok := filterMap[dataID].(map[string]interface{}); ok {
|
||||
if oldData, ok := filterMap[dataID].(map[string]any); ok {
|
||||
oldData[key] = value
|
||||
}
|
||||
|
||||
@@ -449,6 +544,11 @@ func saveXEpgMapping(request RequestStruct) (err error) {
|
||||
|
||||
var tmp = Data.XEPG
|
||||
|
||||
Data.Cache.Images, err = imgcache.New(System.Folder.ImagesCache, fmt.Sprintf("%s://%s/images/", System.ServerProtocol.WEB, System.Domain), Settings.CacheImages)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(mapToJSON(request.EpgMapping)), &tmp)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -463,7 +563,9 @@ func saveXEpgMapping(request RequestStruct) (err error) {
|
||||
|
||||
if System.ScanInProgress == 0 {
|
||||
|
||||
System.ScanInProgress = 1
|
||||
cleanupXEPG()
|
||||
System.ScanInProgress = 0
|
||||
buildXEPG(true)
|
||||
|
||||
} else {
|
||||
@@ -485,8 +587,11 @@ func saveXEpgMapping(request RequestStruct) (err error) {
|
||||
|
||||
}
|
||||
|
||||
System.ScanInProgress = 1
|
||||
cleanupXEPG()
|
||||
System.ScanInProgress = 0
|
||||
buildXEPG(false)
|
||||
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
||||
|
||||
System.BackgroundProcess = false
|
||||
|
||||
@@ -502,7 +607,7 @@ func saveUserData(request RequestStruct) (err error) {
|
||||
|
||||
var userData = request.UserData
|
||||
|
||||
var newCredentials = func(userID string, newUserData map[string]interface{}) (err error) {
|
||||
var newCredentials = func(userID string, newUserData map[string]any) (err error) {
|
||||
|
||||
var newUsername, newPassword string
|
||||
if username, ok := newUserData["username"].(string); ok {
|
||||
@@ -522,7 +627,7 @@ func saveUserData(request RequestStruct) (err error) {
|
||||
|
||||
for userID, newUserData := range userData {
|
||||
|
||||
err = newCredentials(userID, newUserData.(map[string]interface{}))
|
||||
err = newCredentials(userID, newUserData.(map[string]any))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -532,16 +637,16 @@ func saveUserData(request RequestStruct) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
delete(newUserData.(map[string]interface{}), "password")
|
||||
delete(newUserData.(map[string]interface{}), "confirm")
|
||||
delete(newUserData.(map[string]any), "password")
|
||||
delete(newUserData.(map[string]any), "confirm")
|
||||
|
||||
if _, ok := newUserData.(map[string]interface{})["delete"]; ok {
|
||||
if _, ok := newUserData.(map[string]any)["delete"]; ok {
|
||||
|
||||
authentication.RemoveUser(userID)
|
||||
|
||||
} else {
|
||||
|
||||
err = authentication.WriteUserData(userID, newUserData.(map[string]interface{}))
|
||||
err = authentication.WriteUserData(userID, newUserData.(map[string]any))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -591,11 +696,11 @@ func saveWizard(request RequestStruct) (nextStep int, err error) {
|
||||
|
||||
case "m3u", "xmltv":
|
||||
|
||||
var filesMap = make(map[string]interface{})
|
||||
var data = make(map[string]interface{})
|
||||
var filesMap = make(map[string]any)
|
||||
var data = make(map[string]any)
|
||||
var indicator, dataID string
|
||||
|
||||
filesMap = make(map[string]interface{})
|
||||
filesMap = make(map[string]any)
|
||||
|
||||
data["type"] = key
|
||||
data["new"] = true
|
||||
@@ -666,6 +771,10 @@ func saveWizard(request RequestStruct) (nextStep int, err error) {
|
||||
|
||||
}
|
||||
|
||||
if nextStep == 10 {
|
||||
Settings.WizardCompleted = true
|
||||
}
|
||||
|
||||
err = saveSettings(Settings)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -726,9 +835,9 @@ func buildDatabaseDVR() (err error) {
|
||||
|
||||
System.ScanInProgress = 1
|
||||
|
||||
Data.Streams.All = make([]interface{}, 0)
|
||||
Data.Streams.Active = make([]interface{}, 0)
|
||||
Data.Streams.Inactive = make([]interface{}, 0)
|
||||
Data.Streams.All = make([]any, 0, System.UnfilteredChannelLimit)
|
||||
Data.Streams.Active = make([]any, 0, System.UnfilteredChannelLimit)
|
||||
Data.Streams.Inactive = make([]any, 0, System.UnfilteredChannelLimit)
|
||||
Data.Playlist.M3U.Groups.Text = []string{}
|
||||
Data.Playlist.M3U.Groups.Value = []string{}
|
||||
Data.StreamPreviewUI.Active = []string{}
|
||||
@@ -749,7 +858,7 @@ func buildDatabaseDVR() (err error) {
|
||||
|
||||
for n, i := range playlistFile {
|
||||
|
||||
var channels []interface{}
|
||||
var channels []any
|
||||
var groupTitle, tvgID, uuid int = 0, 0, 0
|
||||
var keys = []string{"group-title", "tvg-id", "uuid"}
|
||||
var compatibility = make(map[string]int)
|
||||
@@ -884,20 +993,20 @@ func buildDatabaseDVR() (err error) {
|
||||
sort.Strings(Data.Playlist.M3U.Groups.Text)
|
||||
sort.Strings(Data.Playlist.M3U.Groups.Value)
|
||||
|
||||
if len(Data.Streams.Active) == 0 && len(Data.Streams.All) <= System.DVRLimit && len(Settings.Filter) == 0 {
|
||||
if len(Data.Streams.Active) == 0 && len(Data.Streams.All) <= System.UnfilteredChannelLimit && len(Settings.Filter) == 0 {
|
||||
Data.Streams.Active = Data.Streams.All
|
||||
Data.Streams.Inactive = make([]interface{}, 0)
|
||||
Data.Streams.Inactive = make([]any, 0)
|
||||
|
||||
Data.StreamPreviewUI.Active = Data.StreamPreviewUI.Inactive
|
||||
Data.StreamPreviewUI.Inactive = []string{}
|
||||
|
||||
}
|
||||
|
||||
if len(Data.Streams.Active) > System.DVRLimit {
|
||||
if len(Data.Streams.Active) > System.PlexChannelLimit {
|
||||
showWarning(2000)
|
||||
}
|
||||
|
||||
if len(Settings.Filter) == 0 && len(Data.Streams.All) > System.DVRLimit {
|
||||
if len(Settings.Filter) == 0 && len(Data.Streams.All) > System.UnfilteredChannelLimit {
|
||||
showWarning(2001)
|
||||
}
|
||||
|
||||
@@ -909,6 +1018,10 @@ func buildDatabaseDVR() (err error) {
|
||||
sort.Strings(Data.StreamPreviewUI.Active)
|
||||
sort.Strings(Data.StreamPreviewUI.Inactive)
|
||||
|
||||
if Settings.EpgSource != "XEPG" {
|
||||
queuePlexGuideRefresh("lineup update")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -916,7 +1029,7 @@ func buildDatabaseDVR() (err error) {
|
||||
func getLocalProviderFiles(fileType string) (localFiles []string) {
|
||||
|
||||
var fileExtension string
|
||||
var dataMap = make(map[string]interface{})
|
||||
var dataMap = make(map[string]any)
|
||||
|
||||
switch fileType {
|
||||
|
||||
@@ -944,7 +1057,7 @@ func getLocalProviderFiles(fileType string) (localFiles []string) {
|
||||
// Providerparameter anhand von dem Key ausgeben
|
||||
func getProviderParameter(id, fileType, key string) (s string) {
|
||||
|
||||
var dataMap = make(map[string]interface{})
|
||||
var dataMap = make(map[string]any)
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
@@ -957,7 +1070,7 @@ func getProviderParameter(id, fileType, key string) (s string) {
|
||||
dataMap = Settings.Files.XMLTV
|
||||
}
|
||||
|
||||
if data, ok := dataMap[id].(map[string]interface{}); ok {
|
||||
if data, ok := dataMap[id].(map[string]any); ok {
|
||||
|
||||
if v, ok := data[key].(string); ok {
|
||||
s = v
|
||||
@@ -975,7 +1088,7 @@ func getProviderParameter(id, fileType, key string) (s string) {
|
||||
// Provider Statistiken Kompatibilität aktualisieren
|
||||
func setProviderCompatibility(id, fileType string, compatibility map[string]int) {
|
||||
|
||||
var dataMap = make(map[string]interface{})
|
||||
var dataMap = make(map[string]any)
|
||||
|
||||
switch fileType {
|
||||
case "m3u":
|
||||
@@ -988,7 +1101,7 @@ func setProviderCompatibility(id, fileType string, compatibility map[string]int)
|
||||
dataMap = Settings.Files.XMLTV
|
||||
}
|
||||
|
||||
if data, ok := dataMap[id].(map[string]interface{}); ok {
|
||||
if data, ok := dataMap[id].(map[string]any); ok {
|
||||
|
||||
data["compatibility"] = compatibility
|
||||
|
||||
|
||||
+3
-3
@@ -7,9 +7,9 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func makeInteraceFromHDHR(content []byte, playlistName, id string) (channels []interface{}, err error) {
|
||||
func makeInteraceFromHDHR(content []byte, playlistName, id string) (channels []any, err error) {
|
||||
|
||||
var hdhrData []interface{}
|
||||
var hdhrData []any
|
||||
|
||||
err = json.Unmarshal(content, &hdhrData)
|
||||
if err == nil {
|
||||
@@ -17,7 +17,7 @@ func makeInteraceFromHDHR(content []byte, playlistName, id string) (channels []i
|
||||
for _, d := range hdhrData {
|
||||
|
||||
var channel = make(map[string]string)
|
||||
var data = d.(map[string]interface{})
|
||||
var data = d.(map[string]any)
|
||||
|
||||
channel["group-title"] = playlistName
|
||||
channel["name"] = data["GuideName"].(string)
|
||||
|
||||
+5
-4
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var htmlFolder string
|
||||
@@ -16,7 +17,7 @@ var goFile string
|
||||
var mapName string
|
||||
var packageName string
|
||||
|
||||
var blankMap = make(map[string]interface{})
|
||||
var blankMap = make(map[string]any)
|
||||
|
||||
// HTMLInit : Dateipfade festlegen
|
||||
// mapName = Name der zu erstellenden map
|
||||
@@ -68,14 +69,14 @@ func createMapFromFiles(folder string) string {
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
var content string
|
||||
var content strings.Builder
|
||||
|
||||
for key := range blankMap {
|
||||
var newKey = key
|
||||
content += ` ` + mapName + `["` + newKey + `"` + `] = "` + blankMap[key].(string) + `"` + "\n"
|
||||
content.WriteString(` ` + mapName + `["` + newKey + `"` + `] = "` + blankMap[key].(string) + `"` + "\n")
|
||||
}
|
||||
|
||||
return content
|
||||
return content.String()
|
||||
}
|
||||
|
||||
func readFilesToMap(path string, info os.FileInfo, err error) error {
|
||||
|
||||
+1
-141
@@ -3,155 +3,15 @@ package src
|
||||
import (
|
||||
b64 "encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getCacheImageURL(imageURL string) (cacheImageURL string) {
|
||||
|
||||
if Settings.CacheImages == false {
|
||||
return imageURL
|
||||
}
|
||||
|
||||
imageURL = strings.Trim(imageURL, "\r\n")
|
||||
|
||||
p, err := url.Parse(imageURL)
|
||||
if err != nil {
|
||||
// URL konnte nicht geparst werden, die ursprüngliche image url wird zurückgegeben
|
||||
showInfo(fmt.Sprintf("Image Caching:Image URL: %s", imageURL))
|
||||
showWarning(4101)
|
||||
return imageURL
|
||||
}
|
||||
var urlMD5 = getMD5(imageURL)
|
||||
var fileExtension = filepath.Ext(p.Path)
|
||||
|
||||
if len(fileExtension) == 0 {
|
||||
// Keine Dateierweiterung vorhanden, die ursprüngliche image url wird zurückgegeben
|
||||
return imageURL
|
||||
}
|
||||
|
||||
if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesFiles) == -1 {
|
||||
Data.Cache.ImagesFiles = append(Data.Cache.ImagesFiles, urlMD5+fileExtension)
|
||||
}
|
||||
|
||||
if System.ImageCachingInProgress == 1 {
|
||||
return imageURL
|
||||
}
|
||||
|
||||
if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesCache) != -1 {
|
||||
|
||||
cacheImageURL = fmt.Sprintf("%s://%s/images/%s%s", System.ServerProtocol.WEB, System.Domain, urlMD5, fileExtension)
|
||||
|
||||
} else {
|
||||
|
||||
if strings.Contains(imageURL, System.Domain+"/images/") == false {
|
||||
|
||||
if indexOfString(imageURL, Data.Cache.ImagesURLS) == -1 {
|
||||
Data.Cache.ImagesURLS = append(Data.Cache.ImagesURLS, imageURL)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cacheImageURL = imageURL
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func cachingImages() {
|
||||
|
||||
if Settings.CacheImages == false || System.ImageCachingInProgress == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
System.ImageCachingInProgress = 1
|
||||
|
||||
showInfo("Image Caching:Images are cached")
|
||||
|
||||
for _, imageURL := range Data.Cache.ImagesURLS {
|
||||
|
||||
if len(imageURL) > 0 {
|
||||
cacheImage(imageURL)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
showInfo("Image Caching:Done")
|
||||
|
||||
// Bilder die nicht mehr verwendet werden, werden gelöscht
|
||||
files, err := ioutil.ReadDir(System.Folder.ImagesCache)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
|
||||
if indexOfString(file.Name(), Data.Cache.ImagesFiles) == -1 {
|
||||
|
||||
var debug = fmt.Sprintf("Image Caching:Remove file: %s %s %d", System.Folder.ImagesCache+file.Name(), file.Name(), len(file.Name()))
|
||||
showDebug(debug, 1)
|
||||
err := os.RemoveAll(System.Folder.ImagesCache + file.Name())
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
System.ImageCachingInProgress = 0
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func cacheImage(imageURL string) {
|
||||
|
||||
var debug string
|
||||
var urlMD5 = getMD5(imageURL)
|
||||
var fileExtension = filepath.Ext(imageURL)
|
||||
|
||||
debug = fmt.Sprintf("Image Caching:File: %s Download: %s", urlMD5+fileExtension, imageURL)
|
||||
showDebug(debug, 1)
|
||||
|
||||
resp, err := http.Get(imageURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
var filePath = System.Folder.ImagesCache + urlMD5 + fileExtension
|
||||
|
||||
// Datei speichern
|
||||
file, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func uploadLogo(input, filename string) (logoURL string, err error) {
|
||||
|
||||
b64data := input[strings.IndexByte(input, ',')+1:]
|
||||
|
||||
// BAse64 in bytes umwandeln un speichern
|
||||
sDec, err := b64.StdEncoding.DecodeString(b64data)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -163,7 +23,7 @@ func uploadLogo(input, filename string) (logoURL string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.WEB, System.Domain, filename)
|
||||
logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.XML, System.Domain, filename)
|
||||
|
||||
return
|
||||
|
||||
|
||||
+67
-65
@@ -1,99 +1,101 @@
|
||||
package src
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ShowSystemInfo : Systeminformationen anzeigen
|
||||
func ShowSystemInfo() {
|
||||
|
||||
fmt.Print("Creating the information takes a moment...")
|
||||
err := buildDatabaseDVR()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return
|
||||
}
|
||||
fmt.Print("Creating the information takes a moment...")
|
||||
err := buildDatabaseDVR()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return
|
||||
}
|
||||
|
||||
buildXEPG(false)
|
||||
buildXEPG(false)
|
||||
|
||||
fmt.Println("OK")
|
||||
println()
|
||||
fmt.Println("OK")
|
||||
println()
|
||||
|
||||
fmt.Println(fmt.Sprintf("Version: %s %s.%s", System.Name, System.Version, System.Build))
|
||||
fmt.Println(fmt.Sprintf("Branch: %s", System.Branch))
|
||||
fmt.Println(fmt.Sprintf("GitHub: %s/%s | Git update = %t", System.GitHub.User, System.GitHub.Repo, System.GitHub.Update))
|
||||
fmt.Println(fmt.Sprintf("Folder (config): %s", System.Folder.Config))
|
||||
fmt.Println(fmt.Sprintf("Version: %s %s.%s", System.Name, System.Version, System.Build))
|
||||
fmt.Println(fmt.Sprintf("Branch: %s", System.Branch))
|
||||
fmt.Println(fmt.Sprintf("GitHub: %s/%s | Git update = %t", System.GitHub.User, System.GitHub.Repo, System.GitHub.Update))
|
||||
fmt.Println(fmt.Sprintf("Folder (config): %s", System.Folder.Config))
|
||||
|
||||
fmt.Println(fmt.Sprintf("Streams: %d / %d", len(Data.Streams.Active), len(Data.Streams.All)))
|
||||
fmt.Println(fmt.Sprintf("Filter: %d", len(Data.Filter)))
|
||||
fmt.Println(fmt.Sprintf("XEPG Chanels: %d", int(Data.XEPG.XEPGCount)))
|
||||
fmt.Println(fmt.Sprintf("Streams: %d / %d", len(Data.Streams.Active), len(Data.Streams.All)))
|
||||
fmt.Println(fmt.Sprintf("Filter: %d", len(Data.Filter)))
|
||||
fmt.Println(fmt.Sprintf("XEPG Chanels: %d", int(Data.XEPG.XEPGCount)))
|
||||
|
||||
println()
|
||||
fmt.Println(fmt.Sprintf("IPv4 Addresses:"))
|
||||
println()
|
||||
fmt.Println(fmt.Sprintf("IPv4 Addresses:"))
|
||||
|
||||
for i, ipv4 := range System.IPAddressesV4 {
|
||||
for i, ipv4 := range System.IPAddressesV4 {
|
||||
|
||||
switch count := i; {
|
||||
switch count := i; {
|
||||
|
||||
case count < 10:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 100:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 10:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 100:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
println()
|
||||
fmt.Println(fmt.Sprintf("IPv6 Addresses:"))
|
||||
println()
|
||||
fmt.Println(fmt.Sprintf("IPv6 Addresses:"))
|
||||
|
||||
for i, ipv4 := range System.IPAddressesV6 {
|
||||
for i, ipv4 := range System.IPAddressesV6 {
|
||||
|
||||
switch count := i; {
|
||||
switch count := i; {
|
||||
|
||||
case count < 10:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 100:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 10:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
case count < 100:
|
||||
fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
println("---")
|
||||
println("---")
|
||||
|
||||
fmt.Println("Settings [General]")
|
||||
fmt.Println(fmt.Sprintf("xTeVe Update: %t", Settings.XteveAutoUpdate))
|
||||
fmt.Println(fmt.Sprintf("UUID: %s", Settings.UUID))
|
||||
fmt.Println(fmt.Sprintf("Tuner (Plex / Emby): %d", Settings.Tuner))
|
||||
fmt.Println(fmt.Sprintf("EPG Source: %s", Settings.EpgSource))
|
||||
fmt.Println("Settings [General]")
|
||||
fmt.Println(fmt.Sprintf("xTeVe Update: %t", Settings.XteveAutoUpdate))
|
||||
fmt.Println(fmt.Sprintf("UUID: %s", Settings.UUID))
|
||||
fmt.Println(fmt.Sprintf("Tuner (Plex / Emby): %d", Settings.Tuner))
|
||||
fmt.Println(fmt.Sprintf("EPG Source: %s", Settings.EpgSource))
|
||||
|
||||
println("---")
|
||||
println("---")
|
||||
|
||||
fmt.Println("Settings [Files]")
|
||||
fmt.Println(fmt.Sprintf("Schedule: %s", strings.Join(Settings.Update, ",")))
|
||||
fmt.Println(fmt.Sprintf("Files Update: %t", Settings.FilesUpdate))
|
||||
fmt.Println(fmt.Sprintf("Folder (tmp): %s", Settings.TempPath))
|
||||
fmt.Println(fmt.Sprintf("Image Chaching: %t", Settings.CacheImages))
|
||||
fmt.Println(fmt.Sprintf("Replace EPG Image: %t", Settings.XepgReplaceMissingImages))
|
||||
fmt.Println("Settings [Files]")
|
||||
fmt.Println(fmt.Sprintf("Schedule: %s", strings.Join(Settings.Update, ",")))
|
||||
fmt.Println(fmt.Sprintf("Files Update: %t", Settings.FilesUpdate))
|
||||
fmt.Println(fmt.Sprintf("Folder (tmp): %s", Settings.TempPath))
|
||||
fmt.Println(fmt.Sprintf("Image Chaching: %t", Settings.CacheImages))
|
||||
fmt.Println(fmt.Sprintf("Missing EPG Mode: %s", Settings.XepgMissingEPGMode))
|
||||
fmt.Println(fmt.Sprintf("Replace EPG Image: %t", Settings.XepgReplaceMissingImages))
|
||||
|
||||
println("---")
|
||||
println("---")
|
||||
|
||||
fmt.Println("Settings [Streaming]")
|
||||
fmt.Println(fmt.Sprintf("Buffer: %t", Settings.Buffer))
|
||||
fmt.Println(fmt.Sprintf("Buffer Size: %d KB", Settings.BufferSize))
|
||||
fmt.Println(fmt.Sprintf("Timeout: %d ms", int(Settings.BufferTimeout)))
|
||||
fmt.Println(fmt.Sprintf("User Agent: %s", Settings.UserAgent))
|
||||
fmt.Println("Settings [Streaming]")
|
||||
fmt.Println(fmt.Sprintf("Buffer: %s", Settings.Buffer))
|
||||
fmt.Println(fmt.Sprintf("UDPxy: %s", Settings.UDPxy))
|
||||
fmt.Println(fmt.Sprintf("Buffer Size: %d KB", Settings.BufferSize))
|
||||
fmt.Println(fmt.Sprintf("Timeout: %d ms", int(Settings.BufferTimeout)))
|
||||
fmt.Println(fmt.Sprintf("User Agent: %s", Settings.UserAgent))
|
||||
|
||||
println("---")
|
||||
println("---")
|
||||
|
||||
fmt.Println("Settings [Backup]")
|
||||
fmt.Println(fmt.Sprintf("Folder (backup): %s", Settings.BackupPath))
|
||||
fmt.Println(fmt.Sprintf("Backup Keep: %d", Settings.BackupKeep))
|
||||
fmt.Println("Settings [Backup]")
|
||||
fmt.Println(fmt.Sprintf("Folder (backup): %s", Settings.BackupPath))
|
||||
fmt.Println(fmt.Sprintf("Backup Keep: %d", Settings.BackupKeep))
|
||||
|
||||
}
|
||||
@@ -1,21 +1,22 @@
|
||||
package authentication
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
|
||||
"time"
|
||||
//"fmt"
|
||||
//"log"
|
||||
"time"
|
||||
//"fmt"
|
||||
//"log"
|
||||
)
|
||||
|
||||
const tokenLength = 40
|
||||
@@ -27,19 +28,20 @@ var database string
|
||||
|
||||
var databaseFile = "authentication.json"
|
||||
|
||||
var data = make(map[string]interface{})
|
||||
var tokens = make(map[string]interface{})
|
||||
var data = make(map[string]any)
|
||||
var tokens = make(map[string]any)
|
||||
var tokensMu sync.RWMutex
|
||||
|
||||
var initAuthentication = false
|
||||
|
||||
// Cookie : cookie
|
||||
type Cookie struct {
|
||||
Name string
|
||||
Value string
|
||||
Path string
|
||||
Domain string
|
||||
Expires time.Time
|
||||
RawExpires string
|
||||
Name string
|
||||
Value string
|
||||
Path string
|
||||
Domain string
|
||||
Expires time.Time
|
||||
RawExpires string
|
||||
}
|
||||
|
||||
// Framework examples
|
||||
@@ -128,465 +130,475 @@ func main() {
|
||||
|
||||
// Init : databasePath = Path to authentication.json
|
||||
func Init(databasePath string, validity int) (err error) {
|
||||
database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
|
||||
database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
|
||||
|
||||
// Check if the database already exists
|
||||
if _, err = os.Stat(database); os.IsNotExist(err) {
|
||||
// Create an empty database
|
||||
var defaults = make(map[string]interface{})
|
||||
defaults["dbVersion"] = "1.0"
|
||||
defaults["hash"] = "sha256"
|
||||
defaults["users"] = make(map[string]interface{})
|
||||
// Check if the database already exists
|
||||
if _, err = os.Stat(database); os.IsNotExist(err) {
|
||||
// Create an empty database
|
||||
var defaults = make(map[string]any)
|
||||
defaults["dbVersion"] = "1.0"
|
||||
defaults["hash"] = "sha256"
|
||||
defaults["users"] = make(map[string]any)
|
||||
|
||||
if saveDatabase(defaults) != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if saveDatabase(defaults) != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Loading the database
|
||||
err = loadDatabase()
|
||||
// Loading the database
|
||||
err = loadDatabase()
|
||||
|
||||
// Set Token Validity
|
||||
tokenValidity = validity
|
||||
initAuthentication = true
|
||||
return
|
||||
// Set Token Validity
|
||||
tokenValidity = validity
|
||||
initAuthentication = true
|
||||
return
|
||||
}
|
||||
|
||||
// CreateDefaultUser = created efault user
|
||||
func CreateDefaultUser(username, password string) (err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var users = data["users"].(map[string]interface{})
|
||||
// Check if the default user exists
|
||||
if len(users) > 0 {
|
||||
err = createError(001)
|
||||
return
|
||||
}
|
||||
var users = data["users"].(map[string]any)
|
||||
// Check if the default user exists
|
||||
if len(users) > 0 {
|
||||
err = createError(001)
|
||||
return
|
||||
}
|
||||
|
||||
var defaults = defaultsForNewUser(username, password)
|
||||
users[defaults["_id"].(string)] = defaults
|
||||
saveDatabase(data)
|
||||
var defaults = defaultsForNewUser(username, password)
|
||||
users[defaults["_id"].(string)] = defaults
|
||||
saveDatabase(data)
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// CreateNewUser : create new user
|
||||
func CreateNewUser(username, password string) (userID string, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var checkIfTheUserAlreadyExists = func(username string, userData map[string]interface{}) (err error) {
|
||||
var salt = userData["_salt"].(string)
|
||||
var loginUsername = userData["_username"].(string)
|
||||
var checkIfTheUserAlreadyExists = func(username string, userData map[string]any) (err error) {
|
||||
var salt = userData["_salt"].(string)
|
||||
var loginUsername = userData["_username"].(string)
|
||||
|
||||
if SHA256(username, salt) == loginUsername {
|
||||
err = createError(020)
|
||||
}
|
||||
if SHA256(username, salt) == loginUsername {
|
||||
err = createError(020)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var users = data["users"].(map[string]interface{})
|
||||
for _, userData := range users {
|
||||
err = checkIfTheUserAlreadyExists(username, userData.(map[string]interface{}))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
var users = data["users"].(map[string]any)
|
||||
for _, userData := range users {
|
||||
err = checkIfTheUserAlreadyExists(username, userData.(map[string]any))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var defaults = defaultsForNewUser(username, password)
|
||||
userID = defaults["_id"].(string)
|
||||
users[userID] = defaults
|
||||
var defaults = defaultsForNewUser(username, password)
|
||||
userID = defaults["_id"].(string)
|
||||
users[userID] = defaults
|
||||
|
||||
saveDatabase(data)
|
||||
saveDatabase(data)
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// UserAuthentication : user authentication
|
||||
func UserAuthentication(username, password string) (token string, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var login = func(username, password string, loginData map[string]interface{}) (err error) {
|
||||
err = createError(010)
|
||||
var login = func(username, password string, loginData map[string]any) (err error) {
|
||||
err = createError(010)
|
||||
|
||||
var salt = loginData["_salt"].(string)
|
||||
var loginUsername = loginData["_username"].(string)
|
||||
var loginPassword = loginData["_password"].(string)
|
||||
var salt = loginData["_salt"].(string)
|
||||
var loginUsername = loginData["_username"].(string)
|
||||
var loginPassword = loginData["_password"].(string)
|
||||
|
||||
if SHA256(username, salt) == loginUsername {
|
||||
if SHA256(password, salt) == loginPassword {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if SHA256(username, salt) == loginUsername {
|
||||
if SHA256(password, salt) == loginPassword {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var users = data["users"].(map[string]interface{})
|
||||
for id, loginData := range users {
|
||||
err = login(username, password, loginData.(map[string]interface{}))
|
||||
if err == nil {
|
||||
token = setToken(id, "-")
|
||||
return
|
||||
}
|
||||
}
|
||||
var users = data["users"].(map[string]any)
|
||||
for id, loginData := range users {
|
||||
err = login(username, password, loginData.(map[string]any))
|
||||
if err == nil {
|
||||
token = setToken(id, "-")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// CheckTheValidityOfTheToken : check token
|
||||
func CheckTheValidityOfTheToken(token string) (newToken string, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(011)
|
||||
err = createError(011)
|
||||
|
||||
if v, ok := tokens[token]; ok {
|
||||
var expires = v.(map[string]interface{})["expires"].(time.Time)
|
||||
var userID = v.(map[string]interface{})["id"].(string)
|
||||
tokensMu.Lock()
|
||||
defer tokensMu.Unlock()
|
||||
|
||||
if expires.Sub(time.Now().Local()) < 0 {
|
||||
return
|
||||
}
|
||||
if v, ok := tokens[token]; ok {
|
||||
expires := v.(map[string]any)["expires"].(time.Time)
|
||||
|
||||
newToken = setToken(userID, token)
|
||||
if expires.Sub(time.Now().Local()) < 0 {
|
||||
delete(tokens, token)
|
||||
return
|
||||
}
|
||||
|
||||
err = nil
|
||||
// Keep a stable token per session and only refresh expiration.
|
||||
v.(map[string]any)["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
|
||||
newToken = token
|
||||
err = nil
|
||||
}
|
||||
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserID : get user ID
|
||||
func GetUserID(token string) (userID string, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(002)
|
||||
err = createError(002)
|
||||
|
||||
if v, ok := tokens[token]; ok {
|
||||
var expires = v.(map[string]interface{})["expires"].(time.Time)
|
||||
userID = v.(map[string]interface{})["id"].(string)
|
||||
tokensMu.Lock()
|
||||
defer tokensMu.Unlock()
|
||||
|
||||
if expires.Sub(time.Now().Local()) < 0 {
|
||||
return
|
||||
}
|
||||
if v, ok := tokens[token]; ok {
|
||||
expires := v.(map[string]any)["expires"].(time.Time)
|
||||
userID = v.(map[string]any)["id"].(string)
|
||||
|
||||
err = nil
|
||||
}
|
||||
if expires.Sub(time.Now().Local()) < 0 {
|
||||
delete(tokens, token)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
err = nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// WriteUserData : save user date
|
||||
func WriteUserData(userID string, userData map[string]interface{}) (err error) {
|
||||
func WriteUserData(userID string, userData map[string]any) (err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(030)
|
||||
err = createError(030)
|
||||
|
||||
if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
|
||||
if v, ok := data["users"].(map[string]any)[userID].(map[string]any); ok {
|
||||
|
||||
v["data"] = userData
|
||||
err = saveDatabase(data)
|
||||
v["data"] = userData
|
||||
err = saveDatabase(data)
|
||||
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// ReadUserData : load user date
|
||||
func ReadUserData(userID string) (userData map[string]interface{}, err error) {
|
||||
func ReadUserData(userID string) (userData map[string]any, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(031)
|
||||
err = createError(031)
|
||||
|
||||
if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
|
||||
userData = v["data"].(map[string]interface{})
|
||||
err = nil
|
||||
if v, ok := data["users"].(map[string]any)[userID].(map[string]any); ok {
|
||||
userData = v["data"].(map[string]any)
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// RemoveUser : remove user
|
||||
func RemoveUser(userID string) (err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(032)
|
||||
err = createError(032)
|
||||
|
||||
if _, ok := data["users"].(map[string]interface{})[userID]; ok {
|
||||
if _, ok := data["users"].(map[string]any)[userID]; ok {
|
||||
|
||||
delete(data["users"].(map[string]interface{}), userID)
|
||||
err = saveDatabase(data)
|
||||
delete(data["users"].(map[string]any), userID)
|
||||
err = saveDatabase(data)
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// SetDefaultUserData : set default user data
|
||||
func SetDefaultUserData(defaults map[string]interface{}) (err error) {
|
||||
func SetDefaultUserData(defaults map[string]any) (err error) {
|
||||
|
||||
allUserData, err := GetAllUserData()
|
||||
allUserData, err := GetAllUserData()
|
||||
|
||||
for _, d := range allUserData {
|
||||
var data = d.(map[string]interface{})["data"].(map[string]interface{})
|
||||
var userID = d.(map[string]interface{})["_id"].(string)
|
||||
for _, d := range allUserData {
|
||||
var data = d.(map[string]any)["data"].(map[string]any)
|
||||
var userID = d.(map[string]any)["_id"].(string)
|
||||
|
||||
for k, v := range defaults {
|
||||
if _, ok := data[k]; ok {
|
||||
// Key exist
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
err = WriteUserData(userID, data)
|
||||
}
|
||||
return
|
||||
for k, v := range defaults {
|
||||
if _, ok := data[k]; ok {
|
||||
// Key exist
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
err = WriteUserData(userID, data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ChangeCredentials : change credentials
|
||||
func ChangeCredentials(userID, username, password string) (err error) {
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = createError(032)
|
||||
err = createError(032)
|
||||
|
||||
if userData, ok := data["users"].(map[string]interface{})[userID]; ok {
|
||||
//var userData = tmp.(map[string]interface{})
|
||||
var salt = userData.(map[string]interface{})["_salt"].(string)
|
||||
if userData, ok := data["users"].(map[string]any)[userID]; ok {
|
||||
//var userData = tmp.(map[string]interface{})
|
||||
var salt = userData.(map[string]any)["_salt"].(string)
|
||||
|
||||
if len(username) > 0 {
|
||||
userData.(map[string]interface{})["_username"] = SHA256(username, salt)
|
||||
}
|
||||
if len(username) > 0 {
|
||||
userData.(map[string]any)["_username"] = SHA256(username, salt)
|
||||
}
|
||||
|
||||
if len(password) > 0 {
|
||||
userData.(map[string]interface{})["_password"] = SHA256(password, salt)
|
||||
}
|
||||
if len(password) > 0 {
|
||||
userData.(map[string]any)["_password"] = SHA256(password, salt)
|
||||
}
|
||||
|
||||
err = saveDatabase(data)
|
||||
}
|
||||
err = saveDatabase(data)
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllUserData : get all user data
|
||||
func GetAllUserData() (allUserData map[string]interface{}, err error) {
|
||||
func GetAllUserData() (allUserData map[string]any, err error) {
|
||||
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkInit()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
var defaults = make(map[string]interface{})
|
||||
defaults["dbVersion"] = "1.0"
|
||||
defaults["hash"] = "sha256"
|
||||
defaults["users"] = make(map[string]interface{})
|
||||
saveDatabase(defaults)
|
||||
data = defaults
|
||||
}
|
||||
if len(data) == 0 {
|
||||
var defaults = make(map[string]any)
|
||||
defaults["dbVersion"] = "1.0"
|
||||
defaults["hash"] = "sha256"
|
||||
defaults["users"] = make(map[string]any)
|
||||
saveDatabase(defaults)
|
||||
data = defaults
|
||||
}
|
||||
|
||||
allUserData = data["users"].(map[string]interface{})
|
||||
return
|
||||
allUserData = data["users"].(map[string]any)
|
||||
return
|
||||
}
|
||||
|
||||
// CheckTheValidityOfTheTokenFromHTTPHeader : get token from HTTP header
|
||||
func CheckTheValidityOfTheTokenFromHTTPHeader(w http.ResponseWriter, r *http.Request) (writer http.ResponseWriter, newToken string, err error) {
|
||||
err = createError(011)
|
||||
for _, cookie := range r.Cookies() {
|
||||
if cookie.Name == "Token" {
|
||||
var token string
|
||||
token, err = CheckTheValidityOfTheToken(cookie.Value)
|
||||
//fmt.Println("T", token, err)
|
||||
writer = SetCookieToken(w, token)
|
||||
newToken = token
|
||||
}
|
||||
}
|
||||
//fmt.Println(err)
|
||||
return
|
||||
err = createError(011)
|
||||
for _, cookie := range r.Cookies() {
|
||||
if cookie.Name == "Token" {
|
||||
var token string
|
||||
token, err = CheckTheValidityOfTheToken(cookie.Value)
|
||||
//fmt.Println("T", token, err)
|
||||
writer = SetCookieToken(w, token)
|
||||
newToken = token
|
||||
}
|
||||
}
|
||||
//fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Framework tools
|
||||
|
||||
func checkInit() (err error) {
|
||||
if initAuthentication == false {
|
||||
err = createError(000)
|
||||
}
|
||||
if initAuthentication == false {
|
||||
err = createError(000)
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func saveDatabase(tmpMap interface{}) (err error) {
|
||||
func saveDatabase(tmpMap any) (err error) {
|
||||
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(database, []byte(jsonString), 0600)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile(database, []byte(jsonString), 0600)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func loadDatabase() (err error) {
|
||||
jsonString, err := ioutil.ReadFile(database)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
jsonString, err := ioutil.ReadFile(database)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(jsonString), &data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(jsonString), &data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// SHA256 : password + salt = sha256 string
|
||||
func SHA256(secret, salt string) string {
|
||||
key := []byte(secret)
|
||||
h := hmac.New(sha256.New, key)
|
||||
h.Write([]byte("_remote_db"))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
key := []byte(secret)
|
||||
h := hmac.New(sha256.New, key)
|
||||
h.Write([]byte("_remote_db"))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
|
||||
const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
|
||||
|
||||
var bytes = make([]byte, n)
|
||||
rand.Read(bytes)
|
||||
for i, b := range bytes {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
}
|
||||
return string(bytes)
|
||||
var bytes = make([]byte, n)
|
||||
rand.Read(bytes)
|
||||
for i, b := range bytes {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func randomID(n int) string {
|
||||
const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
|
||||
const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
var bytes = make([]byte, n)
|
||||
rand.Read(bytes)
|
||||
for i, b := range bytes {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
}
|
||||
return string(bytes)
|
||||
var bytes = make([]byte, n)
|
||||
rand.Read(bytes)
|
||||
for i, b := range bytes {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func createError(errCode int) (err error) {
|
||||
var errMsg string
|
||||
switch errCode {
|
||||
case 000:
|
||||
errMsg = "Authentication has not yet been initialized"
|
||||
case 001:
|
||||
errMsg = "Default user already exists"
|
||||
case 002:
|
||||
errMsg = "No user id found for this token"
|
||||
case 010:
|
||||
errMsg = "User authentication failed"
|
||||
case 011:
|
||||
errMsg = "Session has expired"
|
||||
case 020:
|
||||
errMsg = "User already exists"
|
||||
case 030:
|
||||
errMsg = "User data could not be saved"
|
||||
case 031:
|
||||
errMsg = "User data could not be read"
|
||||
case 032:
|
||||
errMsg = "User ID was not found"
|
||||
}
|
||||
var errMsg string
|
||||
switch errCode {
|
||||
case 000:
|
||||
errMsg = "Authentication has not yet been initialized"
|
||||
case 001:
|
||||
errMsg = "Default user already exists"
|
||||
case 002:
|
||||
errMsg = "No user id found for this token"
|
||||
case 010:
|
||||
errMsg = "User authentication failed"
|
||||
case 011:
|
||||
errMsg = "Session has expired"
|
||||
case 020:
|
||||
errMsg = "User already exists"
|
||||
case 030:
|
||||
errMsg = "User data could not be saved"
|
||||
case 031:
|
||||
errMsg = "User data could not be read"
|
||||
case 032:
|
||||
errMsg = "User ID was not found"
|
||||
}
|
||||
|
||||
err = errors.New(errMsg)
|
||||
return
|
||||
err = errors.New(errMsg)
|
||||
return
|
||||
}
|
||||
|
||||
func defaultsForNewUser(username, password string) map[string]interface{} {
|
||||
var defaults = make(map[string]interface{})
|
||||
var salt = randomString(saltLength)
|
||||
defaults["_username"] = SHA256(username, salt)
|
||||
defaults["_password"] = SHA256(password, salt)
|
||||
defaults["_salt"] = salt
|
||||
defaults["_id"] = "id-" + randomID(idLength)
|
||||
//defaults["_one.time.token"] = randomString(tokenLength)
|
||||
defaults["data"] = make(map[string]interface{})
|
||||
func defaultsForNewUser(username, password string) map[string]any {
|
||||
var defaults = make(map[string]any)
|
||||
var salt = randomString(saltLength)
|
||||
defaults["_username"] = SHA256(username, salt)
|
||||
defaults["_password"] = SHA256(password, salt)
|
||||
defaults["_salt"] = salt
|
||||
defaults["_id"] = "id-" + randomID(idLength)
|
||||
//defaults["_one.time.token"] = randomString(tokenLength)
|
||||
defaults["data"] = make(map[string]any)
|
||||
|
||||
return defaults
|
||||
return defaults
|
||||
}
|
||||
|
||||
func setToken(id, oldToken string) (newToken string) {
|
||||
delete(tokens, oldToken)
|
||||
tokensMu.Lock()
|
||||
defer tokensMu.Unlock()
|
||||
|
||||
if oldToken != "-" {
|
||||
delete(tokens, oldToken)
|
||||
}
|
||||
|
||||
loopToken:
|
||||
newToken = randomString(tokenLength)
|
||||
if _, ok := tokens[newToken]; ok {
|
||||
goto loopToken
|
||||
}
|
||||
newToken = randomString(tokenLength)
|
||||
if _, ok := tokens[newToken]; ok {
|
||||
goto loopToken
|
||||
}
|
||||
|
||||
var tmp = make(map[string]interface{})
|
||||
tmp["id"] = id
|
||||
tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
|
||||
var tmp = make(map[string]any)
|
||||
tmp["id"] = id
|
||||
tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
|
||||
|
||||
tokens[newToken] = tmp
|
||||
tokens[newToken] = tmp
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func mapToJSON(tmpMap interface{}) string {
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
if err != nil {
|
||||
return "{}"
|
||||
}
|
||||
return string(jsonString)
|
||||
func mapToJSON(tmpMap any) string {
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
if err != nil {
|
||||
return "{}"
|
||||
}
|
||||
return string(jsonString)
|
||||
}
|
||||
|
||||
// SetCookieToken : set cookie
|
||||
func SetCookieToken(w http.ResponseWriter, token string) http.ResponseWriter {
|
||||
expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
|
||||
cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
|
||||
http.SetCookie(w, &cookie)
|
||||
return w
|
||||
expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
|
||||
cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
|
||||
http.SetCookie(w, &cookie)
|
||||
return w
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package imgcache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Cache : Cache strcut
|
||||
type Cache struct {
|
||||
path string
|
||||
cacheURL string
|
||||
caching bool
|
||||
images map[string]string
|
||||
Queue []string
|
||||
Cache []string
|
||||
Image imageFunc
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type imageFunc struct {
|
||||
GetURL func(string) string
|
||||
Caching func()
|
||||
Remove func()
|
||||
}
|
||||
|
||||
// New : New cahce
|
||||
func New(path, chacheURL string, caching bool) (c *Cache, err error) {
|
||||
|
||||
c = &Cache{}
|
||||
|
||||
c.images = make(map[string]string)
|
||||
c.path = path
|
||||
c.cacheURL = chacheURL
|
||||
c.caching = caching
|
||||
c.Queue = []string{}
|
||||
c.Cache = []string{}
|
||||
|
||||
var queue []string
|
||||
|
||||
c.Image.GetURL = func(src string) (cacheURL string) {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
src = strings.Trim(src, "\r\n")
|
||||
|
||||
if c.caching == false {
|
||||
return src
|
||||
}
|
||||
|
||||
u, err := url.Parse(src)
|
||||
if err != nil || len(filepath.Ext(u.Path)) == 0 {
|
||||
return src
|
||||
}
|
||||
|
||||
var filename = fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))
|
||||
if cacheURL, ok := c.images[fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))]; ok {
|
||||
return cacheURL
|
||||
}
|
||||
|
||||
if indexOfString(filename, c.Cache) == -1 {
|
||||
|
||||
if indexOfString(src, c.Queue) == -1 {
|
||||
c.Queue = append(c.Queue, src)
|
||||
}
|
||||
|
||||
} else {
|
||||
c.images[filename] = c.cacheURL + filename
|
||||
src = c.cacheURL + filename
|
||||
}
|
||||
|
||||
/*
|
||||
if _, err := os.Stat(c.path + filename); err != nil {
|
||||
//c.images[filename] = c.cacheURL + filename
|
||||
if indexOfString(src, c.Queue) == -1 {
|
||||
c.Queue = append(c.Queue, src)
|
||||
}
|
||||
} else {
|
||||
c.images[filename] = c.cacheURL + filename
|
||||
}
|
||||
*/
|
||||
|
||||
return src
|
||||
}
|
||||
|
||||
c.Image.Caching = func() {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
var filename string
|
||||
|
||||
for _, src := range c.Queue {
|
||||
|
||||
resp, err := http.Get(src)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
continue
|
||||
}
|
||||
|
||||
filename = fmt.Sprintf("%s%s%s%s", c.path, string(os.PathSeparator), strToMD5(src), filepath.Ext(src))
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
u, err := url.Parse(src)
|
||||
if err == nil {
|
||||
c.images[fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))] = c.cacheURL + filename
|
||||
}
|
||||
|
||||
queue = append(queue, src)
|
||||
|
||||
}
|
||||
|
||||
for _, q := range queue {
|
||||
c.Queue = removeStringFromSlice(q, c.Queue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
c.Image.Remove = func() {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
|
||||
switch c.caching {
|
||||
|
||||
case true:
|
||||
if _, ok := c.images[file.Name()]; !ok {
|
||||
os.RemoveAll(c.path + file.Name())
|
||||
}
|
||||
|
||||
case false:
|
||||
os.RemoveAll(c.path + file.Name())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
c.Cache = append(c.Cache, file.Name())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package imgcache
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func strToMD5(str string) string {
|
||||
md5Hasher := md5.New()
|
||||
md5Hasher.Write([]byte(str))
|
||||
return hex.EncodeToString(md5Hasher.Sum(nil))
|
||||
}
|
||||
|
||||
func indexOfString(str string, slice []string) int {
|
||||
|
||||
for i, v := range slice {
|
||||
if str == v {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func removeStringFromSlice(str string, slice []string) []string {
|
||||
|
||||
var i = indexOfString(str, slice)
|
||||
|
||||
if i != -1 {
|
||||
slice = append(slice[:i], slice[i+1:]...)
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
@@ -1,84 +1,84 @@
|
||||
package m3u
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"testing"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type M3UStream struct {
|
||||
GroupTitle string `json:"group-title,required"`
|
||||
Name string `json:"name,required"`
|
||||
TvgID string `json:"tvg-id,required"`
|
||||
TvgLogo string `json:"tvg-logo,required"`
|
||||
TvgName string `json:"tvg-name,required"`
|
||||
URL string `json:"url,required"`
|
||||
UUIDKey string `json:"_uuid.key,omitempty"`
|
||||
UUIDValue string `json:"_uuid.value,omitempty"`
|
||||
GroupTitle string `json:"group-title,required"`
|
||||
Name string `json:"name,required"`
|
||||
TvgID string `json:"tvg-id,required"`
|
||||
TvgLogo string `json:"tvg-logo,required"`
|
||||
TvgName string `json:"tvg-name,required"`
|
||||
URL string `json:"url,required"`
|
||||
UUIDKey string `json:"_uuid.key,omitempty"`
|
||||
UUIDValue string `json:"_uuid.value,omitempty"`
|
||||
}
|
||||
|
||||
func TestStream1(t *testing.T) {
|
||||
|
||||
var file = "test_list_1.m3u"
|
||||
var content, err = ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
var file = "test_list_1.m3u"
|
||||
var content, err = ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
streams, err := MakeInterfaceFromM3U(content)
|
||||
streams, err := MakeInterfaceFromM3U(content)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = checkStream(streams)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = checkStream(streams)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
fmt.Println("Streams:", len(streams))
|
||||
t.Log(streams)
|
||||
fmt.Println("Streams:", len(streams))
|
||||
t.Log(streams)
|
||||
|
||||
}
|
||||
|
||||
func checkStream(streamInterface []interface{}) (err error) {
|
||||
func checkStream(streamInterface []any) (err error) {
|
||||
|
||||
for i, s := range streamInterface {
|
||||
for i, s := range streamInterface {
|
||||
|
||||
var stream = s.(map[string]string)
|
||||
var m3uStream M3UStream
|
||||
var stream = s.(map[string]string)
|
||||
var m3uStream M3UStream
|
||||
|
||||
jsonString, err := json.MarshalIndent(stream, "", " ")
|
||||
jsonString, err := json.MarshalIndent(stream, "", " ")
|
||||
|
||||
if err == nil {
|
||||
if err == nil {
|
||||
|
||||
err = json.Unmarshal(jsonString, &m3uStream)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(jsonString, &m3uStream)
|
||||
if err == nil {
|
||||
|
||||
log.Print(fmt.Sprintf("Stream: %d", i))
|
||||
log.Print(fmt.Sprintf("Name*: %s", m3uStream.Name))
|
||||
log.Print(fmt.Sprintf("URL*: %s", m3uStream.URL))
|
||||
log.Print(fmt.Sprintf("tvg-name: %s", m3uStream.TvgName))
|
||||
log.Print(fmt.Sprintf("tvg-id**: %s", m3uStream.TvgID))
|
||||
log.Print(fmt.Sprintf("tvg-logo: %s", m3uStream.TvgLogo))
|
||||
log.Print(fmt.Sprintf("group-title**: %s", m3uStream.GroupTitle))
|
||||
log.Print(fmt.Sprintf("Stream: %d", i))
|
||||
log.Print(fmt.Sprintf("Name*: %s", m3uStream.Name))
|
||||
log.Print(fmt.Sprintf("URL*: %s", m3uStream.URL))
|
||||
log.Print(fmt.Sprintf("tvg-name: %s", m3uStream.TvgName))
|
||||
log.Print(fmt.Sprintf("tvg-id**: %s", m3uStream.TvgID))
|
||||
log.Print(fmt.Sprintf("tvg-logo: %s", m3uStream.TvgLogo))
|
||||
log.Print(fmt.Sprintf("group-title**: %s", m3uStream.GroupTitle))
|
||||
|
||||
if len(m3uStream.UUIDKey) > 0 {
|
||||
log.Print(fmt.Sprintf("UUID key***: %s", m3uStream.UUIDKey))
|
||||
log.Print(fmt.Sprintf("UUID value: %s", m3uStream.UUIDValue))
|
||||
} else {
|
||||
log.Print(fmt.Sprintf("UUID key: false"))
|
||||
}
|
||||
if len(m3uStream.UUIDKey) > 0 {
|
||||
log.Print(fmt.Sprintf("UUID key***: %s", m3uStream.UUIDKey))
|
||||
log.Print(fmt.Sprintf("UUID value: %s", m3uStream.UUIDValue))
|
||||
} else {
|
||||
log.Print(fmt.Sprintf("UUID key: false"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
log.Println(fmt.Sprintf("- - - - - (*: Required) | (**: Nice to have) | (***: Love it) - - - - -"))
|
||||
}
|
||||
log.Println(fmt.Sprintf("- - - - - (*: Required) | (**: Nice to have) | (***: Love it) - - - - -"))
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
#EXTM3U url-tvg="http://example.com/file.xml" x-tvg-url="http://example.com/xteve.xml"
|
||||
#EXTINF:0 channelID="1" tvg-chno="1" tvg-name="Channel.1" tvg-id="tvg.id.1" tvg-logo="https://example/logo.png" group-title="Group 1",Channel 1
|
||||
#EXTINF:0 channelID="1" tvg-chno="1" tvg-name="Channel.1" tvg-id="tvg.id.1" tvg-logo="https://example/logo.png" group-title="Group 1", Channel 1
|
||||
http://example.com/stream/1
|
||||
|
||||
#EXTINF:0 channelID="2" tvg-chno="2" tvg-name="Channel.2" tvg-id="tvg.id.2" tvg-logo="https://example/logo.png" group-title="Group 2",Channel 2
|
||||
#123
|
||||
http://example.com/stream/2
|
||||
|
||||
#EXTINF:123, Sample artist - Sample title
|
||||
http://example.com/stream/3
|
||||
|
||||
#EXTINF:321,Example Artist - Example title
|
||||
http://example.com/stream/4
|
||||
@@ -1,182 +1,186 @@
|
||||
package m3u
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MakeInterfaceFromM3U :
|
||||
func MakeInterfaceFromM3U(byteStream []byte) (allChannels []interface{}, err error) {
|
||||
func MakeInterfaceFromM3U(byteStream []byte) (allChannels []any, err error) {
|
||||
|
||||
var content = string(byteStream)
|
||||
var channelName string
|
||||
var uuids []string
|
||||
var content = string(byteStream)
|
||||
var channelName string
|
||||
var uuids []string
|
||||
|
||||
var parseMetaData = func(channel string) (stream map[string]string) {
|
||||
var parseMetaData = func(channel string) (stream map[string]string) {
|
||||
|
||||
stream = make(map[string]string)
|
||||
var exceptForParameter = `[a-z-A-Z=]*(".*?")`
|
||||
var exceptForChannelName = `,([^\n]*|,[^\r]*)`
|
||||
stream = make(map[string]string)
|
||||
var exceptForParameter = `[a-z-A-Z=]*(".*?")`
|
||||
var exceptForChannelName = `,([^\n]*|,[^\r]*)`
|
||||
|
||||
var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
|
||||
var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
|
||||
|
||||
// Zeilen mit # und leerer Zeilen entfernen
|
||||
for i := len(lines) - 1; i >= 0; i-- {
|
||||
// Zeilen mit # und leerer Zeilen entfernen
|
||||
for i := len(lines) - 1; i >= 0; i-- {
|
||||
|
||||
if len(lines[i]) == 0 || lines[i][0:1] == "#" {
|
||||
lines = append(lines[:i], lines[i+1:]...)
|
||||
}
|
||||
if len(lines[i]) == 0 || lines[i][0:1] == "#" {
|
||||
lines = append(lines[:i], lines[i+1:]...)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if len(lines) >= 2 {
|
||||
if len(lines) >= 2 {
|
||||
|
||||
for _, line := range lines {
|
||||
for _, line := range lines {
|
||||
|
||||
_, err := url.ParseRequestURI(line)
|
||||
_, err := url.ParseRequestURI(line)
|
||||
|
||||
switch err {
|
||||
switch err {
|
||||
|
||||
case nil:
|
||||
stream["url"] = strings.Trim(line, "\r\n")
|
||||
case nil:
|
||||
stream["url"] = strings.Trim(line, "\r\n")
|
||||
|
||||
default:
|
||||
default:
|
||||
|
||||
var value string
|
||||
// Alle Parameter parsen
|
||||
var p = regexp.MustCompile(exceptForParameter)
|
||||
var streamParameter = p.FindAllString(line, -1)
|
||||
var value string
|
||||
// Alle Parameter parsen
|
||||
var p = regexp.MustCompile(exceptForParameter)
|
||||
var streamParameter = p.FindAllString(line, -1)
|
||||
|
||||
for _, p := range streamParameter {
|
||||
for _, p := range streamParameter {
|
||||
|
||||
line = strings.Replace(line, p, "", 1)
|
||||
line = strings.Replace(line, p, "", 1)
|
||||
|
||||
p = strings.Replace(p, `"`, "", -1)
|
||||
var parameter = strings.SplitN(p, "=", 2)
|
||||
p = strings.Replace(p, `"`, "", -1)
|
||||
var parameter = strings.SplitN(p, "=", 2)
|
||||
|
||||
if len(parameter) == 2 {
|
||||
if len(parameter) == 2 {
|
||||
|
||||
// TVG Key als Kleinbuchstaben speichern
|
||||
switch strings.Contains(parameter[0], "tvg") {
|
||||
// TVG Key als Kleinbuchstaben speichern
|
||||
switch strings.Contains(parameter[0], "tvg") {
|
||||
|
||||
case true:
|
||||
stream[strings.ToLower(parameter[0])] = parameter[1]
|
||||
case false:
|
||||
stream[parameter[0]] = parameter[1]
|
||||
case true:
|
||||
stream[strings.ToLower(parameter[0])] = parameter[1]
|
||||
case false:
|
||||
stream[parameter[0]] = parameter[1]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// URL's nicht an die Filterfunktion übergeben
|
||||
if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
|
||||
value = value + parameter[1] + " "
|
||||
}
|
||||
// URL's nicht an die Filterfunktion übergeben
|
||||
if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
|
||||
value = value + parameter[1] + " "
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Kanalnamen parsen
|
||||
n := regexp.MustCompile(exceptForChannelName)
|
||||
var name = n.FindAllString(line, 1)
|
||||
// Kanalnamen parsen
|
||||
n := regexp.MustCompile(exceptForChannelName)
|
||||
var name = n.FindAllString(line, 1)
|
||||
|
||||
if len(name) > 0 {
|
||||
channelName = name[0]
|
||||
channelName = strings.Replace(channelName, `,`, "", 1)
|
||||
channelName = strings.TrimRight(channelName, "\r\n")
|
||||
channelName = strings.TrimRight(channelName, " ")
|
||||
}
|
||||
if len(name) > 0 {
|
||||
channelName = name[0]
|
||||
channelName = strings.Replace(channelName, `,`, "", 1)
|
||||
channelName = strings.TrimRight(channelName, "\r\n")
|
||||
channelName = strings.TrimRight(channelName, " ")
|
||||
}
|
||||
|
||||
if len(channelName) == 0 {
|
||||
if len(channelName) == 0 {
|
||||
|
||||
if v, ok := stream["tvg-name"]; ok {
|
||||
channelName = v
|
||||
}
|
||||
if v, ok := stream["tvg-name"]; ok {
|
||||
channelName = v
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
channelName = strings.TrimRight(channelName, " ")
|
||||
channelName = strings.TrimRight(channelName, " ")
|
||||
|
||||
// Kanäle ohne Namen werden augelassen
|
||||
if len(channelName) == 0 {
|
||||
return
|
||||
}
|
||||
// Kanäle ohne Namen werden augelassen
|
||||
if len(channelName) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
stream["name"] = channelName
|
||||
value = value + channelName
|
||||
stream["name"] = channelName
|
||||
value = value + channelName
|
||||
|
||||
stream["_values"] = value
|
||||
stream["_values"] = value
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Nach eindeutiger ID im Stream suchen
|
||||
for key, value := range stream {
|
||||
// Nach eindeutiger ID im Stream suchen
|
||||
for key, value := range stream {
|
||||
|
||||
if !strings.Contains(strings.ToLower(key), "tvg-id") {
|
||||
if !strings.Contains(strings.ToLower(key), "tvg-id") {
|
||||
|
||||
if strings.Contains(strings.ToLower(key), "id") {
|
||||
if strings.Contains(strings.ToLower(key), "id") {
|
||||
|
||||
if indexOfString(value, uuids) != -1 {
|
||||
log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
|
||||
break
|
||||
}
|
||||
if indexOfString(value, uuids) != -1 {
|
||||
log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
|
||||
break
|
||||
}
|
||||
|
||||
uuids = append(uuids, value)
|
||||
uuids = append(uuids, value)
|
||||
|
||||
stream["_uuid.key"] = key
|
||||
stream["_uuid.value"] = value
|
||||
break
|
||||
stream["_uuid.key"] = key
|
||||
stream["_uuid.value"] = value
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//fmt.Println(content)
|
||||
//fmt.Println(content)
|
||||
if strings.Contains(content, "#EXT-X-TARGETDURATION") || strings.Contains(content, "#EXT-X-MEDIA-SEQUENCE") {
|
||||
err = errors.New("Invalid M3U file, an extended M3U file is required.")
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(content, "#EXTM3U") {
|
||||
if strings.Contains(content, "#EXTM3U") {
|
||||
|
||||
var channels = strings.Split(content, "#EXTINF")
|
||||
var channels = strings.Split(content, "#EXTINF")
|
||||
|
||||
channels = append(channels[:0], channels[1:]...)
|
||||
channels = append(channels[:0], channels[1:]...)
|
||||
|
||||
for _, channel := range channels {
|
||||
for _, channel := range channels {
|
||||
|
||||
var stream = parseMetaData(channel)
|
||||
var stream = parseMetaData(channel)
|
||||
|
||||
if len(stream) > 0 && stream != nil {
|
||||
allChannels = append(allChannels, stream)
|
||||
}
|
||||
if len(stream) > 0 && stream != nil {
|
||||
allChannels = append(allChannels, stream)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
err = errors.New("No valid m3u file")
|
||||
err = errors.New("Invalid M3U file, an extended M3U file is required.")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func indexOfString(element string, data []string) int {
|
||||
|
||||
for k, v := range data {
|
||||
if element == v {
|
||||
return k
|
||||
}
|
||||
}
|
||||
for k, v := range data {
|
||||
if element == v {
|
||||
return k
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
return -1
|
||||
}
|
||||
@@ -22,10 +22,10 @@ type ClientInfo struct {
|
||||
OS string `json:"os,required"`
|
||||
URL string `json:"url,required"`
|
||||
|
||||
Response ServerResponse `json:"response,omitempty"`
|
||||
Response ServerResponse `json:"response"`
|
||||
}
|
||||
|
||||
//ServerResponse : Response from server after client request
|
||||
// ServerResponse : Response from server after client request
|
||||
type ServerResponse struct {
|
||||
Status bool `json:"status,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
@@ -106,7 +106,7 @@ func serverRequest() (err error) {
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
//fmt.Println(resp.StatusCode, Updater.URL, Updater.CMD)
|
||||
err = fmt.Errorf(fmt.Sprintf("%d: %s (%s)", resp.StatusCode, http.StatusText(resp.StatusCode), Updater.URL))
|
||||
err = fmt.Errorf("%d: %s (%s)", resp.StatusCode, http.StatusText(resp.StatusCode), Updater.URL)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -9,11 +9,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
m3u "../src/internal/m3u-parser"
|
||||
m3u "xteve/src/internal/m3u-parser"
|
||||
)
|
||||
|
||||
// Playlisten parsen
|
||||
func parsePlaylist(filename, fileType string) (channels []interface{}, err error) {
|
||||
func parsePlaylist(filename, fileType string) (channels []any, err error) {
|
||||
|
||||
content, err := readByteFromFile(filename)
|
||||
var id = strings.TrimSuffix(getFilenameFromPath(filename), path.Ext(getFilenameFromPath(filename)))
|
||||
@@ -34,7 +34,7 @@ func parsePlaylist(filename, fileType string) (channels []interface{}, err error
|
||||
}
|
||||
|
||||
// Streams filtern
|
||||
func filterThisStream(s interface{}) (status bool) {
|
||||
func filterThisStream(s any) (status bool) {
|
||||
|
||||
status = false
|
||||
var stream = s.(map[string]string)
|
||||
@@ -181,6 +181,7 @@ func checkConditions(streamValues, conditions, coType string) (status bool) {
|
||||
// xTeVe M3U Datei erstellen
|
||||
func buildM3U(groups []string) (m3u string, err error) {
|
||||
|
||||
var imgc = Data.Cache.Images
|
||||
var m3uChannels = make(map[float64]XEPGChannelStruct)
|
||||
var channelNumbers []float64
|
||||
|
||||
@@ -223,7 +224,8 @@ func buildM3U(groups []string) (m3u string, err error) {
|
||||
for _, channelNumber := range channelNumbers {
|
||||
|
||||
var channel = m3uChannels[channelNumber]
|
||||
var parameter = fmt.Sprintf(`#EXTINF:0 channelID="%s" tvg-chno="%s" tvg-name="%s" tvg-id="%s" tvg-logo="%s" group-title="%s",%s`+"\n", channel.XEPG, channel.XChannelID, channel.XName, channel.XChannelID, getCacheImageURL(channel.TvgLogo), channel.XGroupTitle, channel.XName)
|
||||
|
||||
var parameter = fmt.Sprintf(`#EXTINF:0 channelID="%s" tvg-chno="%s" tvg-name="%s" tvg-id="%s" tvg-logo="%s" group-title="%s",%s`+"\n", channel.XEPG, channel.XChannelID, channel.XName, channel.XChannelID, imgc.Image.GetURL(channel.TvgLogo), channel.XGroupTitle, channel.XName)
|
||||
var stream, err = createStreamingURL("M3U", channel.FileM3UID, channel.XChannelID, channel.XName, channel.URL)
|
||||
if err == nil {
|
||||
m3u = m3u + parameter + stream + "\n"
|
||||
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
package src
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var plexRefreshState = struct {
|
||||
sync.Mutex
|
||||
lastRun time.Time
|
||||
scheduled bool
|
||||
inProgress bool
|
||||
queued bool
|
||||
reason string
|
||||
missingConfigLogged bool
|
||||
}{}
|
||||
|
||||
// queuePlexGuideRefresh schedules a debounced Plex DVR guide refresh.
|
||||
func queuePlexGuideRefresh(reason string) {
|
||||
|
||||
if Settings.UsePlexAPI == false {
|
||||
return
|
||||
}
|
||||
|
||||
plexRefreshState.Lock()
|
||||
|
||||
if len(strings.TrimSpace(reason)) > 0 {
|
||||
plexRefreshState.reason = reason
|
||||
}
|
||||
|
||||
if plexRefreshState.scheduled == true || plexRefreshState.inProgress == true {
|
||||
plexRefreshState.queued = true
|
||||
plexRefreshState.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
plexRefreshState.scheduled = true
|
||||
delay := plexRefreshDelayLocked()
|
||||
plexRefreshState.Unlock()
|
||||
|
||||
go runPlexGuideRefresh(delay)
|
||||
}
|
||||
|
||||
func runPlexGuideRefresh(initialDelay time.Duration) {
|
||||
|
||||
if initialDelay > 0 {
|
||||
time.Sleep(initialDelay)
|
||||
}
|
||||
|
||||
for {
|
||||
|
||||
plexRefreshState.Lock()
|
||||
reason := strings.TrimSpace(plexRefreshState.reason)
|
||||
if len(reason) == 0 {
|
||||
reason = "update"
|
||||
}
|
||||
plexRefreshState.scheduled = false
|
||||
plexRefreshState.inProgress = true
|
||||
plexRefreshState.queued = false
|
||||
plexRefreshState.Unlock()
|
||||
|
||||
err := refreshPlexGuide(reason)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
}
|
||||
|
||||
plexRefreshState.Lock()
|
||||
plexRefreshState.lastRun = time.Now()
|
||||
runAgain := plexRefreshState.queued
|
||||
plexRefreshState.inProgress = false
|
||||
nextDelay := time.Duration(0)
|
||||
|
||||
if runAgain == true && Settings.UsePlexAPI == true {
|
||||
plexRefreshState.scheduled = true
|
||||
nextDelay = plexRefreshDelayLocked()
|
||||
}
|
||||
plexRefreshState.Unlock()
|
||||
|
||||
if runAgain == false || Settings.UsePlexAPI == false {
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(nextDelay)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func plexRefreshDelayLocked() (delay time.Duration) {
|
||||
|
||||
const minDelay = 2 * time.Second
|
||||
const cooldown = 20 * time.Second
|
||||
|
||||
if plexRefreshState.lastRun.IsZero() == true {
|
||||
return minDelay
|
||||
}
|
||||
|
||||
since := time.Since(plexRefreshState.lastRun)
|
||||
if since >= cooldown {
|
||||
return minDelay
|
||||
}
|
||||
|
||||
return cooldown - since
|
||||
}
|
||||
|
||||
func refreshPlexGuide(reason string) (err error) {
|
||||
|
||||
baseURL, token, ready := getPlexConfig()
|
||||
if ready == false {
|
||||
return nil
|
||||
}
|
||||
|
||||
dvrs, err := discoverPlexDVRs(baseURL, token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var refreshed int
|
||||
var failed int
|
||||
|
||||
for _, dvr := range dvrs {
|
||||
|
||||
endpoints := getPlexReloadEndpoints(dvr)
|
||||
if len(endpoints) == 0 {
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
|
||||
var endpointErr error
|
||||
for _, endpoint := range endpoints {
|
||||
|
||||
status, _, requestErr := doPlexRequest("POST", baseURL, endpoint, token)
|
||||
if requestErr != nil {
|
||||
endpointErr = requestErr
|
||||
continue
|
||||
}
|
||||
|
||||
if status >= 200 && status < 300 {
|
||||
refreshed++
|
||||
endpointErr = nil
|
||||
break
|
||||
}
|
||||
|
||||
endpointErr = fmt.Errorf("Plex API returned HTTP %d for %s", status, endpoint)
|
||||
}
|
||||
|
||||
if endpointErr != nil {
|
||||
failed++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if refreshed == 0 {
|
||||
if failed == 0 {
|
||||
return errors.New("Plex API guide refresh failed")
|
||||
}
|
||||
|
||||
return fmt.Errorf("Plex API guide refresh failed for %d DVR(s)", failed)
|
||||
}
|
||||
|
||||
showInfo(fmt.Sprintf("Plex API:Guide reload requested for %d DVR(s) (%s)", refreshed, reason))
|
||||
if failed > 0 {
|
||||
showInfo(fmt.Sprintf("Plex API:Guide reload failed for %d DVR(s)", failed))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPlexConfig() (baseURL, token string, ready bool) {
|
||||
|
||||
baseURL = strings.TrimSpace(Settings.PlexURL)
|
||||
token = strings.TrimSpace(Settings.PlexToken)
|
||||
|
||||
if strings.HasPrefix(baseURL, "http://") == false && strings.HasPrefix(baseURL, "https://") == false && len(baseURL) > 0 {
|
||||
baseURL = "http://" + baseURL
|
||||
}
|
||||
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
|
||||
plexRefreshState.Lock()
|
||||
defer plexRefreshState.Unlock()
|
||||
|
||||
if len(baseURL) == 0 || len(token) == 0 {
|
||||
|
||||
if plexRefreshState.missingConfigLogged == false {
|
||||
showInfo("Plex API:Skipped refresh because plex.url or plex.token is empty")
|
||||
plexRefreshState.missingConfigLogged = true
|
||||
}
|
||||
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
plexRefreshState.missingConfigLogged = false
|
||||
|
||||
return baseURL, token, true
|
||||
}
|
||||
|
||||
func discoverPlexDVRs(baseURL, token string) (dvrs []map[string]any, err error) {
|
||||
|
||||
status, body, err := doPlexRequest("GET", baseURL, "/livetv/dvrs", token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if status < 200 || status >= 300 {
|
||||
err = fmt.Errorf("Plex API returned HTTP %d for /livetv/dvrs", status)
|
||||
return
|
||||
}
|
||||
|
||||
var payload = make(map[string]any)
|
||||
err = json.Unmarshal(body, &payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
mediaContainer, ok := payload["MediaContainer"].(map[string]any)
|
||||
if ok == false {
|
||||
err = errors.New("Plex API response missing MediaContainer")
|
||||
return
|
||||
}
|
||||
|
||||
for _, key := range []string{"Dvr", "DVR", "Directory", "Metadata"} {
|
||||
if raw, found := mediaContainer[key]; found == true {
|
||||
if list, ok := raw.([]any); ok == true {
|
||||
dvrs = convertToPlexMapSlice(list)
|
||||
if len(dvrs) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = errors.New("Plex API returned no DVR entries")
|
||||
return
|
||||
}
|
||||
|
||||
func convertToPlexMapSlice(list []any) (dvrs []map[string]any) {
|
||||
|
||||
dvrs = make([]map[string]any, 0, len(list))
|
||||
|
||||
for _, item := range list {
|
||||
if dvr, ok := item.(map[string]any); ok == true {
|
||||
dvrs = append(dvrs, dvr)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getPlexReloadEndpoints(dvr map[string]any) (endpoints []string) {
|
||||
|
||||
endpoints = make([]string, 0, 6)
|
||||
added := make(map[string]bool)
|
||||
|
||||
add := func(endpoint string) {
|
||||
endpoint = strings.TrimSpace(endpoint)
|
||||
if len(endpoint) == 0 {
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(endpoint, "/") == false {
|
||||
endpoint = "/" + endpoint
|
||||
}
|
||||
if added[endpoint] == true {
|
||||
return
|
||||
}
|
||||
added[endpoint] = true
|
||||
endpoints = append(endpoints, endpoint)
|
||||
}
|
||||
|
||||
if key := getPlexMapString(dvr, "key"); len(key) > 0 {
|
||||
if strings.HasPrefix(key, "/") == true {
|
||||
add(strings.TrimRight(key, "/") + "/reloadGuide")
|
||||
} else {
|
||||
add("/livetv/dvrs/" + url.PathEscape(key) + "/reloadGuide")
|
||||
}
|
||||
}
|
||||
|
||||
for _, field := range []string{"uuid", "identifier", "machineIdentifier", "clientIdentifier", "id"} {
|
||||
if value := getPlexMapString(dvr, field); len(value) > 0 {
|
||||
add("/livetv/dvrs/" + url.PathEscape(value) + "/reloadGuide")
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getPlexMapString(data map[string]any, field string) string {
|
||||
|
||||
for key, value := range data {
|
||||
if strings.EqualFold(key, field) == false {
|
||||
continue
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
|
||||
case string:
|
||||
return strings.TrimSpace(v)
|
||||
|
||||
case float64:
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func doPlexRequest(method, baseURL, endpoint, token string) (status int, body []byte, err error) {
|
||||
|
||||
requestURL := strings.TrimRight(baseURL, "/") + "/" + strings.TrimLeft(endpoint, "/")
|
||||
|
||||
req, err := http.NewRequest(method, requestURL, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
query := req.URL.Query()
|
||||
if len(token) > 0 {
|
||||
query.Set("X-Plex-Token", token)
|
||||
req.URL.RawQuery = query.Encode()
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("X-Plex-Token", token)
|
||||
|
||||
if len(System.DeviceID) > 0 {
|
||||
req.Header.Set("X-Plex-Client-Identifier", System.DeviceID)
|
||||
}
|
||||
|
||||
if len(System.Name) > 0 {
|
||||
req.Header.Set("X-Plex-Product", System.Name)
|
||||
req.Header.Set("X-Plex-Device-Name", System.Name)
|
||||
}
|
||||
|
||||
if len(System.Version) > 0 {
|
||||
req.Header.Set("X-Plex-Version", System.Version)
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
status = resp.StatusCode
|
||||
body, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+21
-13
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
m3u "../src/internal/m3u-parser"
|
||||
m3u "xteve/src/internal/m3u-parser"
|
||||
)
|
||||
|
||||
// fileType: Welcher Dateityp soll aktualisiert werden (m3u, hdhr, xml) | fileID: Update einer bestimmten Datei (Provider ID)
|
||||
@@ -17,13 +17,13 @@ func getProviderData(fileType, fileID string) (err error) {
|
||||
var fileExtension, serverFileName string
|
||||
var body = make([]byte, 0)
|
||||
var newProvider = false
|
||||
var dataMap = make(map[string]interface{})
|
||||
var dataMap = make(map[string]any)
|
||||
|
||||
var saveDateFromProvider = func(fileSource, serverFileName, id string, body []byte) (err error) {
|
||||
|
||||
var data = make(map[string]interface{})
|
||||
var data = make(map[string]any)
|
||||
|
||||
if value, ok := dataMap[id].(map[string]interface{}); ok {
|
||||
if value, ok := dataMap[id].(map[string]any); ok {
|
||||
data = value
|
||||
} else {
|
||||
data["id.provider"] = id
|
||||
@@ -65,7 +65,7 @@ func getProviderData(fileType, fileID string) (err error) {
|
||||
}
|
||||
|
||||
case "compatibility":
|
||||
data[key] = make(map[string]interface{})
|
||||
data[key] = make(map[string]any)
|
||||
|
||||
case "counter.download":
|
||||
data[key] = 0.0
|
||||
@@ -142,7 +142,7 @@ func getProviderData(fileType, fileID string) (err error) {
|
||||
|
||||
for dataID, d := range dataMap {
|
||||
|
||||
var data = d.(map[string]interface{})
|
||||
var data = d.(map[string]any)
|
||||
var fileSource = data["file.source"].(string)
|
||||
newProvider = false
|
||||
|
||||
@@ -220,8 +220,8 @@ func getProviderData(fileType, fileID string) (err error) {
|
||||
}
|
||||
|
||||
// Fehler Counter um 1 erhöhen
|
||||
var data = make(map[string]interface{})
|
||||
if value, ok := dataMap[dataID].(map[string]interface{}); ok {
|
||||
var data = make(map[string]any)
|
||||
if value, ok := dataMap[dataID].(map[string]any); ok {
|
||||
|
||||
data = value
|
||||
data["counter.error"] = data["counter.error"].(float64) + 1
|
||||
@@ -238,9 +238,9 @@ func getProviderData(fileType, fileID string) (err error) {
|
||||
// Berechnen der Fehlerquote
|
||||
if newProvider == false {
|
||||
|
||||
if value, ok := dataMap[dataID].(map[string]interface{}); ok {
|
||||
if value, ok := dataMap[dataID].(map[string]any); ok {
|
||||
|
||||
var data = make(map[string]interface{})
|
||||
var data = make(map[string]any)
|
||||
data = value
|
||||
|
||||
if data["counter.error"].(float64) == 0 {
|
||||
@@ -282,15 +282,23 @@ func downloadFileFromServer(providerURL string) (filename string, body []byte, e
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := http.Get(providerURL)
|
||||
req, err := http.NewRequest(http.MethodGet, providerURL, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp.Header.Set("User-Agent", Settings.UserAgent)
|
||||
req.Header.Set("User-Agent", getUserAgent())
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf(fmt.Sprintf("%d: %s "+http.StatusText(resp.StatusCode), resp.StatusCode, providerURL))
|
||||
err = fmt.Errorf("%d: %s %s", resp.StatusCode, providerURL, http.StatusText(resp.StatusCode))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+20
-9
@@ -16,7 +16,7 @@ func showInfo(str string) {
|
||||
return
|
||||
}
|
||||
|
||||
var max = 22
|
||||
var max = 23
|
||||
var msg = strings.SplitN(str, ":", 2)
|
||||
var length = len(msg[0])
|
||||
var space string
|
||||
@@ -48,7 +48,7 @@ func showDebug(str string, level int) {
|
||||
return
|
||||
}
|
||||
|
||||
var max = 22
|
||||
var max = 23
|
||||
var msg = strings.SplitN(str, ":", 2)
|
||||
var length = len(msg[0])
|
||||
var space string
|
||||
@@ -78,7 +78,7 @@ func showDebug(str string, level int) {
|
||||
|
||||
func showHighlight(str string) {
|
||||
|
||||
var max = 22
|
||||
var max = 23
|
||||
var msg = strings.SplitN(str, ":", 2)
|
||||
var length = len(msg[0])
|
||||
var space string
|
||||
@@ -232,7 +232,7 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
case 1004:
|
||||
errMsg = fmt.Sprintf("File not found")
|
||||
case 1005:
|
||||
errMsg = fmt.Sprintf("Invalide m3u")
|
||||
errMsg = fmt.Sprintf("Invalid M3U file, an extended M3U file is required.")
|
||||
case 1006:
|
||||
errMsg = fmt.Sprintf("No playlist!")
|
||||
case 1007:
|
||||
@@ -254,12 +254,13 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
// Datenbank Update
|
||||
case 1030:
|
||||
errMsg = fmt.Sprintf("Invalid settings file (%s)", System.File.Settings)
|
||||
case 1031:
|
||||
errMsg = fmt.Sprintf("Database error. The database version of your settings is not compatible with this version.")
|
||||
|
||||
// M3U Parser
|
||||
case 1050:
|
||||
errMsg = fmt.Sprintf("Invalid duration specification in the M3U8 playlist.")
|
||||
|
||||
// M3U Parser
|
||||
case 1060:
|
||||
errMsg = fmt.Sprintf("Invalid characters found in the tvg parameters, streams with invalid parameters were skipped.")
|
||||
|
||||
@@ -268,6 +269,8 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
errMsg = fmt.Sprintf("Folder could not be created.")
|
||||
case 1071:
|
||||
errMsg = fmt.Sprintf("File could not be created")
|
||||
case 1072:
|
||||
errMsg = fmt.Sprintf("File not found")
|
||||
|
||||
// Backup
|
||||
case 1090:
|
||||
@@ -292,12 +295,14 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
errMsg = fmt.Sprintf("Steaming URL could not be found in any playlist")
|
||||
case 1203:
|
||||
errMsg = fmt.Sprintf("Steaming URL could not be found in any playlist")
|
||||
case 1204:
|
||||
errMsg = fmt.Sprintf("Streaming was stopped by third party transcoder (FFmpeg / VLC)")
|
||||
|
||||
// Warnings
|
||||
case 2000:
|
||||
errMsg = fmt.Sprintf("Plex can not handle more than %d streams. If you do not use Plex, you can ignore this warning.", System.DVRLimit)
|
||||
errMsg = fmt.Sprintf("Plex can not handle more than %d streams. If you do not use Plex, you can ignore this warning.", System.PlexChannelLimit)
|
||||
case 2001:
|
||||
errMsg = fmt.Sprintf("%s has loaded more than %d streams. Use the filter to reduce the number of streams.", System.Name, System.DVRLimit)
|
||||
errMsg = fmt.Sprintf("%s has loaded more than %d streams. Use the filter to reduce the number of streams.", System.Name, System.UnfilteredChannelLimit)
|
||||
case 2002:
|
||||
errMsg = fmt.Sprintf("PMS can not play m3u8 streams")
|
||||
case 2003:
|
||||
@@ -308,13 +313,17 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
errMsg = fmt.Sprintf("There are no channels mapped, use the mapping menu to assign EPG data to the channels.")
|
||||
case 2010:
|
||||
errMsg = fmt.Sprintf("No valid streaming URL")
|
||||
case 2020:
|
||||
errMsg = fmt.Sprintf("FFmpeg binary was not found. Check the FFmpeg binary path in the xTeVe settings.")
|
||||
case 2021:
|
||||
errMsg = fmt.Sprintf("VLC binary was not found. Check the VLC path binary in the xTeVe settings.")
|
||||
|
||||
case 2099:
|
||||
errMsg = fmt.Sprintf("Updates have been disabled by the developer")
|
||||
|
||||
// Tuner
|
||||
case 2105:
|
||||
errMsg = fmt.Sprintf("The number of tuners has changed, you have to delete " + System.Name + " in Plex / Emby HDHR and set it up again.")
|
||||
errMsg = "The number of tuners has changed, you have to delete " + System.Name + " in Plex / Emby HDHR and set it up again."
|
||||
case 2106:
|
||||
errMsg = fmt.Sprintf("This function is only available with XEPG as EPG source")
|
||||
|
||||
@@ -347,6 +356,8 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
errMsg = fmt.Sprintf("This error message comes from the provider")
|
||||
case 4005:
|
||||
errMsg = fmt.Sprintf("Temporary buffer files could not be deleted")
|
||||
case 4006:
|
||||
errMsg = fmt.Sprintf("Server connection timeout")
|
||||
|
||||
// Buffer (M3U8)
|
||||
case 4050:
|
||||
@@ -370,7 +381,7 @@ func getErrMsg(errCode int) (errMsg string) {
|
||||
case 6002:
|
||||
errMsg = fmt.Sprintf("Update failed")
|
||||
case 6003:
|
||||
errMsg = fmt.Sprintf("Server not available")
|
||||
errMsg = fmt.Sprintf("Update server not available")
|
||||
case 6004:
|
||||
errMsg = fmt.Sprintf("xTeVe update available")
|
||||
|
||||
|
||||
@@ -108,3 +108,147 @@ type BandwidthCalculation struct {
|
||||
Stop time.Time
|
||||
TimeDiff float64
|
||||
}
|
||||
|
||||
/*
|
||||
var args = "-hide_banner -loglevel panic -re -i " + url + " -codec copy -f mpegts pipe:1"
|
||||
//var args = "-re -i " + url + " -codec copy -f mpegts pipe:1"
|
||||
cmd := exec.Command("/usr/local/bin/ffmpeg", strings.Split(args, " ")...)
|
||||
|
||||
//run := exec.Command("/usr/local/bin/ffmpeg", "-hide_banner", "-loglevel", "panic", "-re", "-i", url, "-codec", "copy", "-f", "mpegts", "pipe:1")
|
||||
//run := exec.Command("/usr/local/bin/ffmpeg", "-re", "-i", url, "-codec", "copy", "-f", "mpegts", "pipe:1")
|
||||
|
||||
stderr, _ := cmd.StderrPipe()
|
||||
cmd.Start()
|
||||
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
m := scanner.Text()
|
||||
fmt.Println(m)
|
||||
}
|
||||
cmd.Wait()
|
||||
|
||||
os.Exit(0)
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
ffmpegOut, _ := run.StderrPipe()
|
||||
//run.Start()
|
||||
|
||||
scanner = bufio.NewScanner(ffmpegOut)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
m := scanner.Text()
|
||||
fmt.Println(m)
|
||||
}
|
||||
|
||||
ffmpegOut, err = run.StdoutPipe()
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return
|
||||
}
|
||||
|
||||
stderr, stderrErr := run.StderrPipe()
|
||||
if stderrErr != nil {
|
||||
fmt.Println(stderrErr)
|
||||
}
|
||||
|
||||
_ = stderr
|
||||
|
||||
if startErr := run.Start(); startErr != nil {
|
||||
fmt.Println(startErr)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
n, err := ffmpegOut.Read(buffer)
|
||||
_ = n
|
||||
_ = stream
|
||||
_ = fileSize
|
||||
|
||||
if err != nil && err != io.EOF {
|
||||
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
defer bufferFile.Close()
|
||||
|
||||
scanner = bufio.NewScanner(ffmpegOut)
|
||||
|
||||
for scanner.Scan() {
|
||||
//fmt.Printf("%s\n", scanner.Text())
|
||||
//fmt.Println(scanner)
|
||||
thisLine := scanner.Text()
|
||||
line := make([]byte, len(thisLine))
|
||||
|
||||
buffer = append(buffer, line...)
|
||||
|
||||
fmt.Println(len(buffer))
|
||||
|
||||
if len(buffer) > tmpFileSize {
|
||||
|
||||
if _, err := bufferFile.Write(buffer[:]); err != nil {
|
||||
|
||||
ShowError(err, 0)
|
||||
addErrorToStream(err)
|
||||
run.Process.Kill()
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
buffer = make([]byte, 1024*Settings.BufferSize*2)
|
||||
|
||||
debug = fmt.Sprintf("Buffer Status:Done (%s)", tmpFile)
|
||||
showDebug(debug, 2)
|
||||
|
||||
bufferFile.Close()
|
||||
|
||||
stream.Status = true
|
||||
playlist.Streams[streamID] = stream
|
||||
BufferInformation.Store(playlistID, playlist)
|
||||
|
||||
tmpSegment++
|
||||
|
||||
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
|
||||
|
||||
if clientConnection(stream) == false {
|
||||
|
||||
bufferFile.Close()
|
||||
run.Process.Kill()
|
||||
|
||||
err = os.RemoveAll(stream.Folder)
|
||||
if err != nil {
|
||||
ShowError(err, 4005)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
bufferFile, err = os.Create(tmpFile)
|
||||
if err != nil {
|
||||
addErrorToStream(err)
|
||||
run.Process.Kill()
|
||||
return
|
||||
}
|
||||
|
||||
fileSize = 0
|
||||
|
||||
if n == 0 {
|
||||
bufferFile.Close()
|
||||
run.Process.Kill()
|
||||
break
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
+1
-5
@@ -47,11 +47,7 @@ type LineupStatus struct {
|
||||
}
|
||||
|
||||
// Lineup : HDHR Lineup /lineup.json
|
||||
type Lineup []interface {
|
||||
//GuideName string `json:"GuideName"`
|
||||
//GuideNumber string `json:"GuideNumber"`
|
||||
//URL string `json:"URL"`
|
||||
}
|
||||
type Lineup []any
|
||||
|
||||
// LineupStream : HDHR einzelner Stream im Lineup
|
||||
type LineupStream struct {
|
||||
|
||||
+72
-42
@@ -1,5 +1,7 @@
|
||||
package src
|
||||
|
||||
import "xteve/src/internal/imgcache"
|
||||
|
||||
// SystemStruct : Beinhaltet alle Systeminformationen
|
||||
type SystemStruct struct {
|
||||
Addresses struct {
|
||||
@@ -8,19 +10,30 @@ type SystemStruct struct {
|
||||
XML string
|
||||
}
|
||||
|
||||
APIVersion string
|
||||
AppName string
|
||||
ARCH string
|
||||
BackgroundProcess bool
|
||||
Branch string
|
||||
Build string
|
||||
Compatibility string
|
||||
ConfigurationWizard bool
|
||||
DBVersion string
|
||||
Dev bool
|
||||
DeviceID string
|
||||
Domain string
|
||||
DVRLimit int
|
||||
APIVersion string
|
||||
AppName string
|
||||
ARCH string
|
||||
BackgroundProcess bool
|
||||
Branch string
|
||||
Build string
|
||||
Compatibility string
|
||||
ConfigurationWizard bool
|
||||
DBVersion string
|
||||
Dev bool
|
||||
DeviceID string
|
||||
Domain string
|
||||
PlexChannelLimit int
|
||||
UnfilteredChannelLimit int
|
||||
|
||||
FFmpeg struct {
|
||||
DefaultOptions string
|
||||
Path string
|
||||
}
|
||||
|
||||
VLC struct {
|
||||
DefaultOptions string
|
||||
Path string
|
||||
}
|
||||
|
||||
File struct {
|
||||
Authentication string
|
||||
@@ -32,6 +45,10 @@ type SystemStruct struct {
|
||||
XML string
|
||||
}
|
||||
|
||||
Compressed struct {
|
||||
GZxml string
|
||||
}
|
||||
|
||||
Flag struct {
|
||||
Branch string
|
||||
Debug int
|
||||
@@ -85,6 +102,7 @@ type SystemStruct struct {
|
||||
}
|
||||
|
||||
URLBase string
|
||||
UDPxy string
|
||||
Version string
|
||||
WEB struct {
|
||||
Menu []string
|
||||
@@ -100,6 +118,7 @@ type GitStruct struct {
|
||||
// DataStruct : Alle Daten werden hier abgelegt. (Lineup, XMLTV)
|
||||
type DataStruct struct {
|
||||
Cache struct {
|
||||
Images *imgcache.Cache
|
||||
ImagesCache []string
|
||||
ImagesFiles []string
|
||||
ImagesURLS []string
|
||||
@@ -130,18 +149,18 @@ type DataStruct struct {
|
||||
}
|
||||
|
||||
Streams struct {
|
||||
Active []interface{}
|
||||
All []interface{}
|
||||
Inactive []interface{}
|
||||
Active []any
|
||||
All []any
|
||||
Inactive []any
|
||||
}
|
||||
|
||||
XMLTV struct {
|
||||
Files []string
|
||||
Mapping map[string]interface{}
|
||||
Mapping map[string]any
|
||||
}
|
||||
|
||||
XEPG struct {
|
||||
Channels map[string]interface{}
|
||||
Channels map[string]any
|
||||
XEPGCount int64
|
||||
}
|
||||
}
|
||||
@@ -177,6 +196,7 @@ type XEPGChannelStruct struct {
|
||||
XName string `json:"x-name,required"`
|
||||
XUpdateChannelIcon bool `json:"x-update-channel-icon,required"`
|
||||
XUpdateChannelName bool `json:"x-update-channel-name,required"`
|
||||
XDescription string `json:"x-description,required"`
|
||||
}
|
||||
|
||||
// M3UChannelStructXEPG : M3U Struktur für XEPG
|
||||
@@ -231,9 +251,12 @@ type Notification struct {
|
||||
Type string `json:"type,required"`
|
||||
}
|
||||
|
||||
// SettingsStrcut : Inhalt der settings.json
|
||||
type SettingsStrcut struct {
|
||||
// SettingsStruct : Inhalt der settings.json
|
||||
type SettingsStruct struct {
|
||||
API bool `json:"api"`
|
||||
UsePlexAPI bool `json:"use_plexAPI"`
|
||||
PlexURL string `json:"plex.url"`
|
||||
PlexToken string `json:"plex.token"`
|
||||
AuthenticationAPI bool `json:"authentication.api"`
|
||||
AuthenticationM3U bool `json:"authentication.m3u"`
|
||||
AuthenticationPMS bool `json:"authentication.pms"`
|
||||
@@ -242,38 +265,45 @@ type SettingsStrcut struct {
|
||||
BackupKeep int `json:"backup.keep"`
|
||||
BackupPath string `json:"backup.path"`
|
||||
Branch string `json:"git.branch,omitempty"`
|
||||
Buffer bool `json:"buffer"`
|
||||
Buffer string `json:"buffer"`
|
||||
BufferSize int `json:"buffer.size.kb"`
|
||||
BufferTimeout float64 `json:"buffer.timeout"`
|
||||
CacheImages bool `json:"cache.images"`
|
||||
EpgSource string `json:"epgSource"`
|
||||
FFmpegOptions string `json:"ffmpeg.options"`
|
||||
FFmpegPath string `json:"ffmpeg.path"`
|
||||
VLCOptions string `json:"vlc.options"`
|
||||
VLCPath string `json:"vlc.path"`
|
||||
FileM3U []string `json:"file,omitempty"` // Beim Wizard wird die M3U in ein Slice gespeichert
|
||||
FileXMLTV []string `json:"xmltv,omitempty"` // Altes Speichersystem der Provider XML Datei Slice (Wird für die Umwandlung auf das neue benötigt)
|
||||
|
||||
Files struct {
|
||||
HDHR map[string]interface{} `json:"hdhr"`
|
||||
M3U map[string]interface{} `json:"m3u"`
|
||||
XMLTV map[string]interface{} `json:"xmltv"`
|
||||
HDHR map[string]any `json:"hdhr"`
|
||||
M3U map[string]any `json:"m3u"`
|
||||
XMLTV map[string]any `json:"xmltv"`
|
||||
} `json:"files"`
|
||||
|
||||
FilesUpdate bool `json:"files.update"`
|
||||
Filter map[int64]interface{} `json:"filter"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Language string `json:"language"`
|
||||
LogEntriesRAM int `json:"log.entries.ram"`
|
||||
M3U8AdaptiveBandwidthMBPS int `json:"m3u8.adaptive.bandwidth.mbps"`
|
||||
MappingFirstChannel float64 `json:"mapping.first.channel"`
|
||||
Port string `json:"port"`
|
||||
SSDP bool `json:"ssdp"`
|
||||
TempPath string `json:"temp.path"`
|
||||
Tuner int `json:"tuner"`
|
||||
Update []string `json:"update"`
|
||||
UpdateURL string `json:"update.url,omitempty"`
|
||||
UserAgent string `json:"user.agent"`
|
||||
UUID string `json:"uuid"`
|
||||
Version string `json:"version"`
|
||||
XepgReplaceMissingImages bool `json:"xepg.replace.missing.images"`
|
||||
XteveAutoUpdate bool `json:"xteveAutoUpdate"`
|
||||
FilesUpdate bool `json:"files.update"`
|
||||
Filter map[int64]any `json:"filter"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Language string `json:"language"`
|
||||
LogEntriesRAM int `json:"log.entries.ram"`
|
||||
M3U8AdaptiveBandwidthMBPS int `json:"m3u8.adaptive.bandwidth.mbps"`
|
||||
MappingFirstChannel float64 `json:"mapping.first.channel"`
|
||||
Port string `json:"port"`
|
||||
SSDP bool `json:"ssdp"`
|
||||
TempPath string `json:"temp.path"`
|
||||
Tuner int `json:"tuner"`
|
||||
Update []string `json:"update"`
|
||||
UpdateURL string `json:"update.url,omitempty"`
|
||||
UserAgent string `json:"user.agent"`
|
||||
UUID string `json:"uuid"`
|
||||
UDPxy string `json:"udpxy"`
|
||||
Version string `json:"version"`
|
||||
XepgMissingEPGMode string `json:"xepg.missing.epg.mode"`
|
||||
XepgReplaceMissingImages bool `json:"xepg.replace.missing.images"`
|
||||
XteveAutoUpdate bool `json:"xteveAutoUpdate"`
|
||||
WizardCompleted bool `json:"wizard.completed"`
|
||||
}
|
||||
|
||||
// LanguageUI : Sprache für das WebUI
|
||||
|
||||
+38
-27
@@ -6,11 +6,11 @@ type RequestStruct struct {
|
||||
Cmd string `json:"cmd,required"`
|
||||
|
||||
// Benutzer
|
||||
DeleteUser bool `json:"deleteUser,omitempty"`
|
||||
UserData map[string]interface{} `json:"userData,omitempty"`
|
||||
DeleteUser bool `json:"deleteUser,omitempty"`
|
||||
UserData map[string]any `json:"userData,omitempty"`
|
||||
|
||||
// Mapping
|
||||
EpgMapping map[string]interface{} `json:"epgMapping,omitempty"`
|
||||
EpgMapping map[string]any `json:"epgMapping,omitempty"`
|
||||
|
||||
// Restore
|
||||
Base64 string `json:"base64,omitempty"`
|
||||
@@ -18,6 +18,9 @@ type RequestStruct struct {
|
||||
// Neue Werte für die Einstellungen (settings.json)
|
||||
Settings struct {
|
||||
API *bool `json:"api,omitempty"`
|
||||
UsePlexAPI *bool `json:"use_plexAPI,omitempty"`
|
||||
PlexURL *string `json:"plex.url,omitempty"`
|
||||
PlexToken *string `json:"plex.token,omitempty"`
|
||||
AuthenticationAPI *bool `json:"authentication.api,omitempty"`
|
||||
AuthenticationM3U *bool `json:"authentication.m3u,omitempty"`
|
||||
AuthenticationPMS *bool `json:"authentication.pms,omitempty"`
|
||||
@@ -25,32 +28,40 @@ type RequestStruct struct {
|
||||
AuthenticationXML *bool `json:"authentication.xml,omitempty"`
|
||||
BackupKeep *int `json:"backup.keep,omitempty"`
|
||||
BackupPath *string `json:"backup.path,omitempty"`
|
||||
Buffer *bool `json:"buffer,omitempty"`
|
||||
BufferSize *int `json:"buffer.size.kb, omitempty"`
|
||||
Buffer *string `json:"buffer,omitempty"`
|
||||
BufferSize *int `json:"buffer.size.kb,omitempty"`
|
||||
BufferTimeout *float64 `json:"buffer.timeout,omitempty"`
|
||||
CacheImages *bool `json:"cache.images,omitempty"`
|
||||
EpgSource *string `json:"epgSource,omitempty"`
|
||||
FFmpegOptions *string `json:"ffmpeg.options,omitempty"`
|
||||
FFmpegPath *string `json:"ffmpeg.path,omitempty"`
|
||||
VLCOptions *string `json:"vlc.options,omitempty"`
|
||||
VLCPath *string `json:"vlc.path,omitempty"`
|
||||
FilesUpdate *bool `json:"files.update,omitempty"`
|
||||
TempPath *string `json:"temp.path,omitempty"`
|
||||
Tuner *int `json:"tuner,omitempty"`
|
||||
UDPxy *string `json:"udpxy,omitempty"`
|
||||
Update *[]string `json:"update,omitempty"`
|
||||
UserAgent *string `json:"user.agent,omitempty"`
|
||||
XepgMissingEPGMode *string `json:"xepg.missing.epg.mode,omitempty"`
|
||||
XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"`
|
||||
XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"`
|
||||
} `json:"settings,omitempty"`
|
||||
SchemeM3U *string `json:"scheme.m3u,omitempty"`
|
||||
SchemeXML *string `json:"scheme.xml,omitempty"`
|
||||
} `json:"settings"`
|
||||
|
||||
// Upload Logo
|
||||
Filename string `json:"filename,omitempty"`
|
||||
|
||||
// Filter
|
||||
Filter map[int64]interface{} `json:"filter,omitempty"`
|
||||
Filter map[int64]any `json:"filter,omitempty"`
|
||||
|
||||
// Dateien (M3U, HDHR, XMLTV)
|
||||
Files struct {
|
||||
HDHR map[string]interface{} `json:"hdhr,omitempty"`
|
||||
M3U map[string]interface{} `json:"m3u,omitempty"`
|
||||
XMLTV map[string]interface{} `json:"xmltv,omitempty"`
|
||||
} `json:"files,omitempty"`
|
||||
HDHR map[string]any `json:"hdhr,omitempty"`
|
||||
M3U map[string]any `json:"m3u,omitempty"`
|
||||
XMLTV map[string]any `json:"xmltv,omitempty"`
|
||||
} `json:"files"`
|
||||
|
||||
// Wizard
|
||||
Wizard struct {
|
||||
@@ -58,7 +69,7 @@ type RequestStruct struct {
|
||||
M3U *string `json:"m3u,omitempty"`
|
||||
Tuner *int `json:"tuner,omitempty"`
|
||||
XMLTV *string `json:"xmltv,omitempty"`
|
||||
} `json:"wizard,omitempty"`
|
||||
} `json:"wizard"`
|
||||
}
|
||||
|
||||
// ResponseStruct : Antworten an den Client (WEB)
|
||||
@@ -77,7 +88,7 @@ type ResponseStruct struct {
|
||||
Warnings int `json:"warnings"`
|
||||
XEPGCount int64 `json:"xepg"`
|
||||
XML string `json:"xepg-url,required"`
|
||||
} `json:"clientInfo,omitempty"`
|
||||
} `json:"clientInfo"`
|
||||
|
||||
Data struct {
|
||||
Playlist struct {
|
||||
@@ -95,20 +106,20 @@ type ResponseStruct struct {
|
||||
}
|
||||
} `json:"data,required"`
|
||||
|
||||
Alert string `json:"alert,omitempty"`
|
||||
ConfigurationWizard bool `json:"configurationWizard,required"`
|
||||
Error string `json:"err,omitempty"`
|
||||
Log WebScreenLogStruct `json:"log,required"`
|
||||
LogoURL string `json:"logoURL,omitempty"`
|
||||
OpenLink string `json:"openLink,omitempty"`
|
||||
OpenMenu string `json:"openMenu,omitempty"`
|
||||
Reload bool `json:"reload,omitempty"`
|
||||
Settings SettingsStrcut `json:"settings,required"`
|
||||
Status bool `json:"status,required"`
|
||||
Token string `json:"token,omitempty"`
|
||||
Users map[string]interface{} `json:"users,omitempty"`
|
||||
Wizard int `json:"wizard,omitempty"`
|
||||
XEPG map[string]interface{} `json:"xepg,required"`
|
||||
Alert string `json:"alert,omitempty"`
|
||||
ConfigurationWizard bool `json:"configurationWizard,required"`
|
||||
Error string `json:"err,omitempty"`
|
||||
Log WebScreenLogStruct `json:"log,required"`
|
||||
LogoURL string `json:"logoURL,omitempty"`
|
||||
OpenLink string `json:"openLink,omitempty"`
|
||||
OpenMenu string `json:"openMenu,omitempty"`
|
||||
Reload bool `json:"reload,omitempty"`
|
||||
Settings SettingsStruct `json:"settings,required"`
|
||||
Status bool `json:"status,required"`
|
||||
Token string `json:"token,omitempty"`
|
||||
Users map[string]any `json:"users,omitempty"`
|
||||
Wizard int `json:"wizard,omitempty"`
|
||||
XEPG map[string]any `json:"xepg,required"`
|
||||
|
||||
Notification map[string]Notification `json:"notification,omitempty"`
|
||||
}
|
||||
|
||||
@@ -42,12 +42,16 @@ type Program struct {
|
||||
Country []*Country `xml:"country"`
|
||||
EpisodeNum []*EpisodeNum `xml:"episode-num"`
|
||||
Poster []Poster `xml:"icon"`
|
||||
Credits Credits `xml:"credits,omitempty"` //`xml:",innerxml,omitempty"`
|
||||
Rating []Rating `xml:"rating"`
|
||||
StarRating []StarRating `xml:"star-rating"`
|
||||
Language []*Language `xml:"language"`
|
||||
Video Video `xml:"video"`
|
||||
Date string `xml:"date"`
|
||||
PreviouslyShown *PreviouslyShown `xml:"previously-shown"`
|
||||
New *New `xml:"new"`
|
||||
Live *Live `xml:"live"`
|
||||
Premiere *Live `xml:"premiere"`
|
||||
}
|
||||
|
||||
// Title : Programmtitel
|
||||
@@ -74,6 +78,19 @@ type Category struct {
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Rating : Bewertung
|
||||
type Rating struct {
|
||||
System string `xml:"system,attr"`
|
||||
Value string `xml:"value"`
|
||||
Icon []Icon `xml:"icon"`
|
||||
}
|
||||
|
||||
// StarRating : Bewertung / Kritiken
|
||||
type StarRating struct {
|
||||
Value string `xml:"value"`
|
||||
System string `xml:"system,attr"`
|
||||
}
|
||||
|
||||
// Language : Sprachen
|
||||
type Language struct {
|
||||
Value string `xml:",chardata"`
|
||||
@@ -99,6 +116,41 @@ type Poster struct {
|
||||
Width string `xml:"width,attr"`
|
||||
}
|
||||
|
||||
// Credits : Credits
|
||||
type Credits struct {
|
||||
Director []Director `xml:"director,omitempty"`
|
||||
Actor []Actor `xml:"actor,omitempty"`
|
||||
Writer []Writer `xml:"writer,omitempty"`
|
||||
Presenter []Presenter `xml:"presenter,omitempty"`
|
||||
Producer []Producer `xml:"producer,omitempty"`
|
||||
}
|
||||
|
||||
// Director : Director
|
||||
type Director struct {
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Actor : Actor
|
||||
type Actor struct {
|
||||
Value string `xml:",chardata"`
|
||||
Role string `xml:"role,attr,omitempty"`
|
||||
}
|
||||
|
||||
// Writer : Writer
|
||||
type Writer struct {
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Presenter : Presenter
|
||||
type Presenter struct {
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Producer : Producer
|
||||
type Producer struct {
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Video : Video Metadaten
|
||||
type Video struct {
|
||||
Aspect string `xml:"aspect,omitempty"`
|
||||
|
||||
+86
-13
@@ -59,7 +59,7 @@ func createSystemFiles() (err error) {
|
||||
err = checkFile(filename)
|
||||
if err != nil {
|
||||
// Datei existiert nicht, wird jetzt erstellt
|
||||
err = saveMapToJSONFile(filename, make(map[string]interface{}))
|
||||
err = saveMapToJSONFile(filename, make(map[string]any))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -90,22 +90,35 @@ func createSystemFiles() (err error) {
|
||||
}
|
||||
|
||||
// Einstellungen laden und default Werte setzen (xTeVe)
|
||||
func loadSettings() (settings SettingsStrcut, err error) {
|
||||
func loadSettings() (settings SettingsStruct, err error) {
|
||||
|
||||
settingsMap, err := loadJSONFileToMap(System.File.Settings)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Deafult Werte setzten
|
||||
var defaults = make(map[string]interface{})
|
||||
var dataMap = make(map[string]interface{})
|
||||
var freshInstall = len(settingsMap) == 0
|
||||
|
||||
dataMap["xmltv"] = make(map[string]interface{})
|
||||
dataMap["m3u"] = make(map[string]interface{})
|
||||
dataMap["hdhr"] = make(map[string]interface{})
|
||||
// Deafult Werte setzten
|
||||
var defaults = make(map[string]any)
|
||||
var dataMap = make(map[string]any)
|
||||
|
||||
dataMap["xmltv"] = make(map[string]any)
|
||||
dataMap["m3u"] = make(map[string]any)
|
||||
dataMap["hdhr"] = make(map[string]any)
|
||||
|
||||
defaultFFmpegPath := ""
|
||||
if len(os.Getenv("XTEVE_CONFIG")) > 0 {
|
||||
containerFFmpegPath := "/usr/local/bin/ffmpeg"
|
||||
if checkFile(containerFFmpegPath) == nil {
|
||||
defaultFFmpegPath = containerFFmpegPath
|
||||
}
|
||||
}
|
||||
|
||||
defaults["api"] = false
|
||||
defaults["use_plexAPI"] = false
|
||||
defaults["plex.url"] = ""
|
||||
defaults["plex.token"] = ""
|
||||
defaults["authentication.api"] = false
|
||||
defaults["authentication.m3u"] = false
|
||||
defaults["authentication.pms"] = false
|
||||
@@ -113,29 +126,39 @@ func loadSettings() (settings SettingsStrcut, err error) {
|
||||
defaults["authentication.xml"] = false
|
||||
defaults["backup.keep"] = 10
|
||||
defaults["backup.path"] = System.Folder.Backup
|
||||
defaults["buffer"] = false
|
||||
defaults["buffer"] = "-"
|
||||
defaults["buffer.size.kb"] = 1024
|
||||
defaults["buffer.timeout"] = 500
|
||||
defaults["cache.images"] = false
|
||||
defaults["epgSource"] = "PMS"
|
||||
defaults["ffmpeg.path"] = defaultFFmpegPath
|
||||
defaults["ffmpeg.options"] = System.FFmpeg.DefaultOptions
|
||||
defaults["vlc.options"] = System.VLC.DefaultOptions
|
||||
defaults["files"] = dataMap
|
||||
defaults["files.update"] = true
|
||||
defaults["filter"] = make(map[string]interface{})
|
||||
defaults["filter"] = make(map[string]any)
|
||||
defaults["git.branch"] = System.Branch
|
||||
defaults["language"] = "en"
|
||||
defaults["log.entries.ram"] = 500
|
||||
defaults["mapping.first.channel"] = 1000
|
||||
defaults["xepg.missing.epg.mode"] = "strict"
|
||||
defaults["xepg.replace.missing.images"] = true
|
||||
defaults["m3u8.adaptive.bandwidth.mbps"] = 10
|
||||
defaults["port"] = "34400"
|
||||
defaults["ssdp"] = true
|
||||
defaults["tuner"] = 1
|
||||
defaults["update"] = []string{"0000"}
|
||||
defaults["user.agent"] = System.Name
|
||||
defaults["user.agent"] = defaultUserAgent
|
||||
defaults["uuid"] = createUUID()
|
||||
defaults["udpxy"] = ""
|
||||
defaults["version"] = System.DBVersion
|
||||
defaults["xteveAutoUpdate"] = true
|
||||
defaults["temp.path"] = System.Folder.Temp
|
||||
defaults["wizard.completed"] = !freshInstall
|
||||
var defaultTempPath = System.Folder.Temp
|
||||
if len(os.Getenv("XTEVE_CONFIG")) > 0 {
|
||||
defaultTempPath = System.Folder.Config + "tmp" + string(os.PathSeparator)
|
||||
}
|
||||
defaults["temp.path"] = defaultTempPath
|
||||
|
||||
// Default Werte setzen
|
||||
for key, value := range defaults {
|
||||
@@ -159,15 +182,37 @@ func loadSettings() (settings SettingsStrcut, err error) {
|
||||
showInfo(fmt.Sprintf("Git Branch:Switching Git Branch to -> %s", settings.Branch))
|
||||
}
|
||||
|
||||
if len(settings.FFmpegPath) == 0 {
|
||||
containerFFmpegPath := "/usr/local/bin/ffmpeg"
|
||||
if len(os.Getenv("XTEVE_CONFIG")) > 0 && checkFile(containerFFmpegPath) == nil {
|
||||
settings.FFmpegPath = containerFFmpegPath
|
||||
} else {
|
||||
settings.FFmpegPath = searchFileInOS("ffmpeg")
|
||||
}
|
||||
}
|
||||
|
||||
if len(settings.VLCPath) == 0 {
|
||||
settings.VLCPath = searchFileInOS("cvlc")
|
||||
}
|
||||
|
||||
settings.Version = System.DBVersion
|
||||
|
||||
err = saveSettings(settings)
|
||||
|
||||
// Warung wenn FFmpeg nicht gefunden wurde
|
||||
if len(Settings.FFmpegPath) == 0 && Settings.Buffer == "ffmpeg" {
|
||||
showWarning(2020)
|
||||
}
|
||||
|
||||
if len(Settings.VLCPath) == 0 && Settings.Buffer == "vlc" {
|
||||
showWarning(2021)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Einstellungen speichern (xTeVe)
|
||||
func saveSettings(settings SettingsStrcut) (err error) {
|
||||
func saveSettings(settings SettingsStruct) (err error) {
|
||||
|
||||
if settings.BackupKeep == 0 {
|
||||
settings.BackupKeep = 10
|
||||
@@ -181,8 +226,36 @@ func saveSettings(settings SettingsStrcut) (err error) {
|
||||
settings.BufferTimeout = 0
|
||||
}
|
||||
|
||||
var userAgent = strings.TrimSpace(settings.UserAgent)
|
||||
if len(userAgent) == 0 || userAgent == System.Name {
|
||||
settings.UserAgent = defaultUserAgent
|
||||
}
|
||||
|
||||
settings.XepgMissingEPGMode = strings.ToLower(strings.TrimSpace(settings.XepgMissingEPGMode))
|
||||
if settings.XepgMissingEPGMode != "relaxed" {
|
||||
settings.XepgMissingEPGMode = "strict"
|
||||
}
|
||||
|
||||
settings.TempPath = strings.TrimRight(settings.TempPath, string(os.PathSeparator)) + string(os.PathSeparator)
|
||||
System.Folder.Temp = settings.TempPath + settings.UUID + string(os.PathSeparator)
|
||||
|
||||
err = checkFolder(System.Folder.Temp)
|
||||
if err != nil {
|
||||
|
||||
fallbackTempPath := System.Folder.Config + "tmp" + string(os.PathSeparator)
|
||||
fallbackTempFolder := fallbackTempPath + settings.UUID + string(os.PathSeparator)
|
||||
fallbackErr := checkFolder(fallbackTempFolder)
|
||||
|
||||
if fallbackErr != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.TempPath = fallbackTempPath
|
||||
System.Folder.Temp = fallbackTempFolder
|
||||
showInfo(fmt.Sprintf("Temporary Folder:Fallback to %s", getPlatformPath(System.Folder.Temp)))
|
||||
|
||||
}
|
||||
|
||||
err = writeByteToFile(System.File.Settings, []byte(mapToJSON(settings)))
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
+71
-12
@@ -10,8 +10,11 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
@@ -42,13 +45,25 @@ func checkFolder(path string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prüft ob die datei im Dateisystem existiert
|
||||
// Prüft ob die Datei im Dateisystem existiert
|
||||
func checkFile(filename string) (err error) {
|
||||
|
||||
var file = getPlatformFile(filename)
|
||||
|
||||
if _, err = os.Stat(file); os.IsNotExist(err) {
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
fi, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch mode := fi.Mode(); {
|
||||
case mode.IsDir():
|
||||
err = fmt.Errorf("%s: %s", file, getErrMsg(1072))
|
||||
case mode.IsRegular():
|
||||
break
|
||||
}
|
||||
|
||||
return
|
||||
@@ -77,6 +92,7 @@ func GetUserHomeDirectory() (userHomeDirectory string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prüft Dateiberechtigung
|
||||
func checkFilePermission(dir string) (err error) {
|
||||
|
||||
var filename = dir + "permission.test"
|
||||
@@ -115,7 +131,34 @@ func removeOldSystemData() {
|
||||
os.RemoveAll(System.Folder.Temp)
|
||||
}
|
||||
|
||||
//
|
||||
// Sucht eine Datei im OS
|
||||
func searchFileInOS(file string) (path string) {
|
||||
|
||||
switch runtime.GOOS {
|
||||
|
||||
case "linux", "darwin", "freebsd":
|
||||
var args = file
|
||||
var cmd = exec.Command("which", strings.Split(args, " ")...)
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil {
|
||||
|
||||
var slice = strings.Split(strings.Replace(string(out), "\r\n", "\n", -1), "\n")
|
||||
|
||||
if len(slice) > 0 {
|
||||
path = strings.Trim(slice[0], "\r\n")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func removeChildItems(dir string) error {
|
||||
|
||||
files, err := filepath.Glob(filepath.Join(dir, "*"))
|
||||
@@ -136,7 +179,7 @@ func removeChildItems(dir string) error {
|
||||
}
|
||||
|
||||
// JSON
|
||||
func mapToJSON(tmpMap interface{}) string {
|
||||
func mapToJSON(tmpMap any) string {
|
||||
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
if err != nil {
|
||||
@@ -146,30 +189,30 @@ func mapToJSON(tmpMap interface{}) string {
|
||||
return string(jsonString)
|
||||
}
|
||||
|
||||
func jsonToMap(content string) map[string]interface{} {
|
||||
func jsonToMap(content string) map[string]any {
|
||||
|
||||
var tmpMap = make(map[string]interface{})
|
||||
var tmpMap = make(map[string]any)
|
||||
json.Unmarshal([]byte(content), &tmpMap)
|
||||
|
||||
return (tmpMap)
|
||||
}
|
||||
|
||||
func jsonToMapInt64(content string) map[int64]interface{} {
|
||||
func jsonToMapInt64(content string) map[int64]any {
|
||||
|
||||
var tmpMap = make(map[int64]interface{})
|
||||
var tmpMap = make(map[int64]any)
|
||||
json.Unmarshal([]byte(content), &tmpMap)
|
||||
|
||||
return (tmpMap)
|
||||
}
|
||||
|
||||
func jsonToInterface(content string) (tmpMap interface{}, err error) {
|
||||
func jsonToInterface(content string) (tmpMap any, err error) {
|
||||
|
||||
err = json.Unmarshal([]byte(content), &tmpMap)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func saveMapToJSONFile(file string, tmpMap interface{}) error {
|
||||
func saveMapToJSONFile(file string, tmpMap any) error {
|
||||
|
||||
var filename = getPlatformFile(file)
|
||||
jsonString, err := json.MarshalIndent(tmpMap, "", " ")
|
||||
@@ -186,7 +229,7 @@ func saveMapToJSONFile(file string, tmpMap interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadJSONFileToMap(file string) (tmpMap map[string]interface{}, err error) {
|
||||
func loadJSONFileToMap(file string) (tmpMap map[string]any, err error) {
|
||||
|
||||
f, err := os.Open(getPlatformFile(file))
|
||||
defer f.Close()
|
||||
@@ -276,6 +319,22 @@ func resolveHostIP() (err error) {
|
||||
|
||||
}
|
||||
|
||||
if len(System.IPAddress) == 0 {
|
||||
|
||||
switch len(System.IPAddressesV4) {
|
||||
|
||||
case 0:
|
||||
if len(System.IPAddressesV6) > 0 {
|
||||
System.IPAddress = System.IPAddressesV6[0]
|
||||
}
|
||||
|
||||
default:
|
||||
System.IPAddress = System.IPAddressesV4[0]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
System.Hostname, err = os.Hostname()
|
||||
if err != nil {
|
||||
return
|
||||
@@ -300,7 +359,7 @@ func randomString(n int) string {
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func parseTemplate(content string, tmpMap map[string]interface{}) (result string) {
|
||||
func parseTemplate(content string, tmpMap map[string]any) (result string) {
|
||||
|
||||
t := template.Must(template.New("template").Parse(content))
|
||||
|
||||
|
||||
+47
-13
@@ -7,7 +7,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
up2date "../src/internal/up2date/client"
|
||||
up2date "xteve/src/internal/up2date/client"
|
||||
|
||||
"reflect"
|
||||
)
|
||||
@@ -41,19 +41,19 @@ func BinaryUpdate() (err error) {
|
||||
|
||||
resp, err := http.Get(gitInfo)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
return err
|
||||
ShowError(err, 6003)
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
|
||||
if resp.StatusCode == 404 {
|
||||
err = fmt.Errorf(fmt.Sprintf("Update Server: %s (%s)", http.StatusText(resp.StatusCode), gitInfo))
|
||||
err = fmt.Errorf("Update Server: %s (%s)", http.StatusText(resp.StatusCode), gitInfo)
|
||||
ShowError(err, 6003)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = fmt.Errorf(fmt.Sprintf("%d: %s (%s)", resp.StatusCode, http.StatusText(resp.StatusCode), gitInfo))
|
||||
err = fmt.Errorf("%d: %s (%s)", resp.StatusCode, http.StatusText(resp.StatusCode), gitInfo)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func BinaryUpdate() (err error) {
|
||||
err = up2date.GetVersion()
|
||||
if err != nil {
|
||||
|
||||
debug = fmt.Sprintf(err.Error())
|
||||
debug = err.Error()
|
||||
showDebug(debug, 1)
|
||||
|
||||
return nil
|
||||
@@ -95,7 +95,7 @@ func BinaryUpdate() (err error) {
|
||||
|
||||
if len(updater.Response.Reason) > 0 {
|
||||
|
||||
err = fmt.Errorf(fmt.Sprintf("Update Server: %s", updater.Response.Reason))
|
||||
err = fmt.Errorf("Update Server: %s", updater.Response.Reason)
|
||||
ShowError(err, 6002)
|
||||
|
||||
return nil
|
||||
@@ -169,6 +169,13 @@ checkVersion:
|
||||
|
||||
if settingsVersion, ok := settingsMap["version"].(string); ok {
|
||||
|
||||
if settingsVersion > System.DBVersion {
|
||||
showInfo("Settings DB Version:" + settingsVersion)
|
||||
showInfo("System DB Version:" + System.DBVersion)
|
||||
err = errors.New(getErrMsg(1031))
|
||||
return
|
||||
}
|
||||
|
||||
// Letzte Kompatible Version (1.4.4)
|
||||
if settingsVersion < System.Compatibility {
|
||||
err = errors.New(getErrMsg(1013))
|
||||
@@ -185,7 +192,7 @@ checkVersion:
|
||||
}
|
||||
|
||||
// Neuer Filter (WebUI). Alte Filtereinstellungen werden konvertiert
|
||||
if oldFilter, ok := settingsMap["filter"].([]interface{}); ok {
|
||||
if oldFilter, ok := settingsMap["filter"].([]any); ok {
|
||||
var newFilterMap = convertToNewFilter(oldFilter)
|
||||
settingsMap["filter"] = newFilterMap
|
||||
|
||||
@@ -204,10 +211,37 @@ checkVersion:
|
||||
}
|
||||
|
||||
case "2.0.0":
|
||||
|
||||
if oldBuffer, ok := settingsMap["buffer"].(bool); ok {
|
||||
|
||||
var newBuffer string
|
||||
switch oldBuffer {
|
||||
case true:
|
||||
newBuffer = "xteve"
|
||||
case false:
|
||||
newBuffer = "-"
|
||||
}
|
||||
|
||||
settingsMap["buffer"] = newBuffer
|
||||
|
||||
settingsMap["version"] = "2.1.0"
|
||||
|
||||
err = saveMapToJSONFile(System.File.Settings, settingsMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
goto checkVersion
|
||||
|
||||
} else {
|
||||
err = errors.New(getErrMsg(1030))
|
||||
return
|
||||
}
|
||||
|
||||
case "2.1.0":
|
||||
// Falls es in einem späteren Update Änderungen an der Datenbank gibt, geht es hier weiter
|
||||
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -218,11 +252,11 @@ checkVersion:
|
||||
return
|
||||
}
|
||||
|
||||
func convertToNewFilter(oldFilter []interface{}) (newFilterMap map[int]interface{}) {
|
||||
func convertToNewFilter(oldFilter []any) (newFilterMap map[int]any) {
|
||||
|
||||
newFilterMap = make(map[int]interface{})
|
||||
newFilterMap = make(map[int]any)
|
||||
|
||||
switch reflect.TypeOf(oldFilter).Kind() {
|
||||
switch reflect.TypeFor[[]any]().Kind() {
|
||||
|
||||
case reflect.Slice:
|
||||
s := reflect.ValueOf(oldFilter)
|
||||
@@ -251,7 +285,7 @@ func setValueForUUID() (err error) {
|
||||
|
||||
for _, c := range xepg {
|
||||
|
||||
var xepgChannel = c.(map[string]interface{})
|
||||
var xepgChannel = c.(map[string]any)
|
||||
|
||||
if uuidKey, ok := xepgChannel["_uuid.key"].(string); ok {
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package src
|
||||
|
||||
import "strings"
|
||||
|
||||
const defaultUserAgent = "otg/1.5.1 (AppleTv Apple TV 4; tvOS16.0; appletv.client) libcurl/7.58.0 OpenSSL/1.0.2o zlib/1.2.11 clib/1.8.56"
|
||||
|
||||
func getUserAgent() string {
|
||||
|
||||
var userAgent = strings.TrimSpace(Settings.UserAgent)
|
||||
if len(userAgent) == 0 {
|
||||
return defaultUserAgent
|
||||
}
|
||||
|
||||
return userAgent
|
||||
}
|
||||
+42
-44
@@ -1,51 +1,49 @@
|
||||
package src
|
||||
|
||||
var webUI = make(map[string]interface{})
|
||||
var webUI = make(map[string]any)
|
||||
|
||||
func loadHTMLMap() {
|
||||
|
||||
webUI["html/js/settings_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBTZXR0aW5nc0NhdGVnb3J5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gU2V0dGluZ3NDYXRlZ29yeSgpIHsKICAgICAgICB0aGlzLkRvY3VtZW50SUQgPSAiY29udGVudF9zZXR0aW5ncyI7CiAgICB9CiAgICBTZXR0aW5nc0NhdGVnb3J5LnByb3RvdHlwZS5jcmVhdGVDYXRlZ29yeUhlYWRsaW5lID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJINCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgU2V0dGluZ3NDYXRlZ29yeS5wcm90b3R5cGUuY3JlYXRlSFIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJIUiIpOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICAgIFNldHRpbmdzQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZVNldHRpbmdzID0gZnVuY3Rpb24gKHNldHRpbmdzS2V5KSB7CiAgICAgICAgdmFyIHNldHRpbmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgIHZhciBjb250ZW50ID0gbmV3IFBvcHVwQ29udGVudCgpOwogICAgICAgIHZhciBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdW3NldHRpbmdzS2V5XTsKICAgICAgICBzd2l0Y2ggKHNldHRpbmdzS2V5KSB7CiAgICAgICAgICAgIC8vIFRleHRlaW5nYWJlbgogICAgICAgICAgICBjYXNlICJ1cGRhdGUiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnVwZGF0ZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidXBkYXRlIiwgZGF0YS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudXBkYXRlLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJiYWNrdXAucGF0aCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYmFja3VwUGF0aC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAiYmFja3VwLnBhdGgiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MuYmFja3VwUGF0aC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidGVtcC5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy50ZW1wUGF0aC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidGVtcC5wYXRoIiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnRtcFBhdGgucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXIuYWdlbnQiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnVzZXJBZ2VudC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidXNlci5hZ2VudCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy51c2VyQWdlbnQucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2Line truncated
|
||||
webUI["html/login.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keT4KICAgICAgICAgIAogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgoKICAgICAgPGRpdiBpZD0iYm94Ij4KCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPnt7LmxvZ2luLmhlYWRsaW5lfX08L2gxPgogICAgICAgIDwvZGl2PgoKICAgICAgICA8cCBpZD0iZXJyIiBjbGFzcz0iZXJyb3JNc2cgY2VudGVyIj57ey5hdXRoZW50aWNhdGlvbkVycn19PC9wPgoKICAgICAgICA8ZGl2IGlkPSJjb250ZW50Ij4KCiAgICAgICAgICAgIDxmb3JtIGlkPSJhdXRoZW50aWNhdGlvbiIgYWN0aW9uPSIvd2ViLyIgbWV0aG9kPSJwb3N0Ij4KCiAgICAgICAgICAgICAgPGg1Pnt7LmxvZ2luLnVzZXJuYW1lLnRpdGxlfX06PC9oNT4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9InVzZXJuYW1lIiB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VybmFtZSIgcGxhY2Vob2xkZXI9IlVzZXJuYW1lIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICA8aDU+e3subG9naW4ucGFzc3dvcmQudGl0bGV9fTo8L2g1PgogICAgICAgICAgICAgIDxpbnB1dCBpZD0icGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJwYXNzd29yZCIgcGxhY2Vob2xkZXI9IlBhc3N3b3JkIiB2YWx1ZT0iIj4KCiAgICAgICAgICAgIDwvZm9ybT4KCiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgaWQ9ImJveC1mb290ZXIiPgogICAgICAgICAgPGlucHV0IGlkPSJzdWJtaXQiIGNsYXNzPSIiIHR5cGU9ImJ1dHRvbiIgdmFsdWU9Int7LmJ1dHRvbi5sb2dpbn19IiBvbmNsaWNrPSJqYXZhc2NyaXB0OiBsb2dpbigpOyI+CiAgICAgICAgPC9kaXY+CiAgICAgICAgCiAgICAgIDwvZGl2PgoKICAgIDwvYm9keT4KICAgIAo8L2h0bWw+"
|
||||
webUI["html/video/stream-limit.ts"] = "R0AREABC8CUAAcEAAP8B/wAB/IAUSBIBBkZGbXBlZwlTZXJ2aWNlMDF3fEPK//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9HQAAQAACwDQABwQAAAAHwACqxBLL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0dQABAAArASAAHBAADhAPAAG+EA8AAVvU1W////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////R0EAMAdQAAB7DH4AAAAB4AAAgMAKMQAJEKERAAfYYQAAAAEJ8AAAAAFnZAAorNlAeAIn5cBEAAADAAQAAAMAyDxgxlgAAAABaOvjyyLAAAABBgX//6rcRem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTUyIHIyODU0IGU5YTU5MDMgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDE3IC0gaHR0cDovL3dHAQARd3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2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 truncated
|
||||
webUI["html/js/base_ts.js"] = "dmFyIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKdmFyIEJVTEtfRURJVCA9IGZhbHNlOwp2YXIgQ09MVU1OX1RPX1NPUlQ7CnZhciBTRUFSQ0hfTUFQUElORyA9IG5ldyBPYmplY3QoKTsKdmFyIFVORE8gPSBuZXcgT2JqZWN0KCk7CnZhciBTRVJWRVJfQ09OTkVDVElPTiA9IGZhbHNlOwp2YXIgV1NfQVZBSUxBQkxFID0gZmFsc2U7Ci8vIE1lbsO8CnZhciBtZW51SXRlbXMgPSBuZXcgQXJyYXkoKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgicGxheWxpc3QiLCAie3subWFpbk1lbnUuaXRlbS5wbGF5bGlzdH19IiwgIm0zdS5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUucGxheWxpc3R9fSIpKTsKLy9tZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJwbXNJRCIsICJ7ey5tYWluTWVudS5pdGVtLnBtc0lEfX0iLCAibnVtYmVyLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5wbXNJRH19IikpCm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oImZpbHRlciIsICJ7ey5tYWluTWVudS5pdGVtLmZpbHRlcn19IiwgImZpbHRlci5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUuZmlsdGVyfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInhtbHR2IiwgInt7Lm1haW5NZW51Lml0ZW0ueG1sdHZ9fSIsICJ4bWx0di5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUueG1sdHZ9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibWFwcGluZyIsICJ7ey5tYWluTWVudS5pdGVtLm1hcHBpbmd9fSIsICJtYXBwaW5nLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5tYXBwaW5nfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInVzZXJzIiwgInt7Lm1haW5NZW51Lml0ZW0udXNlcnN9fSIsICJ1c2Vycy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUudXNlcnN9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgic2V0dGluZ3MiLCAie3subWFpbk1lbnUuaXRlbS5zZXR0aW5nc319IiwgInNldHRpbmdzLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5zZXR0aW5nc319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJsb2ciLCAie3subWFpbk1lbnUuaXRlbS5sb2d9fSIsICJsb2cucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmxvZ319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJsb2dvdXQiLCAie3subWFpbk1lbnUuaXRlbS5sb2dvdXR9fSIsICJsb2dvdXQucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmxvZ291dH19IikpOwovLyBLYXRlZ29yaWVuIGbDvHIgZGllIEVpbnN0ZWxsdW5nZW4KdmFyIHNldHRpbmdzQ2F0ZWdvcnkgPSBuZXcgQXJyYXkoKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkuZ2VuZXJhbH19IiwgInh0ZXZlQXV0b1VwZGF0ZSx0dW5lcixlcGdTb3VyY2UsYXBpIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5maWxlc319IiwgInVwZGF0ZSxmaWxlcy51cGRhdGUsdGVtcC5wYXRoLGNhY2hlLmltYWdlcyx4ZXBnLnJlcGxhY2UubWlzc2luZy5pbWFnZXMiKSk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LnN0cmVhbWluZ319IiwgImJ1ZmZlcixidWZmZXIuc2l6ZS5rYixidWZmZXIudGltZW91dCx1c2VyLmFnZW50IikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5iYWNrdXB9fSIsICJiYWNrdXAucGF0aCxiYWNrdXAua2VlcCIpKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkuYXV0aGVudGljYXRpb259fSIsICJhdXRoZW50aWNhdGlvbi53ZWIsYXV0aGVudGljYXRpb24ucG1zLGF1dGhlbnRpY2F0aW9uLm0zdSxhdXRoZW50aWNhdGlvbi54bWwsYXV0aGVudGljYXRpb24uYXBpIikpOwpmdW5jdGlvbiBzaG93UG9wVXBFbGVtZW50KGVsbSkgewogICAgdmFyIGFsbEVsZW1lbnRzID0gbmV3IEFycmF5KCJwb3B1cC1jdXN0b20iKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKICAgICAgICBzaG93RWxlbWVudChhbGxFbGVtZW50c1tpXSwgZmFsc2UpOwogICAgfQogICAgc2hvd0VsZW1lbnQoZWxtLCB0cnVlKTsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIHRydWUpOwogICAgfSwgMTApOwogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIHNob3dFbGVtZW50KGVsbUlELCB0eXBlKSB7CiAgICB2YXIgY3NzQ2xhc3M7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIHRydWU6CiAgICAgICAgICAgIGNzc0NsYXNzID0gImJsb2NrIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgY3NzQ2xhc3MgPSAibm9uZSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtSUQpLmNsYXNzTmFtZSA9IGNzc0NsYXNzOwp9CmZ1bmN0aW9uIGNoYW5nZUJ1dHRvbkFjdGlvbihlbGVtZW50LCBidXR0b25JRCwgYXR0cmlidXRlKSB7CiAgICB2YXIgdmFsdWUgPSBlbGVtZW50Lm9wdGlvbnNbZWxlbWVudC5zZWxlY3RlZEluZGV4XS52YWx1ZTsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbklEKS5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7Cn0KZnVuY3Rpb24gZ2V0TG9jYWxEYXRhKGRhdGFUeXBlLCBpZCkgewogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CiAgICAgICAgY2FzZSAibTN1IjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJoZGhyIjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgIGNhc2UgImdyb3VwLXRpdGxlIjoKICAgICAgICAgICAgaWYgKGlkID09IC0xKSB7CiAgICAgICAgICAgICAgICBkYXRhWyJhY3RpdmUiXSA9IHRydWU7CiAgICAgICAgICAgICAgICBkYXRhWyJjYXNlU2Vuc2l0aXZlIl0gPSBmYWxzZTsKICAgICAgICAgICAgICAgIGRhdGFbImRlc2NyaXB0aW9uIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbImV4Y2x1ZGUiXSA9ICIiOwogICAgICAgICAgICAgICAgZGF0YVsiZmlsdGVyIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbImluY2x1ZGUiXSA9ICIiOwogICAgICAgICAgICAgICAgZGF0YVsibmFtZSJdID0gIiI7CiAgICAgICAgICAgICAgICBkYXRhWyJ0eXBlIl0gPSAiZ3JvdXAtdGl0bGUiOwogICAgICAgICAgICAgICAgU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWx0ZXIiXVtpZF0gPSBkYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbHRlciJdW2lkXTsKICAgICAgICAgICAgYnJlYWs7CiLine truncated
|
||||
webUI["html/js/data.js"] = "ZnVuY3Rpb24gc2hvd0NvbmZpZyhvYmopIHsKICBjb25maWcgPSBvYmo7CiAgLy9zZXRNZW51SXRlbSgpOwogIGNyZWF0ZU1lbnUoKTsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYWdlIikuY2xhc3NOYW1lID0gIiI7Cn0KCnNob3dNeVN0cmVhbXMKCmZ1bmN0aW9uIHNob3dNeVN0cmVhbXMoYWxsU3RyZWFtc09iaikgewoKICB2YXIgc3RyZWFtVHlwZUtleXMgPSBnZXRPYmpLZXlzKGFsbFN0cmVhbXNPYmopCgogIGZvciAodmFyIHMgPSAwOyBzIDwgc3RyZWFtVHlwZUtleXMubGVuZ3RoOyBzKyspIHsKICAgIHZhciBzdHJlYW1UeXBlID0gc3RyZWFtVHlwZUtleXNbc107CiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOwogICAgb2JqID0gYWxsU3RyZWFtc09ialtzdHJlYW1UeXBlXTsKICAgIHN3aXRjaChzdHJlYW1UeXBlKSB7CiAgICAgIGNhc2UgImFjdGl2ZVN0cmVhbXMiOiBhY3RpdmVTdHJlYW1zICAgICA9IG9iajsgYnJlYWs7CiAgICB9CgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3RyZWFtVHlwZSkuaW5uZXJIVE1MID0gIiI7CgogICAgdmFyIHN0cmVhbXNPYmogICAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtc05hbWVzICA9IG5ldyBBcnJheSgpOwogICAgCiAgICB2YXIga2V5cyA9IGdldE9iaktleXMob2JqKQogICAgCiAgICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBuYW1lICAgID0gb2JqW2tleXNbaV1dWyJuYW1lIl07CiAgICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICAgIHZhciBzdHJlYW1LZXkgPSBnZXRPYmpLZXlzKG9ialtrZXlzW2ldXSk7CgogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmVhbUtleS5sZW5ndGg7IGorKykgewogICAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICAgIH0KCiAgICAgIHN0cmVhbXNPYmpbbmFtZV0gPSB0bXA7CiAgICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgICB9CgogICAgc3RyZWFtc05hbWVzLnNvcnQoKTsKICAgIAogICAgLy8gQ3JlYXRlIFRhYmxlIGZvciBhY3RpdmVTdHJlYW1zCiAgICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzdHJlYW1UeXBlKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmVhbXNOYW1lcy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdID0gIlRSIjsKICAgICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIHZhciB0bXAgPSBzdHJlYW1zT2JqW3N0cmVhbXNOYW1lc1tpXV0KICAgICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKHRtcCkKCiAgICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgICAgbmV3S2V5WyJfZWxlbWVudCJdICA9ICJURCI7CiAgICAgIC8vbmV3S2V5WyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgc3dpdGNoKHN0cmVhbVR5cGUpIHsKICAgICAgICBjYXNlICJhY3RpdmVTdHJlYW1zIjogbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsICgrKToiOyBicmVhazsKICAgICAgICBjYXNlICJpbmFjdGl2ZVN0cmVhbXMiOiBuZXdLZXlbIl90ZXh0Il0gICA9ICJDaGFubmVsICgtKToiOyBicmVhazsKICAgICAgfQogICAgICAKICAgICAgbmV3S2V5WyJjbGFzcyJdICAgICA9ICJ0ZEtleSI7CiAgICAgIGNvbnNvbGUubG9nKCk7CgoKICAgICAgdmFyIG5ld1ZhbCA9IG5ldyBPYmplY3QoKQogICAgICBuZXdWYWxbIl9lbGVtZW50Il0gID0gIlREIjsKICAgICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgbmV3VmFsWyJjbGFzcyJdICAgICA9ICJ0ZFZhbCI7CiAgICAgIC8vbmV3VmFsWyJfdGV4dCJdICAgICA9IHZhbHVlOwogICAgICAKICAgICAgbGluZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0tleSkpOwogICAgICBsaW5lLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VmFsKSk7CiAgICAgIAogICAgfQoKICB9CgogIHJldHVybgp9CgpmdW5jdGlvbiBzaG93QWN0aXZlU3RyZWFtcyhvYmopIHsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWN0aXZlU3RyZWFtcyIpLmlubmVySFRNTCA9ICIiOwogIGFjdGl2ZVN0cmVhbXMgICAgID0gb2JqOwogIHZhciBzdHJlYW1zT2JqICAgID0gbmV3IE9iamVjdCgpOwogIHZhciBzdHJlYW1zTmFtZXMgID0gbmV3IEFycmF5KCk7CiAgCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKG9iaikKICAKICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5hbWUgICAgPSBvYmpba2V5c1tpXV1bIm5hbWUiXTsKICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtS2V5ID0gZ2V0T2JqS2V5cyhvYmpba2V5c1tpXV0pOwoKICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyZWFtS2V5Lmxlbmd0aDsgaisrKSB7CiAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICB9CgogICAgc3RyZWFtc09ialtuYW1lXSA9IHRtcDsKICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgfQoKICBzdHJlYW1zTmFtZXMuc29ydCgpOwogIAogIC8vIENyZWF0ZSBUYWJsZSBmb3IgYWN0aXZlU3RyZWFtcwogIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJhY3RpdmVTdHJlYW1zIik7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyZWFtc05hbWVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSA9ICJUUiI7CiAgICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CiAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICB2YXIgdG1wID0gc3RyZWFtc09ialtzdHJlYW1zTmFtZXNbaV1dCiAgICB2YXIga2V5cyA9IGdldE9iaktleXModG1wKQoKICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgIG5ld0tleVsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgLy9uZXdLZXlbIl90ZXh0Il0gICAgID0gc3RyZWFtc05hbWVzW2ldOwogICAgbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsOiI7CiAgICBuZXdLZXlbImNsYXNzIl0gICAgID0gInRkS2V5IjsKICAgIGNvbnNvbGUubG9nKCk7CgoKICAgIHZhciBuZXdWYWwgPSBuZXcgT2JqZWN0KCkKICAgIG5ld1ZhbFsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgIG5ld1ZhbFsiY2xhc3MiXSAgICAgPSAidGRWYWwiOwogICAgLy9uZXdWYWxbIl90ZXh0Il0gICAgID0gdmFsdWU7CiAgICAKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdLZXkpKTsKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdWYWwpKTsKICAgIAogIH0KCn0KCmZ1bmN0aW9uIHBhcnNlTG9ncyhvYmopIHsKILine truncated
|
||||
webUI["html/js/files.js"] = "ZnVuY3Rpb24gb3BlbkZpbGVzKGVsbSwgZmlsZVR5cGUpIHsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpLmlubmVySFRNTCA9ICJUZXN0IjsKICAKICBjb2x1bW5Ub1NvcnQgPSAwOyAKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gJ2ZpbGVEZXRhaWwoIi0iLCAiJyArIGZpbGVUeXBlICsgJyIpJzsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSA9ICJVcGRhdGUiOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gPSAiZmlsZURldGFpbCgwKSI7CiAgLy9uZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CgogICAvLyBCdWlsZCB0YWJsZQogIHZhciBuZXdUYWJsZSA9IG5ldyBPYmplY3QoKTsKICBuZXdUYWJsZVsiX2VsZW1lbnQiXSAgPSAiVEFCTEUiOwogIG5ld1RhYmxlWyJpZCJdICAgICAgICA9ICJpZF9tYXBwaW5nIjsKICBuZXdUYWJsZVsiY2xhc3MiXSAgICAgPSAidGFibGUtbWFwcGluZyI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VGFibGUpKTsKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIGNyZWF0ZUZpbGVzVGFibGUoZmlsZVR5cGUpOyAKICB9LCAxMCk7Cgp9CgpmdW5jdGlvbiBjcmVhdGVGaWxlc1RhYmxlKGZpbGVUeXBlKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB2YXIgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCk7CiAgCiAgdGFibGUuaW5uZXJIVE1MID0gIiI7CiAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogIG5ld1RSWyJfZWxlbWVudCJdID0gIlRSIjsKICBuZXdUUlsiY2xhc3MiXSAgICA9ICJ0YWJsZS1tYXBwaW5nLWhlYWRlciI7CiAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICB2YXIgdHIgPSB0YWJsZS5sYXN0Q2hpbGQ7CgogIHN3aXRjaChmaWxlVHlwZSkgewogICAgY2FzZSAieG1sdHYiOiAKICAgICAgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCJ4bWx0diIpOyAKICAgICAgdmFyIHRySGVhZGxpbmVzID0gbmV3IEFycmF5KCJHdWlkZSIsICJMYXN0IFVwZGF0ZSIsICJBdmFpbGFiaWxpdHkgJSIsICJDaGFubmVscyIsICJQcm9ncmFtcyIpCiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgieG1sdHYuY2hhbm5lbHMiLCAieG1sdHYucHJvZ3JhbXMiKQogICAgICBicmVhazsKCiAgICBjYXNlICJtM3UiOgogICAgICBhdmFpbGFibGVGaWxlVHlwZXMgPSBuZXcgQXJyYXkoIm0zdSIsICJoZGhyIik7IAogICAgICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlBsYXlsaXN0IiwgIkxhc3QgVXBkYXRlIiwgIkF2YWlsYWJpbGl0eSAlIiwgIlR5cGUiLCAiU3RyZWFtcyIsICJncm91cC10aXRsZSAlIiwgInR2Zy1pZCAlIiwgIlVuaXF1ZSBJRCAlIik7CiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgic3RyZWFtcyIsICJncm91cC50aXRsZSIsICJ0dmcuaWQiLCAic3RyZWFtLmlkIik7CiAgICAgIGJyZWFrOwogIH0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ckhlYWRsaW5lcy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiVEQiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB0ckhlYWRsaW5lc1tpXTsKICAgIHRyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VEQpKTsKICB9CiAgCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdmFpbGFibGVGaWxlVHlwZXMubGVuZ3RoOyBpKyspIHsKICAgIAogICAgdmFyIGZpbGVUeXBlID0gYXZhaWxhYmxlRmlsZVR5cGVzW2ldCgogICAgdmFyIGRhdGEgPSBjb25maWdbImZpbGVzIl1bZmlsZVR5cGVdOwogICAgCiAgICB2YXIgYWxsRmlsZXMgPSBnZXRPYmpLZXlzKGRhdGEpCiAgCiAgICBmb3IgKHZhciBmID0gMDsgZiA8IGFsbEZpbGVzLmxlbmd0aDsgZisrKSB7CiAgICAgIHZhciBlbG0gICAgICAgICAgID0gZGF0YVthbGxGaWxlc1tmXV07CiAgICAgIHZhciB0YWJsZSAgICAgICAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICAgICAgdmFyIGZpbGVJRCAgICAgICAgPSBlbG1bImlkLnByb3ZpZGVyIl07CiAgICAgIHZhciBuYW1lICAgICAgICAgID0gZWxtWyJuYW1lIl07CiAgICAgIHZhciBsYXN0VXBkYXRlICAgID0gZWxtWyJsYXN0LnVwZGF0ZSJdOwogICAgICB2YXIgYXZhaWxhYmlsaXR5ICA9IGVsbVsicHJvdmlkZXIuYXZhaWxhYmlsaXR5Il07CiAgICAgIHZhciB0eXBlICAgICAgICAgID0gZWxtWyJ0eXBlIl0udG9VcHBlckNhc2UoKTsKICAgICAgdmFyIGNvbXBhdGliaWxpdHkgPSBlbG1bImNvbXBhdGliaWxpdHkiXTsKCiAgICAgIC8vIENyZWF0ZSBUUgogICAgICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld1RSWyJfZWxlbWVudCJdICAgICAgID0gIlRSIjsKICAgICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgICAgbmV3VFJbImlkIl0gICAgICAgICAgICAgPSBmaWxlSUQ7CiAgICAgIG5ld1RSWyJvbmNsaWNrIl0gICAgICAgID0gJ2phdmFzY3JpcHQ6IGZpbGVEZXRhaWwoIicgKyBmaWxlSUQgKyAnIiwiJyArIGZpbGVUeXBlICsgJyIpOyc7CiAgICAgIHRhYmxlLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VFIpKTsKCiAgICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIC8vIENyZWF0ZSBmaWxlIG5hbWUgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBuYW1lOwogICAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgICAgLy8gQ3JlYXRlIGxhc3QgdXBkYXRlIFRECiAgICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICAgIG5ld1REWyJfdGV4dCJdICAgID0gbGFzdFVwZGF0ZTsKICAgICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAgIC8vIENyZWF0ZSBhdmFpbGFiaWxpdHkgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBhdmFpbGFiaWxpdHk7CiAgICAgIGNyZWF0ZU5ld1REKG5ld1RELine truncated
|
||||
webUI["html/js/menu.js"] = "CmZ1bmN0aW9uIHNldE1lbnVJdGVtKCkgewoKICBtZW51ID0gbmV3IE9iamVjdCgpOwogIHN1Yk1lbnUgPSBuZXcgT2JqZWN0KCk7CgogIHZhciBtZW51X20zdSA9IG5ldyBPYmplY3QoKTsKICBtZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9tM3VbIl9lbGVtZW50Il0gICAgICAgID0gIkxJIjsKICBtZW51X20zdVsiX2NvbmZpZ0tleSJdICAgICAgPSAiZmlsZXMubTN1IjsKICBtZW51X20zdVsiX3RleHQiXSAgICAgICAgICAgPSAiUGxheWxpc3QiOwogIG1lbnVfbTN1WyJfaWNvbiJdICAgICAgICAgICA9ICJpbWcvbTN1LnBuZyI7CiAgbWVudV9tM3VbIl9oZWFkbGluZSJdICAgICAgID0gIlBsYXlsaXN0czogTG9jYWwgb3IgcmVtb3RlIjsKICBtZW51X20zdVsiX3VzYWdlIl0gICAgICAgICAgPSAiPGI+SW5mbzwvYj48YnI+QXZhaWxhYmlsaXR5OiBGaWxlIGF2YWlsYWJpbGl0eSBpbiBwZXJjZW50PGJyPlN0cmVhbXM6ICAgICAgTnVtYmVyIG9mIHN0cmVhbXMgaW4gdGhlIGZpbGUuPGJyPmdyb3VwLXRpdGxlOiAgU3RyZWFtcyB0aGF0IGFyZSBhc3NpZ25lZCB0byBhIGdyb3VwLiBTaW1wbGlmaWVzIGZpbHRlcmluZyBzdHJlYW1zPGJyPnR2Zy1pZDogICAgICAgVGhpcyBJRCBpcyB1c2VkIGZvciBhdXRvbWF0aWMgbWFwcGluZywgbXVzdCBtYXRjaCB3aXRoIHRoZSBjaGFubmVsIElEIGluIHRoZSBYTUxUViBmaWxlLjxicj5VbmlxdWUgSUQ6ICAgIFN0cmVhbXMgd2l0aCBhIHVuaXF1ZSBJRCB0byBpZGVudGlmeSB0aGVtLiBBbGxvd3MgY2hhbm5lbCBuYW1lIGNoYW5nZXMgaW4gdGhlIE0zVSB3aXRob3V0IGxvc2luZyB0aGUgWE1MVFYgbWFwcGluZyAoUFBWIC8gbGl2ZSBldmVudHMpLjxicj48YnI+PGI+VXNhZ2UgTTNVOjwvYj48YnI+UmVtb3RlIHBsYXlsaXN0OiBodHRwOi8veW91ci5pcHR2LnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1PGJyPjxicj48Yj5Vc2FnZSBIREhvbWVSdW46PC9iPjxicj5JUDogMTkyLjE2OC4xLjEwOjUwMDQ8YnI+IgogIG1lbnVfbTN1WyJuYW1lIl0gICAgICAgICAgICA9ICJmaWxlIjsKICBtZW51X20zdVsiaWQiXSAgICAgICAgICAgICAgPSAiZmlsZSI7CiAgbWVudV9tM3VbInZhbHVlIl0gICAgICAgICAgID0gbWVudV9tM3VbIm5hbWUiXTsKICBtZW51X20zdVsicGxhY2Vob2xkZXIiXSAgICAgPSAiUGxheWxpc3Q6IGxvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV9tM3VbIm9uY2xpY2siXSAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X20zdVsiY2xhc3MiXSAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfZmlsdGVyID0gbmV3IE9iamVjdCgpOwogIG1lbnVfZmlsdGVyWyJfbWVudVR5cGUiXSAgICA9ICJpbnB1dEFycmF5IjsKICBtZW51X2ZpbHRlclsiX2VsZW1lbnQiXSAgICAgPSAiTEkiOwogIG1lbnVfZmlsdGVyWyJfY29uZmlnS2V5Il0gICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfdGV4dCJdICAgICAgICA9ICJGaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfaWNvbiJdICAgICAgICA9ICJpbWcvZmlsdGVyLnBuZyI7CiAgbWVudV9maWx0ZXJbIl9oZWFkbGluZSJdICAgID0gIkZpbHRlciBieSBNM1UgcGFyYW1ldGVycywgZS5nLiBncm91cC10aXRsZSI7CiAgbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+U3BvcnQgLSBBbGwgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gIXtFUyxERX0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuPGJyPjxicj5UbyBmaWx0ZXIgdGhlIHN0cmVhbXMgb2YgYSBIREhvbWVSdW4sIHRoZSBwbGF5bGlzdCBuYW1lIGNhbiBiZSBlbnRlcmVkOjxicj5NeSB0dW5lciB7SER9IgogIC8vbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+QWxsIHNwb3J0cyBjaGFubmVsczogU3BvcnQ8YnI+QWxsIEhEIHNwb3J0cyBjaGFubmVsczogU3BvcnQge0hEfTxicj5BbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuOiBTcG9ydCB7SER9ICF7RVMsREV9IgogIG1lbnVfZmlsdGVyWyJuYW1lIl0gICAgICAgICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJpZCJdICAgICAgICAgICA9ICJNM1UiOwogIG1lbnVfZmlsdGVyWyJ2YWx1ZSJdICAgICAgICA9IG1lbnVfZmlsdGVyWyJuYW1lIl07CiAgbWVudV9maWx0ZXJbInBsYWNlaG9sZGVyIl0gID0gIkZpbHRlciBzdHJlYW1zOiBTcG9ydCI7CiAgbWVudV9maWx0ZXJbIm9uY2xpY2siXSAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2ZpbHRlclsiY2xhc3MiXSAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICB2YXIgbWVudV9pZCA9IG5ldyBPYmplY3QoKTsKICBtZW51X2lkWyJfbWVudVR5cGUiXSAgICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9pZFsiX2VsZW1lbnQiXSAgICAgICAgID0gIkxJIjsKICBtZW51X2lkWyJfY29uZmlnS2V5Il0gICAgICAgPSAiaWQiOwogIG1lbnVfaWRbIl90ZXh0Il0gICAgICAgICAgICA9ICJQTVMgSUQiOwogIG1lbnVfaWRbIl9pY29uIl0gICAgICAgICAgICA9ICJpbWcvbnVtYmVyLnBuZyI7CiAgbWVudV9pZFsiX2hlYWRsaW5lIl0gICAgICAgID0gIlNldHVwIFBNUyBndWlkZSBudW1iZXIiOwogIG1lbnVfaWRbIl91c2FnZSJdICAgICAgICAgICA9ICdTb21lIHBsYXlsaXN0cyBoYXZlIHVuaXF1ZSBjaGFubmVsIElEcy48YnI+RW50ZXIgdGhlIGtleXdvcmQgb2YgdGhlIElELiBUaGUgY2hhbm5lbCBhc3NpZ25tZW50IGluIFBNUyB3aWxsIGNoYW5nZSBhcyBhIHJlc3VsdC48YnI+PGJyPmUuZy4gY2hhbm5lbElEPGJyPiNFWFRJTkY6MCB0eXBlPSJzdHJlYW0iIDxiPmNoYW5uZWxJZDwvYj49IjgxIiwgTXkgU3RyZWFtaW5nIENoYW5uZWwgSEQ8YnI+PGJyPk9ubHkgZW50ZXIgaGVyZSBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmchJwogIG1lbnVfaWRbIm5hbWUiXSAgICAgICAgICAgICA9ICJpZCI7CiAgbWVudV9pZFsiaWQiXSAgICAgICAgICAgICAgID0gImlkIjsKICBtZW51X2lkWyJ2YWx1ZSJdICAgICAgICAgICAgPSBtZW51X2lkWyJuYW1lIl07CiAgbWVudV9pZFsicGxhY2Vob2xkZXIiXSAgICAgID0gIlVuaXF1ZSBJRCBmcm9tIHRoZSBNM1UgZmlsZSI7CiAgbWVudV9pZFsib25jbGljayJdICAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2lkWyJjbGFzcyJdICAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfeG1sdHYgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV94bWx0dlsiX21lbnVUeXBlIl0gICAgID0gImlucHV0QXJyYXkiOwogIG1lbnVfeG1sdHZbIl9lbGVtZW50Il0gICAgICA9ICJMSSI7CiAgbWVudV94bWx0dlsiX2NvbmZpZ0tleSJdICAgID0gImZpbGVzLnhtbHR2IjsKICBtZW51X3htbHR2WyJfdGV4dCJdICAgICAgICAgPSAiWE1MVFYiOwogIG1lbnVfeG1sdHZbIl9pY29uIl0gICAgICAgICA9ICJpbWcveG1sdHYucG5nIjsKICBtZW51X3htbHR2WyJfaGVhZGxpbmUiXSAgICAgPSAiWE1MVFYgZmlsZXM6IExvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV94bLine truncated
|
||||
webUI["html/lang/de.json"] = "ewogICJtYWluTWVudSI6IHsKICAgICJpdGVtIjp7CiAgICAgICJwbGF5bGlzdCI6ICJXaWVkZXJnYWJlbGlzdGUiLAogICAgICAicG1zSUQiOiAiUE1TIElEIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIiLAogICAgICAieG1sdHYiOiAiWE1MVFYiLAogICAgICAibWFwcGluZyI6ICJNYXBwaW5nIiwKICAgICAgInVzZXJzIjogIkJlbnV0emVyIiwKICAgICAgInNldHRpbmdzIjogIkVpbnN0ZWxsdW5nZW4iLAogICAgICAibG9nIjogIkxvZyIsCiAgICAgICJsb2dvdXQiOiAiQWJtZWxkZW4iCiAgICB9LAogICAgImhlYWRsaW5lIjogewogICAgICAicGxheWxpc3QiOiAiTG9rYWxlIG9kZXIgZW50ZmVybnRlIFdpZWRlcmdhYmVsaXN0ZW4iLAogICAgICAiZmlsdGVyIjogIkZpbHRlcm4gdm9uIEthbsOkbGVuIiwKICAgICAgInhtbHR2IjogIkxva2FsZSBvZGVyIGVudGZlcm50ZSBYTUxUViBEYXRlaWVuIiwKICAgICAgIm1hcHBpbmciOiAiS2Fuw6RsZSBkZXIgV2llZGVyZ2FiZWxpc3RlbiBFUEcgS2Fuw6RsZW4genVvcmRuZW4iLAogICAgICAidXNlcnMiOiAiQmVudXR6ZXJ2ZXJ3YWx0dW5nIiwKICAgICAgInNldHRpbmdzIjogIkVpbnN0ZWxsdW5nZW4iLAogICAgICAibG9nIjogIkxvZyIsCiAgICAgICJsb2dvdXQiOiAiQWJtZWxkZW4iCiAgICB9CiAgfSwKICAiY29uZmlybSI6ewogICAgInJlc3RvcmUiOiAiQWxsZSBEYXRlbiB3ZXJkZW4gbWl0IGRlbmVuIGF1cyBkZW0gQmFja3VwIGVyc2V0enQuIFdpZWRlcmhlc3RlbGx1bmcgZHVyY2hmw7xocmVuPyIKICB9LAogICJhbGVydCI6IHsKICAgICJmaWxlTG9hZGluZ0Vycm9yIjogIkRhdGVpIGtvbm50ZSBuaWNodCBnZWxhZGVuIHdlcmRlbiIsCiAgICAiaW52YWxpZENoYW5uZWxOdW1iZXIiOiAiVW5nw7xsdGlnZSBLYW5hbG51bW1lciIKICB9LAogICJidXR0b24iOnsKICAgICJiYWNrIjogIlp1csO8Y2siLAogICAgImJhY2t1cCI6ICJCYWNrdXAiLAogICAgImJ1bGtFZGl0IjogIk1hc3NlbmJlYXJiZWl0dW5nIiwKICAgICJjYW5jZWwiOiAiQWJicmVjaGVuIiwKICAgICJkZWxldGUiOiAiTMO2c2NoZW4iLAogICAgImRvbmUiOiAiRmVydGlnIiwKICAgICJsb2dpbiI6ICJBbm1lbGRlbiIsCiAgICAibmV3IjogIk5ldSIsCiAgICAibmV4dCI6ICJXZWl0ZXIiLAogICAgInJlc3RvcmUiOiAiV2llZGVyaGVyc3RlbGxlbiIsCiAgICAic2F2ZSI6ICJTcGVjaWhlcm4iLAogICAgInNlYXJjaCI6ICJTdWNoZW4iLAogICAgInVwZGF0ZSI6ICJVcGRhdGUiLAogICAgImNyYWV0ZUFjY291bnQiOiAiQWNjb3VudCBlcnN0ZWxsZW4iLAogICAgInJlc2V0bG9ncyI6ICJMb2dzIGzDtnNjaGVuIiwKICAgICJ1cGxvYWRMb2dvIjogIkxvZ28gaG9jaGxhZGVuIgogIH0sCiAgImZpbHRlciI6IHsKICAgICJ0YWJsZSI6IHsKICAgICAgIm5hbWUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAidHlwZSI6ICJGaWx0ZXIgVHlwIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIiCiAgICB9LAogICAgImN1c3RvbSI6ICJCZW51dHplcmRlZmluaWVydCIsCiAgICAiZ3JvdXAiOiAiR3J1cHBlIiwKICAgICJuYW1lIjogewogICAgICAidGl0bGUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRmlsdGVyIE5hbWUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6IHsKICAgICAgInRpdGxlIjogIkJlc2NocmVpYnVuZyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJCZXNjaHJlaWJ1bmciLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ0eXBlIjogewogICAgICAidGl0bGUiOiAiVHlwIiwKICAgICAgImdyb3VwVGl0bGUiOiAiR3JvdXBlbnRpdGVsIiwKICAgICAgImN1c3RvbUZpbHRlciI6ICJCZW51dHplcmRlZmluaWVydGVyIEZpbHRlciIKICAgIH0sCiAgICAiY2FzZVNlbnNpdGl2ZSI6IHsKICAgICAgInRpdGxlIjogIkdyb8OfLSAvIEtsZWluc2NocmVpYnVuZyBiZWFjaHRlbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWx0ZXJSdWxlIjogewogICAgICAidGl0bGUiOiAiRmlsdGVycmVnZWwiLAogICAgICAicGxhY2Vob2xkZXIiOiAiU3BvcnQge0hEfSAhe0VTLElUfSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbHRlckdyb3VwIjogewogICAgICAidGl0bGUiOiAiR3JvdXBlbnRpdGVsIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJHcnVwcGUgYXVzIGRlciBNM1UgYXVzd8OkaGxlbi4gKFrDpGhsZXIpPGJyPsOkbmRlcnVuZyBkZXMgR3J1cHBlbnRpdGVscyBpbiBkZXIgTTNVIG1hY2h0IGRlbiBGaWx0ZXIgdW5nw7xsdGlnLiIKICAgIH0sCiAgICAiaW5jbHVkZSI6IHsKICAgICAgInRpdGxlIjogIk11c3MgYmVpbmhhbHRlbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGSEQsVUhEIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkthbmFsbmFtZSBtdXNzIGRpZXNlIFfDtnJ0ZXIgZW50aGFsdGVuLjxicj4oS29tbWFnZXRyZW5udCkgS29tbWEgYmVkZXV0ZXQgb2RlciIKICAgIH0sCiAgICAiZXhjbHVkZSI6IHsKICAgICAgInRpdGxlIjogIkRhcmYgbmljaHQgYmVpbmhhbHRlbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJFUyxJVCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJLYW5hbG5hbWUgZGFyZiBkaWVzZSBXw7ZydGVyIG5pY2h0IGVudGhhbHRlbi48YnI+KEtvbW1hZ2V0cmVubnQpS29tbWEgYmVkZXV0ZXQgb2RlciIKICAgIH0KCiAgfSwKICAicGxheWxpc3QiOiB7CiAgICAidGFibGUiOiB7CiAgICAgICJwbGF5bGlzdCI6ICJXaWVkZXJnYWJlbGlzdGUiLAogICAgICAidHVuZXIiOiAiVHVuZXIiLAogICAgICAibGFzdFVwZGF0ZSI6ICJMZXR6dGUgQWt0dWFsaXNpZXJ1bmciLAogICAgICAiYXZhaWxhYmlsaXR5IjogIlZlcmbDvGdiYXJrZWl0IiwKICAgICAgInR5cGUiOiAiVHlwIiwKICAgICAgInN0cmVhbXMiOiAiU3RyZWFtcyIsCiAgICAgICJncm91cFRpdGxlIjogIkdyb3VwZW50aXRlbCIsCiAgICAgICJ0dmdJRCI6ICJ0dmctaWQiLAogICAgICAidW5pcXVlSUQiOiAiRWluZGV1dGlnZSBJRCIKICAgIH0sCiAgICAicGxheWxpc3RUeXBlIjogewogICAgICAidGl0bGUiOiAiV2llZGVyZ2FiZWxpc3RlbiBUeXAiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidHlwZSI6IHsKICAgICAgInRpdGxlIjogIlR5cCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJuYW1lIjogewogICAgICAidGl0bGUiOiAiTmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJOYW1lIGRlciBXaWVkZXJnYWJlbGlzdGUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6IHsKICAgICAgInRpdGxlIjogIkJlc2NocmVpYnVuZyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJCZXNjaHJlaWJ1bmciLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWxlTTNVIjogewogICAgICAidGl0bGUiOiAiTTNVIERhdGVpIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkRhdGVpcGZhZCBvZGVyIFVSTCBkZXIgTTNVIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsZUhESFIiOiB7CiAgICAgICJ0aXRsZSI6ICJIREhvbWVSdW4Line truncated
|
||||
webUI["html/img/filter.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzo2OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cs038OQAAAOISURBVGgF5ZpLSBVRGMfvvfmqCKKiKCqKtE3SQ8haJJm1ctPCZYHrFhXtohcUBLVsU1BRBJKLXpsSKs1aCL1oUUhvMgIloodZKmLZ72+OzNVx7jzOXGfqg/89Z875zv/7f35n7px7vanUP2JptzyGhoYKmK8GW0EZmA/mgW7wHrwDN0BTOp0epPVtxBBnLdgIVoE5YBboBR2gDTTA/5DWn0FeDPaBz8CLdeF0EBR5jYRvKbgABoAXa8Opwit/CudK8NoLs4PPM8ZyBsNnB/jpsD7X0C8cjgDXnaQkqkEPCGMSuGWivxxzx8OQj6xtpHWuPhPloHfEMWzTD0HN2GQY2xuW2Lb+/Fh+VaIQPLE5meh+gmSxFYz+BjBogtjGscfiH26Z2GmbNNltVQAIpwDdP6ZNO2iRYqTpZGhfgWUaiMC2w1kCzkbALcqLvDVvUyK6MW9HFES0b8BvsFwXEZi4F+iBtykCcjtlqf0igr52VJ1eqiIgzzdlrRIZfWfJd3SD8ZbqHvkB4XSDpJNB9V0VcX/cT4Ys/zEzSuSj/3WxW9GpRD7ETpZ/QcOJ6LyfdHugitxNehbob9G7lo4PXWBmQhPqQ/fsDOeUfjqNCU1Csi+TQ5+2luzc3yaRr6elevQZwhZr4bomYam0U41yabYqov5hvSTMjlp6RyuiAarSTLPZmox5246+lVREx/isiuh6NxhUJwF2yEpCWu1bK8WEsjyRgCSa0XrVrjNra2mC7TWD5ilYAuJoA4jSlnppF5dVEU3g0ENTD4b3nsZiZsfGJuGqj8qY+CINGqP2GLZCJ+HjtpblxAJ9k3cPrLfGJrnVUaSCarxw0jFua1lOLNBerANx+byya6IkLM2uLZWpAl6/Mcc1EjvjKtLrJNLqI5HnjfQ+bsVeteb0g2y/t7hGvd7CNjenOL8OkJ40KtOdTF+Cl/nV6Mkf4gxocI9vZPYLLKs9iQrqRIACcM2IXGeSboYrg+rztY5ARaDJWUeo0W+sXudLTFhnApaAW6FkZy/+yuXasLoCrSfwVHAnW0+gK93YawKJMLUIAdNAKwhqnSxcYUpPKB6EBE2mg7VR///EX24jybTQerXnOC70FyVP3gjTPXPTQyaP8NFPNeJrCNTPP667JKOq6VNo/A2hes5ccUjmEmPmDoD5+FMgWCcA+3FG57QJP//kQ1PgGBIOToEDgUn+t4V/AJeGknwARIKLAAAAAElFTkSuQmCC"
|
||||
webUI["html/img/mapping.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0wMlQxMjowODo5NzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CpRxQsEAAAJLSURBVGgF7VoxTgMxEMwBHWlAaeABVCEtBcoD+EBewCdCyQsQtLyAPCBvCBSRIBUPCF1ogqBJjlkrezGr6HTrO98lhy1Z9trr2VmvnbMNjUadUhzHLeQB8hw5LS3QOUbubvIf7X3kKXIZibgS51bCZdWgMT6D8nECgArkngagQN0B8dhbkblalVmLIyheCGUthhjuLBq77MihA0xTjHHBEBBOorHLjjghbNOg4Mg2RYO4hIiEiHiaAV5aSwf8hRgjZdHtTTTc2ZFXpZkY+hMx5k3IZYlr7jgudJHp2JElLaF0K1mirYn8nAWgQB3ibM59ERNCA52d6Nghv9isQiUtn0kURe92I9eBcYA6YZxym8dyDuwRuMw82gjQYQbsPdLDdNCROO0US3uEfp3usTZpjf5J2CNtNFwjl7FHvmBnCB5PCQkQoJudJtGvE23sJEFuI39rQArS7dskXK6nlwkAKiB1VxAxLcyUePAH8cQmlbEul4+UM8LkVjPc2ZHcaFUDBEeqjoC0HyIiZ6RqOUSk6ghI+xyRD9mRQTYfIktPylaX16rhzo48KE29QH8kxjxC/hFtZYiGe70OjWVMW7Dx32bA3iO7//iAC8DOPweZFQhH6O+CmkRvW2f28oV8owEoUHdMPPg70rFJZajTkqT7uZ3ObaHEuuHOjnCpsb8vlKUsur2JhruLA94Y5QEOjuSZPR9jQ0R8zGoezNpFhN5RtUm+/bpgaG1u0jd2OSLDTRopbZ/okxcrLUYKvKprbRfHhXr8m5PK/y1V/gWRKLfiNSmxEAAAAABJRU5ErkJggg=="
|
||||
webUI["html/js/authentication_ts.js"] = "ZnVuY3Rpb24gbG9naW4oKSB7CiAgICB2YXIgZXJyID0gZmFsc2U7CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudCIpOwogICAgdmFyIGZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYXV0aGVudGljYXRpb24iKTsKICAgIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIik7CiAgICBjb25zb2xlLmxvZyhpbnB1dHMpOwogICAgZm9yICh2YXIgaSA9IGlucHV0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICAgIHZhciBrZXkgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICB2YXIgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICJyZWQiOwogICAgICAgICAgICBlcnIgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTsKICAgIH0KICAgIGlmIChlcnIgPT0gdHJ1ZSkgewogICAgICAgIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoImNvbmZpcm0iKSkgewogICAgICAgIGlmIChkYXRhWyJjb25maXJtIl0gIT0gZGF0YVsicGFzc3dvcmQiXSkgewogICAgICAgICAgICBhbGVydCgic2RhZnNkIik7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpLnN0eWxlLmJvcmRlckNvbG9yID0gInJlZCI7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJykuc3R5bGUuYm9yZGVyQ29sb3IgPSAicmVkIjsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImVyciIpLmlubmVySFRNTCA9ICJ7ey5hY2NvdW50LmZhaWxlZH19IjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIGNvbnNvbGUubG9nKGRhdGEpOwogICAgZm9ybS5zdWJtaXQoKTsKfQo="
|
||||
webUI["html/img/BC-QR.jpg"] = "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 truncated
|
||||
webUI["html/img/m3u.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CumjVbcAAAGWSURBVGgF7VoxTgJRFGTFaGKBFnbEcABjb0fiBego7D2ABYmn8ARKRWFNQ6gx4QRQGWJJoY2VhXGdl7Dkh7Dsx3ns3yXvJ5P97L6d92bmhwYqlcWK43gK5L2enP51NP8F7pN721wPnOITZx9qG6HxI8QIZO+9XCHeL+VQKKm8QMyxb6+iCpH528AQYs58xIQWknV8mhDxCjEXWWJCC8maT55fAmOIudpUXAYhMn8dGEHMTZqYsgiR+U+BAcTcrhNTJiEy/xHQg5jOqpjD1RsBP3+id8u3P8TUoij6SuoLIwRDfWOofjLYtteyHa1UfcvvcUT1jqpGauVuHnyAdragjv/TAkley3uhj9Y5ZhDQa2+Olgmhz4IygSWibChNZ4nQFioTWCLKhtJ0lghtoTKBJaJsKE1nidAWKhNYIsqG0nSWCG2hMoElomwoTWeJ0BYqE1giyobSdJYIbaEygSWibChNZ4nQFioTWCLKhtJ0biJzmi1/guXMrpDn/OegO3bXMuAH0TtgAvwARV3y57Q34AGoJkL+AErKZ9cqbH7AAAAAAElFTkSuQmCC"
|
||||
webUI["html/img/users.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0zMFQxNzowODozODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CjU01MMAAANJSURBVGgF1ZnLaxNRFMYz2rpoFbW+SCsihaJQRMT6rPhAXAq6c+HChSguRFd1oRtd+A/oWhQ3oiiWFB91UbqRqlXXgoIIQhFbQTTQao2/GzLDZEjIPefO7SQHPjJz55zzfd/MZCa5N8h5ilKptJvWp8FekAed4Bv4Cj6Dh2A4CIJZPpszMHEV2MQ0SZdB0DROENMHjoEzQBoFCpZnbgYR58E/qfpE/kv2F2dmBvJ94G9ClHb3SiZGUBuASa3qGnVzjG3RmFmkKYrVHGB7e2zfdbOdBhc1TVyNnNSQNqg5wVURf/FdjRxpIEpzuIOio9JCtRHO2hrINkgJLfPFt6vaCII2WYrSpPVJi1RGuBrmTbxeSibIX5j3CUauAfOo9BXzNH4nMJ5TXREI1gHzqPQVRtc2zCyxJdAaGbclcMj7zi/jOdt6rZFhCH7akijznknqVEY4U78heSAhUuTekNSojFQIChIiYe57TtZrSY2LkecQzUjIBLljglz3VJ4qg+AXSDNGabbWXZ2wA6Qjabqg136hhHK6y60V8o2EGyl8/qHHpKZPGkYeQzyvIa9RM86XvFhjvOGQsxGIp2B50ZDJLuG2XZqnLO5rM3viGh9o0OZJon1bRLxxdHLcns1jJiYOAu2U0D2P0uStMXJdcVU+UdMlZ/NYgaA28ERg5ge5/R4l6VsjrANMWJiZJWeXnqm60vnxW90ul6u8ByaS4zX2i+S+qjGuGkrdSEWFzT1vlhlSC19Gui0UtnNriSfi6vX1ZWRjPcLEeGrzYqkb4SyvQGxvQnC93cF6BzIfx8gpYBsfSdycuei4AAR1ggugCCRh1lbugIF4vwXbhtisjfSDc+ARSOOf4lv6mNWv1VIj1ouQNF9K851gDzArtWbV1uYxS5o4zB+sp+AuKPC+cVv5RXwPuATMmUpreY1Wopgh+ybYKj4dFHWB+8DMwTZTjCHmsJUhEgfAF9DMcQtx9V8dHMyDqWZ2ENM2FL8yVV92kkY56GM5Lc6Z1vY0jbp5EJQnuqPLg4kdLWTCnIxVIJoDi4wweNYcbbGIfuLEjRxqMRNGbvTvsmyE22oZg70taKQn1BxekXw40GKfK0O9oZHsJ8ZCRbLPaI3xP7YzeQoHxWckAAAAAElFTkSuQmCC"
|
||||
webUI["html/img/x_black.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTozNzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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 truncated
|
||||
webUI["html/img/logo_b_880x200.jpg"] = "/9j/4AAQSkZJRgABAQABLAEsAAD/4QDIRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAPAAAAcgEyAAIAAAAUAAAAgodpAAQAAAABAAAAlgAAAAAAAAEsAAAAAQAAASwAAAABUGl4ZWxtYXRvciAzLjMAADIwMTk6MDg6MDIgMjA6MDg6MTQAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAA3CgAwAEAAAAAQAAAMgAAAAA/+EJkGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iUGl4ZWxtYXRvciAzLjMiIHhtcDpNb2RpZnlEYXRlPSIyMDE5LTA4LTAyVDIwOjA4OjE0Ii8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAyANwAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/dAAQAbv/aAAwDAQACEQMRAD8A/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9D+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgLine truncated
|
||||
webUI["html/img/stream-limit.jpg"] = "/9j/4AAQSkZJRgABAQAAAQABAAD/4gJoSUNDX1BST0ZJTEUAAQEAAAJYbGNtcwQwAABtbnRyUkdCIFhZWiAH4wAFABcAFgAuAAphY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAAEBjcHJ0AAABSAAAAE53dHB0AAABmAAAABRjaGFkAAABrAAAACxyWFlaAAAB2AAAABRiWFlaAAAB7AAAABRnWFlaAAACAAAAABRyVFJDAAACFAAAACBnVFJDAAACFAAAACBiVFJDAAACFAAAACBjaHJtAAACNAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACQAAAAcAHMAUgBHAEIAIABJAEUAQwA2ADEAOQA2ADYALQAyAC4AMQAAbWx1YwAAAAAAAAABAAAADGVuVVMAAAAyAAAAHABOAG8AIABjAG8AcAB5AHIAaQBnAGgAdAAsACAAdQBzAGUAIABmAHIAZQBlAGwAeQAAAABYWVogAAAAAAAA9tYAAQAAAADTLXNmMzIAAAAAAAEMSgAABeP///MqAAAHmwAA/Yf///ui///9owAAA9gAAMCUWFlaIAAAAAAAAG+UAAA47gAAA5BYWVogAAAAAAAAJJ0AAA+DAAC2vlhZWiAAAAAAAABipQAAt5AAABjecGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltjaHJtAAAAAAADAAAAAKPXAABUewAATM0AAJmaAAAmZgAAD1z/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAQ4B4ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD/AD/6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKLine truncated
|
||||
webUI["html/img/x_ transparent.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTo3NjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI1NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoeXQb1AAAaJElEQVR4Ae2dCZhcVZXHz+1KSFiGkISkqyIoOgI68EkgOBNkEcQRlIFRZDGABAQEhInGbxw+RUZRNhWRLawDYR0GHAaHUVkGvwGURUcgwIiAOGxjV3UHAslHQrbuM/9TlQ6d7qruWt527/u/7+uuqvvucu7vvnveuffde54IDxIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARLwiIDzQtayHi0q23shaydCOnlISu7nnWThRdrFOkPWyCleyNqJkF1yjhTd8k6yiDvtuLgLiCR/lVnIZ14keWU7k2Xyuu4oU92r2RazQ+nWypXI4W86zCXbyZ28KBvJ97MtpEhX1gWsyleS08TJU17I2omQKpvLarmqkywyn7ZHPw9rLvTOvwbX6xEyxS3Nenv4oQCcWwmQc/D3dtaBdiyfyv5S1mM7zieLGSzWEsS6KIuiRSzTGTD9H404z1iy80MBWNVL7hn8nx8LhaxlqnKBvKbvyppYHctTM/0nd5xPljNwcrcUs2/6DyL0RwGYxDOcjR3vGBQ+4M8tMElmdQ3n6NGjYPofGE6F6tTESRmm/1xxTuuczWSQH08BhqJbqlNkuTyJoK2GBgf53S6mkrvB+7qZ6b9Gfod6hHv3dzKAGbX9pNvd51N7+WUBGNlJbgm07FH4G/AJdFuyqlwotXFzW8kzk2itXAFZwu38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 truncated
|
||||
webUI["html/js/configuaration.js"] = "dmFyIGNvbmZpZ01lbnUgPSBuZXcgT2JqZWN0KCk7CnZhciB3aXphcmQgPSBuZXcgQXJyYXkoImtleSIsICJ0dW5lciIsICJlcGdTb3VyY2UiLCAibTN1IiwgImNvbXBsZXRlIik7CnZhciBhY3RpdmVXaXphcmQ7CnZhciBkdnJJUAoKdmFyIGNvbmZpZ01lbnVfdHVuZXIgPSBuZXcgT2JqZWN0KCk7CmNvbmZpZ01lbnVfdHVuZXJbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X3R1bmVyWyJfbWVudVR5cGUiXSAgICAgPSAic2luZ2xlSW5wdXQiOwpjb25maWdNZW51X3R1bmVyWyJfY29uZmlnS2V5Il0gICAgPSAidHVuZXIiOwpjb25maWdNZW51X3R1bmVyWyJfbGFiZWwiXSAgICAgICAgPSAiQXZhaWxhYmxlIHR1bmVycyI7CmNvbmZpZ01lbnVfdHVuZXJbIm5hbWUiXSAgICAgICAgICA9ICJ0dW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbImlkIl0gICAgICAgICAgICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbInBsYWNlaG9sZGVyIl0gICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbIl91c2FnZSJdICAgICAgICA9ICJUaGlzIHNldHRpbmcgaXMgb25seSB1c2VkIGJ5IFBsZXggYW5kIEVtYnkuPGJyPlRoZSBudW1iZXIgb2YgY29uY3VycmVudCBzdHJlYW1zIGFsbG93ZWQgYnkgdGhlIElQVFYgcHJvdmlkZXIuIgoKCnZhciBvcHRpb25WYWx1ZXMgPSBuZXcgQXJyYXkoKTsKZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICBvcHRpb25WYWx1ZXMucHVzaChpKQp9CmNvbmZpZ01lbnVfdHVuZXJbIl9vcHRpb25WYWx1ZXMiXSA9IG9wdGlvblZhbHVlczsKCnZhciBjb25maWdNZW51X2VwZyA9IG5ldyBPYmplY3QoKTsKY29uZmlnTWVudV9lcGdbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X2VwZ1siX21lbnVUeXBlIl0gICAgID0gInNpbmdsZUlucHV0IjsKY29uZmlnTWVudV9lcGdbIl9jb25maWdLZXkiXSAgICA9ICJlcGdTb3VyY2UiOwpjb25maWdNZW51X2VwZ1siX2xhYmVsIl0gICAgICAgID0gIlNlbGVjdGlvbiBvZiB0aGUgRVBHIHNvdXJjZSI7CmNvbmZpZ01lbnVfZXBnWyJuYW1lIl0gICAgICAgICAgPSAiZXBnU291cmNlIjsKY29uZmlnTWVudV9lcGdbImlkIl0gICAgICAgICAgICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbInBsYWNlaG9sZGVyIl0gICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbIl9vcHRpb25WYWx1ZXMiXSA9IG5ldyBBcnJheSgiUE1TIiwgIlhFUEciKTsKY29uZmlnTWVudV9lcGdbIl91c2FnZSJdICAgICAgICA9ICJQTVM6ICAgVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5PGJyPlhFUEc6ICBVc2Ugb2YgZXh0ZXJuYWwgRVBHIGRhdGEgKFhNTFRWKTxicj4gICAgICAgU2V2ZXJhbCBYTUxUViBzb3VyY2VzIHBvc3NpYmxlPGJyPiAgICAgICBBbGxvd3MgZWRpdGluZyBhbmQgb3JkZXIgY2hhbm5lbHM8YnI+ICAgICAgIE0zVSAvIFhNTFRWIGV4cG9ydCAoSFRUUCBsaW5rIGZvciBJUFRWIGFwcHMpIgoKdmFyIGNvbmZpZ01lbnVfbTN1ID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X20zdVsiX2VsZW1lbnQiXSAgICAgICAgPSAiSU5QVVQiOwpjb25maWdNZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CmNvbmZpZ01lbnVfbTN1WyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9tM3VbIl9sYWJlbCJdICAgICAgICAgID0gIk0zVSBGaWxlOiBsb2NhbCBvciByZW1vdGUiOwpjb25maWdNZW51X20zdVsibmFtZSJdICAgICAgICAgICAgPSAiZmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJpZCJdICAgICAgICAgICAgICA9ICJtM3UiOwpjb25maWdNZW51X20zdVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfbTN1WyJwbGFjZWhvbGRlciJdICAgICA9ICJNM1UgRmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJfdXNhZ2UiXSAgICAgICAgICA9ICJSZW1vdGUgcGxheWxpc3Q6IGh0dHA6Ly95b3VyLnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1IgoKCmNvbmZpZ01lbnVfbTN1WyJ2YWx1ZSJdICAgICAgICAgICA9ICJodHRwOi8vd2Vic3J2LmxvY2FsOjgwODAva2FiZWwubTN1IjsKCnZhciBjb25maWdNZW51X2NvbXBsZXRlID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X2NvbXBsZXRlWyJfZWxlbWVudCJdICAgICAgICA9ICJIMiI7CmNvbmZpZ01lbnVfY29tcGxldGVbIl9tZW51VHlwZSJdICAgICAgID0gImlucHV0QXJyYXkiOwpjb25maWdNZW51X2NvbXBsZXRlWyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsiX3RleHQiXSAgICAgICAgICAgPSAieFRlVmUgd2FzIHN1Y2Nlc3NmdWxseSBzZXQgdXAiOwpjb25maWdNZW51X2NvbXBsZXRlWyJuYW1lIl0gICAgICAgICAgICA9ICJjb21wbGV0ZSI7CmNvbmZpZ01lbnVfY29tcGxldGVbImlkIl0gICAgICAgICAgICAgID0gImNvbXBsZXRlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfY29tcGxldGVbImNsYXNzIl0gICAgICAgICAgID0gImNlbnRlciI7Cgpjb25maWdNZW51WyJ0dW5lciJdICAgICA9IGNvbmZpZ01lbnVfdHVuZXI7CmNvbmZpZ01lbnVbImVwZ1NvdXJjZSJdID0gY29uZmlnTWVudV9lcGc7CmNvbmZpZ01lbnVbIm0zdSJdICAgICAgID0gY29uZmlnTWVudV9tM3U7CmNvbmZpZ01lbnVbImNvbXBsZXRlIl0gID0gY29uZmlnTWVudV9jb21wbGV0ZTsKCmZ1bmN0aW9uIHJlYWR5Rm9yQ29uZmlndXJhdGlvbigpIHsKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICBkYXRhWyJjbWQiXSA9ICJnZXRTZXJ2ZXJDb25maWciOwogIHhUZVZlKGRhdGEpOwogIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsKfQoKZnVuY3Rpb24gY3JlYXRlQ29uZmlndXJhdGlvbihlbG0pIHsKCiAgYWN0aXZlV2l6YXJkID0gZWxtOwogIHZhciBpdGVtICA9IGNvbmZpZ01lbnVbZWxtXTsKCiAgdmFyIGRpdiAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKTsKICBkaXYuaW5uZXJIVE1MID0gIiI7CiAgZGl2LnNldEF0dHJpYnV0ZSgiZGF0YS1jb25maWdLZXkiLCBpdGVtWyJfY29uZmlnS2V5Il0pOwogIGRpdi5zZXRBdHRyaWJ1dGUoImRhdGEtbWVudVR5cGUiLCBpdGVtWyJfbWVudVR5cGUiXSk7CiAgCiAgc3dpdGNoKGl0ZW0uaGFzT3duUHJvcGVydHkoIl9sYWJlbCIpKSB7CiAgICBjYXNlIHRydWU6CiAgICAgIHZhciBuZXdJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdJdGVtWyJfZWxlbWVudCJdID0gIkxBQkVMIjsKICAgICAgbmV3SXRlbVsiX3RleHQiXSAgICA9IGl0ZW1bIl9sYWJlbCJdOyAKICAgICAgbmV3SXRlbVsiZm9yIl0gICAgICA9IGl0ZW1bImlkIl07CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0l0ZW0pKTsKICAgICAgYnJlYWsKICB9CgogIHN3aXRjaChpdGVtWyJfZWxlbWVudCJdKSB7CiAgICBjYXNlICJTRUxFQ1QiOgogICAgICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChpdGVtKSk7CiAgICAgIHZhciBzZWxlY3RFbGVtZW50ID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJTRUxFQ1QiKVswXTsKICAgICAgdmFyIHZhbHVlcyA9IGl0ZW1bIl9vcHRpb25WYWx1ZXMiXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBLine truncated
|
||||
webUI["html/js/configuration_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBXaXphcmRDYXRlZ29yeSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFdpemFyZENhdGVnb3J5KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJjb250ZW50IjsKICAgIH0KICAgIFdpemFyZENhdGVnb3J5LnByb3RvdHlwZS5jcmVhdGVDYXRlZ29yeUhlYWRsaW5lID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJINCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgcmV0dXJuIFdpemFyZENhdGVnb3J5Owp9KCkpOwp2YXIgV2l6YXJkSXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHsKICAgIF9fZXh0ZW5kcyhXaXphcmRJdGVtLCBfc3VwZXIpOwogICAgZnVuY3Rpb24gV2l6YXJkSXRlbShrZXksIGhlYWRsaW5lKSB7CiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpczsKICAgICAgICBfdGhpcy5oZWFkbGluZSA9IGhlYWRsaW5lOwogICAgICAgIF90aGlzLmtleSA9IGtleTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CiAgICBXaXphcmRJdGVtLnByb3RvdHlwZS5jcmVhdGVXaXphcmQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGhlYWRsaW5lID0gdGhpcy5jcmVhdGVDYXRlZ29yeUhlYWRsaW5lKHRoaXMuaGVhZGxpbmUpOwogICAgICAgIHZhciBrZXkgPSB0aGlzLmtleTsKICAgICAgICB2YXIgY29udGVudCA9IG5ldyBQb3B1cENvbnRlbnQoKTsKICAgICAgICB2YXIgZGVzY3JpcHRpb247CiAgICAgICAgdmFyIGRvYyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuRG9jdW1lbnRJRCk7CiAgICAgICAgZG9jLmlubmVySFRNTCA9ICIiOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChoZWFkbGluZSk7CiAgICAgICAgc3dpdGNoIChrZXkpIHsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IDEwMDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dC5wdXNoKGkpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIjEiLCBrZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBzZWxlY3QuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gInt7LndpemFyZC50dW5lci5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJlcGdTb3VyY2UiOgogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBbIlBNUyIsICJYRVBHIl07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gWyJQTVMiLCAiWEVQRyJdOwogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIlhFUEciLCBrZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBzZWxlY3QuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gInt7LndpemFyZC5lcGdTb3VyY2UuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAibTN1IjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBrZXksICIiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sud2l6YXJkLm0zdS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIndpemFyZCIpOwogICAgICAgICAgICAgICAgaW5wdXQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLm0zdS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ4bWx0diI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0Iiwga2V5LCAiIik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LndpemFyZC54bWx0di5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIndpemFyZCIpOwogICAgICAgICAgICAgICAgaW5wdXQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLnhtbHR2LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhrZXkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhciBwcmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBwcmUuaW5uZXJIVE1MID0gZGVzY3JpcHRpb247CiAgICAgICAgZG9jLmFwcGVuZENoaWxkKHByZSk7CiAgICAgICAgY29uc29sZS5sb2coaGVhZGxpbmUsIGtleSk7CiAgICB9OwogICAgcmV0dXJuIFdpemFyZEl0ZW07Cn0oV2l6YXJkQ2F0ZWdvcnkpKTsKZnVuY3Rpb24gcmVhZHlGb3JDb25maWd1cmF0aW9uKHdpemFyZCkgewogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoImdldFNlcnZlckNvbmZpZyIpOwogICAgc2VydmVyLnJlcXVlc3QobmV3IE9iamVjdCgpKTsKICAgIHNob3dFbGVtZW50KCJsbLine truncated
|
||||
webUI["html/js/log.js"] = "dmFyIGxvZ0ludGVydmFsCgoKZnVuY3Rpb24gdXBkYXRlTG9nKCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldExvZyI7CiAgeFRlVmUoZGF0YSk7CiAgd3JpdGVMb2dJbkRpdigpOwogIHJldHVybgp9CgpmdW5jdGlvbiB3cml0ZUxvZ0luRGl2KCkgewogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIikubGFzdENoaWxkLmxhc3RDaGlsZDsKICBkaXYuaW5uZXJIVE1MID0gIiI7CgogIHZhciBtYXggPSA1MDsKICAKICAKICBmb3IgKHZhciBpID0gMDsgaSA8IGxvZ3MubGVuZ3RoOyBpKyspIHsKICAgIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3QoKTsKICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJQIjsKCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiRVJST1IiKSkgewovLyAgICAgIGNhc2UgIndhcm5pbmdzIjogIG1zZ1R5cGUgPSAid2FybmluZ01zZyI7IGJyZWFrOwogICAgICBuZXdFbnRyeVsiY2xhc3MiXSAgID0gImVycm9yTXNnIjsKICAgIH0KCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiV0FSTklORyIpKSB7Ci8vICAgICAgY2FzZSAid2FybmluZ3MiOiAgbXNnVHlwZSA9ICJ3YXJuaW5nTXNnIjsgYnJlYWs7CiAgICAgIG5ld0VudHJ5WyJjbGFzcyJdICAgPSAid2FybmluZ01zZyI7CiAgICB9CgogICAgbmV3RW50cnlbIl90ZXh0Il0gICAgID0gbG9nc1tpXTsKICAgIAogICAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICB9CgogIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB2YXIgc2Nyb2xsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgc2Nyb2xsRGl2LnNjcm9sbFRvcCA9IHNjcm9sbERpdi5zY3JvbGxIZWlnaHQ7Cn0KCmZ1bmN0aW9uIHNob3dMb2cob2JqKSB7CiAgLy9sb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7CgogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKCiAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIkhSIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogIC8vZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiRW1wdHkgTG9nIjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJlbXB0eUxvZygpIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiY29kZSI7CiAgbmV3RW50cnlbIl90ZXh0Il0gICAgICAgID0gIlVwZGF0ZSBMb2c6ICI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJjaGVja2JveCI7CiAgLy9uZXdFbnRyeVsiY2hlY2tlZCJdICAgICA9ICJjaGVja2JveCI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAibG9nVXBkYXRlcyh0aGlzKSI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgCgoKICAKICB2YXIgbmV3V3JhcHBlciA9IG5ldyBPYmplY3QoKTsKICBuZXdXcmFwcGVyWyJfZWxlbWVudCJdICA9ICJESVYiOwogIG5ld1dyYXBwZXJbImlkIl0gICAgICAgID0gImJveC13cmFwcGVyIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdXcmFwcGVyKSk7CiAgZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld1ByZSA9IG5ldyBPYmplY3QoKTsKICBuZXdQcmVbIl9lbGVtZW50Il0gID0gIlBSRSI7CiAgbmV3UHJlWyJpZCJdICAgICAgICA9ICJsb2dTY3JlZW4iOwogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1ByZSkpOwoKICBkaXYgPSBkaXYubGFzdENoaWxkOwoKICB3cml0ZUxvZ0luRGl2KCkKICByZXR1cm4KfQoKZnVuY3Rpb24gZW1wdHlMb2coKSB7CiAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgZGF0YVsiY21kIl0gPSAiZW1wdHlMb2ciOwogIHhUZVZlKGRhdGEpOwogIHJldHVybgp9CgpmdW5jdGlvbiBsb2dVcGRhdGVzKGVsbSkgewogIHN3aXRjaChlbG0uY2hlY2tlZCkgewogICAgY2FzZSBmYWxzZTogY2xlYXJJbnRlcnZhbChsb2dJbnRlcnZhbCk7IGJyZWFrOwogICAgY2FzZSB0cnVlOiBsb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7IGJyZWFrOwogICAgCiAgfQp9"
|
||||
webUI["html/js/menu_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBNYWluTWVudSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIE1haW5NZW51KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJtYWluLW1lbnUiOwogICAgICAgIHRoaXMuSFRNTFRhZyA9ICJMSSI7CiAgICAgICAgdGhpcy5JbWFnZVBhdGggPSAiaW1nLyI7CiAgICB9CiAgICBNYWluTWVudS5wcm90b3R5cGUuY3JlYXRlSU1HID0gZnVuY3Rpb24gKHNyYykgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU1HIik7CiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoInNyYyIsIHRoaXMuSW1hZ2VQYXRoICsgc3JjKTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICBNYWluTWVudS5wcm90b3R5cGUuY3JlYXRlVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlAiKTsKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICAgIHJldHVybiBNYWluTWVudTsKfSgpKTsKdmFyIE1haW5NZW51SXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHsKICAgIF9fZXh0ZW5kcyhNYWluTWVudUl0ZW0sIF9zdXBlcik7CiAgICBmdW5jdGlvbiBNYWluTWVudUl0ZW0obWVudUtleSwgdmFsdWUsIGltYWdlLCBoZWFkbGluZSkgewogICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7CiAgICAgICAgX3RoaXMubWVudUtleSA9IG1lbnVLZXk7CiAgICAgICAgX3RoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICBfdGhpcy5pbWdTcmMgPSBpbWFnZTsKICAgICAgICBfdGhpcy5oZWFkbGluZSA9IGhlYWRsaW5lOwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KICAgIE1haW5NZW51SXRlbS5wcm90b3R5cGUuY3JlYXRlSXRlbSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgaXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkxJIik7CiAgICAgICAgaXRlbS5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAiamF2YXNjcmlwdDogb3BlblRoaXNNZW51KHRoaXMpIik7CiAgICAgICAgaXRlbS5zZXRBdHRyaWJ1dGUoImlkIiwgdGhpcy5pZCk7CiAgICAgICAgdmFyIGltZyA9IHRoaXMuY3JlYXRlSU1HKHRoaXMuaW1nU3JjKTsKICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmNyZWF0ZVZhbHVlKHRoaXMudmFsdWUpOwogICAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQoaW1nKTsKICAgICAgICBpdGVtLmFwcGVuZENoaWxkKHZhbHVlKTsKICAgICAgICB2YXIgZG9jID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5Eb2N1bWVudElEKTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaXRlbSk7CiAgICAgICAgc3dpdGNoICh0aGlzLm1lbnVLZXkpIHsKICAgICAgICAgICAgY2FzZSAicGxheWxpc3QiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3sucGxheWxpc3QudGFibGUucGxheWxpc3R9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS50dW5lcn19IiwgInt7LnBsYXlsaXN0LnRhYmxlLmxhc3RVcGRhdGV9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS5hdmFpbGFiaWxpdHl9fSAlIiwgInt7LnBsYXlsaXN0LnRhYmxlLnR5cGV9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS5zdHJlYW1zfX0iLCAie3sucGxheWxpc3QudGFibGUuZ3JvdXBUaXRsZX19ICUiLCAie3sucGxheWxpc3QudGFibGUudHZnSUR9fSAlIiwgInt7LnBsYXlsaXN0LnRhYmxlLnVuaXF1ZUlEfX0gJSJdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbInt7LnhtbHR2LnRhYmxlLmd1aWRlfX0iLCAie3sueG1sdHYudGFibGUubGFzdFVwZGF0ZX19IiwgInt7LnhtbHR2LnRhYmxlLmF2YWlsYWJpbGl0eX19ICUiLCAie3sueG1sdHYudGFibGUuY2hhbm5lbHN9fSIsICJ7ey54bWx0di50YWJsZS5wcm9ncmFtc319Il07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmlsdGVyIjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbInt7LmZpbHRlci50YWJsZS5uYW1lfX0iLCAie3suZmlsdGVyLnRhYmxlLnR5cGV9fSIsICJ7ey5maWx0ZXIudGFibGUuZmlsdGVyfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1c2VycyI6CiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlSGVhZGVyID0gWyJ7ey51c2Vycy50YWJsZS51c2VybmFtZX19IiwgInt7LnVzZXJzLnRhYmxlLnBhc3N3b3JkfX0iLCAie3sudXNlcnMudGFibGUud2VifX0iLCAie3sudXNlcnMudGFibGUucG1zfX0iLCAie3sudXNlcnMudGFibGUubTN1fX0iLCAie3sudXNlcnMudGFibGUueG1sfX0iLCAie3sudXNlcnMudGFibGUuYXBpfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbIkJVTEsiLCAie3subWFwcGluZy50YWJsZS5jaE5vfX0iLCAie3subWFwcGluZy50YWJsZS5sb2dvfX0iLCAie3subWFwcGluZy50YWJsZS5jaGFubmVsTmFtZX19IiwgInt7Lm1hcHBpbmcudGFibGUucGxheWxpc3R9fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmdyb3VwVGl0bGV9fSIsICJ7ey5tYXBwaW5nLnRhYmxlLnhtbHR2RmlsZX19IiwgInt7Lm1hcHBpbmcudGFibGUueG1sdHZJRH19Il07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLy9jb25zb2xlLmxvZyh0aGlzLm1lbnVLZXksIHRoaXMudGFibGVIZWFkZXIpOwogICAgfTsKICAgIHJldHVybiBNYWluTWVudUl0ZW07Cn0oTWFpbk1lbnUpKTsKdmFyIENvbnRlbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBDb250ZW50KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJjb250ZW50IjsKICAgICAgICB0aGlzLlRhYmxlSUQgPSAiY29udGVudF90YWJsZSI7CiAgICAgICAgdGhpcy5oZWFkZXJDbGFzcyA9ICJjb250ZW50X3RhYmxlX2hlYWRlciI7CiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbklEID0gImNvbnRlbnQtaW50ZXJhY3Line truncated
|
||||
webUI["html/maintenance.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgPC9oZWFkPgoKICAgIDxib2R5PgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImhlYWRlciIgY2xhc3M9ImltZ0NlbnRlciI+PC9kaXY+CgogICAgICA8ZGl2IGlkPSJib3giPgoKICAgICAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgICAgICA8aDEgaWQ9ImhlYWQtdGV4dCIgY2xhc3M9ImNlbnRlciI+TWFpbnRlbmFuY2U8L2gxPiAgICAgIAogICAgICAgIDwvZGl2PiAgCgogICAgICAgIDxkaXYgaWQ9ImNvbnRlbnQiPgogICAgICAgICAgeFRlVmUgaXMgdXBkYXRpbmcgdGhlIGRhdGFiYXNlLCBwbGVhc2UgdHJ5IGFnYWluIGxhdGVyLgogICAgICAgIDwvZGl2PgoKICAgICAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj48L2Rpdj4KICAgICAgICAKICAgICAgPC9kaXY+CgogICAgPC9ib2R5Pgo8L2h0bWw+"
|
||||
webUI["html/css/base.css"] = "KiB7CiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lOwogIC1tb3otYXBwZWFyYW5jZTogbm9uZTsKICAtbXMtYXBwZWFyYW5jZTogbm9uZTsKICBmb250LWZhbWlseTogIkFyaWFsIiwgc2Fucy1zZXJpZjsKICBsZXR0ZXItc3BhY2luZzogMnB4OyAKfQoKLyoKOjotd2Via2l0LXNjcm9sbGJhciB7IAogICAgZGlzcGxheTogbm9uZTsgCn0KKi8KCjo6LXdlYmtpdC1zY3JvbGxiYXIgewogIHdpZHRoOiAxMnB4OwogIGhlaWdodDogMTJweDsKfQoKIAo6Oi13ZWJraXQtc2Nyb2xsYmFyLXRyYWNrIHsKICAtd2Via2l0LWJveC1zaGFkb3c6IGluc2V0IDAgMCA2cHggcmdiYSgwLDAsMCwwLjMpOyAKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgICAKfQogCjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIgewogIGJvcmRlci1yYWRpdXM6IDVweDsKICAtd2Via2l0LWJveC1zaGFkb3c6IGluc2V0IDAgMCA2cHggcmdiYSgwLCAwLCAwLDAuNik7IAogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7Cn0KCjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXIgewogIGJhY2tncm91bmQ6ICMzMzM7IAp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLWNvcm5lciB7IAogIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyAKfQoKYSB7CiAgY29sb3I6ICMwMEU2RkY7Cn0KCmh0bWwsIGJvZHkgewogIGNvbG9yOiAjZmZmOwogIG1hcmdpbjogMHB4IGF1dG87CiAgaGVpZ2h0OiAxMDAlOwogIGZvbnQtc2l6ZTogMTRweDsKfQoKaDIgewogIGZvbnQtc2l6ZTogMjRweDsKICBsZXR0ZXItc3BhY2luZzogMnB4Owp9CgpoMyB7CiAgZm9udC1zaXplOiAyMnB4OwogIGxldHRlci1zcGFjaW5nOiAxcHg7Cn0KCmg0IHsKICBmb250LXNpemU6IDIwcHg7CiAgbGV0dGVyLXNwYWNpbmc6IDFweDsKICBsaW5lLWhlaWdodDogMS41ZW07Cgp9CgpoNSB7CiAgZm9udC1zaXplOiAxNnB4OwogIGxldHRlci1zcGFjaW5nOiAxcHg7CiAgbGluZS1oZWlnaHQ6IDEuMmVtOwogIG1hcmdpbjogMjVweCAwcHggMTBweCAwcHg7Cn0KCmhyIHsKICBib3JkZXI6IDA7CiAgaGVpZ2h0OiAxcHg7CiAgYmFja2dyb3VuZDogIzMzMzsKICBtYXJnaW46IDEwcHggMHB4Owp9CgpwIHsKICBtYXJnaW46IDJweDsKICBwYWRkaW5nOiAycHggNXB4Owp9CgpwcmUgewogIG1hcmdpbjogMHB4IDBweCA1cHggMHB4OwogIGZvbnQtc2l6ZTogMTJweDsKICBjb2xvcjogI2RkZDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOyAKICBmb250LXNpemU6IDEycHg7IAogIGZvbnQtc3R5bGU6IG5vcm1hbDsgCiAgZm9udC12YXJpYW50OiBub3JtYWw7IAogIGxpbmUtaGVpZ2h0OiAxLjZlbTsgCn0KCmxhYmVsIHsKICBtYXJnaW4tYm90dG9tOiAyMHB4OwogIGRpc3BsYXk6IGJsb2NrOwp9CgpsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIGJhY2tncm91bmQtY29sb3I6ICMxMTE7CiAgcGFkZGluZzogMTBweCAyMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBib3JkZXItbGVmdDogc29saWQgMnB4ICMxMTE7CiAgdHJhbnNpdGlvbjogYWxsIDAuMzsKfQoKbGk6aG92ZXIgewogIGJvcmRlci1jb2xvcjogIzAwRTZGRgp9CgpzZWxlY3QgewogIGN1cnNvcjogcG9pbnRlcjsKICB3aWR0aDogY2FsYygxMDAlICsgMnB4KTsKICBib3JkZXI6IHNvbGlkIDBweCAjMDBFNkZGOwogIGJvcmRlci1yYWRpdXM6IDBweDsKICBvdXRsaW5lOiBub25lOwogIGNvbG9yOiAjZmZmOwogIHBhZGRpbmc6IDlweCAxMHB4OwogIGRpc3BsYXk6YmxvY2s7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBmb250LXNpemU6IDE0cHg7CiAgbWFyZ2luOiA1cHggMHB4IDVweCAwcHg7Cn0KCnNlbGVjdDpmb2N1cyB7CiAgb3V0bGluZTogbm9uZTsKfQoKaW5wdXQgewogIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTsKICBtYXJnaW46IDVweCAwcHg7CiAgcGFkZGluZzogMi41cHggMTBweDsKICBvdXRsaW5lOiBub25lOwogIGZvbnQtc2l6ZTogMTRweDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLCBpbnB1dFt0eXBlPXN1Ym1pdF0gewogIGN1cnNvcjogcG9pbnRlcjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIG1hcmdpbjogMTBweCAxMHB4OwogIHBhZGRpbmc6IDEwcHggMjVweDsKICBib3JkZXI6IHNvbGlkIDBweDsKICBib3JkZXItY29sb3I6ICMwMDA7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIG91dGxpbmU6IG5vbmU7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXTpmb2N1cyB7IAogICBvdXRsaW5lOiBub25lOwp9CgppbnB1dFt0eXBlPWJ1dHRvbl06aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMwMEU2RkY7CiAgY29sb3I6ICMwMDA7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXTpob3Zlci5kZWxldGUgIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9dGV4dF0sIGlucHV0W3R5cGU9c2VhcmNoXSwgaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIGNvbG9yOiAjZmZmOwogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDBweCk7CiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMHB4KTsKICB3aWR0aDogY2FsYygxMDAlIC0gMHB4KTsKICBvdXRsaW5lOiBub25lOwogIGJvcmRlcjogc29saWQgMXB4IHRyYW5zcGFyZW50OwogIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OwogIGJvcmRlci1ib3R0b20tY29sb3I6ICM1NTU7CiAgYm9yZGVyLXJhZGl1czogMHB4OwogIHBhZGRpbmc6IDhweCAxMHB4Owp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdIHsKICBib3JkZXI6IHNvbGlkIDFweCAjMDBFNkZGOwogIGJhY2tncm91bmQtY29sb3I6ICMzMzM7CiAgaGVpZ2h0OiAyNXB4OwogIHdpZHRoOiAyNXB4OwogIGN1cnNvcjogcG9pbnRlcjsKICAvKgogIC13ZWJraXQtYXBwZWFyYW5jZTogY2hlY2tib3g7CiAgKi8KfQoKaW5wdXRbdHlwZT0iY2hlY2tib3giXTpjaGVja2VkIHsKICBjb2xvcjogI2ZmZjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDBFNkZGOwogIC8qZGlzcGxheTogaW5saW5lLWJsb2NrOyovCn0KCmlucHV0W3R5cGU9ImNoZWNrYm94Il06YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC00cHg7CiAgY29udGVudDogIiAiOwp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdOmNoZWNrZWQ6YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC0zcHg7CiAgY29udGVudDogIuKckyI7CiAgY29sb3I6ICMwMDA7Cn0KCgppbnB1dFt0eXBlPWJ1dHRvbl0uY2FuY2VsIHsKICAKICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKICBib3JkZXItY29sb3I6IHJlZDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLnNhdmV7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBmbG9hdDogcmlnaHQ7Cn0KCgppbnB1dFt0eXBlPWJ1dHRvbl0uYmxhY2ssIGlucHV0W3R5cGU9c3VibWl0XS5ibGFja3sKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIGJvcmRlci1jb2xvcjogIzAwMDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLmNlbnRlcnsKICBtYXJnaW4tcmlnaHQ6IGF1dG87CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsKICBib3JkZXItY29sb3I6ICMwMDA7Cn0KCi5wb2ludGVyIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5wb2ludGVyOmhvdmVyIHsKICBjb2xLine truncated
|
||||
webUI["html/img/log.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xNFQxMToxMDo0MjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CkP32mEAAANASURBVGgF7ZlPiE1RHMffw1AYhiL5k1HEijJiYaFZiHoyFspW2RFRkkSZGgtFWJIwi9FYmo0VOywkKTbKgjSlWcifRCPX51dv6s2d33md77vvXjfmV9859/7u93x/v98959x73p1KRbAkSargAhgDH0E/qIYkuHYEvAPGvwbmNOEerXM/0Q6BRSFuZj/ix0DaDnvCkGppIucDAe4OhzvkcUO+GaELAf8ux7/b8Zlrr+Pvc3zm6nX8NccXdKmFLHaUPJ/Ruhyu5zNap8Nd6PiCLrUQTyi0Rjy/5/M0Zd+smB7M32XwtgBr07aC6yfSTs7XO77OALfH4VbgHsD/HLytVquJx4nyIdQFBsHftscksK5Z0sGhpuN8Or4Aa5sJFHjtO7G2MjKvvZjN1sglOpSlCMt9LrDZ4S4Hd0Qg24vrK+gAZbPtjMqTdFKhEdkIsYxFWP720JlioUK6pzDL41jtpRIqxOOWxecuB3fhRGT8E85YBK8VygI6GSRTCxlH3TaJgyw4O2678aCxO94LbNPovYDdmOrUukIBN/MqwjJEOwGPOHR31W4VONVCLEBR9lAJpBbSrYhn5K5R+quFnGUOr1ICtMIlxjz6XVb6qot9JeKvCPSAdlQJJHDtd8hOIN0wtRDLxx6Ntr0ulalTq1TJNyYzXUjj3SjD8X87Iva7uR8s5+2bi6FtX1oOgi8g2tSn1g2yPx+t3gIR/c90s1+C1vuO/YkxdWrdjxFtE2dE0VELWaqIZ+QuUfqrhZxmyKUvgEoyE1xizOR4YOI8plXXyAZEbYsyTJvXFsUW+x6wGUSbWogJ237rZHSEgojq1CooLT3MdCH6Pcu3xz8zIq0s9lvc2+sgz6dWH/rnQPB/jlybZGoh99hCHJqk0P6TD0jaI/4b7dVYeXVq2bemokyKpRZiHwWKMimWWshxhryjoEpOKXHUNbIN8WcUc5s2r8Vue7l9oAaiTS3EhDeB6EUYnUlGojq1MobLr3uokB/5hcys7OYWKuRl5nD5Cbi5uYXw0ntPHoay2S8Seuol5RZSJ0r/n/DEc/BdrN9kTZrH7BkwDspgwyQxW6uggU3nHnAXvAG/QZE2SrARsL8hJffwDxM0mNDPvT8IAAAAAElFTkSuQmCC"
|
||||
webUI["html/img/xmltv.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQyMDowNzozMzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Co6j9bsAAAGgSURBVGgF7VqxTsNADL0gYGEon8DOwsbAAH8BYmJn6cYIn8DC3h0+oixISFRiYYCJL0AwMMBAeK5w2rpV6uikxHfYknW98+vds18TK21DWGBlWR7CH+BfcEv2AzLP8HP42gLqkyUATuEp2PWEdQjF9ATs1zF/g29Mrxt+vVcUxR3xWxEktzFPJQmivsv8ZSI9DiQyVnxlIonwn6fpiczXpNuVVXH8O+a3Ys3y9NUyuf/NTTbEHZTjUlGSRzSiPhroUIENwB4AS/vS/susDwDhTpYBER9g7wHh5DWyibV9CiitCZbIafDEYUuJHQI3Nr/9ciWsjK6IFSWYhyvClbAyZqOIlYJG84jq7E1Ot97Zm+TinV1TrWwudk9EI3ebGFekzWprzspGEU2ySWCiOrs/s9dr7M/s9fVJJJrNXcsTsfaJc0WsKZINH+/sf1Jqvl1n1f2ZnStRN/pdq646XcSkIh9dkIg4s+IrE3nCpp8RG7f91ns+cCYR/LD4jcAZB42PN+A7/mcQ8ZxJhBYQvMJwBB/BKTFLVoLMC/wCfgyv7BesTKUC2LKM3wAAAABJRU5ErkJggg=="
|
||||
webUI["html/js/mapping-editor.js"] = "dmFyIG1hcHBpbmdFcnJvciAgPSBmYWxzZTsKdmFyIGJ1bGsgICAgICAgICAgPSBmYWxzZTsKdmFyIGJ1bGtFZGl0QWxsICAgPSBmYWxzZTsgCnZhciBzZWxlY3RPYmogICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc2VhcmNoT2JqICAgICA9IG5ldyBPYmplY3QoKTsKCnZhciBidWxrSURzICAgICAgID0gbmV3IEFycmF5KCk7CnZhciBidWxrQ2hhbmdlT2JqID0gbmV3IE9iamVjdCgpOwoKZnVuY3Rpb24gY2hlY2tVbmRvKGtleSwgZWxtKSB7CiAgdmFyIHRtcCA9IG5ldyBPYmplY3QoKTsKICB0bXAgPSBlbG0KICBjb25zb2xlLmxvZygiLS0iKTsKICBpZiAodW5kby5oYXNPd25Qcm9wZXJ0eSgiZXBnTWFwcGluZyIpKSB7CiAgICB4RVBHWyJlcGdNYXBwaW5nIl0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHVuZG9bImVwZ01hcHBpbmciXSkpOzsKICB9IGVsc2UgewogICAgdW5kb1siZXBnTWFwcGluZyJdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlbG0pKTsKICB9Cn0KCi8vdmFyIHBsZXhDYXRlZ29yaWVzID0gbmV3IEFycmF5KCItIiwgIkFjdGlvbiBzcG9ydHMiLCAiQWN0aW9uIiwgIkFkdWx0cyBvbmx5IiwgIkFkdmVudHVyZSIsICJBZXJvYmljcyIsICJBbmltYWxzIiwgIkFuaW1hdGVkIiwgIkFuaW1lIiwgIkFudGhvbG9neSIsICJBcmNoZXJ5IiwgIkFydCIsICJBcnRzL2NyYWZ0cyIsICJBdWN0aW9uIiwgIkF1dG8gcmFjaW5nIiwgIkF1dG8iLCAiQXZpYXRpb24iLCAiQXdhcmRzIiwgIkJhbGxldCIsICJCYXNlYmFsbCIsICJCYXNrZXRiYWxsIiwgIkJpY3ljbGUgcmFjaW5nIiwgIkJpY3ljbGUiLCAiQmlsbGlhcmRzIiwgIkJpb2dyYXBoeSIsICJCb2F0IHJhY2luZyIsICJCb2F0IiwgIkJvd2xpbmciLCAiQm94aW5nIiwgIkJ1cy4vZmluYW5jaWFsIiwgIkNoaWxkcmVuIiwgIkNvbGxlY3RpYmxlcyIsICJDb21lZHkgZHJhbWEiLCAiQ29tZWR5IiwgIkNvbW11bml0eSIsICJDb21wdXRlcnMiLCAiQ29uc3VtZXIiLCAiQ29va2luZyIsICJDcmltZSBkcmFtYSIsICJDcmltZSIsICJEYW5jZSIsICJEYXJrIGNvbWVkeSIsICJEZWJhdGUiLCAiRGl2aW5nIiwgIkRvY3VkcmFtYSIsICJEb2N1bWVudGFyeSIsICJEcmFtYSIsICJFZHVjYXRpb25hbCIsICJFbnRlcnRhaW5tZW50IiwgIkVudmlyb25tZW50IiwgIkVxdWVzdHJpYW4iLCAiRXJvdGljIiwgIkV2ZW50IiwgIkZhbnRhc3kiLCAiRmFzaGlvbiIsICJGZWF0dXJlIEZpbG0iLCAiRmlzaGluZyIsICJGb290YmFsbCIsICJHYW1lIHNob3ciLCAiR2FtaW5nIiwgIkdheS9sZXNiaWFuIiwgIkdvbGYiLCAiSGFuZGJhbGwiLCAiSGVhbHRoIiwgIkhpc3RvcmljYWwgZHJhbWEiLCAiSGlzdG9yeSIsICJIb2NrZXkiLCAiSG9saWRheSIsICJIb21lIGltcHJvdmVtZW50IiwgIkhvcnJvciIsICJIb3JzZSIsICJIb3VzZS9nYXJkZW4iLCAiSG93LXRvIiwgIkludGVydmlldyIsICJJbnRsIHNvY2NlciIsICJMYXciLCAiTWFydGlhbCBhcnRzIiwgIk1lZGljYWwiLCAiTWlsaXRhcnkiLCAiTWluaXNlcmllcyIsICJNaXhlZCBtYXJ0aWFsIGFydHMiLCAiTW90b3JjeWNsZSByYWNpbmciLCAiTW90b3JjeWNsZSIsICJNb3RvcnNwb3J0cyIsICJNb3VudGFpbiBiaWtpbmciLCAiTXVzaWMiLCAiTXVzaWNhbCBjb21lZHkiLCAiTXVzaWNhbCIsICJNeXN0ZXJ5IiwgIk5hdHVyZSIsICJOZXdzIiwgIk5ld3NtYWdhemluZSIsICJPbHltcGljcyIsICJPcGVyYSIsICJPdXRkb29ycyIsICJQYXJhZGUiLCAiUGFyYW5vcm1hbCIsICJQYXJlbnRpbmciLCAiUGVyZm9ybWluZyBhcnRzIiwgIlBsYXlvZmYgc3BvcnRzIiwgIlBva2VyIiwgIlBvbGl0aWNzIiwgIlBybyB3cmVzdGxpbmciLCAiUHVibGljIGFmZmFpcnMiLCAiUmVhbGl0eSIsICJSZWxpZ2lvdXMiLCAiUm9kZW8iLCAiUm9sbGVyIGRlcmJ5IiwgIlJvbWFuY2UiLCAiUm9tYW50aWMgY29tZWR5IiwgIlJ1Z2J5IiwgIlJ1bm5pbmciLCAiU2FpbGluZyIsICJTY2llbmNlIGZpY3Rpb24iLCAiU2NpZW5jZSIsICJTZWxmIGltcHJvdmVtZW50IiwgIlNlcmllcyIsICJTaG9vdGluZyIsICJTaG9wcGluZyIsICJTaG9ydCBGaWxtIiwgIlNpdGNvbSIsICJTa2lpbmciLCAiU25vb2tlciIsICJTb2FwIiwgIlNvY2NlciIsICJTcGVjaWFsIiwgIlNwb3J0cyIsICJzcG9ydHMiLCAiU3BvcnRzIGV2ZW50IiwgIlNwb3J0cyBub24tZXZlbnQiLCAiU3BvcnRzIHRhbGsiLCAiU3RhbmR1cCIsICJTdXJmaW5nIiwgIlN1c3BlbnNlIiwgIlRWIE1vdmllIiwgIlRhbGsiLCAiVGVjaG5vbG9neSIsICJUZW5uaXMiLCAiVGhlYXRlciIsICJUaHJpbGxlciIsICJUcmFjay9maWVsZCIsICJUcmF2ZWwiLCAiVHJpYXRobG9uIiwgIlZhcmlldHkiLCAiVm9sbGV5YmFsbCIsICJXYXIiLCAiV2F0ZXJzcG9ydHMiLCAiV2VhdGhlciIsICJXZXN0ZXJuIiwgIldyZXN0bGluZyIsICJZYWNodCByYWNpbmciLCAibW92aWUiLCAic2VyaWVzIiwgInNwb3J0cyIsICJ0dnNob3ciKTsKdmFyIHBsZXhDYXRlZ29yaWVzVmFsdWVzID0gbmV3IEFycmF5KCItIiwgIktpZHMiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKdmFyIHBsZXhDYXRlZ29yaWVzT3B0aW9uID0gbmV3IEFycmF5KCItIiwgIktpZHMgKEVtYnkgb25seSkiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKCgpmdW5jdGlvbiBvcGVuTWFwcGluZ0VkaXRvcihlbG0pIHsKICB2YXIgY29sdW1uVG9Tb3J0ICA9IDEKCiAgY2hlY2tVbmRvKCJlcGdNYXBwaW5nIiwgeEVQR1siZXBnTWFwcGluZyJdKQoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiU2F2ZSI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAic2F2ZVhFUEcoKSI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiQnVsayBFZGl0IjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJidWxrRWRpdCgpIjsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiSU5QVVQiOwogIG5ld0VudHJ5WyJ0eXBlIl0gICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gICAgICAgPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSAgICAgICA9ICJTaG93IFhFUEciOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gICAgID0gInNob3dYRVBHKCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlLine truncated
|
||||
webUI["html/js/network_ts.js"] = "dmFyIFNlcnZlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFNlcnZlcihjbWQpIHsKICAgICAgICB0aGlzLmNtZCA9IGNtZDsKICAgIH0KICAgIFNlcnZlci5wcm90b3R5cGUucmVxdWVzdCA9IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgaWYgKFNFUlZFUl9DT05ORUNUSU9OID09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfQ09OTkVDVElPTiA9IHRydWU7CiAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgaWYgKHRoaXMuY21kICE9ICJ1cGRhdGVMb2ciKSB7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgIFVORE8gPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAod2luZG93LmxvY2F0aW9uLnByb3RvY29sKSB7CiAgICAgICAgICAgIGNhc2UgImh0dHA6IjoKICAgICAgICAgICAgICAgIHRoaXMucHJvdG9jb2wgPSAid3M6Ly8iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImh0dHBzOiI6CiAgICAgICAgICAgICAgICB0aGlzLnByb3RvY29sID0gIndzczovLyI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHVybCA9IHRoaXMucHJvdG9jb2wgKyB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgKyAiOiIgKyB3aW5kb3cubG9jYXRpb24ucG9ydCArICIvZGF0YS8iICsgIj9Ub2tlbj0iICsgZ2V0Q29va2llKCJUb2tlbiIpOwogICAgICAgIGRhdGFbImNtZCJdID0gdGhpcy5jbWQ7CiAgICAgICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh1cmwpOwogICAgICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgV1NfQVZBSUxBQkxFID0gdHJ1ZTsKICAgICAgICAgICAgY29uc29sZS5sb2coIlJFUVVFU1QgKEpTKToiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSRVFVRVNUOiAoSlNPTikiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgICAgICB0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgIH07CiAgICAgICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJObyB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byB4VGVWZSBjb3VsZCBiZSBlc3RhYmxpc2hlZC4gQ2hlY2sgeW91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIFNFUlZFUl9DT05ORUNUSU9OID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChXU19BVkFJTEFCTEUgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGFsZXJ0KCJObyB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byB4VGVWZSBjb3VsZCBiZSBlc3RhYmxpc2hlZC4gQ2hlY2sgeW91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHdzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIFNFUlZFUl9DT05ORUNUSU9OID0gZmFsc2U7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgZmFsc2UpOwogICAgICAgICAgICBjb25zb2xlLmxvZygiUkVTUE9OU0U6Iik7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IEpTT04ucGFyc2UoZS5kYXRhKTsKICAgICAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpOwogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoInRva2VuIikpIHsKICAgICAgICAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9ICJUb2tlbj0iICsgcmVzcG9uc2VbInRva2VuIl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlWyJzdGF0dXMiXSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYWxlcnQocmVzcG9uc2VbImVyciJdKTsKICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgicmVsb2FkIikpIHsKICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoImxvZ29VUkwiKSkgewogICAgICAgICAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjaGFubmVsLWljb24iKTsKICAgICAgICAgICAgICAgIGRpdi52YWx1ZSA9IHJlc3BvbnNlWyJsb2dvVVJMIl07CiAgICAgICAgICAgICAgICBkaXYuY2xhc3NOYW1lID0gImNoYW5nZWQiOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAoZGF0YVsiY21kIl0pIHsKICAgICAgICAgICAgICAgIGNhc2UgInVwZGF0ZUxvZyI6CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSWyJsb2ciXSA9IHJlc3BvbnNlWyJsb2ciXTsKICAgICAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfbG9nIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0xvZ3MoZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICBTRVJWRVIgPSByZXNwb25zZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoIm9wZW5NZW51IikpIHsKICAgICAgICAgICAgICAgIHZhciBtZW51ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocmVzcG9uc2VbIm9wZW5NZW51Il0pOwogICAgICAgICAgICAgICAgbWVudS5jbGljaygpOwogICAgICAgICAgICAgICAgc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgib3BlbkxpbmsiKSkgewogICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcmVzcG9uc2VbIm9wZW5MaW5rIl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJhbGVydCIpKSB7CiAgICAgICAgICAgICAgICBhbGVydChyZXNwb25zZVsiYWxlcnQiXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJyZWxvYWQiKSkgewogICAgICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJ3aXphcmQiKSkgewogICAgICAgICAgICAgICAgY3JlYXRlTGF5b3V0KCk7CiAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uV2l6YXJkW3Jlc3BvbnNlWyJ3aXphcmQiXV0uY3JlYXRlV2l6YXJkKCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3JlYXRlTGF5b3V0KCk7CiAgICAgICAgfTsKICAgIH07CiAgICByZXR1cm4gU2VydmVyOwp9KCkpOwpmdW5jdGlvbiBnZXRDb29raWUobmFtZSkgewogICAgdmFyIHZhbHVlID0gIjsgIiArIGRvY3VtZW50LmNvb2tpZTsKICAgIHZhciBwYXJ0cyA9IHZhbHVLine truncated
|
||||
webUI["html/configuration.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvY29uZmlndXJhdGlvbl90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbWVudV90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvc2V0dGluZ3NfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2Jhc2VfdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keSBvbmxvYWQ9ImphdmFzY3JpcHQ6IHJlYWR5Rm9yQ29uZmlndXJhdGlvbigwKTsiPgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImxvYWRpbmciIGNsYXNzPSJibG9jayI+CiAgICAgICAgPGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgogICAgICA8ZGl2IGlkPSJib3giPgogICAgICAgIAogICAgICAgIDx0YWJsZSBpZD0iY2xpZW50SW5mbyIgY2xhc3M9InZpc2libGUiPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5WZXJzaW9uOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5PUzo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9Im9zIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5VVUlEOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0idXVpZCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5BcmNoOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0iYXJjaCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+U3RyZWFtczo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+RFZSOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0iRFZSIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgIDwvdGFibGU+CiAgICAgICAgCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPkNvbmZpZ3VyYXRpb248L2gxPiAgICAgIAogICAgICAgIDwvZGl2PgogICAgICAgIDxwIGlkPSJlcnIiIGNsYXNzPSJlcnJvck1zZyBjZW50ZXIiPjwvcD4gICAKICAgICAgICA8ZGl2IGlkPSJjb250ZW50Ij4KICAgICAgICAgICAgCiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBpZD0iYm94LWZvb3RlciI+CiAgICAgICAgICA8aW5wdXQgaWQ9Im5leHQiIGNsYXNzPSIiIHR5cGU9ImJ1dHRvbiIgbmFtZT0ibmV4dCIgdmFsdWU9Ik5leHQiIG9uY2xpY2s9ImphdmFzY3JpcHQ6IHNhdmVXaXphcmQoKTsiPgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvYm9keT4KPC9odG1sPg=="
|
||||
webUI["html/css/screen.css"] = "bmF2IGltZyB7CiAgZGlzcGxheTogYmxvY2s7CiAgbWF4LWhlaWdodDogMjBweDsKICBtYXgtd2lkdGg6IDIwcHg7CiAgZmxvYXQ6IGxlZnQ7Cn0KCm5hdiBwIHsKICB0ZXh0LWFsaWduOiBsZWZ0OwogIHBhZGRpbmc6IDBweCAzMHB4Owp9CgojbGF5b3V0IHsKICBkaXNwbGF5OiBibG9jazsKICBoZWlnaHQ6IDEwMCU7Cn0KCgoubGF5b3V0LWxlZnQgewogIGRpc3BsYXk6IGJsb2NrOwogIG1pbi13aWR0aDogMTUwcHg7CiAgbWF4LXdpZHRoOiAyMCU7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBoZWlnaHQ6IGluaGVyaXQ7CiAgZmxvYXQ6IGxlZnQ7Cn0KCi5sYXlvdXQtcmlnaHQgewogIGRpc3BsYXk6IGJsb2NrOwogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7Cn0KCiNtZW51LXdyYXBwZXIgewogIGhlaWdodDogMTAwJTsKfQoKCiNsb2dvIHsKICBkaXNwbGF5OiBibG9jazsKICBtaW4td2lkdGg6IDE4MHB4OwogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvbG9nb193XzYwMHgyMDAucG5nIik7CiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7IAogIGJhY2tncm91bmQtc2l6ZTogMTAwJTsKfQoKCiNwYWdlIHsKICBtYXgtd2lkdGg6IDk1MHB4OwogIG1hcmdpbjogYXV0bzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwoKICAvKgogIGhlaWdodDogLXdlYmtpdC1jYWxjKDEwMCUgLSAxMzBweCk7CiAgaGVpZ2h0OiAtbW96LWNhbGMoMTAwJSAtIDEzMHB4KTsKICBoZWlnaHQ6IGNhbGMoMTAwJSAtIDEzMHB4KTsKICAqLwogIAogIG1pbi1oZWlnaHQ6IC13ZWJraXQtY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IC1tb3otY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IGNhbGMoMTAwJSAtIDEyMHB4KTsKICAKICAKICBib3gtc2hhZG93OiAwcHggNXB4IDVweCAjMjIyOwogIAp9CgojdWlTZXR0aW5nIHsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luLXJpZ2h0OiAyNXB4Owp9CgojYm94IGlucHV0W3R5cGU9dGV4dF0sICNib3ggaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiAtbW96LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiBjYWxjKDEwMCUgLSAyMHB4KTsKfQoKI2JveCBpbnB1dFt0eXBlPXN1Ym1pdF17CiAgbWFyZ2luOiA1MHB4IGF1dG87Cn0KCiNzZXR0aW5ncyB7CiAgZGlzcGxheTogYmxvY2s7CiAgcGFkZGluZzogMTBweCAxMHB4Owp9Cgojc2V0dGluZ3MgaDUgewogIG1hcmdpbjogNTBweCAwcHggMTBweCAwcHg7Cn0KCiNjb250ZW50LWludGVyYWN0aW9uIC5zZWFyY2ggewogIHdpZHRoOiAyMDBweDsKICBib3JkZXI6IDFweCBzb2xpZCAjMDAwOwogIHBhZGRpbmc6IDlweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzMzOwogIG1hcmdpbjogMTBweDsKICBmbG9hdDogcmlnaHQ7CiAgYm9yZGVyLXJhZGl1czogM3B4OwoKfQoKI215U3RyZWFtcyB7CiAgcG9zaXRpb246IGZpeGVkOwogIGJvdHRvbTogMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMxMTE7CiAgd2lkdGg6IDEwMCU7CiAgbWF4LXdpZHRoOiA5NTBweDsKCiAgLyoKICBtYXgtaGVpZ2h0OiAxMDBweDsKICAqLwogIG1hcmdpbi1ib3R0b206IDBweDsKfQoKI215U3RyZWFtcyBpbWcgewogIHdpZHRoOiA0JTsKICBwYWRkaW5nOiAycHggNXB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBmbG9hdDogcmlnaHQ7Cn0KCiNzZXR0aW5ncy1mb290ZXIgewoKfQoKCi8qIFdpemFyZCovCiNib3ggewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7CiAgbWluLWhlaWdodDogNDAwcHg7CiAgCiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsKfQoKI2JveCBwewogIHBhZGRpbmc6IDEwcHggMHB4Owp9CgojYm94LWZvb3RlciB7CiAgbWFyZ2luLXRvcDogYXV0bzsKfQoKI2JveC1mb290ZXIgewogIG1hcmdpbjogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgojaGVhZGxpbmUgewogIGJhY2tncm91bmQtY29sb3I6ICMyMjI7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMnB4ICMyMjI7CiAgdHJhbnNpdGlvbjogYWxsIDAuNXM7CiAgcGFkZGluZzogMTBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7Cn0KCiNjb250ZW50IHsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdzogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgovKiAtLS0gKi8KCgojY2xpZW50SW5mbywgI2FjdGl2ZVN0cmVhbXMsICNpbmFjdGl2ZVN0cmVhbXMgewogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgZGlzcGxheTogYmxvY2s7CiAgZm9udC1zaXplOiA5cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBjb2xvcjogIzAwRTZGRjsKICBib3JkZXItYm90dG9tOiBzb2xpZCAwcHg7OwogIHBhZGRpbmc6IDBweDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIG92ZXJmbG93LXg6IGhpZGRlbjsKICBib3JkZXItc3BhY2luZzogNHB4IDRweDsKICBib3JkZXItYm90dG9tOiBzb2xpZCAxcHggIzQ0NDsKfQoKI215U3RyZWFtc0JveCB7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHBhZGRpbmc6IDBweDsKICAvKmhlaWdodDogMTAwcHg7Ki8KICBtYXgtaGVpZ2h0OiAxNTBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwogIGNvbG9yOiB3aGl0ZTsKICBkaXNwbGF5OmZsZXg7CiAganVzdGlmeS1jb250ZW50OmNlbnRlcjsKICBhbGlnbi1pdGVtczpjZW50ZXI7Cn0KCiNvcGVuU3RyZWFtcyB7CiAgd2lkdGg6IDIwcHg7CiAgaGVpZ2h0OiAyMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBmbG9hdDogcmlnaHQ7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHJpZ2h0OiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvdG91Y2gucG5nIik7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICAKICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gcmlnaHQ7ICAKfQoKI2FsbFN0cmVhbXMgewogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwJTsKICBwYWRkaW5nOiAycHg7ICAgICAKfQoKI2FjdGl2ZVN0cmVhbXMsICNpbmFjdGl2ZVN0cmVhbXMgewogIG92ZXJmbG93LXk6IHNjcm9sbDsKICB3aWR0aDogNTAlOwogIG1heC1oZWlnaHQ6IDEwMHB4OwogIGZsb2F0OiBsZWZ0Owp9CgojYWN0aXZlU3RyZWFtcyAudGRLZXksICNpbmFjdGl2ZVN0cmVhbXMgLnRkS2V5IHsKICB3aWR0aDogNzVweDsKfQoKCgoKI2luYWN0aXZlU3RyZWFtcyAudGRLZXkgewogIGNvbG9yOiByZWQ7Cn0KCiNjbGllbnRJbmZvIC50ZFZhbCwgI2xvZ0luZm8gLnRkVmFsLCAjYWN0aXZlU3RyZWFtcyAudGRWYWwsICNpbmFjdGl2ZVN0cmVhbXMgLnRkVmFsLCAjbWFwcGluZ0luZm8gLnRkVmFsewogIGNvbG9yOiAjYWFhOwogIHdoaXRlLXNwYWNlOiBpbmhlcml0Owp9CgojYm94LXdyYXBwZXIgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICB3aWR0aDogMTAwJTsKICAKICBvdmVyZmxvdy15OiBzY3JvbGw7Cn0KCiNjb250ZW50X3RhYmxlLCAjbWFwcGluZy1kZXRhaWwtdGFibGUsICNjb250ZW50X3RhYmxlIHsKICBkaXNwbGF5OiB0YWJsZTsKICAKICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOwogIG92ZXJmbG93LXk6IHNjcm9sbDsKICB3aWR0aDogMTAwJTsKfQoKCiNjb250ZW50X3RhYmxlIC5jb250ZW50X3RhYLine truncated
|
||||
webUI["html/img/x_white.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMToyNTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI1NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgrJkQrHAAAWO0lEQVR4Ae1da5icRZV+537pyfRcEdbltl5AFEkgywaDgI8sAWRZszyyYBACbAgQQgARuSmykfVBXJEIAgqEIGC4emGjQUVWMJJduUSeIIquoiJgpjPTPcncb/t+3ZlmMtPd0z3p/r5zvjr1I+n+uqerznvOW3Wq6pyqsrGxMVgxBFxFoNxVwU1uQ8BDwAhgduA0AkYAp9VvwhsBzAacRsAI4LT6TXgjgNmA0wgYAZxWvwlvBDAbcBoBI4DT6jfhjQBmA04jYARwWv0mvBHAbMBpBIwATqvfhDcCmA04jYARwGn1m/BGALMBpxEwAjitfhPeCGA24DQCRgCn1W/CGwHMBpxGwAjgtPpNeCOA2YDTCBgBnFa/CW8EMBtwGgEjgNPqN+GNAGYDTiNgBHBa/Sa8EcBswGkEjABOq9+ENwKYDTiNgBHAafWb8EYAswGnETACOK1+E94IYDbgNAJGAKfVb8IbAcwGnEbACOC0+k14I4DZgNMIGAGcVr8JbwQwG3AaASOA0+o34Y0AZgNOI2AEcFr9JrwRwGzAaQSMAE6r34Q3ApgNOI2AEcBp9ZvwRgCzAacRqAxQ+nv68JvhAOsvrOr51Ti+prA/CfDbr4/ilp4A6y+s6isbECkr7E+K9e0gCfDcEFbpUVJjOTa3Y08lQ+bSBP6rv1hGUtrf2bcSlzWUtoocvx6kPq9vxPurcrRN1kfdozgnIatJ2VrzzT411l9VhvubEA2o+yeAQRKgFvhWE+qCEz6bAWV7vr4fq/uyfSjl+RujWNEtpTHTtmPlLMwLtBMMkgBE54BK3Ng4LUqCvnBJN/4yKqg9U5tC56dLdgvTbT62FpdF0u+CeREwASj00nos5FigpMRHQQsTW+7tw2NKXP89KrAmisCH/7KxsbHA1dk5hoM68NpI4A3JtwFrmnB6Xb5f9u17dH7e26Gj+y8vw+MtOLraN2yyVhT8CMCmtZTh3iYQFC3lom7Q2qSVc/U4P5dHRFg/NSiCAGzHkdW4Iri1sEJNmU42rU1UofPzPSXOD3dUrp0lBTwRLlAKDO6JHbEVzwxKgWbadtzbjEUyZi9vJp2fTnmD0lQMW8rxQjv2ktLxihkBiBT35O5rAvebtJQVCfxVhs1xOFJh/dTsHU2CrJ/tkWVu+1bgtqgW+8fWUZwvYMX9vn58V4nzsyyChcLCSQS5QGnDX5zAmt70O+kv1jbjX4NzhBQ5P7OrsLENwuwfEgmwfQxzYvidkji5tnL8qh3tAQ2lC7vwHQ3df0M5nm3DfhXiurOA9JYTh4YyL0SCUSIqSmwUywJyhO7v12H91OPNjRKtnw2TSAA2a24VrhOzUjYtDx/qw8O+d8N0fi4UthSbDajT63GGvH3DVGslukCplnGDekEnfjSQDVVZz3erwEvtaPNx1NLi/OxX6Tk/HNVlFqEjAMEiYow4aJfnNWZU5JYRLPexP/6WEuenht5ss1zrpyrlEoCN26Mcq/Wsiq7tw7d9Ga+4+eAn2TISPs+HNzRiTpA5V9M3UzQB2PyP1ODCoCNmp0dx/Bvnc0Oq9LGF5yW8LQj55aO1WF4vvZly5wBp5NirHhrDi0PpB6JfLKrzAvtKV9b249Su0v180X55rwov5IFhjsKLAgIQwV8NY24MfaXvXIuire+24MTS7PfQ+WHAs/zuv7IMT7bi8EBTvfJUpXQXKCWGrsQxLyy5NFxl5IV866fKrmnQYf1sqg4CsKFMHPsXqWvJKZam/31jBEwYKHp5oB+Pis9IptQfrgGPOdFSdLhAKTR1JY6taynmOUJbks4Pd52FF+6HbGrzlu+0FD0t1ZY4xjNUEsVzhOj8yLf+sjIvzVeR9ZOlmgjA5jJxTMvw+pcR8AiJopQH+/GIBufn0giOLc3svygwZvwRTS5QSgBdiWPrW7Fg11K/tTg/86rxVCs0LPzsRARlIwDbzo1F7ywxJQ1fEkf3rjlCDDWV7/w0lXtKUWf9NCcldrQTabGPnsSxP4/g0l1whB7qx8ManJ+vR8FsPo1FnwuURvnMBO5Wkjj2o9aZnALSwZWfGDrEH5d0Tj1u1xOylbaf1AvFBGDi2MEx/FZD4tjeldhceEjwyXEw00B4ObAK/9MGJTs0GbBU6QKl5FCUOPbHYXxqWwb0czyi8yPf+uvLsJbHG+cQQ/xHiglAbA+pwn8oSRy7vRdP5n3kEZ2foNIsC7LYVVHveGPVRTcBCP0nI/hHDWvPPIL17AR68lsRuqBbget/ah3OVt35J4mrngCMt71HSeLYH4ZxeR6OENOLHxTv+r+jUtMJTjnGKMWT4IlSrRvACZ0THwh9zWCBJ1u8/exsJTbmBTwzwVJyqS7Dhlbv4IIQFPUjQEoHWhLHUo5QjsXbCxLSrZ+Af2FWSKyfsoSEAJTki404SEOf9H/DuDLL1tgj/XhAvPNzQi0u1pOkmuofc/wbEhcoJeHLycSx3vwmmjlAKfVHvAnhp1MSplQ4P29ntLO/p7+UXBelrsDP33+PkhvHRrkiFMekvl6+81ORvMfEz7OPfDCe8LhAKbC4La8iceyVYVw9YUXoUQ3Oz9UNOCr79N0HYy1FFaFygVIAMR+XN44xCk14oSP0s1YcVgUVzs+RNXiiBToD3nIZQthGAMrarOTGMTpCZ8XBM0V5ypXwdU+egM27S8Jn/bSWEI4AKb5/djtWTvAxcnUCgX7GHSWuCwkvj7XgBA3b7TOAMbQEoAfEG8d+nnf4zQywc+RPLooou8y8IL2ElgBE4dURzI4hIf4khYIU5vOX51Z7m76hm/q+hWII5wBp4Zg4pjdRIy1FgC94YSFvKgmx9RPbMBOA4vH2rjPFn88aoInnrvrWKN4ZypnvBLHD7AKlxGQEMhPHuO5upSAEzqrHnWoTHfOXNPwEIBbPDeEDWzEoPkQif7WV+psHVOEXbXBh7Ay5C5QyFEWJY6W27Hx+vy6Z6OiC9RMNJwhAOS+J4JiQrmTnY9MFfefLjThQeaJj/vI64QKl4OC1igfFpO+55q+5En3zY3V4sJQXfJSo2TP+WVdGAAK0e/LGMeZkWcmGwD6V4BFXThWHCEC9Hs8bxxzxbQu3Yt5MzlX/Jsc6CLcIQKu4vhGzNSSOFW7Au/oXK2dhnnvIODQHSBvIr0dwSAfkJ46lG+zDiwU1+EGLdzeza8W5EYAK3r8CX3HM081t1rtXeEfLOGj9hMVFAlDsJXU4Sf+hTrnNOs9PmZfzzSbs5qghuEoAGsc3otgz7IEu+XDg8shMTq7O55dVfMfFOUBaMU8P4UNbMeJwiMT8avx3q3fniLPF1ZEvqfAPVuEqPRd6Ft1GW3itS7PT1k9InR4BKD8Tx47cig1OJo492oKFzoeHOD0CkACcBTDdW8uNY0UcBJZFzPo9OF0nACHYu8K5/X9uBf5nYxHZpPinjACe8k6uBfM/HCkN5VjbDOd9nx3aNgLsAGJVI97txmrIzY3Yz9Z/x3s7I8AOJCIMBWsGT74Pdzm9HmfYDuAEHRsB3gLj4Eo1N4691ehCXnGIu8Vc/50Rc30ZdGc0wD2x4zrx+MCkx2F4W1OGZ9owxw03L3+F2QiwE1b0gNYwMCaMLvINjWb9O+k69cYILine truncated
|
||||
webUI["html/js/authentication.js"] = "ZnVuY3Rpb24gY3JlYXRlRmlyc3RBY2NvdW50KGVsbSkgewogIHZhciBlcnIgPSBmYWxzZTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtKTsKICBjb25zb2xlLmxvZyhkaXYpOwoKICB2YXIgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoZW50aWNhdGlvbicpOwogIAogIGNvbnN0IHVzZXJuYW1lICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1c2VybmFtZScpOwogIGNvbnN0IHBhc3N3b3JkICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpOwogIGNvbnN0IGNvbmZpcm0gICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJyk7CgogIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ0lOUFVUJykKICBjb25zb2xlLmxvZyhjb25maXJtKTsKCiAgc3dpdGNoKGNvbmZpcm0pIHsKICAgIGNhc2UgbnVsbDogYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6IAogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChpbnB1dHNbaV0udmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICdyZWQnOwogICAgICAgICAgZXJyID0gdHJ1ZQogICAgICAgIH0KICAgICAgfQoKICAgICAgc3dpdGNoKGVycikgewogICAgICAgIGNhc2UgdHJ1ZTogcmV0dXJuOyBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOiAKICAgICAgICAgIGlmIChwYXNzd29yZC52YWx1ZSAhPSBjb25maXJtLnZhbHVlKSB7CiAgICAgICAgICAgIGNvbmZpcm0uc3R5bGUuYm9yZGVyQ29sb3IgPSAncmVkJzsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICB9CgoKICAKCiAgZm9ybS5zdWJtaXQoKTsKICByZXR1cm47Cn0="
|
||||
webUI["html/js/base.js"] = "dmFyIGNvbmZpZyAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciBtZW51ICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc3ViTWVudSAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGFjdGl2ZVN0cmVhbXMgPSBuZXcgT2JqZWN0KCk7CnZhciB4RVBHICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgdXNlcnMgICAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGxvZyAgICAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciB1bmRvICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgd2ViU29ja2V0cyAgICA9IHRydWU7CnZhciBjbG9zZUxvZywgdmVyc2lvbiwgYWN0aXZlTWVudTsKdmFyIGNvbHVtblRvU29ydCAgPSAwCgoKaWYgKHdpbmRvdy5XZWJTb2NrZXQgPT09IHVuZGVmaW5lZCkgewogIGFsZXJ0KCJZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJTb2NrZXRzIik7CiAgd2ViU29ja2V0cyA9IGZhbHNlOwp9IAoKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldFNlcnZlckNvbmZpZyI7CiAgeFRlVmUoZGF0YSk7CiAgLy9zaG93TG9hZGluZ1NjcmVlbihmYWxzZSk7CgogIHZhciByZXNpemVIYW5kbGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgib3BlblN0cmVhbXMiKTsKICB2YXIgYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpOwogIHJlc2l6ZUhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLCBpbml0aWFsaXNlUmVzaXplLCBmYWxzZSk7CgogIGZ1bmN0aW9uIGluaXRpYWxpc2VSZXNpemUoZSkgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlbW92ZSIsIHN0YXJ0UmVzaXppbmcsIGZhbHNlKTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJtb3VzZXVwIiwgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgfQoKICBmdW5jdGlvbiBzdGFydFJlc2l6aW5nKGUpIHsKICAgIGJveC5zdHlsZS5oZWlnaHQgPSAoZS5jbGllbnRZIC0gYm94Lm9mZnNldFRvcCkgKyAicHgiOwogICAgICAKICAgIHZhciBlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWxsU3RyZWFtcyIpOwogICAgaWYgKGUuY2xpZW50WSA+IDEyMCkgewogICAgICBlbG0uY2xhc3NOYW1lID0gInZpc2libGUiOyAKICAgIH0gZWxzZSB7CiAgICAgIGVsbS5jbGFzc05hbWUgPSAibm90VmlzaWJsZSI7IAogICAgfQoKICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKCiAgfQogIGZ1bmN0aW9uIHN0b3BSZXNpemluZyhlKSB7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzdGFydFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB9CgogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJyZXNpemUiLCBmdW5jdGlvbigpewogICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogIH0sIHRydWUpOwp9CgoKZnVuY3Rpb24gZ2V0T2JqS2V5cyhvYmopIHsKICB2YXIga2V5cyA9IG5ldyBBcnJheSgpOwoKICBmb3IgKHZhciBpIGluIG9iaikgewogICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkgewogICAgICBrZXlzLnB1c2goaSk7CiAgICB9CiAgfQoKICByZXR1cm4ga2V5czsKfQoKCmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQoaXRlbSkgewogIC8vY29uc29sZS5sb2coaXRlbSk7CiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0ZW1bIl9lbGVtZW50Il0pOwogIGlmIChpdGVtLmhhc093blByb3BlcnR5KCJfdGV4dCIpKSB7CiAgICAvL2VsZW1lbnQuaW5uZXJIVE1MID0gIjxwPiIgKyBpdGVtWyJfdGV4dCJdICsgIjwvcD4iOwogICAgZWxlbWVudC5pbm5lckhUTUwgPSBpdGVtWyJfdGV4dCJdOwogIH0KCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGl0ZW0pOwogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgaWYgKGtleXNbaV0uY2hhckF0KDApICE9ICJfIikgewogICAgICAvL2NvbnNvbGUubG9nKGtleXNbaV0sIGl0ZW1ba2V5c1tpXV0pOwogICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXlzW2ldLCBpdGVtW2tleXNbaV1dKTsKICAgIH0KICB9CgogIC8vY29uc29sZS5sb2coZWxlbWVudCk7CiAgcmV0dXJuIGVsZW1lbnQ7Cn0KCmZ1bmN0aW9uIG1vZGlmeU9wdGlvbihpZCwgb3B0aW9ucywgdmFsdWVzKSB7CiAgdmFyIHNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICBzZWxlY3QuaW5uZXJIVE1MID0gIiI7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykgewogIAogICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKQogIAogICAgZWxlbWVudC52YWx1ZSA9IHZhbHVlc1tpXTsKICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gb3B0aW9uc1tpXTsKCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgCiAgfQoKfQoKCmZ1bmN0aW9uIHN0YXJ0V2ViU29ja2V0KCkgewogIGlmICh3ZWJTb2NrZXRzID09IGZhbHNlKSB7CiAgICByZXR1cm47CiAgfQoKICAvL3dzLnNlbmQoJ3siY21kIjogImdldFNlcnZlckNvbmZpZzEifScpOwoKfQoKZnVuY3Rpb24gY2hlY2tFcnIob2JqKSB7CiAgLy9hbGVydChvYmpbImVyciJdKQogIC8vc2NyZWVuTG9nKG9ialsiZXJyIl0sICJlcnJvciIpCiAgY29uc29sZS5sb2cob2JqKTsKICB2YXIgbmV3T2JqID0gbmV3IE9iamVjdCgpOwogIHZhciBuZXdFcnIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RXJyWyJrZXkiXSAgID0gIkVycm9yIjsKICBuZXdFcnJbInZhbHVlIl0gPSBvYmpbImVyciJdOwogIG5ld0VyclsidHlwZSJdICA9ICJlcnJvciI7CgogIG5ld09ialswXSA9IG5ld0VycgogIHNob3dMb2cobmV3T2JqKTsKICByZXR1cm4KfQoKZnVuY3Rpb24gc2NyZWVuTG9nKG1zZywgbXNnVHlwZSwgc2hvdykgewogIHJldHVybgogIGNsZWFyVGltZW91dChjbG9zZUxvZykKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIHZhciBuZXdNc2cgPSBuZXcgT2JqZWN0KCk7CiAgCiAgbmV3TXNnWyJfZWxlbWVudCJdID0gIlAiOwogIAogIHN3aXRjaChtc2dUeXBlKSB7CiAgICBjYXNlICJlcnJvciI6ICAgbmV3TXNnWyJjbGFzcyJdID0gImVycm9yTXNnIjsgYnJlYWs7CiAgICBjYXNlICJ3YXJuaW5nIjogbmV3TXNnWyJjbGFzcyJdID0gIndhcm5pbmdNc2ciOyBicmVhazsKICAgIC8vZGVmYXVsdDogICAgICBuZXdNc2dbImNsYXNzIl0gPSAiaW5mb01zZyIKICB9CgogIG5ld01zZ1siX3RleHQiXSA9IG1zZzsKCiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3TXNnKSk7CgogIGRpdi5zY3JvbGxUb3AgPSBkaXYuc2Nyb2xsSGVpZ2h0OwoKICBpZiAoc2hvdyA9PSBmYWxzZSkgewogICAgcmV0dXJuOwogIH0KCiAgZGl2LmNsYXNzTmFtZSA9ICIiCiAgY2xvc2VMb2cgPSBzZXRUaW1lb3V0KGNsb3NlU2NyZWVuTG9nLCAxMDAwMCk7Cn0KCgpmdW5jdGlvbiBjbG9zZVNjcmVlbkxvZygpIHsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIGRpdi5jbGFzc05hbWUgPSAic2NyZWVuTG9nSGlkZGVuIgp9CgpmdW5jdGlvbiBzaLine truncated
|
||||
webUI["html/js/classes_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBNYWluTWVudSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIE1haW5NZW51KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJtYWluLW1lbnUiOwogICAgICAgIHRoaXMuSFRNTFRhZyA9ICJMSSI7CiAgICB9CiAgICBNYWluTWVudS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgIGNvbnNvbGUubG9nKHRoaXMuRG9jdW1lbnRJRCk7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51Owp9KCkpOwp2YXIgTWFpbk1lbnVJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKE1haW5NZW51SXRlbSwgX3N1cGVyKTsKICAgIGZ1bmN0aW9uIE1haW5NZW51SXRlbSgpIHsKICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7CiAgICB9CiAgICBNYWluTWVudUl0ZW0ucHJvdG90eXBlLmNyZWF0ZTIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuSFRNTFRhZyk7CiAgICAgICAgZWxlbWVudC5pbm5lclRleHQgPSB0aGlzLlZhbHVlOwogICAgICAgIGNvbnNvbGUubG9nKGVsZW1lbnQpOwogICAgfTsKICAgIHJldHVybiBNYWluTWVudUl0ZW07Cn0oTWFpbk1lbnUpKTsKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogICAgdmFyIGl0ZW0gPSBuZXcgTWFpbk1lbnVJdGVtKCk7CiAgICBpdGVtLlZhbHVlID0gIlRlc3QiOwogICAgaXRlbS5jcmVhdGUyKCk7Cn0K"
|
||||
webUI["html/js/users.js"] = "ZnVuY3Rpb24gb3BlblVzZXJzKGVsbSkgewogIGNvbG9tblNvcnQgPSAwOwoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gInVzZXJEZXRhaWwoMCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CgogIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2V0dGluZ3MiKTsKCiAgIC8vIEJ1aWxkIHRhYmxlCiAgdmFyIG5ld1RhYmxlID0gbmV3IE9iamVjdCgpOwogIG5ld1RhYmxlWyJfZWxlbWVudCJdICA9ICJUQUJMRSI7CiAgbmV3VGFibGVbImlkIl0gICAgICAgID0gImlkX21hcHBpbmciOwogIG5ld1RhYmxlWyJjbGFzcyJdICAgICA9ICJ0YWJsZS1tYXBwaW5nIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUYWJsZSkpOwoKICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IAogICAgY3JlYXRlVXNlcnNUYWJsZSgpOyAKICB9LCAxMCk7Cn0KCmZ1bmN0aW9uIGNyZWF0ZVVzZXJzVGFibGUoKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB0YWJsZS5pbm5lckhUTUwgPSAiIjsKICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3VFJbIl9lbGVtZW50Il0gPSAiVFIiOwogIG5ld1RSWyJjbGFzcyJdICAgID0gInRhYmxlLW1hcHBpbmctaGVhZGVyIjsKICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1RSKSk7CgogIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlVzZXJuYW1lIiwgIlBhc3N3b3JkIiwgIldFQiIsICJQTVMiLCAiTTNVIiwgIlhNTCIsICJBUEkiKQoKICBmb3IgKHZhciBpID0gMDsgaSA8IHRySGVhZGxpbmVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJURCI7CiAgICBuZXdURFsiX3RleHQiXSAgICA9IHRySGVhZGxpbmVzW2ldOwogICAgdHIuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdURCkpOwogIH0KCgogIC8vIFNvcnQgdXNlcnMKICB2YXIgdXNlcklkcyA9IGdldE9iaktleXModXNlcnMpOwoKICB2YXIgdXNlck9iaiA9IG5ldyBPYmplY3QoKTsKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB1c2VySWRzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgdXNlcm5hbWUgPSB1c2Vyc1t1c2VySWRzW2ldXVsiZGF0YSJdWyJ1c2VybmFtZSJdOwogICAgdXNlck9ialt1c2VybmFtZV0gPSB1c2VySWRzW2ldOwogIH0KCiAgdmFyIGFsbFVzZXJzID0gZ2V0T2JqS2V5cyh1c2VyT2JqKTsKICBhbGxVc2Vycy5zb3J0KCk7CiAgLy8gLS0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGxVc2Vycy5sZW5ndGg7IGkrKykgewogICAgdmFyIHRhYmxlICAgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpZF9tYXBwaW5nIik7CiAgICB2YXIgdXNlcklEICAgID0gdXNlck9ialthbGxVc2Vyc1tpXV07CiAgICB2YXIgdXNlcm5hbWUgID0gYWxsVXNlcnNbaV07CiAgICB2YXIgaXRlbSAgICAgID0gdXNlcnNbdXNlcklEXVsiZGF0YSJdOwoKICAgIC8vIENyZWF0ZSBUUgogICAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogICAgbmV3VFJbIl9lbGVtZW50Il0gICAgICAgPSAiVFIiOwogICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgIG5ld1RSWyJpZCJdICAgICAgICAgICAgID0gdXNlcklEOwogICAgbmV3VFJbIm9uY2xpY2siXSAgICAgICAgPSAnamF2YXNjcmlwdDogdXNlckRldGFpbCgiJyArIHVzZXJJRCArICciKTsnOwogICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAvLyBDcmVhdGUgdXNlcm5hbWUgVEQKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB1c2VybmFtZTsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHBhc3N3b3JkIFRECiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIG5ld1REWyJfdGV4dCJdICAgID0gIi4uLi4uIjsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHdlYiBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgc3dpdGNoKGl0ZW1bImF1dGhlbnRpY2F0aW9uLndlYiJdKXsKICAgICAgY2FzZSB0cnVlOiBuZXdURFsiX3RleHQiXSAgICA9ICLinJMiOyBicmVhazsKICAgICAgZGVmYXVsdDogICBuZXdURFsiX3RleHQiXSAgICA9ICItIjsgYnJlYWs7CiAgICB9CiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgIC8vIENyZWF0ZSBQTVMgYWNjZXNzCiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5wbXMiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7IGJyZWFrOwogICAgfQogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAvLyBDcmVhdGUgTTNVIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ubTN1Il0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIFhNTFRWIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ueG1sIl0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIEFQSSBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwoKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5hcGkiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7Line truncated
|
||||
webUI["html/create-first-user.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keT4KICAgICAgICAgIAogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgoKICAgICAgPGRpdiBpZD0iYm94Ij4KCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPnt7LmFjY291bnQuaGVhZGxpbmV9fTwvaDE+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxwIGlkPSJlcnIiIGNsYXNzPSJlcnJvck1zZyBjZW50ZXIiPjwvcD4KCiAgICAgICAgPGRpdiBpZD0iY29udGVudCI+CgogICAgICAgICAgICA8Zm9ybSBpZD0iYXV0aGVudGljYXRpb24iIGFjdGlvbj0iL3dlYi8iIG1ldGhvZD0icG9zdCI+CgogICAgICAgICAgICAgIDxoNT57ey5hY2NvdW50LnVzZXJuYW1lLnRpdGxlfX06PC9oNT4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9InVzZXJuYW1lIiB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VybmFtZSIgcGxhY2Vob2xkZXI9IlVzZXJuYW1lIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICA8aDU+e3suYWNjb3VudC5wYXNzd29yZC50aXRsZX19OjwvaDU+CiAgICAgICAgICAgICAgPGlucHV0IGlkPSJwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIiBwbGFjZWhvbGRlcj0iUGFzc3dvcmQiIHZhbHVlPSIiPgogICAgICAgICAgICAgIDxoNT57ey5hY2NvdW50LmNvbmZpcm0udGl0bGV9fTo8L2g1PgogICAgICAgICAgICAgIDxpbnB1dCBpZD0iY29uZmlybSIgIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJjb25maXJtIiAgcGxhY2Vob2xkZXI9IkNvbmZpcm0iIHZhbHVlPSIiPgogICAgICAgICAgICAgIAogICAgICAgICAgICA8L2Zvcm0+CgogICAgICAgIDwvZGl2PgogICAgICAgIAogICAgICAgIDxkaXYgaWQ9ImJveC1mb290ZXIiPgogICAgICAgICAgPGlucHV0IGlkPSJzdWJtaXQiIGNsYXNzPSIiIHR5cGU9ImJ1dHRvbiIgdmFsdWU9Int7LmJ1dHRvbi5jcmFldGVBY2NvdW50fX0iIG9uY2xpY2s9ImphdmFzY3JpcHQ6IGxvZ2luKCk7Ij4KICAgICAgICA8L2Rpdj4KICAgICAgCiAgICAgICAgCiAgICAgIDwvZGl2PgogICAgPC9ib2R5Pgo8L2h0bWw+"
|
||||
webUI["html/img/logo_w_600x200.png"] = "iVBORw0KGgoAAAANSUhEUgAAAlgAAADICAYAAAA0n5+2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAuIwAALiMBeKU/dgAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MzAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjAwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAg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 truncated
|
||||
webUI["html/index.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPCEtLS0KICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIiAvPiAKICAgIC0tPgogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL25ldHdvcmtfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL21lbnVfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL3NldHRpbmdzX3RzLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9sb2dzX3RzLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9iYXNlX3RzLmpzIj48L3NjcmlwdD4KCiAgPC9oZWFkPgoKICAgIDxib2R5IG9ubG9hZD0iamF2YXNjcmlwdDogUGFnZVJlYWR5KCk7Ij4KCiAgICAgIDxkaXYgaWQ9ImxvYWRpbmciIGNsYXNzPSJub25lIj4KICAgICAgICA8ZGl2IGNsYXNzPSJsb2FkZXIiPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgaWQ9InBvcHVwIiBjbGFzcz0ibm9uZSI+CiAgICAgICAgPGRpdiBpZD0icG9wdXAtY3VzdG9tIj48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJsYXlvdXQiPgoKICAgICAgICA8IS0tCiAgICAgICAgPGRpdiBpZD0ibm90aWZpY2F0aW9uIj4KICAgICAgICAgIDxkaXYgY2xhc3M9ImVsZW1lbnQiPgogICAgICAgICAgICA8aDU+WEVQRzwvaDU+CiAgICAgICAgICAgIDxwcmU+MTEuMDUuMjAxOSAtIDIwOjIxPC9wcmU+CiAgICAgICAgICAgIDxocj4KICAgICAgICAgICAgPHA+SGFsbG8gZGFzIGlzdCBlaW4gVGVzdC4gVW5kIG5vY2ggbWVociBUZXh0LjwvcD4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAtLT4KCiAgICAgICAgPGRpdiBpZD0ibWVudS13cmFwcGVyIiBjbGFzcz0ibGF5b3V0LWxlZnQiPgogICAgICAgICAgPGRpdiBpZD0gImJyYW5jaCI+PC9kaXY+CiAgICAgICAgICA8ZGl2IGlkPSJsb2dvIj48L2Rpdj4KICAgICAgICAgIDxuYXYgaWQ9Im1haW4tbWVudSI+PC9uYXY+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgY2xhc3M9ImxheW91dC1yaWdodCI+CgogICAgICAgICAgPHRhYmxlIGlkPSJjbGllbnRJbmZvIiBjbGFzcz0iIj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij54VGVWZTo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPk9TOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJvcyIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkgcGhvbmUiPkRWUiBJUDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0iRFZSIiBjbGFzcz0idGRWYWwgcGhvbmUiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgIDwvdHI+CgogICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VVVJRDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0idXVpZCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkFyY2g6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9ImFyY2giIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5IHBob25lIj5NM1UgVVJMOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJtM3UtdXJsIiBjbGFzcz0idGRWYWwgcGhvbmUiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgIDwvdHI+CgogICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+QXZhaWxhYmxlIFN0cmVhbXM6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5FUEcgU291cmNlOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJlcGdTb3VyY2UiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5IHBob25lIj5YRVBHIFVSTDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0ieGVwZy11cmwiIGNsYXNzPSJ0ZFZhbCBwaG9uZSI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPC90cj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5YRVBHIENoYW5uZWxzOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJ4ZXBnIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+RXJyb3JzOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJlcnJvcnMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5XYXJuaW5nczo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0id2FybmluZ3MiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPC90cj4KCiAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAKICAgICAgICAgIDxkaXYgaWQ9Im15U3RyZWFtc0JveCIgY2xhc3M9Im5vdFZpc2libGUiPgoKICAgICAgICAgICAgPGRpdiBpZD0iYWxsU3RyZWFtcyI+CiAgICAgICAgICAgICAgPHRhYmxlIGlkPSJhY3RpdmVTdHJlYW1zIj48L3RhYmxlPgogICAgICAgICAgICAgIDx0YWJsZSBpZD0iaW5hY3RpdmVTdHJlYW1zIj48L3RhYmxlPgogICAgICAgICAgICA8L2Rpdj4KCiAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIAogICAgICAgICAgPGRpdiBpZD0iY29udGVudCIgY2xhc3M9IiI+PC9kaXY+CiAgICAgICAgICAgIAogICAgICAgIDwvZGl2PgoKICAgICAgPC9kaXY+CiAgICAgIAogICAgPC9ib2R5PgogICAgCjwvaHRtbD4="
|
||||
webUI["html/js/logs_ts.js"] = "dmFyIExvZyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIExvZygpIHsKICAgIH0KICAgIExvZy5wcm90b3R5cGUuY3JlYXRlTG9nID0gZnVuY3Rpb24gKGVudHJ5KSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiV0FSTklORyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gIndhcm5pbmdNc2ciOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiRVJST1IiKSAhPSAtMSkgewogICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9ICJlcnJvck1zZyI7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeS5pbmRleE9mKCJERUJVRyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImRlYnVnTXNnIjsKICAgICAgICB9CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBlbnRyeTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICByZXR1cm4gTG9nOwp9KCkpOwpmdW5jdGlvbiBzaG93TG9ncyhib3R0b20pIHsKICAgIHZhciBsb2cgPSBuZXcgTG9nKCk7CiAgICB2YXIgbG9ncyA9IFNFUlZFUlsibG9nIl1bImxvZyJdOwogICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X2xvZyIpOwogICAgZGl2LmlubmVySFRNTCA9ICIiOwogICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGxvZ3MpOwogICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChsb2dJRCkgewogICAgICAgIHZhciBlbnRyeSA9IGxvZy5jcmVhdGVMb2cobG9nc1tsb2dJRF0pOwogICAgICAgIGRpdi5hcHBlbmQoZW50cnkpOwogICAgfSk7CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAoYm90dG9tID09IHRydWUpIHsKICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYm94LXdyYXBwZXIiKTsKICAgICAgICAgICAgd3JhcHBlci5zY3JvbGxUb3AgPSB3cmFwcGVyLnNjcm9sbEhlaWdodDsKICAgICAgICB9CiAgICB9LCAxMCk7Cn0KZnVuY3Rpb24gcmVzZXRMb2dzKCkgewogICAgdmFyIGNtZCA9ICJyZXNldExvZ3MiOwogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcihjbWQpOwogICAgc2VydmVyLnJlcXVlc3QoZGF0YSk7Cn0K"
|
||||
webUI["html/lang/en.json"] = "ewogICJtYWluTWVudSI6IHsKICAgICJpdGVtIjp7CiAgICAgICJwbGF5bGlzdCI6ICJQbGF5bGlzdCIsCiAgICAgICJwbXNJRCI6ICJQTVMgSUQiLAogICAgICAiZmlsdGVyIjogIkZpbHRlciIsCiAgICAgICJ4bWx0diI6ICJYTUxUViIsCiAgICAgICJtYXBwaW5nIjogIk1hcHBpbmciLAogICAgICAidXNlcnMiOiAiVXNlcnMiLAogICAgICAic2V0dGluZ3MiOiAiU2V0dGluZ3MiLAogICAgICAibG9nIjogIkxvZyIsCiAgICAgICJsb2dvdXQiOiAiTG9nb3V0IgogICAgfSwKICAgICJoZWFkbGluZSI6IHsKICAgICAgInBsYXlsaXN0IjogIkxvY2FsIG9yIHJlbW90ZSBwbGF5bGlzdHMiLAogICAgICAiZmlsdGVyIjogIkZpbHRlciBwbGF5bGlzdCIsCiAgICAgICJ4bWx0diI6ICJMb2NhbCBvciByZW1vdGUgWE1MVFYgZmlsZXMiLAogICAgICAibWFwcGluZyI6ICJNYXAgcGxheWxpc3QgY2hhbm5lbHMgdG8gRVBHIGNoYW5uZWxzIiwKICAgICAgInVzZXJzIjogIlVzZXIgbWFuYWdlbWVudCIsCiAgICAgICJzZXR0aW5ncyI6ICJTZXR0aW5ncyIsCiAgICAgICJsb2ciOiAiTG9nIiwKICAgICAgImxvZ291dCI6ICJMb2dvdXQiCiAgICB9CiAgfSwKICAiY29uZmlybSI6ewogICAgInJlc3RvcmUiOiAiQWxsIGRhdGEgd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRob3NlIGZyb20gdGhlIGJhY2t1cC4gU2hvdWxkIHRoZSBmaWxlcyBiZSByZXN0b3JlZD8iCiAgfSwKICAiYWxlcnQiOiB7CiAgICAiZmlsZUxvYWRpbmdFcnJvciI6ICJGaWxlIGNvdWxkbid0IGJlIGxvYWRlZCIsCiAgICAiaW52YWxpZENoYW5uZWxOdW1iZXIiOiAiSW52YWxpZCBjaGFubmVsIG51bWJlciIsCiAgICAibWlzc2luZ0lucHV0IjogIk1pc3NpbmcgaW5wdXQiCiAgfSwKICAiYnV0dG9uIjp7CiAgICAiYmFjayI6ICJCYWNrIiwKICAgICJiYWNrdXAiOiAiQmFja3VwIiwKICAgICJidWxrRWRpdCI6ICJCdWxrIEVkaXQiLAogICAgImNhbmNlbCI6ICJDYW5jZWwiLAogICAgImRlbGV0ZSI6ICJEZWxldGUiLAogICAgImRvbmUiOiAiRG9uZSIsCiAgICAibG9naW4iOiAiTG9naW4iLAogICAgIm5ldyI6ICJOZXciLAogICAgIm5leHQiOiAiTmV4dCIsCiAgICAicmVzdG9yZSI6ICJSZXN0b3JlIiwKICAgICJzYXZlIjogIlNhdmUiLAogICAgInNlYXJjaCI6ICJTZWFyY2giLAogICAgInVwZGF0ZSI6ICJVcGRhdGUiLAogICAgImNyYWV0ZUFjY291bnQiOiAiQ3JlYXRlIEFjY291bnQiLAogICAgInJlc2V0TG9ncyI6ICJSZXNldCBMb2dzIiwKICAgICJ1cGxvYWRMb2dvIjogIlVwbG9hZCBMb2dvIgogIH0sCiAgImZpbHRlciI6IHsKICAgICJ0YWJsZSI6IHsKICAgICAgIm5hbWUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAidHlwZSI6ICJGaWx0ZXIgVHlwZSIsCiAgICAgICJmaWx0ZXIiOiAiRmlsdGVyIgogICAgfSwKICAgICJjdXN0b20iOiAiQ3VzdG9tIiwKICAgICJncm91cCI6ICJHcm91cCIsCiAgICAibmFtZSI6IHsKICAgICAgInRpdGxlIjogIkZpbHRlciBOYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkZpbHRlciBuYW1lIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZGVzY3JpcHRpb24iOiB7CiAgICAgICJ0aXRsZSI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR5cGUiOiB7CiAgICAgICJ0aXRsZSI6ICJUeXBlIiwKICAgICAgImdyb3VwVGl0bGUiOiAiR3JvdXAgVGl0bGUiLAogICAgICAiY3VzdG9tRmlsdGVyIjogIkN1c3RvbSBGaWx0ZXIiCiAgICB9LAogICAgImNhc2VTZW5zaXRpdmUiOiB7CiAgICAgICJ0aXRsZSI6ICJDYXNlIFNlbnNpdGl2ZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWx0ZXJSdWxlIjogewogICAgICAidGl0bGUiOiAiRmlsdGVyIFJ1bGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiU3BvcnQge0hEfSAhe0VTLElUfSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbHRlckdyb3VwIjogewogICAgICAidGl0bGUiOiAiR3JvdXAgVGl0bGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlNlbGVjdCBhIE0zVSBncm91cC4gKENvdW50ZXIpPGJyPkNoYW5naW5nIHRoZSBncm91cCB0aXRsZSBpbiB0aGUgTTNVIGludmFsaWRhdGVzIHRoZSBmaWx0ZXIuIgogICAgfSwKICAgICJpbmNsdWRlIjogewogICAgICAidGl0bGUiOiAiSW5jbHVkZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGSEQsVUhEIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkNoYW5uZWwgbmFtZSBtdXN0IGluY2x1ZGUuPGJyPihDb21tYSBzZXBhcmF0ZWQpIENvbW1hIG1lYW5zIG9yIgogICAgfSwKICAgICJleGNsdWRlIjogewogICAgICAidGl0bGUiOiAiRXhjbHVkZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJFUyxJVCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFubmVsIG5hbWUgbXVzdCBub3QgY29udGFpbi48YnI+KENvbW1hIHNlcGFyYXRlZCkgQ29tbWEgbWVhbnMgb3IiCiAgICB9CgogIH0sCiAgInBsYXlsaXN0IjogewogICAgInRhYmxlIjogewogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAidHVuZXIiOiAiVHVuZXIiLAogICAgICAibGFzdFVwZGF0ZSI6ICJMYXN0IFVwZGF0ZSIsCiAgICAgICJhdmFpbGFiaWxpdHkiOiAiQXZhaWxhYmlsaXR5IiwKICAgICAgInR5cGUiOiAiVHlwZSIsCiAgICAgICJzdHJlYW1zIjogIlN0cmVhbXMiLAogICAgICAiZ3JvdXBUaXRsZSI6ICJncm91cC10aXRsZSIsCiAgICAgICJ0dmdJRCI6ICJ0dmctaWQiLAogICAgICAidW5pcXVlSUQiOiAiVW5pcXVlIElEIgogICAgfSwKICAgICJwbGF5bGlzdFR5cGUiOiB7CiAgICAgICJ0aXRsZSI6ICJQbGF5bGlzdCB0eXBlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR5cGUiOiB7CiAgICAgICJ0aXRsZSI6ICJUeXBlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgIm5hbWUiOiB7CiAgICAgICJ0aXRsZSI6ICJOYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBsYXlsaXN0IG5hbWUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6IHsKICAgICAgInRpdGxlIjogIkRlc2NyaXB0aW9uIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkRlc2NyaXB0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsZU0zVSI6IHsKICAgICAgInRpdGxlIjogIk0zVSBGaWxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkZpbGUgcGF0aCBvciBVUkwgb2YgdGhlIE0zVSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbGVIREhSIjogewogICAgICAidGl0bGUiOiAiSERIb21lUnVuIElQIiwKICAgICAgInBsYWNlaG9sZGVyIjogIklQIGFkZHJlc3MgYW5kIHBvcnQgKDE5Mi4xNjguMS4xMDo1MDA0KSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR1bmVyIjogewogICAgICAidGl0bGUiOiAiVHVuZXIgLyBTdHJlYW1zIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJOdW1iZXIgb2YgcGFyYWxsZWwgY29ubmVjdGlvbnMgdGhhdCBjYW4gYmUgZXN0YWJLine truncated
|
||||
webUI["html/img/logout.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xM1QxMToxMDoxODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg27QeEAAANQSURBVGgF7Zk9aBRBGIZzSRSN8YdoCpEkghCCqK1o4g9IsBCCNmIniCAiWAhqI8G02qiIoqCCWggSEcFKEFPYpVAU8QdFUyiKRpRokBjP55OdZDLZvZnZ7N3Ngh887M7sN/O9797t7c5eTc3/8D8DxWKxGS5Ai//oAEYgvB4OwleQaAtAlp8ERG+Bp6Jei/wYQfRy6NfE67vhG0FtA/TBqK7c2A/bCGJ3wpAhOq4ZphGUroEHcYoT+sIygsgmOAu/EwQndYdhBHV1sB8+Jym19Lf6/faVIRuBG+GRRajtcPWMoKwFbtgUOh6vvBGEzYFj8MNRpEtaZY2gaAe8cVHmmXOc/K3QXIZv/+SUFFgJ96AS8ZwiZ6Ab6iZVzGCPiRbCKRiDasQHip6EdD/PDKyFvfAJQgg5kVfB/VoieT0MQojxE1G9UG/7otWS0A7pPkrb7DM/Ppcp+mAAM/bFGEmL4RL8gVDjI8JWOZ0bEjvhSahO0CXXsLMZWZYegREIMV4jaoHTJyNJJLfC7RCdoOm6sxGVyKAeeBegoU6l0XmLiXlwAqp1o4w7j3d1AwW9YdtnNrnQzkOXLddyfAPHv8Ey6ABpd8N88In2QqHwymfARC5mCrAH0i6qGDr9jk3fbNgFz8A1DkwIS7tDpSVwGdLcexIfPZhPHpf2wS+wRX9a/dPGUakLzBdwNgGJRlQBJtgMw5aJ3qr8TLYUmwVHwXXxZTUiwphvHYxDUnzPxIA5CdXa4E5SVa3fyUhkRtYqpSKbNYxpJiq+ncpDJar7GGlknvcl5mqM05BZH4Xl3iOLpLh7j7OR6MScSzAykplg20QIWA0PDSG+RuTdQVy8sNXP9DgK5N4jK9AvkRpfI4sYF/c2836mQl0nQ4zce66AfZFkTMqYl2DGaSMt/CYOHpsuaPco5bLUzUuMGkLHaQ+ovjwZUZrVdpAHRnnw/Bd5MrJCiY62t4x2+E2uBfkfRg95TdSkK8/LJ7JWF83+Nb5Ww0Zf+E3OviwXVMgT8dLwVRsKEd0A+uP8biMlH01MHAYVF/Oh2lCJenkDqpbUN9nPyzU91QnCRbyEPEXn1sQhxMv7tG1T7cW3rK/r44eVtxfxm6gwBh38zJqPJuUtXu3Z/wLwuBaBLgMkKwAAAABJRU5ErkJggg=="
|
||||
webUI["html/img/settings.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0xMFQxODowODo4OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Ckxt87EAAAS7SURBVGgFzZpdiFVVGIbn5N+IMgVhaRLqWI7mQIJoIVRgOhQZNDAhWcbcVuPV3BRE6I14440iQQSaN0p6kz8zI0k5inUhZSSaYOVYODMo5eiMOOPf+LzH2cPMPmvttdbe53jOBy9rr2+938/ae51vr733qaoqgQwPD68B/wDJfXAP3AE94JMShCy+SxJ9CvSDJFlU7MiPFdsh/hrBdIffBsd48HApJjLPI4tnPThBlFJMZI5HBuWZCIt9AmgEzeAJR6JzHeMadnKI8wbYCz4Fkz18JlNwMgf8BCL5j4O3bVaMdUfEhPZqgv1U7HbEbDvoT7HZOPUYNwAlHheV09a4A3RTgMqtj9QY7JdgeM5i3I4+fDIYrQeq/UnyNYOTlBDtS+BwEjk2doz+KyO2OY5bwVCME+/qylTHT4C1D3k+uB33Yul3ov/eMuajlu1RH+II5wtT4hNNSnQ6U/kzbRkfq351bCfF8apAm7kmvq38njWRK0S305SHcSK5XO4U5O9MBmXWbSe3E6YccialdKzH2TTnQEF10XgZ5DdivsxEhkyxjVdERAwu03xmMiqD7hYx19km4cyHq6KyeHKkWpSz+ciVrHVpRYZk/wLHp0H2bULkNKzt4Eq86TKxLq3IECf6nXwV9QPbAfjHQSfoD7SN6L63gYhvbrkiTwKf/dPYpbdPVxKMnigdg0VAG8FQye8AzBl6aIk2A+wPiNoHd63LNZx3wbUAvz/CfTzJb/43AmkGpLfAi0DPE/NALQgtve+xFPdi5xRiNkHa5ySOJ/TR7RrBJdqL4AAxL+p+8ToYAFklNCnF3pM1KPba2L6v8vons5oPsko9ZyZoa0PsOoKezxoY+y5N5DYHWSvDTXzUMJH7IUkRW0tbyyV0CcfDDKmqDMe1KfqnQyehGNgo9q8p4hWYFGsiBY4fsSK/BRkkaPgj5PhMy720BnVFesfnlKo3Das0bw8XYJf196GEuzWRLSDoRypLg2w06FyqTS6Cx7iK1eeqGqrnugmuBgvB8+A5UAuqQYiU+oZ4h2T+BV3gAlDp/pai0U1rFpVGMAv8AHzFd4vShMOQLcoB+DNB/sSbM3ZoMV4BQsW0adSJSbNp1Hu1mY40/YZxpPdJaUSfFzrBMXAjjQNsdvll6cHCWVvKJIphdhcny11pqmolCk5aIDif0BKdZBucgPlO8kh/r8O4HtwClSCbk86HtQqQuUrvKVCf5OARjt0lll4H/WKKmbS0tmJQKZNQ7nq9+w0n2LhTN04E8jKMPpZ1hcli8tGTZYEYJwJrZQGzchTGz3a2ifwdkHc73LYAfpx6DcWXQK1LeiDsdpFGx7UOwUGQJKpmGyIjjvWh50iSQWzsZ/ofgvx+jnYp+B/YpJcB7QXDBKPJ4JDF6+/oCwoBuhoL36R+Jp4RJH16u2IgaxJpHhMehsBY3wTjV2YbOuuumLHrwCW6msbSj74O/DHGgV4Ohl8Jw1nSMmsB+tL6Wnw83odzBrhEr2GtgvFE8A74ADxtJZZygMC25cjQqBwqdg62qpUlziUP45Cq6OGuqqoUE/FJ8i+v7MpJYvEsHl1A5gNty2vLmaN3bBLdAvqB3svqXxLRvyEuc9zs7SiA+ACpw05pJx8SoAAAAABJRU5ErkJggg=="
|
||||
webUI["html/js/data.js"] = "ZnVuY3Rpb24gc2hvd0NvbmZpZyhvYmopIHsKICBjb25maWcgPSBvYmo7CiAgLy9zZXRNZW51SXRlbSgpOwogIGNyZWF0ZU1lbnUoKTsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYWdlIikuY2xhc3NOYW1lID0gIiI7Cn0KCnNob3dNeVN0cmVhbXMKCmZ1bmN0aW9uIHNob3dNeVN0cmVhbXMoYWxsU3RyZWFtc09iaikgewoKICB2YXIgc3RyZWFtVHlwZUtleXMgPSBnZXRPYmpLZXlzKGFsbFN0cmVhbXNPYmopCgogIGZvciAodmFyIHMgPSAwOyBzIDwgc3RyZWFtVHlwZUtleXMubGVuZ3RoOyBzKyspIHsKICAgIHZhciBzdHJlYW1UeXBlID0gc3RyZWFtVHlwZUtleXNbc107CiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOwogICAgb2JqID0gYWxsU3RyZWFtc09ialtzdHJlYW1UeXBlXTsKICAgIHN3aXRjaChzdHJlYW1UeXBlKSB7CiAgICAgIGNhc2UgImFjdGl2ZVN0cmVhbXMiOiBhY3RpdmVTdHJlYW1zICAgICA9IG9iajsgYnJlYWs7CiAgICB9CgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3RyZWFtVHlwZSkuaW5uZXJIVE1MID0gIiI7CgogICAgdmFyIHN0cmVhbXNPYmogICAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtc05hbWVzICA9IG5ldyBBcnJheSgpOwogICAgCiAgICB2YXIga2V5cyA9IGdldE9iaktleXMob2JqKQogICAgCiAgICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBuYW1lICAgID0gb2JqW2tleXNbaV1dWyJuYW1lIl07CiAgICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICAgIHZhciBzdHJlYW1LZXkgPSBnZXRPYmpLZXlzKG9ialtrZXlzW2ldXSk7CgogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmVhbUtleS5sZW5ndGg7IGorKykgewogICAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICAgIH0KCiAgICAgIHN0cmVhbXNPYmpbbmFtZV0gPSB0bXA7CiAgICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgICB9CgogICAgc3RyZWFtc05hbWVzLnNvcnQoKTsKICAgIAogICAgLy8gQ3JlYXRlIFRhYmxlIGZvciBhY3RpdmVTdHJlYW1zCiAgICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzdHJlYW1UeXBlKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmVhbXNOYW1lcy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdID0gIlRSIjsKICAgICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIHZhciB0bXAgPSBzdHJlYW1zT2JqW3N0cmVhbXNOYW1lc1tpXV0KICAgICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKHRtcCkKCiAgICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgICAgbmV3S2V5WyJfZWxlbWVudCJdICA9ICJURCI7CiAgICAgIC8vbmV3S2V5WyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgc3dpdGNoKHN0cmVhbVR5cGUpIHsKICAgICAgICBjYXNlICJhY3RpdmVTdHJlYW1zIjogbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsICgrKToiOyBicmVhazsKICAgICAgICBjYXNlICJpbmFjdGl2ZVN0cmVhbXMiOiBuZXdLZXlbIl90ZXh0Il0gICA9ICJDaGFubmVsICgtKToiOyBicmVhazsKICAgICAgfQogICAgICAKICAgICAgbmV3S2V5WyJjbGFzcyJdICAgICA9ICJ0ZEtleSI7CiAgICAgIGNvbnNvbGUubG9nKCk7CgoKICAgICAgdmFyIG5ld1ZhbCA9IG5ldyBPYmplY3QoKQogICAgICBuZXdWYWxbIl9lbGVtZW50Il0gID0gIlREIjsKICAgICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgbmV3VmFsWyJjbGFzcyJdICAgICA9ICJ0ZFZhbCI7CiAgICAgIC8vbmV3VmFsWyJfdGV4dCJdICAgICA9IHZhbHVlOwogICAgICAKICAgICAgbGluZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0tleSkpOwogICAgICBsaW5lLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VmFsKSk7CiAgICAgIAogICAgfQoKICB9CgogIHJldHVybgp9CgpmdW5jdGlvbiBzaG93QWN0aXZlU3RyZWFtcyhvYmopIHsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWN0aXZlU3RyZWFtcyIpLmlubmVySFRNTCA9ICIiOwogIGFjdGl2ZVN0cmVhbXMgICAgID0gb2JqOwogIHZhciBzdHJlYW1zT2JqICAgID0gbmV3IE9iamVjdCgpOwogIHZhciBzdHJlYW1zTmFtZXMgID0gbmV3IEFycmF5KCk7CiAgCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKG9iaikKICAKICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5hbWUgICAgPSBvYmpba2V5c1tpXV1bIm5hbWUiXTsKICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtS2V5ID0gZ2V0T2JqS2V5cyhvYmpba2V5c1tpXV0pOwoKICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyZWFtS2V5Lmxlbmd0aDsgaisrKSB7CiAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICB9CgogICAgc3RyZWFtc09ialtuYW1lXSA9IHRtcDsKICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgfQoKICBzdHJlYW1zTmFtZXMuc29ydCgpOwogIAogIC8vIENyZWF0ZSBUYWJsZSBmb3IgYWN0aXZlU3RyZWFtcwogIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJhY3RpdmVTdHJlYW1zIik7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyZWFtc05hbWVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSA9ICJUUiI7CiAgICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CiAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICB2YXIgdG1wID0gc3RyZWFtc09ialtzdHJlYW1zTmFtZXNbaV1dCiAgICB2YXIga2V5cyA9IGdldE9iaktleXModG1wKQoKICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgIG5ld0tleVsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgLy9uZXdLZXlbIl90ZXh0Il0gICAgID0gc3RyZWFtc05hbWVzW2ldOwogICAgbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsOiI7CiAgICBuZXdLZXlbImNsYXNzIl0gICAgID0gInRkS2V5IjsKICAgIGNvbnNvbGUubG9nKCk7CgoKICAgIHZhciBuZXdWYWwgPSBuZXcgT2JqZWN0KCkKICAgIG5ld1ZhbFsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgIG5ld1ZhbFsiY2xhc3MiXSAgICAgPSAidGRWYWwiOwogICAgLy9uZXdWYWxbIl90ZXh0Il0gICAgID0gdmFsdWU7CiAgICAKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdLZXkpKTsKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdWYWwpKTsKICAgIAogIH0KCn0KCmZ1bmN0aW9uIHBhcnNlTG9ncyhvYmopIHsKICLine truncated
|
||||
webUI["html/js/menu.js"] = "CmZ1bmN0aW9uIHNldE1lbnVJdGVtKCkgewoKICBtZW51ID0gbmV3IE9iamVjdCgpOwogIHN1Yk1lbnUgPSBuZXcgT2JqZWN0KCk7CgogIHZhciBtZW51X20zdSA9IG5ldyBPYmplY3QoKTsKICBtZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9tM3VbIl9lbGVtZW50Il0gICAgICAgID0gIkxJIjsKICBtZW51X20zdVsiX2NvbmZpZ0tleSJdICAgICAgPSAiZmlsZXMubTN1IjsKICBtZW51X20zdVsiX3RleHQiXSAgICAgICAgICAgPSAiUGxheWxpc3QiOwogIG1lbnVfbTN1WyJfaWNvbiJdICAgICAgICAgICA9ICJpbWcvbTN1LnBuZyI7CiAgbWVudV9tM3VbIl9oZWFkbGluZSJdICAgICAgID0gIlBsYXlsaXN0czogTG9jYWwgb3IgcmVtb3RlIjsKICBtZW51X20zdVsiX3VzYWdlIl0gICAgICAgICAgPSAiPGI+SW5mbzwvYj48YnI+QXZhaWxhYmlsaXR5OiBGaWxlIGF2YWlsYWJpbGl0eSBpbiBwZXJjZW50PGJyPlN0cmVhbXM6ICAgICAgTnVtYmVyIG9mIHN0cmVhbXMgaW4gdGhlIGZpbGUuPGJyPmdyb3VwLXRpdGxlOiAgU3RyZWFtcyB0aGF0IGFyZSBhc3NpZ25lZCB0byBhIGdyb3VwLiBTaW1wbGlmaWVzIGZpbHRlcmluZyBzdHJlYW1zPGJyPnR2Zy1pZDogICAgICAgVGhpcyBJRCBpcyB1c2VkIGZvciBhdXRvbWF0aWMgbWFwcGluZywgbXVzdCBtYXRjaCB3aXRoIHRoZSBjaGFubmVsIElEIGluIHRoZSBYTUxUViBmaWxlLjxicj5VbmlxdWUgSUQ6ICAgIFN0cmVhbXMgd2l0aCBhIHVuaXF1ZSBJRCB0byBpZGVudGlmeSB0aGVtLiBBbGxvd3MgY2hhbm5lbCBuYW1lIGNoYW5nZXMgaW4gdGhlIE0zVSB3aXRob3V0IGxvc2luZyB0aGUgWE1MVFYgbWFwcGluZyAoUFBWIC8gbGl2ZSBldmVudHMpLjxicj48YnI+PGI+VXNhZ2UgTTNVOjwvYj48YnI+UmVtb3RlIHBsYXlsaXN0OiBodHRwOi8veW91ci5pcHR2LnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1PGJyPjxicj48Yj5Vc2FnZSBIREhvbWVSdW46PC9iPjxicj5JUDogMTkyLjE2OC4xLjEwOjUwMDQ8YnI+IgogIG1lbnVfbTN1WyJuYW1lIl0gICAgICAgICAgICA9ICJmaWxlIjsKICBtZW51X20zdVsiaWQiXSAgICAgICAgICAgICAgPSAiZmlsZSI7CiAgbWVudV9tM3VbInZhbHVlIl0gICAgICAgICAgID0gbWVudV9tM3VbIm5hbWUiXTsKICBtZW51X20zdVsicGxhY2Vob2xkZXIiXSAgICAgPSAiUGxheWxpc3Q6IGxvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV9tM3VbIm9uY2xpY2siXSAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X20zdVsiY2xhc3MiXSAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfZmlsdGVyID0gbmV3IE9iamVjdCgpOwogIG1lbnVfZmlsdGVyWyJfbWVudVR5cGUiXSAgICA9ICJpbnB1dEFycmF5IjsKICBtZW51X2ZpbHRlclsiX2VsZW1lbnQiXSAgICAgPSAiTEkiOwogIG1lbnVfZmlsdGVyWyJfY29uZmlnS2V5Il0gICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfdGV4dCJdICAgICAgICA9ICJGaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfaWNvbiJdICAgICAgICA9ICJpbWcvZmlsdGVyLnBuZyI7CiAgbWVudV9maWx0ZXJbIl9oZWFkbGluZSJdICAgID0gIkZpbHRlciBieSBNM1UgcGFyYW1ldGVycywgZS5nLiBncm91cC10aXRsZSI7CiAgbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+U3BvcnQgLSBBbGwgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gIXtFUyxERX0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuPGJyPjxicj5UbyBmaWx0ZXIgdGhlIHN0cmVhbXMgb2YgYSBIREhvbWVSdW4sIHRoZSBwbGF5bGlzdCBuYW1lIGNhbiBiZSBlbnRlcmVkOjxicj5NeSB0dW5lciB7SER9IgogIC8vbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+QWxsIHNwb3J0cyBjaGFubmVsczogU3BvcnQ8YnI+QWxsIEhEIHNwb3J0cyBjaGFubmVsczogU3BvcnQge0hEfTxicj5BbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuOiBTcG9ydCB7SER9ICF7RVMsREV9IgogIG1lbnVfZmlsdGVyWyJuYW1lIl0gICAgICAgICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJpZCJdICAgICAgICAgICA9ICJNM1UiOwogIG1lbnVfZmlsdGVyWyJ2YWx1ZSJdICAgICAgICA9IG1lbnVfZmlsdGVyWyJuYW1lIl07CiAgbWVudV9maWx0ZXJbInBsYWNlaG9sZGVyIl0gID0gIkZpbHRlciBzdHJlYW1zOiBTcG9ydCI7CiAgbWVudV9maWx0ZXJbIm9uY2xpY2siXSAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2ZpbHRlclsiY2xhc3MiXSAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICB2YXIgbWVudV9pZCA9IG5ldyBPYmplY3QoKTsKICBtZW51X2lkWyJfbWVudVR5cGUiXSAgICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9pZFsiX2VsZW1lbnQiXSAgICAgICAgID0gIkxJIjsKICBtZW51X2lkWyJfY29uZmlnS2V5Il0gICAgICAgPSAiaWQiOwogIG1lbnVfaWRbIl90ZXh0Il0gICAgICAgICAgICA9ICJQTVMgSUQiOwogIG1lbnVfaWRbIl9pY29uIl0gICAgICAgICAgICA9ICJpbWcvbnVtYmVyLnBuZyI7CiAgbWVudV9pZFsiX2hlYWRsaW5lIl0gICAgICAgID0gIlNldHVwIFBNUyBndWlkZSBudW1iZXIiOwogIG1lbnVfaWRbIl91c2FnZSJdICAgICAgICAgICA9ICdTb21lIHBsYXlsaXN0cyBoYXZlIHVuaXF1ZSBjaGFubmVsIElEcy48YnI+RW50ZXIgdGhlIGtleXdvcmQgb2YgdGhlIElELiBUaGUgY2hhbm5lbCBhc3NpZ25tZW50IGluIFBNUyB3aWxsIGNoYW5nZSBhcyBhIHJlc3VsdC48YnI+PGJyPmUuZy4gY2hhbm5lbElEPGJyPiNFWFRJTkY6MCB0eXBlPSJzdHJlYW0iIDxiPmNoYW5uZWxJZDwvYj49IjgxIiwgTXkgU3RyZWFtaW5nIENoYW5uZWwgSEQ8YnI+PGJyPk9ubHkgZW50ZXIgaGVyZSBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmchJwogIG1lbnVfaWRbIm5hbWUiXSAgICAgICAgICAgICA9ICJpZCI7CiAgbWVudV9pZFsiaWQiXSAgICAgICAgICAgICAgID0gImlkIjsKICBtZW51X2lkWyJ2YWx1ZSJdICAgICAgICAgICAgPSBtZW51X2lkWyJuYW1lIl07CiAgbWVudV9pZFsicGxhY2Vob2xkZXIiXSAgICAgID0gIlVuaXF1ZSBJRCBmcm9tIHRoZSBNM1UgZmlsZSI7CiAgbWVudV9pZFsib25jbGljayJdICAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2lkWyJjbGFzcyJdICAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfeG1sdHYgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV94bWx0dlsiX21lbnVUeXBlIl0gICAgID0gImlucHV0QXJyYXkiOwogIG1lbnVfeG1sdHZbIl9lbGVtZW50Il0gICAgICA9ICJMSSI7CiAgbWVudV94bWx0dlsiX2NvbmZpZ0tleSJdICAgID0gImZpbGVzLnhtbHR2IjsKICBtZW51X3htbHR2WyJfdGV4dCJdICAgICAgICAgPSAiWE1MVFYiOwogIG1lbnVfeG1sdHZbIl9pY29uIl0gICAgICAgICA9ICJpbWcveG1sdHYucG5nIjsKICBtZW51X3htbHR2WyJfaGVhZGxpbmUiXSAgICAgPSAiWE1MVFYgZmlsZXM6IExvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV94bWLine truncated
|
||||
webUI["html/index.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+CiAgICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJjc3Mvc2NyZWVuLmNzcyIgdHlwZT0idGV4dC9jc3MiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJjc3MvYmFzZS5jc3MiIHR5cGU9InRleHQvY3NzIj4KCiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbWVudV90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvc2V0dGluZ3NfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2xvZ3NfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2Jhc2VfdHMuanMiPjwvc2NyaXB0PgoKICA8L2hlYWQ+CgogICAgPGJvZHkgY2xhc3M9ImFwcC1zaGVsbCIgb25sb2FkPSJqYXZhc2NyaXB0OiBQYWdlUmVhZHkoKTsiPgoKICAgICAgPGEgY2xhc3M9InNraXAtbGluayIgaHJlZj0iI2NvbnRlbnQiPlNraXAgdG8gbWFpbiBjb250ZW50PC9hPgoKICAgICAgPGRpdiBpZD0ibG9hZGluZyIgY2xhc3M9Im5vbmUiIHJvbGU9InN0YXR1cyIgYXJpYS1saXZlPSJwb2xpdGUiIGFyaWEtbGFiZWw9IkxvYWRpbmciIGFyaWEtaGlkZGVuPSJ0cnVlIj4KICAgICAgICA8ZGl2IGNsYXNzPSJsb2FkZXIiPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgaWQ9InBvcHVwIiBjbGFzcz0ibm9uZSIgcm9sZT0iZGlhbG9nIiBhcmlhLW1vZGFsPSJ0cnVlIiBhcmlhLWhpZGRlbj0idHJ1ZSIgdGFiaW5kZXg9Ii0xIj4KICAgICAgICA8ZGl2IGlkPSJwb3B1cC1jdXN0b20iIHJvbGU9ImRvY3VtZW50IiB0YWJpbmRleD0iLTEiPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgaWQ9ImxheW91dC1vdmVybGF5IiBhcmlhLWhpZGRlbj0idHJ1ZSIgdGFiaW5kZXg9Ii0xIj48L2Rpdj4KICAgICAgPGRpdiBpZD0ibGF5b3V0Ij4KCiAgICAgICAgPCEtLQogICAgICAgIDxkaXYgaWQ9Im5vdGlmaWNhdGlvbiI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJlbGVtZW50Ij4KICAgICAgICAgICAgPGg1PlhFUEc8L2g1PgogICAgICAgICAgICA8cHJlPjExLjA1LjIwMTkgLSAyMDoyMTwvcHJlPgogICAgICAgICAgICA8aHI+CiAgICAgICAgICAgIDxwPkhhbGxvIGRhcyBpc3QgZWluIFRlc3QuIFVuZCBub2NoIG1laHIgVGV4dC48L3A+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgLS0+CgogICAgICAgIDxhc2lkZSBpZD0ibWVudS13cmFwcGVyIiBjbGFzcz0ibGF5b3V0LWxlZnQiIGFyaWEtbGFiZWw9IlNpZGViYXIgbWVudSI+CiAgICAgICAgICA8ZGl2IGlkPSAiYnJhbmNoIj48L2Rpdj4KICAgICAgICAgIDxkaXYgaWQ9ImxvZ28iPjwvZGl2PgogICAgICAgICAgPG5hdiBpZD0ibWFpbi1tZW51IiByb2xlPSJtZW51YmFyIiBhcmlhLWxhYmVsPSJNYWluIG5hdmlnYXRpb24iPjwvbmF2PgogICAgICAgIDwvYXNpZGU+CgogICAgICAgIDxtYWluIGlkPSJzaGVsbC1tYWluIiBjbGFzcz0ibGF5b3V0LXJpZ2h0Ij4KICAgICAgICAgIDxoZWFkZXIgaWQ9InNoZWxsLWhlYWRlciI+CiAgICAgICAgICAgIDxidXR0b24gaWQ9Im1lbnUtdG9nZ2xlIiB0eXBlPSJidXR0b24iIGFyaWEtZXhwYW5kZWQ9ImZhbHNlIiBhcmlhLWNvbnRyb2xzPSJtZW51LXdyYXBwZXIiIGFyaWEtbGFiZWw9IlRvZ2dsZSBuYXZpZ2F0aW9uIG1lbnUiPk1lbnU8L2J1dHRvbj4KICAgICAgICAgICAgPGgyIGlkPSJzaGVsbC10aXRsZSI+eFRlVmUgQ29udHJvbCBQYW5lbDwvaDI+CiAgICAgICAgICAgIDxwIGlkPSJjb25uZWN0aW9uLWluZGljYXRvciIgY2xhc3M9InN0YXR1cy1pZGxlIiByb2xlPSJzdGF0dXMiIGFyaWEtbGl2ZT0icG9saXRlIiBhcmlhLWF0b21pYz0idHJ1ZSI+Q29ubmVjdGluZy4uLjwvcD4KICAgICAgICAgIDwvaGVhZGVyPgoKICAgICAgICAgIDx0YWJsZSBpZD0iY2xpZW50SW5mbyIgY2xhc3M9IiIgYXJpYS1sYWJlbD0iU2VydmVyIGluZm9ybWF0aW9uIj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij54VGVWZTo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIiBkYXRhLWxhYmVsPSJ4VGVWZSI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5PUzo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0ib3MiIGNsYXNzPSJ0ZFZhbCIgZGF0YS1sYWJlbD0iT1MiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSBwaG9uZSI+RFZSIElQOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJEVlIiIGNsYXNzPSJ0ZFZhbCBwaG9uZSIgZGF0YS1sYWJlbD0iRFZSIElQIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8L3RyPgoKICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPlVVSUQ6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9InV1aWQiIGNsYXNzPSJ0ZFZhbCIgZGF0YS1sYWJlbD0iVVVJRCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5BcmNoOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJhcmNoIiBjbGFzcz0idGRWYWwiIGRhdGEtbGFiZWw9IkFyY2giPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSBwaG9uZSI+TTNVIFVSTDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0ibTN1LXVybCIgY2xhc3M9InRkVmFsIHBob25lIiBkYXRhLWxhYmVsPSJNM1UgVVJMIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8L3RyPgoKICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkF2YWlsYWJsZSBTdHJlYW1zOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJzdHJlYW1zIiBjbGFzcz0idGRWYWwiIGRhdGEtbGFiZWw9IkF2YWlsYWJsZSBTdHJlYW1zIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkVQRyBTb3VyY2U6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9ImVwZ1NvdXJjZSIgY2xhc3M9InRkVmFsIiBkYXRhLWxhYmVsPSJFUEcgU291cmNlIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkgcGhvbmUiPlhFUEcgVVJMOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJ4ZXBnLXVybCIgY2xhc3M9InRkVmFsIHBob25lIiBkYXRhLWxhYmVsPSJYRVBHIFVSTCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPC90cj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5YRVBHIENoYW5uZWxzOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJ4ZXBnIiBjbGFzcz0idGRWYWwiIGRhdGEtbGFiZWLine truncated
|
||||
webUI["html/js/files.js"] = "ZnVuY3Rpb24gb3BlbkZpbGVzKGVsbSwgZmlsZVR5cGUpIHsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpLmlubmVySFRNTCA9ICJUZXN0IjsKICAKICBjb2x1bW5Ub1NvcnQgPSAwOyAKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gJ2ZpbGVEZXRhaWwoIi0iLCAiJyArIGZpbGVUeXBlICsgJyIpJzsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSA9ICJVcGRhdGUiOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gPSAiZmlsZURldGFpbCgwKSI7CiAgLy9uZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CgogICAvLyBCdWlsZCB0YWJsZQogIHZhciBuZXdUYWJsZSA9IG5ldyBPYmplY3QoKTsKICBuZXdUYWJsZVsiX2VsZW1lbnQiXSAgPSAiVEFCTEUiOwogIG5ld1RhYmxlWyJpZCJdICAgICAgICA9ICJpZF9tYXBwaW5nIjsKICBuZXdUYWJsZVsiY2xhc3MiXSAgICAgPSAidGFibGUtbWFwcGluZyI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VGFibGUpKTsKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIGNyZWF0ZUZpbGVzVGFibGUoZmlsZVR5cGUpOyAKICB9LCAxMCk7Cgp9CgpmdW5jdGlvbiBjcmVhdGVGaWxlc1RhYmxlKGZpbGVUeXBlKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB2YXIgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCk7CiAgCiAgdGFibGUuaW5uZXJIVE1MID0gIiI7CiAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogIG5ld1RSWyJfZWxlbWVudCJdID0gIlRSIjsKICBuZXdUUlsiY2xhc3MiXSAgICA9ICJ0YWJsZS1tYXBwaW5nLWhlYWRlciI7CiAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICB2YXIgdHIgPSB0YWJsZS5sYXN0Q2hpbGQ7CgogIHN3aXRjaChmaWxlVHlwZSkgewogICAgY2FzZSAieG1sdHYiOiAKICAgICAgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCJ4bWx0diIpOyAKICAgICAgdmFyIHRySGVhZGxpbmVzID0gbmV3IEFycmF5KCJHdWlkZSIsICJMYXN0IFVwZGF0ZSIsICJBdmFpbGFiaWxpdHkgJSIsICJDaGFubmVscyIsICJQcm9ncmFtcyIpCiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgieG1sdHYuY2hhbm5lbHMiLCAieG1sdHYucHJvZ3JhbXMiKQogICAgICBicmVhazsKCiAgICBjYXNlICJtM3UiOgogICAgICBhdmFpbGFibGVGaWxlVHlwZXMgPSBuZXcgQXJyYXkoIm0zdSIsICJoZGhyIik7IAogICAgICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlBsYXlsaXN0IiwgIkxhc3QgVXBkYXRlIiwgIkF2YWlsYWJpbGl0eSAlIiwgIlR5cGUiLCAiU3RyZWFtcyIsICJncm91cC10aXRsZSAlIiwgInR2Zy1pZCAlIiwgIlVuaXF1ZSBJRCAlIik7CiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgic3RyZWFtcyIsICJncm91cC50aXRsZSIsICJ0dmcuaWQiLCAic3RyZWFtLmlkIik7CiAgICAgIGJyZWFrOwogIH0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ckhlYWRsaW5lcy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiVEQiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB0ckhlYWRsaW5lc1tpXTsKICAgIHRyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VEQpKTsKICB9CiAgCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdmFpbGFibGVGaWxlVHlwZXMubGVuZ3RoOyBpKyspIHsKICAgIAogICAgdmFyIGZpbGVUeXBlID0gYXZhaWxhYmxlRmlsZVR5cGVzW2ldCgogICAgdmFyIGRhdGEgPSBjb25maWdbImZpbGVzIl1bZmlsZVR5cGVdOwogICAgCiAgICB2YXIgYWxsRmlsZXMgPSBnZXRPYmpLZXlzKGRhdGEpCiAgCiAgICBmb3IgKHZhciBmID0gMDsgZiA8IGFsbEZpbGVzLmxlbmd0aDsgZisrKSB7CiAgICAgIHZhciBlbG0gICAgICAgICAgID0gZGF0YVthbGxGaWxlc1tmXV07CiAgICAgIHZhciB0YWJsZSAgICAgICAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICAgICAgdmFyIGZpbGVJRCAgICAgICAgPSBlbG1bImlkLnByb3ZpZGVyIl07CiAgICAgIHZhciBuYW1lICAgICAgICAgID0gZWxtWyJuYW1lIl07CiAgICAgIHZhciBsYXN0VXBkYXRlICAgID0gZWxtWyJsYXN0LnVwZGF0ZSJdOwogICAgICB2YXIgYXZhaWxhYmlsaXR5ICA9IGVsbVsicHJvdmlkZXIuYXZhaWxhYmlsaXR5Il07CiAgICAgIHZhciB0eXBlICAgICAgICAgID0gZWxtWyJ0eXBlIl0udG9VcHBlckNhc2UoKTsKICAgICAgdmFyIGNvbXBhdGliaWxpdHkgPSBlbG1bImNvbXBhdGliaWxpdHkiXTsKCiAgICAgIC8vIENyZWF0ZSBUUgogICAgICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld1RSWyJfZWxlbWVudCJdICAgICAgID0gIlRSIjsKICAgICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgICAgbmV3VFJbImlkIl0gICAgICAgICAgICAgPSBmaWxlSUQ7CiAgICAgIG5ld1RSWyJvbmNsaWNrIl0gICAgICAgID0gJ2phdmFzY3JpcHQ6IGZpbGVEZXRhaWwoIicgKyBmaWxlSUQgKyAnIiwiJyArIGZpbGVUeXBlICsgJyIpOyc7CiAgICAgIHRhYmxlLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VFIpKTsKCiAgICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIC8vIENyZWF0ZSBmaWxlIG5hbWUgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBuYW1lOwogICAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgICAgLy8gQ3JlYXRlIGxhc3QgdXBkYXRlIFRECiAgICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICAgIG5ld1REWyJfdGV4dCJdICAgID0gbGFzdFVwZGF0ZTsKICAgICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAgIC8vIENyZWF0ZSBhdmFpbGFiaWxpdHkgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBhdmFpbGFiaWxpdHk7CiAgICAgIGNyZWF0ZU5ld1REKG5ld1RELLine truncated
|
||||
webUI["html/js/menu_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIE1haW5NZW51ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gTWFpbk1lbnUoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gIm1haW4tbWVudSI7CiAgICAgICAgdGhpcy5IVE1MVGFnID0gIkxJIjsKICAgICAgICB0aGlzLkltYWdlUGF0aCA9ICJpbWcvIjsKICAgIH0KICAgIE1haW5NZW51LnByb3RvdHlwZS5jcmVhdGVJTUcgPSBmdW5jdGlvbiAoc3JjKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTUciKTsKICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgic3JjIiwgdGhpcy5JbWFnZVBhdGggKyBzcmMpOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICAgIE1haW5NZW51LnByb3RvdHlwZS5jcmVhdGVWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51Owp9KCkpOwp2YXIgTWFpbk1lbnVJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKE1haW5NZW51SXRlbSwgX3N1cGVyKTsKICAgIGZ1bmN0aW9uIE1haW5NZW51SXRlbShtZW51S2V5LCB2YWx1ZSwgaW1hZ2UsIGhlYWRsaW5lKSB7CiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpczsKICAgICAgICBfdGhpcy5tZW51S2V5ID0gbWVudUtleTsKICAgICAgICBfdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIF90aGlzLmltZ1NyYyA9IGltYWdlOwogICAgICAgIF90aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQogICAgTWFpbk1lbnVJdGVtLnByb3RvdHlwZS5jcmVhdGVJdGVtID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBpdGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiTEkiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgib25jbGljayIsICJqYXZhc2NyaXB0OiBvcGVuVGhpc01lbnUodGhpcykiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgiaWQiLCB0aGlzLmlkKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgiZGF0YS1tZW51IiwgdGhpcy5tZW51S2V5KTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgicm9sZSIsICJtZW51aXRlbSIpOwogICAgICAgIGl0ZW0uc2V0QXR0cmlidXRlKCJ0YWJpbmRleCIsICIwIik7CiAgICAgICAgaXRlbS5zZXRBdHRyaWJ1dGUoImFyaWEtY29udHJvbHMiLCAiY29udGVudCIpOwogICAgICAgIGl0ZW0uc2V0QXR0cmlidXRlKCJhcmlhLWxhYmVsIiwgdGhpcy52YWx1ZSk7CiAgICAgICAgaXRlbS5zZXRBdHRyaWJ1dGUoIm9ua2V5ZG93biIsICJpZihldmVudC5rZXk9PT0nRW50ZXInIHx8IGV2ZW50LmtleT09PScgJyl7ZXZlbnQucHJldmVudERlZmF1bHQoKTtvcGVuVGhpc01lbnUodGhpcyk7fSIpOwogICAgICAgIHZhciBpbWcgPSB0aGlzLmNyZWF0ZUlNRyh0aGlzLmltZ1NyYyk7CiAgICAgICAgaW1nLnNldEF0dHJpYnV0ZSgiYWx0IiwgIiIpOwogICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuY3JlYXRlVmFsdWUodGhpcy52YWx1ZSk7CiAgICAgICAgaXRlbS5hcHBlbmRDaGlsZChpbWcpOwogICAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQodmFsdWUpOwogICAgICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChpdGVtKTsKICAgICAgICBzd2l0Y2ggKHRoaXMubWVudUtleSkgewogICAgICAgICAgICBjYXNlICJwbGF5bGlzdCI6CiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlSGVhZGVyID0gWyJ7ey5wbGF5bGlzdC50YWJsZS5wbGF5bGlzdH19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnR1bmVyfX0iLCAie3sucGxheWxpc3QudGFibGUubGFzdFVwZGF0ZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLmF2YWlsYWJpbGl0eX19ICUiLCAie3sucGxheWxpc3QudGFibGUudHlwZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnN0cmVhbXN9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS5ncm91cFRpdGxlfX0gJSIsICJ7ey5wbGF5bGlzdC50YWJsZS50dmdJRH19ICUiLCAie3sucGxheWxpc3QudGFibGUudW5pcXVlSUR9fSAlIl07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3sueG1sdHYudGFibGUuZ3VpZGV9fSIsICJ7ey54bWx0di50YWJsZS5sYXN0VXBkYXRlfX0iLCAie3sueG1sdHYudGFibGUuYXZhaWxhYmlsaXR5fX0gJSIsICJ7ey54bWx0di50YWJsZS5jaGFubmVsc319IiwgInt7LnhtbHR2LnRhYmxlLnByb2dyYW1zfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3suZmlsdGVyLnRhYmxlLm5hbWV9fSIsICJ7ey5maWx0ZXIudGFibGUudHlwZX19IiwgInt7LmZpbHRlci50YWJsZS5maWx0ZXJ9fSJdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbInt7LnVzZXJzLnRhYmxlLnVzZXJuYW1lfX0iLCAie3sudXNlcnMudGFibGUucGFzc3dvcmR9fSIsICJ7ey51c2Vycy50YWJsZS53ZWJ9fSIsICJ7ey51c2Vycy50YWJsZS5wbXN9fSIsICJ7ey51c2Vycy50YWJsZS5tM3V9fSIsICJ7ey51c2Vycy50YWJsZS54bWx9fSIsICJ7ey51c2Vycy50YWJsZS5hcGl9fSJdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIm1hcHBpbmciOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsiQlVMSyIsICJ7ey5tYXBwaW5nLnRhYmxlLmNoTm99fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmxvZ299fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmNoYW5uZWxOYW1lfX0iLCAie3subWFwcGluZy50YWJsZS5wbGF5bGlzdH19IiwgInt7Lm1hcHBpbmcudGFibGUuZ3JvdXBUaXRsZX1Line truncated
|
||||
webUI["html/js/users.js"] = "ZnVuY3Rpb24gb3BlblVzZXJzKGVsbSkgewogIGNvbG9tblNvcnQgPSAwOwoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gInVzZXJEZXRhaWwoMCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CgogIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2V0dGluZ3MiKTsKCiAgIC8vIEJ1aWxkIHRhYmxlCiAgdmFyIG5ld1RhYmxlID0gbmV3IE9iamVjdCgpOwogIG5ld1RhYmxlWyJfZWxlbWVudCJdICA9ICJUQUJMRSI7CiAgbmV3VGFibGVbImlkIl0gICAgICAgID0gImlkX21hcHBpbmciOwogIG5ld1RhYmxlWyJjbGFzcyJdICAgICA9ICJ0YWJsZS1tYXBwaW5nIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUYWJsZSkpOwoKICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IAogICAgY3JlYXRlVXNlcnNUYWJsZSgpOyAKICB9LCAxMCk7Cn0KCmZ1bmN0aW9uIGNyZWF0ZVVzZXJzVGFibGUoKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB0YWJsZS5pbm5lckhUTUwgPSAiIjsKICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3VFJbIl9lbGVtZW50Il0gPSAiVFIiOwogIG5ld1RSWyJjbGFzcyJdICAgID0gInRhYmxlLW1hcHBpbmctaGVhZGVyIjsKICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1RSKSk7CgogIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlVzZXJuYW1lIiwgIlBhc3N3b3JkIiwgIldFQiIsICJQTVMiLCAiTTNVIiwgIlhNTCIsICJBUEkiKQoKICBmb3IgKHZhciBpID0gMDsgaSA8IHRySGVhZGxpbmVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJURCI7CiAgICBuZXdURFsiX3RleHQiXSAgICA9IHRySGVhZGxpbmVzW2ldOwogICAgdHIuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdURCkpOwogIH0KCgogIC8vIFNvcnQgdXNlcnMKICB2YXIgdXNlcklkcyA9IGdldE9iaktleXModXNlcnMpOwoKICB2YXIgdXNlck9iaiA9IG5ldyBPYmplY3QoKTsKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB1c2VySWRzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgdXNlcm5hbWUgPSB1c2Vyc1t1c2VySWRzW2ldXVsiZGF0YSJdWyJ1c2VybmFtZSJdOwogICAgdXNlck9ialt1c2VybmFtZV0gPSB1c2VySWRzW2ldOwogIH0KCiAgdmFyIGFsbFVzZXJzID0gZ2V0T2JqS2V5cyh1c2VyT2JqKTsKICBhbGxVc2Vycy5zb3J0KCk7CiAgLy8gLS0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGxVc2Vycy5sZW5ndGg7IGkrKykgewogICAgdmFyIHRhYmxlICAgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpZF9tYXBwaW5nIik7CiAgICB2YXIgdXNlcklEICAgID0gdXNlck9ialthbGxVc2Vyc1tpXV07CiAgICB2YXIgdXNlcm5hbWUgID0gYWxsVXNlcnNbaV07CiAgICB2YXIgaXRlbSAgICAgID0gdXNlcnNbdXNlcklEXVsiZGF0YSJdOwoKICAgIC8vIENyZWF0ZSBUUgogICAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogICAgbmV3VFJbIl9lbGVtZW50Il0gICAgICAgPSAiVFIiOwogICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgIG5ld1RSWyJpZCJdICAgICAgICAgICAgID0gdXNlcklEOwogICAgbmV3VFJbIm9uY2xpY2siXSAgICAgICAgPSAnamF2YXNjcmlwdDogdXNlckRldGFpbCgiJyArIHVzZXJJRCArICciKTsnOwogICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAvLyBDcmVhdGUgdXNlcm5hbWUgVEQKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB1c2VybmFtZTsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHBhc3N3b3JkIFRECiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIG5ld1REWyJfdGV4dCJdICAgID0gIi4uLi4uIjsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHdlYiBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgc3dpdGNoKGl0ZW1bImF1dGhlbnRpY2F0aW9uLndlYiJdKXsKICAgICAgY2FzZSB0cnVlOiBuZXdURFsiX3RleHQiXSAgICA9ICLinJMiOyBicmVhazsKICAgICAgZGVmYXVsdDogICBuZXdURFsiX3RleHQiXSAgICA9ICItIjsgYnJlYWs7CiAgICB9CiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgIC8vIENyZWF0ZSBQTVMgYWNjZXNzCiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5wbXMiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7IGJyZWFrOwogICAgfQogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAvLyBDcmVhdGUgTTNVIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ubTN1Il0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIFhNTFRWIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ueG1sIl0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIEFQSSBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwoKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5hcGkiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7ILine truncated
|
||||
webUI["html/video/stream-limit.ts"] = "R0AREABC8CUAAcEAAP8B/wAB/IAUSBIBBkZGbXBlZwlTZXJ2aWNlMDF3fEPK//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9HQAAQAACwDQABwQAAAAHwACqxBLL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0dQABAAArASAAHBAADhAPAAG+EA8AAVvU1W////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////R0EAMAdQAAB7DH4AAAAB4AAAgMAKMQAJEKERAAfYYQAAAAEJ8AAAAAFnZAAorNlAeAIn5cBEAAADAAQAAAMAyDxgxlgAAAABaOvjyyLAAAABBgX//6rcRem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTUyIHIyODU0IGU5YTU5MDMgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDE3IC0gaHR0cDovL3dHAQARd3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2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 truncated
|
||||
webUI["html/img/logout.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xM1QxMToxMDoxODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg27QeEAAANQSURBVGgF7Zk9aBRBGIZzSRSN8YdoCpEkghCCqK1o4g9IsBCCNmIniCAiWAhqI8G02qiIoqCCWggSEcFKEFPYpVAU8QdFUyiKRpRokBjP55OdZDLZvZnZ7N3Ngh887M7sN/O9797t7c5eTc3/8D8DxWKxGS5Ai//oAEYgvB4OwleQaAtAlp8ERG+Bp6Jei/wYQfRy6NfE67vhG0FtA/TBqK7c2A/bCGJ3wpAhOq4ZphGUroEHcYoT+sIygsgmOAu/EwQndYdhBHV1sB8+Jym19Lf6/faVIRuBG+GRRajtcPWMoKwFbtgUOh6vvBGEzYFj8MNRpEtaZY2gaAe8cVHmmXOc/K3QXIZv/+SUFFgJ96AS8ZwiZ6Ab6iZVzGCPiRbCKRiDasQHip6EdD/PDKyFvfAJQgg5kVfB/VoieT0MQojxE1G9UG/7otWS0A7pPkrb7DM/Ppcp+mAAM/bFGEmL4RL8gVDjI8JWOZ0bEjvhSahO0CXXsLMZWZYegREIMV4jaoHTJyNJJLfC7RCdoOm6sxGVyKAeeBegoU6l0XmLiXlwAqp1o4w7j3d1AwW9YdtnNrnQzkOXLddyfAPHv8Ey6ABpd8N88In2QqHwymfARC5mCrAH0i6qGDr9jk3fbNgFz8A1DkwIS7tDpSVwGdLcexIfPZhPHpf2wS+wRX9a/dPGUakLzBdwNgGJRlQBJtgMw5aJ3qr8TLYUmwVHwXXxZTUiwphvHYxDUnzPxIA5CdXa4E5SVa3fyUhkRtYqpSKbNYxpJiq+ncpDJar7GGlknvcl5mqM05BZH4Xl3iOLpLh7j7OR6MScSzAykplg20QIWA0PDSG+RuTdQVy8sNXP9DgK5N4jK9AvkRpfI4sYF/c2836mQl0nQ4zce66AfZFkTMqYl2DGaSMt/CYOHpsuaPco5bLUzUuMGkLHaQ+ovjwZUZrVdpAHRnnw/Bd5MrJCiY62t4x2+E2uBfkfRg95TdSkK8/LJ7JWF83+Nb5Ww0Zf+E3OviwXVMgT8dLwVRsKEd0A+uP8biMlH01MHAYVF/Oh2lCJenkDqpbUN9nPyzU91QnCRbyEPEXn1sQhxMv7tG1T7cW3rK/r44eVtxfxm6gwBh38zJqPJuUtXu3Z/wLwuBaBLgMkKwAAAABJRU5ErkJggg=="
|
||||
webUI["html/img/x_ transparent.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTo3NjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI1NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoeXQb1AAAaJElEQVR4Ae2dCZhcVZXHz+1KSFiGkISkqyIoOgI68EkgOBNkEcQRlIFRZDGABAQEhInGbxw+RUZRNhWRLawDYR0GHAaHUVkGvwGURUcgwIiAOGxjV3UHAslHQrbuM/9TlQ6d7qruWt527/u/7+uuqvvucu7vvnveuffde54IDxIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARLwiIDzQtayHi0q23shaydCOnlISu7nnWThRdrFOkPWyCleyNqJkF1yjhTd8k6yiDvtuLgLiCR/lVnIZ14keWU7k2Xyuu4oU92r2RazQ+nWypXI4W86zCXbyZ28KBvJ97MtpEhX1gWsyleS08TJU17I2omQKpvLarmqkywyn7ZHPw9rLvTOvwbX6xEyxS3Nenv4oQCcWwmQc/D3dtaBdiyfyv5S1mM7zieLGSzWEsS6KIuiRSzTGTD9H404z1iy80MBWNVL7hn8nx8LhaxlqnKBvKbvyppYHctTM/0nd5xPljNwcrcUs2/6DyL0RwGYxDOcjR3vGBQ+4M8tMElmdQ3n6NGjYPofGE6F6tTESRmm/1xxTuuczWSQH08BhqJbqlNkuTyJoK2GBgf53S6mkrvB+7qZ6b9Gfod6hHv3dzKAGbX9pNvd51N7+WUBGNlJbgm07FH4G/AJdFuyqlwotXFzW8kzk2itXAFZwu38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 truncated
|
||||
webUI["html/js/base_ts.js"] = "dmFyIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKdmFyIEJVTEtfRURJVCA9IGZhbHNlOwp2YXIgQ09MVU1OX1RPX1NPUlQ7CnZhciBTRUFSQ0hfTUFQUElORyA9IG5ldyBPYmplY3QoKTsKdmFyIFVORE8gPSBuZXcgT2JqZWN0KCk7CnZhciBTRVJWRVJfQ09OTkVDVElPTiA9IGZhbHNlOwp2YXIgV1NfQVZBSUxBQkxFID0gZmFsc2U7CnZhciBBQ1RJVkVfTUVOVV9JRCA9ICIiOwp2YXIgTEFTVF9GT0NVU0VEX0VMRU1FTlQgPSBudWxsOwp2YXIgTEFTVF9CVUxLX0NIRUNLQk9YID0gbnVsbDsKLy8gTWVudQp2YXIgbWVudUl0ZW1zID0gbmV3IEFycmF5KCk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInBsYXlsaXN0IiwgInt7Lm1haW5NZW51Lml0ZW0ucGxheWxpc3R9fSIsICJtM3UucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLnBsYXlsaXN0fX0iKSk7Ci8vbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgicG1zSUQiLCAie3subWFpbk1lbnUuaXRlbS5wbXNJRH19IiwgIm51bWJlci5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUucG1zSUR9fSIpKQptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJmaWx0ZXIiLCAie3subWFpbk1lbnUuaXRlbS5maWx0ZXJ9fSIsICJmaWx0ZXIucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmZpbHRlcn19IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJ4bWx0diIsICJ7ey5tYWluTWVudS5pdGVtLnhtbHR2fX0iLCAieG1sdHYucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLnhtbHR2fX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oIm1hcHBpbmciLCAie3subWFpbk1lbnUuaXRlbS5tYXBwaW5nfX0iLCAibWFwcGluZy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUubWFwcGluZ319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJ1c2VycyIsICJ7ey5tYWluTWVudS5pdGVtLnVzZXJzfX0iLCAidXNlcnMucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLnVzZXJzfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInNldHRpbmdzIiwgInt7Lm1haW5NZW51Lml0ZW0uc2V0dGluZ3N9fSIsICJzZXR0aW5ncy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUuc2V0dGluZ3N9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibG9nIiwgInt7Lm1haW5NZW51Lml0ZW0ubG9nfX0iLCAibG9nLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5sb2d9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibG9nb3V0IiwgInt7Lm1haW5NZW51Lml0ZW0ubG9nb3V0fX0iLCAibG9nb3V0LnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5sb2dvdXR9fSIpKTsKLy8gS2F0ZWdvcmllbiBmw7xyIGRpZSBFaW5zdGVsbHVuZ2VuCnZhciBzZXR0aW5nc0NhdGVnb3J5ID0gbmV3IEFycmF5KCk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LmdlbmVyYWx9fSIsICJ4dGV2ZUF1dG9VcGRhdGUsdHVuZXIsZXBnU291cmNlLGFwaSx1c2VfcGxleEFQSSxwbGV4LnVybCxwbGV4LnRva2VuIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5maWxlc319IiwgInVwZGF0ZSxmaWxlcy51cGRhdGUsdGVtcC5wYXRoLGNhY2hlLmltYWdlcyx4ZXBnLm1pc3NpbmcuZXBnLm1vZGUseGVwZy5yZXBsYWNlLm1pc3NpbmcuaW1hZ2VzIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5zdHJlYW1pbmd9fSIsICJidWZmZXIsdWRweHksYnVmZmVyLnNpemUua2IsYnVmZmVyLnRpbWVvdXQsdXNlci5hZ2VudCxmZm1wZWcucGF0aCxmZm1wZWcub3B0aW9ucyx2bGMucGF0aCx2bGMub3B0aW9ucyIpKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkuYmFja3VwfX0iLCAiYmFja3VwLnBhdGgsYmFja3VwLmtlZXAiKSk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LmF1dGhlbnRpY2F0aW9ufX0iLCAiYXV0aGVudGljYXRpb24ud2ViLGF1dGhlbnRpY2F0aW9uLnBtcyxhdXRoZW50aWNhdGlvbi5tM3UsYXV0aGVudGljYXRpb24ueG1sLGF1dGhlbnRpY2F0aW9uLmFwaSIpKTsKZnVuY3Rpb24gc2hvd1BvcFVwRWxlbWVudChlbG0pIHsKICAgIHZhciBhbGxFbGVtZW50cyA9IG5ldyBBcnJheSgicG9wdXAtY3VzdG9tIik7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFsbEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgc2hvd0VsZW1lbnQoYWxsRWxlbWVudHNbaV0sIGZhbHNlKTsKICAgIH0KICAgIHNob3dFbGVtZW50KGVsbSwgdHJ1ZSk7CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICBzaG93RWxlbWVudCgicG9wdXAiLCB0cnVlKTsKICAgIH0sIDEwKTsKICAgIHJldHVybjsKfQpmdW5jdGlvbiBzaG93RWxlbWVudChlbG1JRCwgdHlwZSkgewogICAgdmFyIGNzc0NsYXNzOwogICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICBjc3NDbGFzcyA9ICJibG9jayI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgIGNzc0NsYXNzID0gIm5vbmUiOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtSUQpOwogICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY3NzQ2xhc3M7CiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgiYXJpYS1oaWRkZW4iLCB0eXBlID09IHRydWUgPyAiZmFsc2UiIDogInRydWUiKTsKICAgIGlmIChlbG1JRCA9PSAibG9hZGluZyIgJiYgZG9jdW1lbnQuYm9keSAhPSBudWxsKSB7CiAgICAgICAgZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImFyaWEtYnVzeSIsIHR5cGUgPT0gdHJ1ZSA/ICJ0cnVlIiA6ICJmYWxzZSIpOwogICAgfQogICAgaWYgKGVsbUlEID09ICJwb3B1cCIpIHsKICAgICAgICB2YXIgcG9wdXBDb250ZW50XzEgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtY3VzdG9tIik7CiAgICAgICAgaWYgKHR5cGUgPT0gdHJ1ZSkgewogICAgICAgICAgICBMQVNUX0ZPQ1VTRURfRUxFTUVOVCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7CiAgICAgICAgICAgIGlmIChwb3B1cENvbnRlbnRfMSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBwb3B1cENvbnRlbnRfMS5mb2N1cygpOwogICAgICAgICAgICAgICAgfSwgMjApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBpZiAoTEFTVF9GT0NVU0VEX0VMRU1FTlQgIT0gbnVsbCAmJiBMQVNUX0ZPQ1VTRURfRUxFTUVOVC5mb2N1cyAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIExBU1RfRk9DVVNFRF9FTEVNRU5ULmZvY3VzKCk7CiAgICAgICAgICAgICAgICB9LCALine truncated
|
||||
webUI["html/js/configuration_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIFdpemFyZENhdGVnb3J5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gV2l6YXJkQ2F0ZWdvcnkoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gImNvbnRlbnQiOwogICAgfQogICAgV2l6YXJkQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkg0Iik7CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICByZXR1cm4gV2l6YXJkQ2F0ZWdvcnk7Cn0oKSk7CnZhciBXaXphcmRJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKFdpemFyZEl0ZW0sIF9zdXBlcik7CiAgICBmdW5jdGlvbiBXaXphcmRJdGVtKGtleSwgaGVhZGxpbmUpIHsKICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzOwogICAgICAgIF90aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgX3RoaXMua2V5ID0ga2V5OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KICAgIFdpemFyZEl0ZW0ucHJvdG90eXBlLmNyZWF0ZVdpemFyZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgaGVhZGxpbmUgPSB0aGlzLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUodGhpcy5oZWFkbGluZSk7CiAgICAgICAgdmFyIGtleSA9IHRoaXMua2V5OwogICAgICAgIHZhciBjb250ZW50ID0gbmV3IFBvcHVwQ29udGVudCgpOwogICAgICAgIHZhciBkZXNjcmlwdGlvbjsKICAgICAgICB2YXIgd2l6YXJkRmllbGQgPSBudWxsOwogICAgICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5zZXRBdHRyaWJ1dGUoImFyaWEtYnVzeSIsICJ0cnVlIik7CiAgICAgICAgZG9jLmlubmVySFRNTCA9ICIiOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChoZWFkbGluZSk7CiAgICAgICAgc3dpdGNoIChrZXkpIHsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IDEwMDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dC5wdXNoKGkpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIjEiLCBrZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBzZWxlY3QuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIHdpemFyZEZpZWxkID0gc2VsZWN0OwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLnR1bmVyLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImVwZ1NvdXJjZSI6CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFsiUE1TIiwgIlhFUEciXTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbIlBNUyIsICJYRVBHIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCAiWEVQRyIsIGtleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJjbGFzcyIsICJ3aXphcmQiKTsKICAgICAgICAgICAgICAgIHNlbGVjdC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgd2l6YXJkRmllbGQgPSBzZWxlY3Q7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJ7ey53aXphcmQuZXBnU291cmNlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0Iiwga2V5LCAiIik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LndpemFyZC5tM3UucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJjbGFzcyIsICJ3aXphcmQiKTsKICAgICAgICAgICAgICAgIGlucHV0LmlkID0ga2V5OwogICAgICAgICAgICAgICAgZG9jLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHdpemFyZEZpZWxkID0gaW5wdXQ7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJ7ey53aXphcmQubTN1LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBrZXksICIiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sud2l6YXJkLnhtbHR2LnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBpbnB1dC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB3aXphcmRGaWVsZCA9IGlucHV0OwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLnhtbHR2LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhrZXkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhciBwcmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBwcmUuaWQgPSAid2l6YXJkLWRlc2NyaXB0aW9uLSIgKyBrZXLine truncated
|
||||
webUI["html/create-first-user.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keSBjbGFzcz0iYXV0aC1zY3JlZW4iPgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImhlYWRlciIgY2xhc3M9ImltZ0NlbnRlciI+PC9kaXY+CgogICAgICA8bWFpbiBpZD0iYm94IiByb2xlPSJtYWluIiBhcmlhLWxhYmVsbGVkYnk9ImhlYWQtdGV4dCI+CgogICAgICAgIDxkaXYgaWQ9ImhlYWRsaW5lIj4KICAgICAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj57ey5hY2NvdW50LmhlYWRsaW5lfX08L2gxPgogICAgICAgIDwvZGl2PgoKICAgICAgICA8cCBpZD0iZXJyIiBjbGFzcz0iZXJyb3JNc2cgY2VudGVyIiByb2xlPSJhbGVydCIgYXJpYS1saXZlPSJhc3NlcnRpdmUiIGFyaWEtYXRvbWljPSJ0cnVlIj48L3A+CgogICAgICAgIDxkaXYgaWQ9ImNvbnRlbnQiPgoKICAgICAgICAgICAgPGZvcm0gaWQ9ImF1dGhlbnRpY2F0aW9uIiBhY3Rpb249IiIgbWV0aG9kPSJwb3N0IiBhcmlhLWRlc2NyaWJlZGJ5PSJlcnIiIG5vdmFsaWRhdGU+CgogICAgICAgICAgICAgIDxsYWJlbCBmb3I9InVzZXJuYW1lIj57ey5hY2NvdW50LnVzZXJuYW1lLnRpdGxlfX06PC9sYWJlbD4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9InVzZXJuYW1lIiB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VybmFtZSIgcGxhY2Vob2xkZXI9IlVzZXJuYW1lIiB2YWx1ZT0iIiBhdXRvY29tcGxldGU9InVzZXJuYW1lIj4KICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJwYXNzd29yZCI+e3suYWNjb3VudC5wYXNzd29yZC50aXRsZX19OjwvbGFiZWw+CiAgICAgICAgICAgICAgPGlucHV0IGlkPSJwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIiBwbGFjZWhvbGRlcj0iUGFzc3dvcmQiIHZhbHVlPSIiIGF1dG9jb21wbGV0ZT0ibmV3LXBhc3N3b3JkIj4KICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJjb25maXJtIj57ey5hY2NvdW50LmNvbmZpcm0udGl0bGV9fTo8L2xhYmVsPgogICAgICAgICAgICAgIDxpbnB1dCBpZD0iY29uZmlybSIgIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJjb25maXJtIiAgcGxhY2Vob2xkZXI9IkNvbmZpcm0iIHZhbHVlPSIiIGF1dG9jb21wbGV0ZT0ibmV3LXBhc3N3b3JkIj4KICAgICAgICAgICAgICAKICAgICAgICAgICAgPC9mb3JtPgoKICAgICAgICA8L2Rpdj4KICAgICAgICAKICAgICAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj4KICAgICAgICAgIDxpbnB1dCBpZD0ic3VibWl0IiBjbGFzcz0iIiB0eXBlPSJidXR0b24iIHZhbHVlPSJ7ey5idXR0b24uY3JhZXRlQWNjb3VudH19IiBhcmlhLWxhYmVsPSJ7ey5idXR0b24uY3JhZXRlQWNjb3VudH19IiBvbmNsaWNrPSJqYXZhc2NyaXB0OiBsb2dpbigpOyI+CiAgICAgICAgPC9kaXY+CiAgICAgIAogICAgICAgIAogICAgICA8L21haW4+CiAgICA8L2JvZHk+CjwvaHRtbD4K"
|
||||
webUI["html/img/m3u.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CumjVbcAAAGWSURBVGgF7VoxTgJRFGTFaGKBFnbEcABjb0fiBego7D2ABYmn8ARKRWFNQ6gx4QRQGWJJoY2VhXGdl7Dkh7Dsx3ns3yXvJ5P97L6d92bmhwYqlcWK43gK5L2enP51NP8F7pN721wPnOITZx9qG6HxI8QIZO+9XCHeL+VQKKm8QMyxb6+iCpH528AQYs58xIQWknV8mhDxCjEXWWJCC8maT55fAmOIudpUXAYhMn8dGEHMTZqYsgiR+U+BAcTcrhNTJiEy/xHQg5jOqpjD1RsBP3+id8u3P8TUoij6SuoLIwRDfWOofjLYtteyHa1UfcvvcUT1jqpGauVuHnyAdragjv/TAkley3uhj9Y5ZhDQa2+Olgmhz4IygSWibChNZ4nQFioTWCLKhtJ0lghtoTKBJaJsKE1nidAWKhNYIsqG0nSWCG2hMoElomwoTWeJ0BYqE1giyobSdJYIbaEygSWibChNZ4nQFioTWCLKhtJ0biJzmi1/guXMrpDn/OegO3bXMuAH0TtgAvwARV3y57Q34AGoJkL+AErKZ9cqbH7AAAAAAElFTkSuQmCC"
|
||||
webUI["html/js/logs_ts.js"] = "dmFyIExvZyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIExvZygpIHsKICAgIH0KICAgIExvZy5wcm90b3R5cGUuY3JlYXRlTG9nID0gZnVuY3Rpb24gKGVudHJ5KSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiV0FSTklORyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gIndhcm5pbmdNc2ciOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiRVJST1IiKSAhPSAtMSkgewogICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9ICJlcnJvck1zZyI7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeS5pbmRleE9mKCJERUJVRyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImRlYnVnTXNnIjsKICAgICAgICB9CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBlbnRyeTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICByZXR1cm4gTG9nOwp9KCkpOwpmdW5jdGlvbiBzaG93TG9ncyhib3R0b20pIHsKICAgIHZhciBsb2cgPSBuZXcgTG9nKCk7CiAgICB2YXIgbG9ncyA9IFNFUlZFUlsibG9nIl1bImxvZyJdOwogICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X2xvZyIpOwogICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYm94LXdyYXBwZXIiKTsKICAgIHZhciBzaG91bGRTdGlja1RvQm90dG9tID0gYm90dG9tOwogICAgZGl2LmlubmVySFRNTCA9ICIiOwogICAgaWYgKHdyYXBwZXIgIT0gbnVsbCAmJiBzaG91bGRTdGlja1RvQm90dG9tID09IGZhbHNlKSB7CiAgICAgICAgdmFyIGRpc3RhbmNlVG9Cb3R0b20gPSB3cmFwcGVyLnNjcm9sbEhlaWdodCAtIHdyYXBwZXIuc2Nyb2xsVG9wIC0gd3JhcHBlci5jbGllbnRIZWlnaHQ7CiAgICAgICAgaWYgKGRpc3RhbmNlVG9Cb3R0b20gPCA4MCkgewogICAgICAgICAgICBzaG91bGRTdGlja1RvQm90dG9tID0gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICB2YXIga2V5cyA9IGdldE9iaktleXMobG9ncyk7CiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGxvZ0lEKSB7CiAgICAgICAgdmFyIGVudHJ5ID0gbG9nLmNyZWF0ZUxvZyhsb2dzW2xvZ0lEXSk7CiAgICAgICAgZGl2LmFwcGVuZChlbnRyeSk7CiAgICB9KTsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgIGlmIChzaG91bGRTdGlja1RvQm90dG9tID09IHRydWUgJiYgd3JhcHBlciAhPSBudWxsKSB7CiAgICAgICAgICAgIHdyYXBwZXIuc2Nyb2xsVG9wID0gd3JhcHBlci5zY3JvbGxIZWlnaHQ7CiAgICAgICAgfQogICAgfSwgMTApOwp9CmZ1bmN0aW9uIHJlc2V0TG9ncygpIHsKICAgIHZhciBjbWQgPSAicmVzZXRMb2dzIjsKICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9Cg=="
|
||||
webUI["html/css/screen.css"] = "I2xheW91dCB7CiAgZGlzcGxheTogZ3JpZDsKICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDI5MHB4IG1pbm1heCgwLCAxZnIpOwogIGdhcDogMTZweDsKICBtaW4taGVpZ2h0OiAxMDB2aDsKICBwYWRkaW5nOiAxNnB4Owp9CgojbGF5b3V0LW92ZXJsYXkgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5sYXlvdXQtbGVmdCB7CiAgbWluLXdpZHRoOiAwOwogIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1sKTsKICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1saW5lKTsKICBiYWNrZ3JvdW5kOgogICAgbGluZWFyLWdyYWRpZW50KDE4MGRlZywgcmdiYSgxOCwgMzYsIDU4LCAwLjk1KSAwJSwgcmdiYSgxMCwgMjMsIDM4LCAwLjk1KSAxMDAlKSwKICAgIHJhZGlhbC1ncmFkaWVudChjaXJjbGUgYXQgMjAlIDAlLCByZ2JhKDUzLCAyMTAsIDI1NSwgMC4xMiksIHRyYW5zcGFyZW50IDQ4JSk7CiAgYm94LXNoYWRvdzogdmFyKC0tc2hhZG93LTIpOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCiNtZW51LXdyYXBwZXIgewogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKICBoZWlnaHQ6IDEwMCU7CiAgcGFkZGluZzogMTRweDsKfQoKI2JyYW5jaCB7CiAgbWluLWhlaWdodDogMThweDsKICBtYXJnaW46IDJweCAwIDZweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgZm9udC1zaXplOiAxMXB4OwogIGNvbG9yOiAjZmY5ZjhkOwogIGxldHRlci1zcGFjaW5nOiAwLjA4ZW07CiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsKfQoKI2xvZ28gewogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogNzZweDsKICBib3JkZXItcmFkaXVzOiAxMnB4OwogIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWxpbmUtc29mdCk7CiAgYmFja2dyb3VuZDoKICAgIGxpbmVhci1ncmFkaWVudCgxODBkZWcsIHJnYmEoMjYsIDQ5LCA3MywgMC41NSksIHJnYmEoMTMsIDI4LCA0NSwgMC42KSksCiAgICB1cmwoIi4uL2ltZy9sb2dvX3dfNjAweDIwMC5wbmciKSBjZW50ZXIgbm8tcmVwZWF0OwogIGJhY2tncm91bmQtc2l6ZTogY29udGFpbjsKICBtYXJnaW4tYm90dG9tOiAxMnB4Owp9CgojbWFpbi1tZW51IHsKICBkaXNwbGF5OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgZ2FwOiA3cHg7CiAgb3ZlcmZsb3c6IGF1dG87CiAgcGFkZGluZy1yaWdodDogNHB4Owp9CgojbWFpbi1tZW51IGxpIHsKICBkaXNwbGF5OiBmbGV4OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgZ2FwOiAxMHB4OwogIG1pbi1oZWlnaHQ6IDQycHg7CiAgcGFkZGluZzogOHB4IDExcHg7CiAgYm9yZGVyLXJhZGl1czogMTJweDsKICBib3JkZXI6IDFweCBzb2xpZCB0cmFuc3BhcmVudDsKICBiYWNrZ3JvdW5kOiByZ2JhKDExLCAyNSwgNDAsIDAuNTgpOwp9CgojbWFpbi1tZW51IGxpOmhvdmVyIHsKICBib3JkZXItY29sb3I6IHZhcigtLWFjY2VudC1zb2Z0KTsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMnB4KTsKfQoKI21haW4tbWVudSBsaTpmb2N1cy12aXNpYmxlIHsKICBib3JkZXItY29sb3I6IHJnYmEoMTAzLCAyMzIsIDI1NSwgMC42Mik7CiAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDJweCk7CiAgYm94LXNoYWRvdzogMCAwIDAgM3B4IHJnYmEoNTMsIDIxMCwgMjU1LCAwLjIzKTsKfQoKI21haW4tbWVudSBsaS5tZW51LWFjdGl2ZSB7CiAgYm9yZGVyLWNvbG9yOiByZ2JhKDEwMywgMjMyLCAyNTUsIDAuNTUpOwogIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM2ZmU2ZmYgMCUsICMxY2M1ZmYgMTAwJSk7CiAgYm94LXNoYWRvdzogMCAxMHB4IDE4cHggcmdiYSgyOCwgMTk3LCAyNTUsIDAuMyk7Cn0KCiNtYWluLW1lbnUgbGkubWVudS1hY3RpdmUgcCB7CiAgY29sb3I6ICMwMzExMWE7Cn0KCiNtYWluLW1lbnUgbGkubWVudS1hY3RpdmUgaW1nIHsKICBmaWx0ZXI6IGJyaWdodG5lc3MoMC4wNCkgc2F0dXJhdGUoMTIwJSk7Cn0KCm5hdiBpbWcgewogIGRpc3BsYXk6IGJsb2NrOwogIHdpZHRoOiAxOHB4OwogIGhlaWdodDogMThweDsKICBtYXgtd2lkdGg6IDE4cHg7CiAgbWF4LWhlaWdodDogMThweDsKICBmbGV4OiAwIDAgYXV0bzsKfQoKbmF2IHAgewogIG1hcmdpbjogMDsKICBwYWRkaW5nOiAwOwogIHRleHQtYWxpZ246IGxlZnQ7CiAgZm9udC1zaXplOiAxMnB4OwogIGZvbnQtd2VpZ2h0OiA2MDA7CiAgY29sb3I6ICNkN2VlZmU7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKICBvdmVyZmxvdzogaGlkZGVuOwogIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzOwp9CgoubGF5b3V0LXJpZ2h0IHsKICBtaW4td2lkdGg6IDA7CiAgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLWwpOwogIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWxpbmUpOwogIGJhY2tncm91bmQ6CiAgICBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCByZ2JhKDE3LCAzNCwgNTQsIDAuOTQpIDAlLCByZ2JhKDEwLCAyMCwgMzQsIDAuOTYpIDEwMCUpLAogICAgcmFkaWFsLWdyYWRpZW50KGNpcmNsZSBhdCAxMDAlIDAlLCByZ2JhKDUzLCAyMTAsIDI1NSwgMC4wOCksIHRyYW5zcGFyZW50IDM0JSk7CiAgYm94LXNoYWRvdzogdmFyKC0tc2hhZG93LTIpOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKICBvdmVyZmxvdzogaGlkZGVuOwp9Cgojc2hlbGwtaGVhZGVyIHsKICBkaXNwbGF5OiBmbGV4OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgZ2FwOiAxMnB4OwogIHBhZGRpbmc6IDEycHggMTRweDsKICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tbGluZS1zb2Z0KTsKICBiYWNrZ3JvdW5kOiByZ2JhKDEwLCAyMiwgMzYsIDAuNTIpOwp9Cgojc2hlbGwtdGl0bGUgewogIG1hcmdpbjogMDsKICBmb250LXNpemU6IDEuMDhyZW07CiAgZm9udC13ZWlnaHQ6IDcwMDsKICBjb2xvcjogI2Q4ZjFmZjsKICBsZXR0ZXItc3BhY2luZzogMC4wNGVtOwp9CgojbWVudS10b2dnbGUgewogIGRpc3BsYXk6IG5vbmU7CiAgbWluLXdpZHRoOiA3MnB4OwogIHBhZGRpbmc6IDhweCAxNHB4OwogIG1hcmdpbjogMDsKICBmb250LXNpemU6IDEycHg7Cn0KCiNjb25uZWN0aW9uLWluZGljYXRvciB7CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgcGFkZGluZzogNXB4IDExcHg7CiAgYm9yZGVyLXJhZGl1czogOTk5cHg7CiAgZm9udC1zaXplOiAxMXB4OwogIGZvbnQtd2VpZ2h0OiA3MDA7CiAgbGV0dGVyLXNwYWNpbmc6IDAuMDVlbTsKICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwp9CgojY29ubmVjdGlvbi1pbmRpY2F0b3Iuc3RhdHVzLWlkbGUgewogIGNvbG9yOiAjZDhlZGZmOwogIGJvcmRlcjogMXB4IHNvbGlkICMzYTU4Nzc7CiAgYmFja2dyb3VuZDogcmdiYSgyMCwgNDIsIDY2LCAwLjY1KTsKfQoKI2Nvbm5lY3Rpb24taW5kaWNhdG9yLnN0YXR1cy1idXN5IHsKICBjb2xvcjogIzA3MjAzMTsKICBib3JkZXI6IDFweCBzb2xpZCAjN2VlOGZmOwogIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM3YmU4ZmYgMCUsICMzM2NkZmYgMTAwJSk7Cn0KCiNjb25uZWN0aW9uLWluZGljYXRvci5zdGF0dXMtb25saW5lIHsKICBjb2xvcjogIzA1MjIxOTsKICBib3JkZXI6IDFweCBzb2xpZCAjOWZmMGM4OwogIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM5MmYwYzAgMCUsICM0ZmNlOTMgMTAwJSk7Cn0KCiNjb25uZWN0aW9uLWluZGljYXRvci5zdGF0dXMtb2ZmbGluZSB7CiAgY29sb3I6ICNmZmU1ZTU7CiAgYm9yZGVyOiAxcHggc29saWQgI2ZmOWLine truncated
|
||||
webUI["html/img/BC-QR.jpg"] = "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 truncated
|
||||
webUI["html/img/log.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xNFQxMToxMDo0MjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CkP32mEAAANASURBVGgF7ZlPiE1RHMffw1AYhiL5k1HEijJiYaFZiHoyFspW2RFRkkSZGgtFWJIwi9FYmo0VOywkKTbKgjSlWcifRCPX51dv6s2d33md77vvXjfmV9859/7u93x/v98959x73p1KRbAkSargAhgDH0E/qIYkuHYEvAPGvwbmNOEerXM/0Q6BRSFuZj/ix0DaDnvCkGppIucDAe4OhzvkcUO+GaELAf8ux7/b8Zlrr+Pvc3zm6nX8NccXdKmFLHaUPJ/Ruhyu5zNap8Nd6PiCLrUQTyi0Rjy/5/M0Zd+smB7M32XwtgBr07aC6yfSTs7XO77OALfH4VbgHsD/HLytVquJx4nyIdQFBsHftscksK5Z0sGhpuN8Or4Aa5sJFHjtO7G2MjKvvZjN1sglOpSlCMt9LrDZ4S4Hd0Qg24vrK+gAZbPtjMqTdFKhEdkIsYxFWP720JlioUK6pzDL41jtpRIqxOOWxecuB3fhRGT8E85YBK8VygI6GSRTCxlH3TaJgyw4O2678aCxO94LbNPovYDdmOrUukIBN/MqwjJEOwGPOHR31W4VONVCLEBR9lAJpBbSrYhn5K5R+quFnGUOr1ICtMIlxjz6XVb6qot9JeKvCPSAdlQJJHDtd8hOIN0wtRDLxx6Ntr0ulalTq1TJNyYzXUjj3SjD8X87Iva7uR8s5+2bi6FtX1oOgi8g2tSn1g2yPx+t3gIR/c90s1+C1vuO/YkxdWrdjxFtE2dE0VELWaqIZ+QuUfqrhZxmyKUvgEoyE1xizOR4YOI8plXXyAZEbYsyTJvXFsUW+x6wGUSbWogJ237rZHSEgojq1CooLT3MdCH6Pcu3xz8zIq0s9lvc2+sgz6dWH/rnQPB/jlybZGoh99hCHJqk0P6TD0jaI/4b7dVYeXVq2bemokyKpRZiHwWKMimWWshxhryjoEpOKXHUNbIN8WcUc5s2r8Vue7l9oAaiTS3EhDeB6EUYnUlGojq1MobLr3uokB/5hcys7OYWKuRl5nD5Cbi5uYXw0ntPHoay2S8Seuol5RZSJ0r/n/DEc/BdrN9kTZrH7BkwDspgwyQxW6uggU3nHnAXvAG/QZE2SrARsL8hJffwDxM0mNDPvT8IAAAAAElFTkSuQmCC"
|
||||
webUI["html/js/base.js"] = "dmFyIGNvbmZpZyAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciBtZW51ICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc3ViTWVudSAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGFjdGl2ZVN0cmVhbXMgPSBuZXcgT2JqZWN0KCk7CnZhciB4RVBHICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgdXNlcnMgICAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGxvZyAgICAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciB1bmRvICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgd2ViU29ja2V0cyAgICA9IHRydWU7CnZhciBjbG9zZUxvZywgdmVyc2lvbiwgYWN0aXZlTWVudTsKdmFyIGNvbHVtblRvU29ydCAgPSAwCgoKaWYgKHdpbmRvdy5XZWJTb2NrZXQgPT09IHVuZGVmaW5lZCkgewogIGFsZXJ0KCJZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJTb2NrZXRzIik7CiAgd2ViU29ja2V0cyA9IGZhbHNlOwp9IAoKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldFNlcnZlckNvbmZpZyI7CiAgeFRlVmUoZGF0YSk7CiAgLy9zaG93TG9hZGluZ1NjcmVlbihmYWxzZSk7CgogIHZhciByZXNpemVIYW5kbGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgib3BlblN0cmVhbXMiKTsKICB2YXIgYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpOwogIHJlc2l6ZUhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLCBpbml0aWFsaXNlUmVzaXplLCBmYWxzZSk7CgogIGZ1bmN0aW9uIGluaXRpYWxpc2VSZXNpemUoZSkgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlbW92ZSIsIHN0YXJ0UmVzaXppbmcsIGZhbHNlKTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJtb3VzZXVwIiwgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgfQoKICBmdW5jdGlvbiBzdGFydFJlc2l6aW5nKGUpIHsKICAgIGJveC5zdHlsZS5oZWlnaHQgPSAoZS5jbGllbnRZIC0gYm94Lm9mZnNldFRvcCkgKyAicHgiOwogICAgICAKICAgIHZhciBlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWxsU3RyZWFtcyIpOwogICAgaWYgKGUuY2xpZW50WSA+IDEyMCkgewogICAgICBlbG0uY2xhc3NOYW1lID0gInZpc2libGUiOyAKICAgIH0gZWxzZSB7CiAgICAgIGVsbS5jbGFzc05hbWUgPSAibm90VmlzaWJsZSI7IAogICAgfQoKICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKCiAgfQogIGZ1bmN0aW9uIHN0b3BSZXNpemluZyhlKSB7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzdGFydFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB9CgogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJyZXNpemUiLCBmdW5jdGlvbigpewogICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogIH0sIHRydWUpOwp9CgoKZnVuY3Rpb24gZ2V0T2JqS2V5cyhvYmopIHsKICB2YXIga2V5cyA9IG5ldyBBcnJheSgpOwoKICBmb3IgKHZhciBpIGluIG9iaikgewogICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkgewogICAgICBrZXlzLnB1c2goaSk7CiAgICB9CiAgfQoKICByZXR1cm4ga2V5czsKfQoKCmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQoaXRlbSkgewogIC8vY29uc29sZS5sb2coaXRlbSk7CiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0ZW1bIl9lbGVtZW50Il0pOwogIGlmIChpdGVtLmhhc093blByb3BlcnR5KCJfdGV4dCIpKSB7CiAgICAvL2VsZW1lbnQuaW5uZXJIVE1MID0gIjxwPiIgKyBpdGVtWyJfdGV4dCJdICsgIjwvcD4iOwogICAgZWxlbWVudC5pbm5lckhUTUwgPSBpdGVtWyJfdGV4dCJdOwogIH0KCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGl0ZW0pOwogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgaWYgKGtleXNbaV0uY2hhckF0KDApICE9ICJfIikgewogICAgICAvL2NvbnNvbGUubG9nKGtleXNbaV0sIGl0ZW1ba2V5c1tpXV0pOwogICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXlzW2ldLCBpdGVtW2tleXNbaV1dKTsKICAgIH0KICB9CgogIC8vY29uc29sZS5sb2coZWxlbWVudCk7CiAgcmV0dXJuIGVsZW1lbnQ7Cn0KCmZ1bmN0aW9uIG1vZGlmeU9wdGlvbihpZCwgb3B0aW9ucywgdmFsdWVzKSB7CiAgdmFyIHNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICBzZWxlY3QuaW5uZXJIVE1MID0gIiI7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykgewogIAogICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKQogIAogICAgZWxlbWVudC52YWx1ZSA9IHZhbHVlc1tpXTsKICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gb3B0aW9uc1tpXTsKCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgCiAgfQoKfQoKCmZ1bmN0aW9uIHN0YXJ0V2ViU29ja2V0KCkgewogIGlmICh3ZWJTb2NrZXRzID09IGZhbHNlKSB7CiAgICByZXR1cm47CiAgfQoKICAvL3dzLnNlbmQoJ3siY21kIjogImdldFNlcnZlckNvbmZpZzEifScpOwoKfQoKZnVuY3Rpb24gY2hlY2tFcnIob2JqKSB7CiAgLy9hbGVydChvYmpbImVyciJdKQogIC8vc2NyZWVuTG9nKG9ialsiZXJyIl0sICJlcnJvciIpCiAgY29uc29sZS5sb2cob2JqKTsKICB2YXIgbmV3T2JqID0gbmV3IE9iamVjdCgpOwogIHZhciBuZXdFcnIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RXJyWyJrZXkiXSAgID0gIkVycm9yIjsKICBuZXdFcnJbInZhbHVlIl0gPSBvYmpbImVyciJdOwogIG5ld0VyclsidHlwZSJdICA9ICJlcnJvciI7CgogIG5ld09ialswXSA9IG5ld0VycgogIHNob3dMb2cobmV3T2JqKTsKICByZXR1cm4KfQoKZnVuY3Rpb24gc2NyZWVuTG9nKG1zZywgbXNnVHlwZSwgc2hvdykgewogIHJldHVybgogIGNsZWFyVGltZW91dChjbG9zZUxvZykKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIHZhciBuZXdNc2cgPSBuZXcgT2JqZWN0KCk7CiAgCiAgbmV3TXNnWyJfZWxlbWVudCJdID0gIlAiOwogIAogIHN3aXRjaChtc2dUeXBlKSB7CiAgICBjYXNlICJlcnJvciI6ICAgbmV3TXNnWyJjbGFzcyJdID0gImVycm9yTXNnIjsgYnJlYWs7CiAgICBjYXNlICJ3YXJuaW5nIjogbmV3TXNnWyJjbGFzcyJdID0gIndhcm5pbmdNc2ciOyBicmVhazsKICAgIC8vZGVmYXVsdDogICAgICBuZXdNc2dbImNsYXNzIl0gPSAiaW5mb01zZyIKICB9CgogIG5ld01zZ1siX3RleHQiXSA9IG1zZzsKCiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3TXNnKSk7CgogIGRpdi5zY3JvbGxUb3AgPSBkaXYuc2Nyb2xsSGVpZ2h0OwoKICBpZiAoc2hvdyA9PSBmYWxzZSkgewogICAgcmV0dXJuOwogIH0KCiAgZGl2LmNsYXNzTmFtZSA9ICIiCiAgY2xvc2VMb2cgPSBzZXRUaW1lb3V0KGNsb3NlU2NyZWVuTG9nLCAxMDAwMCk7Cn0KCgpmdW5jdGlvbiBjbG9zZVNjcmVlbkxvZygpIHsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIGRpdi5jbGFzc05hbWUgPSAic2NyZWVuTG9nSGlkZGVuIgp9CgpmdW5jdGlvbiBzaGLine truncated
|
||||
webUI["html/js/log.js"] = "dmFyIGxvZ0ludGVydmFsCgoKZnVuY3Rpb24gdXBkYXRlTG9nKCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldExvZyI7CiAgeFRlVmUoZGF0YSk7CiAgd3JpdGVMb2dJbkRpdigpOwogIHJldHVybgp9CgpmdW5jdGlvbiB3cml0ZUxvZ0luRGl2KCkgewogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIikubGFzdENoaWxkLmxhc3RDaGlsZDsKICBkaXYuaW5uZXJIVE1MID0gIiI7CgogIHZhciBtYXggPSA1MDsKICAKICAKICBmb3IgKHZhciBpID0gMDsgaSA8IGxvZ3MubGVuZ3RoOyBpKyspIHsKICAgIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3QoKTsKICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJQIjsKCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiRVJST1IiKSkgewovLyAgICAgIGNhc2UgIndhcm5pbmdzIjogIG1zZ1R5cGUgPSAid2FybmluZ01zZyI7IGJyZWFrOwogICAgICBuZXdFbnRyeVsiY2xhc3MiXSAgID0gImVycm9yTXNnIjsKICAgIH0KCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiV0FSTklORyIpKSB7Ci8vICAgICAgY2FzZSAid2FybmluZ3MiOiAgbXNnVHlwZSA9ICJ3YXJuaW5nTXNnIjsgYnJlYWs7CiAgICAgIG5ld0VudHJ5WyJjbGFzcyJdICAgPSAid2FybmluZ01zZyI7CiAgICB9CgogICAgbmV3RW50cnlbIl90ZXh0Il0gICAgID0gbG9nc1tpXTsKICAgIAogICAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICB9CgogIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB2YXIgc2Nyb2xsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgc2Nyb2xsRGl2LnNjcm9sbFRvcCA9IHNjcm9sbERpdi5zY3JvbGxIZWlnaHQ7Cn0KCmZ1bmN0aW9uIHNob3dMb2cob2JqKSB7CiAgLy9sb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7CgogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKCiAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIkhSIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogIC8vZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiRW1wdHkgTG9nIjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJlbXB0eUxvZygpIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiY29kZSI7CiAgbmV3RW50cnlbIl90ZXh0Il0gICAgICAgID0gIlVwZGF0ZSBMb2c6ICI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJjaGVja2JveCI7CiAgLy9uZXdFbnRyeVsiY2hlY2tlZCJdICAgICA9ICJjaGVja2JveCI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAibG9nVXBkYXRlcyh0aGlzKSI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgCgoKICAKICB2YXIgbmV3V3JhcHBlciA9IG5ldyBPYmplY3QoKTsKICBuZXdXcmFwcGVyWyJfZWxlbWVudCJdICA9ICJESVYiOwogIG5ld1dyYXBwZXJbImlkIl0gICAgICAgID0gImJveC13cmFwcGVyIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdXcmFwcGVyKSk7CiAgZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld1ByZSA9IG5ldyBPYmplY3QoKTsKICBuZXdQcmVbIl9lbGVtZW50Il0gID0gIlBSRSI7CiAgbmV3UHJlWyJpZCJdICAgICAgICA9ICJsb2dTY3JlZW4iOwogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1ByZSkpOwoKICBkaXYgPSBkaXYubGFzdENoaWxkOwoKICB3cml0ZUxvZ0luRGl2KCkKICByZXR1cm4KfQoKZnVuY3Rpb24gZW1wdHlMb2coKSB7CiAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgZGF0YVsiY21kIl0gPSAiZW1wdHlMb2ciOwogIHhUZVZlKGRhdGEpOwogIHJldHVybgp9CgpmdW5jdGlvbiBsb2dVcGRhdGVzKGVsbSkgewogIHN3aXRjaChlbG0uY2hlY2tlZCkgewogICAgY2FzZSBmYWxzZTogY2xlYXJJbnRlcnZhbChsb2dJbnRlcnZhbCk7IGJyZWFrOwogICAgY2FzZSB0cnVlOiBsb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7IGJyZWFrOwogICAgCiAgfQp9"
|
||||
webUI["html/configuration.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvY29uZmlndXJhdGlvbl90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbWVudV90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvc2V0dGluZ3NfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2Jhc2VfdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keSBjbGFzcz0iYXV0aC1zY3JlZW4gd2l6YXJkLXNjcmVlbiIgb25sb2FkPSJqYXZhc2NyaXB0OiByZWFkeUZvckNvbmZpZ3VyYXRpb24oMCk7Ij4KICAgICAgICAgIAogICAgICA8ZGl2IGlkPSJsb2FkaW5nIiBjbGFzcz0iYmxvY2siIHJvbGU9InN0YXR1cyIgYXJpYS1saXZlPSJwb2xpdGUiIGFyaWEtbGFiZWw9IkxvYWRpbmciIGFyaWEtaGlkZGVuPSJmYWxzZSI+CiAgICAgICAgPGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgogICAgICA8bWFpbiBpZD0iYm94IiByb2xlPSJtYWluIiBhcmlhLWxhYmVsbGVkYnk9ImhlYWQtdGV4dCI+CiAgICAgICAgCiAgICAgICAgPHRhYmxlIGlkPSJjbGllbnRJbmZvIiBjbGFzcz0idmlzaWJsZSIgYXJpYS1sYWJlbD0iU2VydmVyIGluZm9ybWF0aW9uIj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VmVyc2lvbjo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9InZlcnNpb24iIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+T1M6PC90ZD4KICAgICAgICAgICAgPHRkIGlkPSJvcyIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VVVJRDo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9InV1aWQiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+QXJjaDo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9ImFyY2giIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgIDwvdHI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPlN0cmVhbXM6PC90ZD4KICAgICAgICAgICAgPHRkIGlkPSJzdHJlYW1zIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkRWUjo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9IkRWUiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICAgIAogICAgICAgIDxkaXYgaWQ9ImhlYWRsaW5lIj4KICAgICAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj5Db25maWd1cmF0aW9uPC9oMT4gICAgICAKICAgICAgICA8L2Rpdj4KICAgICAgICA8cCBpZD0iZXJyIiBjbGFzcz0iZXJyb3JNc2cgY2VudGVyIiByb2xlPSJhbGVydCIgYXJpYS1saXZlPSJhc3NlcnRpdmUiIGFyaWEtYXRvbWljPSJ0cnVlIj48L3A+ICAgCiAgICAgICAgPGRpdiBpZD0iY29udGVudCIgcm9sZT0icmVnaW9uIiBhcmlhLWxpdmU9InBvbGl0ZSIgYXJpYS1idXN5PSJmYWxzZSIgdGFiaW5kZXg9Ii0xIiBhcmlhLWxhYmVsPSJDb25maWd1cmF0aW9uIHN0ZXAiPgogICAgICAgICAgICAKICAgICAgICA8L2Rpdj4KICAgICAgICA8cCBpZD0ic3ItYW5ub3VuY2VyIiBjbGFzcz0ic3Itb25seSIgYXJpYS1saXZlPSJwb2xpdGUiIGFyaWEtYXRvbWljPSJ0cnVlIj48L3A+CiAgICAgICAgPGRpdiBpZD0iYm94LWZvb3RlciI+CiAgICAgICAgICA8aW5wdXQgaWQ9Im5leHQiIGNsYXNzPSIiIHR5cGU9ImJ1dHRvbiIgbmFtZT0ibmV4dCIgdmFsdWU9Ik5leHQiIGFyaWEtY29udHJvbHM9ImNvbnRlbnQiIG9uY2xpY2s9ImphdmFzY3JpcHQ6IHNhdmVXaXphcmQoKTsiPgogICAgICAgIDwvZGl2PgogICAgICA8L21haW4+CiAgICA8L2JvZHk+CjwvaHRtbD4K"
|
||||
webUI["html/img/mapping.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0wMlQxMjowODo5NzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CpRxQsEAAAJLSURBVGgF7VoxTgMxEMwBHWlAaeABVCEtBcoD+EBewCdCyQsQtLyAPCBvCBSRIBUPCF1ogqBJjlkrezGr6HTrO98lhy1Z9trr2VmvnbMNjUadUhzHLeQB8hw5LS3QOUbubvIf7X3kKXIZibgS51bCZdWgMT6D8nECgArkngagQN0B8dhbkblalVmLIyheCGUthhjuLBq77MihA0xTjHHBEBBOorHLjjghbNOg4Mg2RYO4hIiEiHiaAV5aSwf8hRgjZdHtTTTc2ZFXpZkY+hMx5k3IZYlr7jgudJHp2JElLaF0K1mirYn8nAWgQB3ibM59ERNCA52d6Nghv9isQiUtn0kURe92I9eBcYA6YZxym8dyDuwRuMw82gjQYQbsPdLDdNCROO0US3uEfp3usTZpjf5J2CNtNFwjl7FHvmBnCB5PCQkQoJudJtGvE23sJEFuI39rQArS7dskXK6nlwkAKiB1VxAxLcyUePAH8cQmlbEul4+UM8LkVjPc2ZHcaFUDBEeqjoC0HyIiZ6RqOUSk6ghI+xyRD9mRQTYfIktPylaX16rhzo48KE29QH8kxjxC/hFtZYiGe70OjWVMW7Dx32bA3iO7//iAC8DOPweZFQhH6O+CmkRvW2f28oV8owEoUHdMPPg70rFJZajTkqT7uZ3ObaHEuuHOjnCpsb8vlKUsur2JhruLA94Y5QEOjuSZPR9jQ0R8zGoezNpFhN5RtUm+/bpgaG1u0jd2OSLDTRopbZ/okxcrLUYKvKprbRfHhXr8m5PK/y1V/gWRKLfiNSmxEAAAAABJRU5ErkJggg=="
|
||||
webUI["html/img/stream-limit.jpg"] = "/9j/4AAQSkZJRgABAQAAAQABAAD/4gJoSUNDX1BST0ZJTEUAAQEAAAJYbGNtcwQwAABtbnRyUkdCIFhZWiAH4wAFABcAFgAuAAphY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAAEBjcHJ0AAABSAAAAE53dHB0AAABmAAAABRjaGFkAAABrAAAACxyWFlaAAAB2AAAABRiWFlaAAAB7AAAABRnWFlaAAACAAAAABRyVFJDAAACFAAAACBnVFJDAAACFAAAACBiVFJDAAACFAAAACBjaHJtAAACNAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACQAAAAcAHMAUgBHAEIAIABJAEUAQwA2ADEAOQA2ADYALQAyAC4AMQAAbWx1YwAAAAAAAAABAAAADGVuVVMAAAAyAAAAHABOAG8AIABjAG8AcAB5AHIAaQBnAGgAdAAsACAAdQBzAGUAIABmAHIAZQBlAGwAeQAAAABYWVogAAAAAAAA9tYAAQAAAADTLXNmMzIAAAAAAAEMSgAABeP///MqAAAHmwAA/Yf///ui///9owAAA9gAAMCUWFlaIAAAAAAAAG+UAAA47gAAA5BYWVogAAAAAAAAJJ0AAA+DAAC2vlhZWiAAAAAAAABipQAAt5AAABjecGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltjaHJtAAAAAAADAAAAAKPXAABUewAATM0AAJmaAAAmZgAAD1z/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAQ4B4ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD/AD/6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKALine truncated
|
||||
webUI["html/img/x_black.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTozNzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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 truncated
|
||||
webUI["html/js/network_ts.js"] = "dmFyIFNlcnZlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFNlcnZlcihjbWQpIHsKICAgICAgICB0aGlzLmNtZCA9IGNtZDsKICAgIH0KICAgIFNlcnZlci5wcm90b3R5cGUucmVxdWVzdCA9IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgaWYgKFNFUlZFUl9DT05ORUNUSU9OID09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfQ09OTkVDVElPTiA9IHRydWU7CiAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgaWYgKHRoaXMuY21kICE9ICJ1cGRhdGVMb2ciKSB7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgIFVORE8gPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICAgIHNldENvbm5lY3Rpb25TdGF0ZSgiYnVzeSIpOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCkgewogICAgICAgICAgICBjYXNlICJodHRwOiI6CiAgICAgICAgICAgICAgICB0aGlzLnByb3RvY29sID0gIndzOi8vIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJodHRwczoiOgogICAgICAgICAgICAgICAgdGhpcy5wcm90b2NvbCA9ICJ3c3M6Ly8iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhciB3c0hvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdDsKICAgICAgICBpZiAod3NIb3N0ID09IHVuZGVmaW5lZCB8fCB3c0hvc3QubGVuZ3RoIDwgMSkgewogICAgICAgICAgICB3c0hvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWU7CiAgICAgICAgfQogICAgICAgIHZhciB1cmwgPSB0aGlzLnByb3RvY29sICsgd3NIb3N0ICsgIi9kYXRhLyIgKyAiP1Rva2VuPSIgKyBnZXRDb29raWUoIlRva2VuIik7CiAgICAgICAgZGF0YVsiY21kIl0gPSB0aGlzLmNtZDsKICAgICAgICB2YXIgcmVxdWVzdENtZCA9IGRhdGFbImNtZCJdOwogICAgICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXQodXJsKTsKICAgICAgICB2YXIgaXNMb2dVcGRhdGUgPSBkYXRhWyJjbWQiXSA9PSAidXBkYXRlTG9nIjsKICAgICAgICB2YXIgcmVzcG9uc2VSZWNlaXZlZCA9IGZhbHNlOwogICAgICAgIHZhciByZXF1ZXN0RmluaXNoZWQgPSBmYWxzZTsKICAgICAgICB2YXIgdGltZW91dE1zID0gMTIwMDA7CiAgICAgICAgdmFyIHJlcXVlc3RUaW1lb3V0OwogICAgICAgIHZhciBmaW5pc2hSZXF1ZXN0ID0gZnVuY3Rpb24gKHN0YXRlLCByZXNwb25zZVN1Y2Nlc3MpIHsKICAgICAgICAgICAgaWYgKHJlc3BvbnNlU3VjY2VzcyA9PT0gdm9pZCAwKSB7IHJlc3BvbnNlU3VjY2VzcyA9IGZhbHNlOyB9CiAgICAgICAgICAgIGlmIChyZXF1ZXN0RmluaXNoZWQgPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVlc3RGaW5pc2hlZCA9IHRydWU7CiAgICAgICAgICAgIFNFUlZFUl9DT05ORUNUSU9OID0gZmFsc2U7CiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQocmVxdWVzdFRpbWVvdXQpOwogICAgICAgICAgICBpZiAocmVzcG9uc2VTdWNjZXNzID09IHRydWUpIHsKICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSAib25saW5lIikgewogICAgICAgICAgICAgICAgICAgIFdTX0ZBSUxVUkVfQ09VTlQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgV1NfRkFJTFVSRV9DT1VOVCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc0xvZ1VwZGF0ZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgc2hvd0VsZW1lbnQoImxvYWRpbmciLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0YXRlICE9ICIiKSB7CiAgICAgICAgICAgICAgICBzZXRDb25uZWN0aW9uU3RhdGUoc3RhdGUpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXF1ZXN0VGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgY29uc29sZS5sb2coIldlYnNvY2tldCByZXF1ZXN0IHRpbWVkIG91dC4iKTsKICAgICAgICAgICAgdmFyIHRpbWVvdXRTdGF0ZSA9ICJvZmZsaW5lIjsKICAgICAgICAgICAgaWYgKGlzTG9nVXBkYXRlID09IHRydWUgJiYgV1NfRkFJTFVSRV9DT1VOVCA8IDIpIHsKICAgICAgICAgICAgICAgIHRpbWVvdXRTdGF0ZSA9ICJpZGxlIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5pc2hSZXF1ZXN0KHRpbWVvdXRTdGF0ZSwgZmFsc2UpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgd3MuY2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgdGltZW91dE1zKTsKICAgICAgICB3cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIFdTX0FWQUlMQUJMRSA9IHRydWU7CiAgICAgICAgICAgIGlmIChkYXRhWyJjbWQiXSAhPSAidXBkYXRlTG9nIikgewogICAgICAgICAgICAgICAgc2V0Q29ubmVjdGlvblN0YXRlKCJidXN5Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29uc29sZS5sb2coIlJFUVVFU1QgKEpTKToiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSRVFVRVNUOiAoSlNPTikiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgICAgICB0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgIH07CiAgICAgICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJObyB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byB4VGVWZSBjb3VsZCBiZSBlc3RhYmxpc2hlZC4gQ2hlY2sgeW91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIHZhciBlcnJvclN0YXRlID0gIm9mZmxpbmUiOwogICAgICAgICAgICBpZiAoaXNMb2dVcGRhdGUgPT0gdHJ1ZSAmJiBXU19GQUlMVVJFX0NPVU5UIDwgMikgewogICAgICAgICAgICAgICAgZXJyb3JTdGF0ZSA9ICJpZGxlIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5pc2hSZXF1ZXN0KGVycm9yU3RhdGUsIGZhbHNlKTsKICAgICAgICAgICAgaWYgKFdTX0FWQUlMQUJMRSA9PSBmYWxzZSAmJiBpc0xvZ1VwZGF0ZSA9PSBmYWxzZSAmJiByZXF1ZXN0Q21kICE9ICJnZXRTZXJ2ZXJDb25maWciKSB7CiAgICAgICAgICAgICAgICBhbGVydCgiTm8gd2Vic29ja2V0IGNvbm5lY3Rpb24gdG8geFRlVmUgY291bGQgYmUgZXN0YWJsaXNoZWQuIENoZWNrIHlvdXIgbmV0d29yayBjb25maWd1cmF0aW9uLiIpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICB3cy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICByZXNwb25zZVJlY2VpdmVkID0gdHJ1ZTsKICAgICAgICAgICAgZmluaXNoUmVxdWVzdCgib25saW5lIiwgdHJ1ZSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSRVNQT05TRToiKTsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gSlNPTi5wYXJzZShlLmRhdGEpOwogICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZSk7CiAgICAgICAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0Line truncated
|
||||
webUI["html/img/settings.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0xMFQxODowODo4OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Ckxt87EAAAS7SURBVGgFzZpdiFVVGIbn5N+IMgVhaRLqWI7mQIJoIVRgOhQZNDAhWcbcVuPV3BRE6I14440iQQSaN0p6kz8zI0k5inUhZSSaYOVYODMo5eiMOOPf+LzH2cPMPmvttdbe53jOBy9rr2+938/ae51vr733qaoqgQwPD68B/wDJfXAP3AE94JMShCy+SxJ9CvSDJFlU7MiPFdsh/hrBdIffBsd48HApJjLPI4tnPThBlFJMZI5HBuWZCIt9AmgEzeAJR6JzHeMadnKI8wbYCz4Fkz18JlNwMgf8BCL5j4O3bVaMdUfEhPZqgv1U7HbEbDvoT7HZOPUYNwAlHheV09a4A3RTgMqtj9QY7JdgeM5i3I4+fDIYrQeq/UnyNYOTlBDtS+BwEjk2doz+KyO2OY5bwVCME+/qylTHT4C1D3k+uB33Yul3ov/eMuajlu1RH+II5wtT4hNNSnQ6U/kzbRkfq351bCfF8apAm7kmvq38njWRK0S305SHcSK5XO4U5O9MBmXWbSe3E6YccialdKzH2TTnQEF10XgZ5DdivsxEhkyxjVdERAwu03xmMiqD7hYx19km4cyHq6KyeHKkWpSz+ciVrHVpRYZk/wLHp0H2bULkNKzt4Eq86TKxLq3IECf6nXwV9QPbAfjHQSfoD7SN6L63gYhvbrkiTwKf/dPYpbdPVxKMnigdg0VAG8FQye8AzBl6aIk2A+wPiNoHd63LNZx3wbUAvz/CfTzJb/43AmkGpLfAi0DPE/NALQgtve+xFPdi5xRiNkHa5ySOJ/TR7RrBJdqL4AAxL+p+8ToYAFklNCnF3pM1KPba2L6v8vons5oPsko9ZyZoa0PsOoKezxoY+y5N5DYHWSvDTXzUMJH7IUkRW0tbyyV0CcfDDKmqDMe1KfqnQyehGNgo9q8p4hWYFGsiBY4fsSK/BRkkaPgj5PhMy720BnVFesfnlKo3Das0bw8XYJf196GEuzWRLSDoRypLg2w06FyqTS6Cx7iK1eeqGqrnugmuBgvB8+A5UAuqQYiU+oZ4h2T+BV3gAlDp/pai0U1rFpVGMAv8AHzFd4vShMOQLcoB+DNB/sSbM3ZoMV4BQsW0adSJSbNp1Hu1mY40/YZxpPdJaUSfFzrBMXAjjQNsdvll6cHCWVvKJIphdhcny11pqmolCk5aIDif0BKdZBucgPlO8kh/r8O4HtwClSCbk86HtQqQuUrvKVCf5OARjt0lll4H/WKKmbS0tmJQKZNQ7nq9+w0n2LhTN04E8jKMPpZ1hcli8tGTZYEYJwJrZQGzchTGz3a2ifwdkHc73LYAfpx6DcWXQK1LeiDsdpFGx7UOwUGQJKpmGyIjjvWh50iSQWzsZ/ofgvx+jnYp+B/YpJcB7QXDBKPJ4JDF6+/oCwoBuhoL36R+Jp4RJH16u2IgaxJpHhMehsBY3wTjV2YbOuuumLHrwCW6msbSj74O/DHGgV4Ohl8Jw1nSMmsB+tL6Wnw83odzBrhEr2GtgvFE8A74ADxtJZZygMC25cjQqBwqdg62qpUlziUP45Cq6OGuqqoUE/FJ8i+v7MpJYvEsHl1A5gNty2vLmaN3bBLdAvqB3svqXxLRvyEuc9zs7SiA+ACpw05pJx8SoAAAAABJRU5ErkJggg=="
|
||||
webUI["html/img/x_white.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMToyNTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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 truncated
|
||||
webUI["html/img/xmltv.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQyMDowNzozMzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Co6j9bsAAAGgSURBVGgF7VqxTsNADL0gYGEon8DOwsbAAH8BYmJn6cYIn8DC3h0+oixISFRiYYCJL0AwMMBAeK5w2rpV6uikxHfYknW98+vds18TK21DWGBlWR7CH+BfcEv2AzLP8HP42gLqkyUATuEp2PWEdQjF9ATs1zF/g29Mrxt+vVcUxR3xWxEktzFPJQmivsv8ZSI9DiQyVnxlIonwn6fpiczXpNuVVXH8O+a3Ys3y9NUyuf/NTTbEHZTjUlGSRzSiPhroUIENwB4AS/vS/susDwDhTpYBER9g7wHh5DWyibV9CiitCZbIafDEYUuJHQI3Nr/9ciWsjK6IFSWYhyvClbAyZqOIlYJG84jq7E1Ot97Zm+TinV1TrWwudk9EI3ebGFekzWprzspGEU2ySWCiOrs/s9dr7M/s9fVJJJrNXcsTsfaJc0WsKZINH+/sf1Jqvl1n1f2ZnStRN/pdq646XcSkIh9dkIg4s+IrE3nCpp8RG7f91ns+cCYR/LD4jcAZB42PN+A7/mcQ8ZxJhBYQvMJwBB/BKTFLVoLMC/wCfgyv7BesTKUC2LKM3wAAAABJRU5ErkJggg=="
|
||||
webUI["html/js/authentication.js"] = "ZnVuY3Rpb24gY3JlYXRlRmlyc3RBY2NvdW50KGVsbSkgewogIHZhciBlcnIgPSBmYWxzZTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtKTsKICBjb25zb2xlLmxvZyhkaXYpOwoKICB2YXIgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoZW50aWNhdGlvbicpOwogIAogIGNvbnN0IHVzZXJuYW1lICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1c2VybmFtZScpOwogIGNvbnN0IHBhc3N3b3JkICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpOwogIGNvbnN0IGNvbmZpcm0gICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJyk7CgogIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ0lOUFVUJykKICBjb25zb2xlLmxvZyhjb25maXJtKTsKCiAgc3dpdGNoKGNvbmZpcm0pIHsKICAgIGNhc2UgbnVsbDogYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6IAogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChpbnB1dHNbaV0udmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICdyZWQnOwogICAgICAgICAgZXJyID0gdHJ1ZQogICAgICAgIH0KICAgICAgfQoKICAgICAgc3dpdGNoKGVycikgewogICAgICAgIGNhc2UgdHJ1ZTogcmV0dXJuOyBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOiAKICAgICAgICAgIGlmIChwYXNzd29yZC52YWx1ZSAhPSBjb25maXJtLnZhbHVlKSB7CiAgICAgICAgICAgIGNvbmZpcm0uc3R5bGUuYm9yZGVyQ29sb3IgPSAncmVkJzsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICB9CgoKICAKCiAgZm9ybS5zdWJtaXQoKTsKICByZXR1cm47Cn0="
|
||||
webUI["html/js/mapping-editor.js"] = "dmFyIG1hcHBpbmdFcnJvciAgPSBmYWxzZTsKdmFyIGJ1bGsgICAgICAgICAgPSBmYWxzZTsKdmFyIGJ1bGtFZGl0QWxsICAgPSBmYWxzZTsgCnZhciBzZWxlY3RPYmogICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc2VhcmNoT2JqICAgICA9IG5ldyBPYmplY3QoKTsKCnZhciBidWxrSURzICAgICAgID0gbmV3IEFycmF5KCk7CnZhciBidWxrQ2hhbmdlT2JqID0gbmV3IE9iamVjdCgpOwoKZnVuY3Rpb24gY2hlY2tVbmRvKGtleSwgZWxtKSB7CiAgdmFyIHRtcCA9IG5ldyBPYmplY3QoKTsKICB0bXAgPSBlbG0KICBjb25zb2xlLmxvZygiLS0iKTsKICBpZiAodW5kby5oYXNPd25Qcm9wZXJ0eSgiZXBnTWFwcGluZyIpKSB7CiAgICB4RVBHWyJlcGdNYXBwaW5nIl0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHVuZG9bImVwZ01hcHBpbmciXSkpOzsKICB9IGVsc2UgewogICAgdW5kb1siZXBnTWFwcGluZyJdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlbG0pKTsKICB9Cn0KCi8vdmFyIHBsZXhDYXRlZ29yaWVzID0gbmV3IEFycmF5KCItIiwgIkFjdGlvbiBzcG9ydHMiLCAiQWN0aW9uIiwgIkFkdWx0cyBvbmx5IiwgIkFkdmVudHVyZSIsICJBZXJvYmljcyIsICJBbmltYWxzIiwgIkFuaW1hdGVkIiwgIkFuaW1lIiwgIkFudGhvbG9neSIsICJBcmNoZXJ5IiwgIkFydCIsICJBcnRzL2NyYWZ0cyIsICJBdWN0aW9uIiwgIkF1dG8gcmFjaW5nIiwgIkF1dG8iLCAiQXZpYXRpb24iLCAiQXdhcmRzIiwgIkJhbGxldCIsICJCYXNlYmFsbCIsICJCYXNrZXRiYWxsIiwgIkJpY3ljbGUgcmFjaW5nIiwgIkJpY3ljbGUiLCAiQmlsbGlhcmRzIiwgIkJpb2dyYXBoeSIsICJCb2F0IHJhY2luZyIsICJCb2F0IiwgIkJvd2xpbmciLCAiQm94aW5nIiwgIkJ1cy4vZmluYW5jaWFsIiwgIkNoaWxkcmVuIiwgIkNvbGxlY3RpYmxlcyIsICJDb21lZHkgZHJhbWEiLCAiQ29tZWR5IiwgIkNvbW11bml0eSIsICJDb21wdXRlcnMiLCAiQ29uc3VtZXIiLCAiQ29va2luZyIsICJDcmltZSBkcmFtYSIsICJDcmltZSIsICJEYW5jZSIsICJEYXJrIGNvbWVkeSIsICJEZWJhdGUiLCAiRGl2aW5nIiwgIkRvY3VkcmFtYSIsICJEb2N1bWVudGFyeSIsICJEcmFtYSIsICJFZHVjYXRpb25hbCIsICJFbnRlcnRhaW5tZW50IiwgIkVudmlyb25tZW50IiwgIkVxdWVzdHJpYW4iLCAiRXJvdGljIiwgIkV2ZW50IiwgIkZhbnRhc3kiLCAiRmFzaGlvbiIsICJGZWF0dXJlIEZpbG0iLCAiRmlzaGluZyIsICJGb290YmFsbCIsICJHYW1lIHNob3ciLCAiR2FtaW5nIiwgIkdheS9sZXNiaWFuIiwgIkdvbGYiLCAiSGFuZGJhbGwiLCAiSGVhbHRoIiwgIkhpc3RvcmljYWwgZHJhbWEiLCAiSGlzdG9yeSIsICJIb2NrZXkiLCAiSG9saWRheSIsICJIb21lIGltcHJvdmVtZW50IiwgIkhvcnJvciIsICJIb3JzZSIsICJIb3VzZS9nYXJkZW4iLCAiSG93LXRvIiwgIkludGVydmlldyIsICJJbnRsIHNvY2NlciIsICJMYXciLCAiTWFydGlhbCBhcnRzIiwgIk1lZGljYWwiLCAiTWlsaXRhcnkiLCAiTWluaXNlcmllcyIsICJNaXhlZCBtYXJ0aWFsIGFydHMiLCAiTW90b3JjeWNsZSByYWNpbmciLCAiTW90b3JjeWNsZSIsICJNb3RvcnNwb3J0cyIsICJNb3VudGFpbiBiaWtpbmciLCAiTXVzaWMiLCAiTXVzaWNhbCBjb21lZHkiLCAiTXVzaWNhbCIsICJNeXN0ZXJ5IiwgIk5hdHVyZSIsICJOZXdzIiwgIk5ld3NtYWdhemluZSIsICJPbHltcGljcyIsICJPcGVyYSIsICJPdXRkb29ycyIsICJQYXJhZGUiLCAiUGFyYW5vcm1hbCIsICJQYXJlbnRpbmciLCAiUGVyZm9ybWluZyBhcnRzIiwgIlBsYXlvZmYgc3BvcnRzIiwgIlBva2VyIiwgIlBvbGl0aWNzIiwgIlBybyB3cmVzdGxpbmciLCAiUHVibGljIGFmZmFpcnMiLCAiUmVhbGl0eSIsICJSZWxpZ2lvdXMiLCAiUm9kZW8iLCAiUm9sbGVyIGRlcmJ5IiwgIlJvbWFuY2UiLCAiUm9tYW50aWMgY29tZWR5IiwgIlJ1Z2J5IiwgIlJ1bm5pbmciLCAiU2FpbGluZyIsICJTY2llbmNlIGZpY3Rpb24iLCAiU2NpZW5jZSIsICJTZWxmIGltcHJvdmVtZW50IiwgIlNlcmllcyIsICJTaG9vdGluZyIsICJTaG9wcGluZyIsICJTaG9ydCBGaWxtIiwgIlNpdGNvbSIsICJTa2lpbmciLCAiU25vb2tlciIsICJTb2FwIiwgIlNvY2NlciIsICJTcGVjaWFsIiwgIlNwb3J0cyIsICJzcG9ydHMiLCAiU3BvcnRzIGV2ZW50IiwgIlNwb3J0cyBub24tZXZlbnQiLCAiU3BvcnRzIHRhbGsiLCAiU3RhbmR1cCIsICJTdXJmaW5nIiwgIlN1c3BlbnNlIiwgIlRWIE1vdmllIiwgIlRhbGsiLCAiVGVjaG5vbG9neSIsICJUZW5uaXMiLCAiVGhlYXRlciIsICJUaHJpbGxlciIsICJUcmFjay9maWVsZCIsICJUcmF2ZWwiLCAiVHJpYXRobG9uIiwgIlZhcmlldHkiLCAiVm9sbGV5YmFsbCIsICJXYXIiLCAiV2F0ZXJzcG9ydHMiLCAiV2VhdGhlciIsICJXZXN0ZXJuIiwgIldyZXN0bGluZyIsICJZYWNodCByYWNpbmciLCAibW92aWUiLCAic2VyaWVzIiwgInNwb3J0cyIsICJ0dnNob3ciKTsKdmFyIHBsZXhDYXRlZ29yaWVzVmFsdWVzID0gbmV3IEFycmF5KCItIiwgIktpZHMiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKdmFyIHBsZXhDYXRlZ29yaWVzT3B0aW9uID0gbmV3IEFycmF5KCItIiwgIktpZHMgKEVtYnkgb25seSkiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKCgpmdW5jdGlvbiBvcGVuTWFwcGluZ0VkaXRvcihlbG0pIHsKICB2YXIgY29sdW1uVG9Tb3J0ICA9IDEKCiAgY2hlY2tVbmRvKCJlcGdNYXBwaW5nIiwgeEVQR1siZXBnTWFwcGluZyJdKQoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiU2F2ZSI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAic2F2ZVhFUEcoKSI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiQnVsayBFZGl0IjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJidWxrRWRpdCgpIjsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiSU5QVVQiOwogIG5ld0VudHJ5WyJ0eXBlIl0gICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gICAgICAgPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSAgICAgICA9ICJTaG93IFhFUEciOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gICAgID0gInNob3dYRVBHKCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsLine truncated
|
||||
webUI["html/maintenance.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgPC9oZWFkPgoKICAgIDxib2R5IGNsYXNzPSJhdXRoLXNjcmVlbiI+CiAgICAgICAgICAKICAgICAgPGRpdiBpZD0iaGVhZGVyIiBjbGFzcz0iaW1nQ2VudGVyIj48L2Rpdj4KCiAgICAgIDxkaXYgaWQ9ImJveCI+CgogICAgICAgIDxkaXYgaWQ9ImhlYWRsaW5lIj4KICAgICAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj5NYWludGVuYW5jZTwvaDE+ICAgICAgCiAgICAgICAgPC9kaXY+ICAKCiAgICAgICAgPGRpdiBpZD0iY29udGVudCI+CiAgICAgICAgICB4VGVWZSBpcyB1cGRhdGluZyB0aGUgZGF0YWJhc2UsIHBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuCiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgaWQ9ImJveC1mb290ZXIiPjwvZGl2PgogICAgICAgIAogICAgICA8L2Rpdj4KCiAgICA8L2JvZHk+CjwvaHRtbD4K"
|
||||
webUI["html/img/filter.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzo2OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cs038OQAAAOISURBVGgF5ZpLSBVRGMfvvfmqCKKiKCqKtE3SQ8haJJm1ctPCZYHrFhXtohcUBLVsU1BRBJKLXpsSKs1aCL1oUUhvMgIloodZKmLZ72+OzNVx7jzOXGfqg/89Z875zv/7f35n7px7vanUP2JptzyGhoYKmK8GW0EZmA/mgW7wHrwDN0BTOp0epPVtxBBnLdgIVoE5YBboBR2gDTTA/5DWn0FeDPaBz8CLdeF0EBR5jYRvKbgABoAXa8Opwit/CudK8NoLs4PPM8ZyBsNnB/jpsD7X0C8cjgDXnaQkqkEPCGMSuGWivxxzx8OQj6xtpHWuPhPloHfEMWzTD0HN2GQY2xuW2Lb+/Fh+VaIQPLE5meh+gmSxFYz+BjBogtjGscfiH26Z2GmbNNltVQAIpwDdP6ZNO2iRYqTpZGhfgWUaiMC2w1kCzkbALcqLvDVvUyK6MW9HFES0b8BvsFwXEZi4F+iBtykCcjtlqf0igr52VJ1eqiIgzzdlrRIZfWfJd3SD8ZbqHvkB4XSDpJNB9V0VcX/cT4Ys/zEzSuSj/3WxW9GpRD7ETpZ/QcOJ6LyfdHugitxNehbob9G7lo4PXWBmQhPqQ/fsDOeUfjqNCU1Csi+TQ5+2luzc3yaRr6elevQZwhZr4bomYam0U41yabYqov5hvSTMjlp6RyuiAarSTLPZmox5246+lVREx/isiuh6NxhUJwF2yEpCWu1bK8WEsjyRgCSa0XrVrjNra2mC7TWD5ilYAuJoA4jSlnppF5dVEU3g0ENTD4b3nsZiZsfGJuGqj8qY+CINGqP2GLZCJ+HjtpblxAJ9k3cPrLfGJrnVUaSCarxw0jFua1lOLNBerANx+byya6IkLM2uLZWpAl6/Mcc1EjvjKtLrJNLqI5HnjfQ+bsVeteb0g2y/t7hGvd7CNjenOL8OkJ40KtOdTF+Cl/nV6Mkf4gxocI9vZPYLLKs9iQrqRIACcM2IXGeSboYrg+rztY5ARaDJWUeo0W+sXudLTFhnApaAW6FkZy/+yuXasLoCrSfwVHAnW0+gK93YawKJMLUIAdNAKwhqnSxcYUpPKB6EBE2mg7VR///EX24jybTQerXnOC70FyVP3gjTPXPTQyaP8NFPNeJrCNTPP667JKOq6VNo/A2hes5ccUjmEmPmDoD5+FMgWCcA+3FG57QJP//kQ1PgGBIOToEDgUn+t4V/AJeGknwARIKLAAAAAElFTkSuQmCC"
|
||||
webUI["html/img/logo_b_880x200.jpg"] = "/9j/4AAQSkZJRgABAQABLAEsAAD/4QDIRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAPAAAAcgEyAAIAAAAUAAAAgodpAAQAAAABAAAAlgAAAAAAAAEsAAAAAQAAASwAAAABUGl4ZWxtYXRvciAzLjMAADIwMTk6MDg6MDIgMjA6MDg6MTQAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAA3CgAwAEAAAAAQAAAMgAAAAA/+EJkGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iUGl4ZWxtYXRvciAzLjMiIHhtcDpNb2RpZnlEYXRlPSIyMDE5LTA4LTAyVDIwOjA4OjE0Ii8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAyANwAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/dAAQAbv/aAAwDAQACEQMRAD8A/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9D+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgALine truncated
|
||||
webUI["html/img/logo_w_600x200.png"] = "iVBORw0KGgoAAAANSUhEUgAAAlgAAADICAYAAAA0n5+2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAuIwAALiMBeKU/dgAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MzAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjAwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAg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 truncated
|
||||
webUI["html/js/settings_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIFNldHRpbmdzQ2F0ZWdvcnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBTZXR0aW5nc0NhdGVnb3J5KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJjb250ZW50X3NldHRpbmdzIjsKICAgIH0KICAgIFNldHRpbmdzQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkg0Iik7CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICBTZXR0aW5nc0NhdGVnb3J5LnByb3RvdHlwZS5jcmVhdGVIUiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkhSIik7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgU2V0dGluZ3NDYXRlZ29yeS5wcm90b3R5cGUuY3JlYXRlU2V0dGluZ3MgPSBmdW5jdGlvbiAoc2V0dGluZ3NLZXkpIHsKICAgICAgICB2YXIgc2V0dGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgdmFyIGNvbnRlbnQgPSBuZXcgUG9wdXBDb250ZW50KCk7CiAgICAgICAgdmFyIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bc2V0dGluZ3NLZXldOwogICAgICAgIHN3aXRjaCAoc2V0dGluZ3NLZXkpIHsKICAgICAgICAgICAgLy8gVGV4dGVpbmdhYmVuCiAgICAgICAgICAgIGNhc2UgInVwZGF0ZSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudXBkYXRlLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ1cGRhdGUiLCBkYXRhLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy51cGRhdGUucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJhY2t1cC5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5iYWNrdXBQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJiYWNrdXAucGF0aCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy5iYWNrdXBQYXRoLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ0ZW1wLnBhdGgiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnRlbXBQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ0ZW1wLnBhdGgiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudG1wUGF0aC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidXNlci5hZ2VudCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudXNlckFnZW50LnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ1c2VyLmFnZW50IiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnVzZXJBZ2VudC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRLine truncated
|
||||
webUI["html/lang/en.json"] = "ewogICJtYWluTWVudSI6CiAgewogICAgIml0ZW0iOgogICAgewogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAicG1zSUQiOiAiUE1TIElEIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIiLAogICAgICAieG1sdHYiOiAiWE1MVFYiLAogICAgICAibWFwcGluZyI6ICJNYXBwaW5nIiwKICAgICAgInVzZXJzIjogIlVzZXJzIiwKICAgICAgInNldHRpbmdzIjogIlNldHRpbmdzIiwKICAgICAgImxvZyI6ICJMb2ciLAogICAgICAibG9nb3V0IjogIkxvZ291dCIKICAgIH0sCiAgICAiaGVhZGxpbmUiOgogICAgewogICAgICAicGxheWxpc3QiOiAiTG9jYWwgb3IgcmVtb3RlIHBsYXlsaXN0cyIsCiAgICAgICJmaWx0ZXIiOiAiRmlsdGVyIHBsYXlsaXN0IiwKICAgICAgInhtbHR2IjogIkxvY2FsIG9yIHJlbW90ZSBYTUxUViBmaWxlcyIsCiAgICAgICJtYXBwaW5nIjogIk1hcCBwbGF5bGlzdCBjaGFubmVscyB0byBFUEcgY2hhbm5lbHMiLAogICAgICAidXNlcnMiOiAiVXNlciBtYW5hZ2VtZW50IiwKICAgICAgInNldHRpbmdzIjogIlNldHRpbmdzIiwKICAgICAgImxvZyI6ICJMb2ciLAogICAgICAibG9nb3V0IjogIkxvZ291dCIKICAgIH0KICB9LAogICJjb25maXJtIjoKICB7CiAgICAicmVzdG9yZSI6ICJBbGwgZGF0YSB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhvc2UgZnJvbSB0aGUgYmFja3VwLiBTaG91bGQgdGhlIGZpbGVzIGJlIHJlc3RvcmVkPyIKICB9LAogICJhbGVydCI6CiAgewogICAgImZpbGVMb2FkaW5nRXJyb3IiOiAiRmlsZSBjb3VsZG4ndCBiZSBsb2FkZWQiLAogICAgImludmFsaWRDaGFubmVsTnVtYmVyIjogIkludmFsaWQgY2hhbm5lbCBudW1iZXIiLAogICAgIm1pc3NpbmdJbnB1dCI6ICJNaXNzaW5nIGlucHV0IgogIH0sCiAgImJ1dHRvbiI6CiAgewogICAgImJhY2siOiAiQmFjayIsCiAgICAiYmFja3VwIjogIkJhY2t1cCIsCiAgICAiYnVsa0VkaXQiOiAiQnVsayBFZGl0IiwKICAgICJjYW5jZWwiOiAiQ2FuY2VsIiwKICAgICJlZGl0IjogIkVkaXQiLAogICAgImRlbGV0ZSI6ICJEZWxldGUiLAogICAgImRvbmUiOiAiRG9uZSIsCiAgICAibG9naW4iOiAiTG9naW4iLAogICAgIm5ldyI6ICJOZXciLAogICAgIm5leHQiOiAiTmV4dCIsCiAgICAicmVzdG9yZSI6ICJSZXN0b3JlIiwKICAgICJzYXZlIjogIlNhdmUiLAogICAgInNlYXJjaCI6ICJTZWFyY2giLAogICAgInVwZGF0ZSI6ICJVcGRhdGUiLAogICAgImNyYWV0ZUFjY291bnQiOiAiQ3JlYXRlIEFjY291bnQiLAogICAgInJlc2V0TG9ncyI6ICJSZXNldCBMb2dzIiwKICAgICJ1cGxvYWRMb2dvIjogIlVwbG9hZCBMb2dvIgogIH0sCiAgImZpbHRlciI6CiAgewogICAgInRhYmxlIjoKICAgIHsKICAgICAgIm5hbWUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAidHlwZSI6ICJGaWx0ZXIgVHlwZSIsCiAgICAgICJmaWx0ZXIiOiAiRmlsdGVyIgogICAgfSwKICAgICJjdXN0b20iOiAiQ3VzdG9tIiwKICAgICJncm91cCI6ICJHcm91cCIsCiAgICAibmFtZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJGaWx0ZXIgTmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWx0ZXIgbmFtZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImRlc2NyaXB0aW9uIjoKICAgIHsKICAgICAgInRpdGxlIjogIkRlc2NyaXB0aW9uIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkRlc2NyaXB0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidHlwZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJUeXBlIiwKICAgICAgImdyb3VwVGl0bGUiOiAiR3JvdXAgVGl0bGUiLAogICAgICAiY3VzdG9tRmlsdGVyIjogIkN1c3RvbSBGaWx0ZXIiCiAgICB9LAogICAgImNhc2VTZW5zaXRpdmUiOgogICAgewogICAgICAidGl0bGUiOiAiQ2FzZSBTZW5zaXRpdmUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsdGVyUnVsZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJGaWx0ZXIgUnVsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJTcG9ydCB7SER9ICF7RVMsSVR9IiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsdGVyR3JvdXAiOgogICAgewogICAgICAidGl0bGUiOiAiR3JvdXAgVGl0bGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlNlbGVjdCBhIE0zVSBncm91cC4gKENvdW50ZXIpPGJyPkNoYW5naW5nIHRoZSBncm91cCB0aXRsZSBpbiB0aGUgTTNVIGludmFsaWRhdGVzIHRoZSBmaWx0ZXIuIgogICAgfSwKICAgICJpbmNsdWRlIjoKICAgIHsKICAgICAgInRpdGxlIjogIkluY2x1ZGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRkhELFVIRCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFubmVsIG5hbWUgbXVzdCBpbmNsdWRlLjxicj4oQ29tbWEgc2VwYXJhdGVkKSBDb21tYSBtZWFucyBvciIKICAgIH0sCiAgICAiZXhjbHVkZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJFeGNsdWRlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkVTLElUIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkNoYW5uZWwgbmFtZSBtdXN0IG5vdCBjb250YWluLjxicj4oQ29tbWEgc2VwYXJhdGVkKSBDb21tYSBtZWFucyBvciIKICAgIH0KCiAgfSwKICAicGxheWxpc3QiOgogIHsKICAgICJ0YWJsZSI6CiAgICB7CiAgICAgICJwbGF5bGlzdCI6ICJQbGF5bGlzdCIsCiAgICAgICJ0dW5lciI6ICJUdW5lciIsCiAgICAgICJsYXN0VXBkYXRlIjogIkxhc3QgVXBkYXRlIiwKICAgICAgImF2YWlsYWJpbGl0eSI6ICJBdmFpbGFiaWxpdHkiLAogICAgICAidHlwZSI6ICJUeXBlIiwKICAgICAgInN0cmVhbXMiOiAiU3RyZWFtcyIsCiAgICAgICJncm91cFRpdGxlIjogImdyb3VwLXRpdGxlIiwKICAgICAgInR2Z0lEIjogInR2Zy1pZCIsCiAgICAgICJ1bmlxdWVJRCI6ICJVbmlxdWUgSUQiCiAgICB9LAogICAgInBsYXlsaXN0VHlwZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJQbGF5bGlzdCB0eXBlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR5cGUiOgogICAgewogICAgICAidGl0bGUiOiAiVHlwZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJuYW1lIjoKICAgIHsKICAgICAgInRpdGxlIjogIk5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiUGxheWxpc3QgbmFtZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImRlc2NyaXB0aW9uIjoKICAgIHsKICAgICAgInRpdGxlIjogIkRlc2NyaXB0aW9uIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkRlc2NyaXB0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsZU0zVSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJNM1UgRmlsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWxlIHBhdGggb3IgVVJMIG9mIHRoZSBNM1UiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWxlSERIUiI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJIREhvbWVSdW4gSVAiLAogICAgICAicGxhY2Vob2xkZXIiOiAiSVAgYWRkcmVzcyBhbmQgcG9ydCAoMTkyLjE2OC4xLjEwOjUwMDQpIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidHVuZXIiOgogICAgewogICAgICAidGl0bGUiOiAiVHVuLine truncated
|
||||
webUI["html/login.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keSBjbGFzcz0iYXV0aC1zY3JlZW4iPgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImhlYWRlciIgY2xhc3M9ImltZ0NlbnRlciI+PC9kaXY+CgogICAgICA8bWFpbiBpZD0iYm94IiByb2xlPSJtYWluIiBhcmlhLWxhYmVsbGVkYnk9ImhlYWQtdGV4dCI+CgogICAgICAgIDxkaXYgaWQ9ImhlYWRsaW5lIj4KICAgICAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj57ey5sb2dpbi5oZWFkbGluZX19PC9oMT4KICAgICAgICA8L2Rpdj4KCiAgICAgICAgPHAgaWQ9ImVyciIgY2xhc3M9ImVycm9yTXNnIGNlbnRlciIgcm9sZT0iYWxlcnQiIGFyaWEtbGl2ZT0iYXNzZXJ0aXZlIiBhcmlhLWF0b21pYz0idHJ1ZSI+e3suYXV0aGVudGljYXRpb25FcnJ9fTwvcD4KCiAgICAgICAgPGRpdiBpZD0iY29udGVudCI+CgogICAgICAgICAgICA8Zm9ybSBpZD0iYXV0aGVudGljYXRpb24iIGFjdGlvbj0iIiBtZXRob2Q9InBvc3QiIGFyaWEtZGVzY3JpYmVkYnk9ImVyciIgbm92YWxpZGF0ZT4KCiAgICAgICAgICAgICAgPGxhYmVsIGZvcj0idXNlcm5hbWUiPnt7LmxvZ2luLnVzZXJuYW1lLnRpdGxlfX06PC9sYWJlbD4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9InVzZXJuYW1lIiB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VybmFtZSIgcGxhY2Vob2xkZXI9IlVzZXJuYW1lIiB2YWx1ZT0iIiBhdXRvY29tcGxldGU9InVzZXJuYW1lIj4KICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJwYXNzd29yZCI+e3subG9naW4ucGFzc3dvcmQudGl0bGV9fTo8L2xhYmVsPgogICAgICAgICAgICAgIDxpbnB1dCBpZD0icGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJwYXNzd29yZCIgcGxhY2Vob2xkZXI9IlBhc3N3b3JkIiB2YWx1ZT0iIiBhdXRvY29tcGxldGU9ImN1cnJlbnQtcGFzc3dvcmQiPgoKICAgICAgICAgICAgPC9mb3JtPgoKICAgICAgICA8L2Rpdj4KCiAgICAgICAgPGRpdiBpZD0iYm94LWZvb3RlciI+CiAgICAgICAgICA8aW5wdXQgaWQ9InN1Ym1pdCIgY2xhc3M9IiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0ie3suYnV0dG9uLmxvZ2lufX0iIGFyaWEtbGFiZWw9Int7LmJ1dHRvbi5sb2dpbn19IiBvbmNsaWNrPSJqYXZhc2NyaXB0OiBsb2dpbigpOyI+CiAgICAgICAgPC9kaXY+CiAgICAgICAgCiAgICAgIDwvbWFpbj4KCiAgICA8L2JvZHk+CiAgICAKPC9odG1sPgo="
|
||||
webUI["html/css/base.css"] = "OnJvb3QgewogIC0tYmctMDogIzA3MTExZDsKICAtLWJnLTE6ICMwYzFhMmI7CiAgLS1iZy0yOiAjMTIyMzNhOwogIC0tcGFuZWw6ICMxMDIyMzg7CiAgLS1wYW5lbC1zb2Z0OiAjMGYxZjMzOwogIC0tbGluZTogIzI3NDQ2MjsKICAtLWxpbmUtc29mdDogIzFiMzM0ZDsKICAtLXRleHQ6ICNlOWY1ZmY7CiAgLS10ZXh0LW11dGVkOiAjYjdjZWUxOwogIC0tYWNjZW50OiAjMzVkMmZmOwogIC0tYWNjZW50LXN0cm9uZzogIzEyYjlmZjsKICAtLWFjY2VudC1zb2Z0OiByZ2JhKDUzLCAyMTAsIDI1NSwgMC4yKTsKICAtLW9rOiAjMmZkMThhOwogIC0td2FybjogI2ZmYzE1YTsKICAtLWVycm9yOiAjZmY2ZjZmOwogIC0tcmFkaXVzLXM6IDEwcHg7CiAgLS1yYWRpdXMtbTogMTRweDsKICAtLXJhZGl1cy1sOiAxOHB4OwogIC0tc2hhZG93LTE6IDAgMjBweCA0NXB4IHJnYmEoMCwgMCwgMCwgMC4zMik7CiAgLS1zaGFkb3ctMjogMCAxMnB4IDMwcHggcmdiYSgwLCAwLCAwLCAwLjI4KTsKfQoKKiB7CiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lOwogIC1tb3otYXBwZWFyYW5jZTogbm9uZTsKICAtbXMtYXBwZWFyYW5jZTogbm9uZTsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIGZvbnQtZmFtaWx5OiAiU3BhY2UgR3JvdGVzayIsICJBdmVuaXIgTmV4dCIsICJUcmVidWNoZXQgTVMiLCBzYW5zLXNlcmlmOwogIGxldHRlci1zcGFjaW5nOiAwLjAyZW07Cn0KCjo6LXdlYmtpdC1zY3JvbGxiYXIgewogIHdpZHRoOiAxMXB4OwogIGhlaWdodDogMTFweDsKfQoKOjotd2Via2l0LXNjcm9sbGJhci10cmFjayB7CiAgYm9yZGVyLXJhZGl1czogOTk5cHg7CiAgYmFja2dyb3VuZDogcmdiYSg3LCAxNywgMjksIDAuNjUpOwp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHsKICBib3JkZXItcmFkaXVzOiA5OTlweDsKICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDcsIDE3LCAyOSwgMC42KTsKICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCAjMmQ1OTdmLCAjMWU0MDYwKTsKfQoKOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7CiAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDE4MGRlZywgIzM2NzhhYywgIzIwNTM3Yyk7Cn0KCjo6LXdlYmtpdC1zY3JvbGxiYXItY29ybmVyIHsKICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsKfQoKaHRtbCwKYm9keSB7CiAgbWluLWhlaWdodDogMTAwJTsKICBtYXJnaW46IDA7CiAgY29sb3I6IHZhcigtLXRleHQpOwogIGZvbnQtc2l6ZTogMTRweDsKICBiYWNrZ3JvdW5kOgogICAgcmFkaWFsLWdyYWRpZW50KGNpcmNsZSBhdCAxNSUgMTIlLCByZ2JhKDY0LCAxMzIsIDE4MywgMC4yMiksIHRyYW5zcGFyZW50IDMyJSksCiAgICByYWRpYWwtZ3JhZGllbnQoY2lyY2xlIGF0IDg4JSAyJSwgcmdiYSgxOCwgMTg1LCAyNTUsIDAuMTYpLCB0cmFuc3BhcmVudCAzMCUpLAogICAgbGluZWFyLWdyYWRpZW50KDE4MGRlZywgdmFyKC0tYmctMSkgMCUsIHZhcigtLWJnLTApIDU2JSwgIzA2MGQxNyAxMDAlKTsKfQoKYm9keSB7CiAgbGluZS1oZWlnaHQ6IDEuNDU7Cn0KCmEgewogIGNvbG9yOiB2YXIoLS1hY2NlbnQpOwp9CgphOmhvdmVyIHsKICBjb2xvcjogIzhkZTdmZjsKfQoKaDEsCmgyLApoMywKaDQsCmg1IHsKICBtYXJnaW46IDA7CiAgZm9udC13ZWlnaHQ6IDYwMDsKICBsZXR0ZXItc3BhY2luZzogMC4wM2VtOwp9CgpoMSB7CiAgZm9udC1zaXplOiAxLjcycmVtOwp9CgpoMiB7CiAgZm9udC1zaXplOiAxLjM1cmVtOwp9CgpoMyB7CiAgZm9udC1zaXplOiAxLjJyZW07Cn0KCmg0IHsKICBmb250LXNpemU6IDEuMDVyZW07Cn0KCmg1IHsKICBmb250LXNpemU6IDAuOTJyZW07CiAgbWFyZ2luOiA4cHggMDsKICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7Cn0KCnAgewogIG1hcmdpbjogMDsKICBwYWRkaW5nOiAwOwp9CgpwcmUgewogIG1hcmdpbjogMDsKICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7CiAgZm9udC1zaXplOiAxMnB4OwogIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsKICBsaW5lLWhlaWdodDogMS41NTsKICBsZXR0ZXItc3BhY2luZzogMC4wMTVlbTsKICBmb250LWZhbWlseTogIklCTSBQbGV4IE1vbm8iLCAiU0ZNb25vLVJlZ3VsYXIiLCAiQ29uc29sYXMiLCBtb25vc3BhY2U7Cn0KCmhyIHsKICBib3JkZXI6IDA7CiAgaGVpZ2h0OiAxcHg7CiAgbWFyZ2luOiAxMnB4IDA7CiAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCB0cmFuc3BhcmVudCwgdmFyKC0tbGluZSksIHRyYW5zcGFyZW50KTsKfQoKbGFiZWwgewogIG1hcmdpbi1ib3R0b206IDhweDsKICBkaXNwbGF5OiBibG9jazsKfQoKbGkgewogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTsKICBjdXJzb3I6IHBvaW50ZXI7CiAgdHJhbnNpdGlvbjogYWxsIDAuMjVzIGVhc2U7Cn0KCnNlbGVjdCwKaW5wdXQsCnRleHRhcmVhLApidXR0b24gewogIG91dGxpbmU6IG5vbmU7CiAgY29sb3I6IHZhcigtLXRleHQpOwogIGZvbnQtc2l6ZTogMTNweDsKfQoKOmZvY3VzLXZpc2libGUgewogIG91dGxpbmU6IDJweCBzb2xpZCAjOTFlYWZmOwogIG91dGxpbmUtb2Zmc2V0OiAycHg7Cn0KCmlucHV0LApzZWxlY3QgewogIG1hcmdpbjogNHB4IDA7Cn0KCmlucHV0W3R5cGU9dGV4dF0sCmlucHV0W3R5cGU9c2VhcmNoXSwKaW5wdXRbdHlwZT1wYXNzd29yZF0sCmlucHV0W3R5cGU9bnVtYmVyXSwKc2VsZWN0LAp0ZXh0YXJlYSB7CiAgd2lkdGg6IDEwMCU7CiAgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLXMpOwogIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWxpbmUpOwogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTAsIDIyLCAzNiwgMC43OCk7CiAgY29sb3I6IHZhcigtLXRleHQpOwogIHBhZGRpbmc6IDEwcHggMTFweDsKICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgMC4ycyBlYXNlLCBib3gtc2hhZG93IDAuMnMgZWFzZSwgYmFja2dyb3VuZC1jb2xvciAwLjJzIGVhc2U7Cn0KCmlucHV0W3R5cGU9dGV4dF06Zm9jdXMsCmlucHV0W3R5cGU9c2VhcmNoXTpmb2N1cywKaW5wdXRbdHlwZT1wYXNzd29yZF06Zm9jdXMsCmlucHV0W3R5cGU9bnVtYmVyXTpmb2N1cywKc2VsZWN0OmZvY3VzLAp0ZXh0YXJlYTpmb2N1cyB7CiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1hY2NlbnQpOwogIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDUzLCAyMTAsIDI1NSwgMC4xNyk7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg5LCAyNSwgNDAsIDAuOTUpOwp9CgppbnB1dFt0eXBlPXRleHRdOjpwbGFjZWhvbGRlciwKaW5wdXRbdHlwZT1zZWFyY2hdOjpwbGFjZWhvbGRlciwKaW5wdXRbdHlwZT1wYXNzd29yZF06OnBsYWNlaG9sZGVyLAp0ZXh0YXJlYTo6cGxhY2Vob2xkZXIgewogIGNvbG9yOiAjN2U5YWI0Owp9CgppbnB1dFt0eXBlPWJ1dHRvbl0sCmlucHV0W3R5cGU9c3VibWl0XSwKYnV0dG9uIHsKICBjdXJzb3I6IHBvaW50ZXI7CiAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7CiAgYm9yZGVyLXJhZGl1czogOTk5cHg7CiAgY29sb3I6ICMwMzEwMWE7CiAgcGFkZGluZzogMTBweCAxOHB4OwogIG1hcmdpbjogOHB4IDhweCA4cHggMDsKICBmb250LXdlaWdodDogNzAwOwogIGxldHRlci1zcGFjaW5nOiAwLjAzZW07CiAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzY3ZThmZiAwJSwgIzEyYjlmZiAxMDAlKTsKICBib3gtc2hhZG93OiAwIDEwcHggMjJweCByZ2JhKDE4LCAxODUsIDI1NSwgMC4zKTsKICB0cmFuc2l0Line truncated
|
||||
webUI["html/img/users.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0zMFQxNzowODozODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CjU01MMAAANJSURBVGgF1ZnLaxNRFMYz2rpoFbW+SCsihaJQRMT6rPhAXAq6c+HChSguRFd1oRtd+A/oWhQ3oiiWFB91UbqRqlXXgoIIQhFbQTTQao2/GzLDZEjIPefO7SQHPjJz55zzfd/MZCa5N8h5ilKptJvWp8FekAed4Bv4Cj6Dh2A4CIJZPpszMHEV2MQ0SZdB0DROENMHjoEzQBoFCpZnbgYR58E/qfpE/kv2F2dmBvJ94G9ClHb3SiZGUBuASa3qGnVzjG3RmFmkKYrVHGB7e2zfdbOdBhc1TVyNnNSQNqg5wVURf/FdjRxpIEpzuIOio9JCtRHO2hrINkgJLfPFt6vaCII2WYrSpPVJi1RGuBrmTbxeSibIX5j3CUauAfOo9BXzNH4nMJ5TXREI1gHzqPQVRtc2zCyxJdAaGbclcMj7zi/jOdt6rZFhCH7akijznknqVEY4U78heSAhUuTekNSojFQIChIiYe57TtZrSY2LkecQzUjIBLljglz3VJ4qg+AXSDNGabbWXZ2wA6Qjabqg136hhHK6y60V8o2EGyl8/qHHpKZPGkYeQzyvIa9RM86XvFhjvOGQsxGIp2B50ZDJLuG2XZqnLO5rM3viGh9o0OZJon1bRLxxdHLcns1jJiYOAu2U0D2P0uStMXJdcVU+UdMlZ/NYgaA28ERg5ge5/R4l6VsjrANMWJiZJWeXnqm60vnxW90ul6u8ByaS4zX2i+S+qjGuGkrdSEWFzT1vlhlSC19Gui0UtnNriSfi6vX1ZWRjPcLEeGrzYqkb4SyvQGxvQnC93cF6BzIfx8gpYBsfSdycuei4AAR1ggugCCRh1lbugIF4vwXbhtisjfSDc+ARSOOf4lv6mNWv1VIj1ouQNF9K851gDzArtWbV1uYxS5o4zB+sp+AuKPC+cVv5RXwPuATMmUpreY1Wopgh+ybYKj4dFHWB+8DMwTZTjCHmsJUhEgfAF9DMcQtx9V8dHMyDqWZ2ENM2FL8yVV92kkY56GM5Lc6Z1vY0jbp5EJQnuqPLg4kdLWTCnIxVIJoDi4wweNYcbbGIfuLEjRxqMRNGbvTvsmyE22oZg70taKQn1BxekXw40GKfK0O9oZHsJ8ZCRbLPaI3xP7YzeQoHxWckAAAAAElFTkSuQmCC"
|
||||
webUI["html/js/authentication_ts.js"] = "ZnVuY3Rpb24gbG9naW4oKSB7CiAgICB2YXIgZXJyID0gZmFsc2U7CiAgICB2YXIgZmlyc3RJbnZhbGlkID0gbnVsbDsKICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50Iik7CiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJhdXRoZW50aWNhdGlvbiIpOwogICAgdmFyIGVyckVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZXJyIik7CiAgICBpZiAoZXJyRWxlbWVudCAhPSBudWxsKSB7CiAgICAgICAgZXJyRWxlbWVudC5pbm5lckhUTUwgPSAiIjsKICAgIH0KICAgIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIik7CiAgICBjb25zb2xlLmxvZyhpbnB1dHMpOwogICAgZm9yICh2YXIgaSA9IGlucHV0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICAgIHZhciBrZXkgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICB2YXIgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICJyZWQiOwogICAgICAgICAgICBpbnB1dHNbaV0uc2V0QXR0cmlidXRlKCJhcmlhLWludmFsaWQiLCAidHJ1ZSIpOwogICAgICAgICAgICBpZiAoZmlyc3RJbnZhbGlkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGZpcnN0SW52YWxpZCA9IGlucHV0c1tpXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlcnIgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaW5wdXRzW2ldLnN0eWxlLmJvcmRlckNvbG9yID0gIiI7CiAgICAgICAgICAgIGlucHV0c1tpXS5zZXRBdHRyaWJ1dGUoImFyaWEtaW52YWxpZCIsICJmYWxzZSIpOwogICAgICAgIH0KICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTsKICAgIH0KICAgIGlmIChlcnIgPT0gdHJ1ZSkgewogICAgICAgIGlmIChmaXJzdEludmFsaWQgIT0gbnVsbCkgewogICAgICAgICAgICBmaXJzdEludmFsaWQuZm9jdXMoKTsKICAgICAgICB9CiAgICAgICAgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoZGF0YS5oYXNPd25Qcm9wZXJ0eSgiY29uZmlybSIpKSB7CiAgICAgICAgaWYgKGRhdGFbImNvbmZpcm0iXSAhPSBkYXRhWyJwYXNzd29yZCJdKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpLnN0eWxlLmJvcmRlckNvbG9yID0gInJlZCI7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJykuc3R5bGUuYm9yZGVyQ29sb3IgPSAicmVkIjsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3N3b3JkJykuc2V0QXR0cmlidXRlKCJhcmlhLWludmFsaWQiLCAidHJ1ZSIpOwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29uZmlybScpLnNldEF0dHJpYnV0ZSgiYXJpYS1pbnZhbGlkIiwgInRydWUiKTsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImVyciIpLmlubmVySFRNTCA9ICJ7ey5hY2NvdW50LmZhaWxlZH19IjsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3N3b3JkJykuZm9jdXMoKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIGNvbnNvbGUubG9nKGRhdGEpOwogICAgZm9ybS5zdWJtaXQoKTsKfQpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZnVuY3Rpb24gKCkgewogICAgdmFyIGZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYXV0aGVudGljYXRpb24iKTsKICAgIGlmIChmb3JtID09IG51bGwpIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB2YXIgaW5wdXRzID0gZm9ybS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaW5wdXRzW2ldLmFkZEV2ZW50TGlzdGVuZXIoImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgaWYgKGV2ZW50LmtleSA9PSAiRW50ZXIiKSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgbG9naW4oKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQogICAgaWYgKGlucHV0cy5sZW5ndGggPiAwKSB7CiAgICAgICAgaW5wdXRzWzBdLmZvY3VzKCk7CiAgICB9Cn0pOwo="
|
||||
webUI["html/js/classes_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBNYWluTWVudSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIE1haW5NZW51KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJtYWluLW1lbnUiOwogICAgICAgIHRoaXMuSFRNTFRhZyA9ICJMSSI7CiAgICB9CiAgICBNYWluTWVudS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgIGNvbnNvbGUubG9nKHRoaXMuRG9jdW1lbnRJRCk7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51Owp9KCkpOwp2YXIgTWFpbk1lbnVJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKE1haW5NZW51SXRlbSwgX3N1cGVyKTsKICAgIGZ1bmN0aW9uIE1haW5NZW51SXRlbSgpIHsKICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7CiAgICB9CiAgICBNYWluTWVudUl0ZW0ucHJvdG90eXBlLmNyZWF0ZTIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuSFRNTFRhZyk7CiAgICAgICAgZWxlbWVudC5pbm5lclRleHQgPSB0aGlzLlZhbHVlOwogICAgICAgIGNvbnNvbGUubG9nKGVsZW1lbnQpOwogICAgfTsKICAgIHJldHVybiBNYWluTWVudUl0ZW07Cn0oTWFpbk1lbnUpKTsKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogICAgdmFyIGl0ZW0gPSBuZXcgTWFpbk1lbnVJdGVtKCk7CiAgICBpdGVtLlZhbHVlID0gIlRlc3QiOwogICAgaXRlbS5jcmVhdGUyKCk7Cn0K"
|
||||
webUI["html/js/configuaration.js"] = "dmFyIGNvbmZpZ01lbnUgPSBuZXcgT2JqZWN0KCk7CnZhciB3aXphcmQgPSBuZXcgQXJyYXkoImtleSIsICJ0dW5lciIsICJlcGdTb3VyY2UiLCAibTN1IiwgImNvbXBsZXRlIik7CnZhciBhY3RpdmVXaXphcmQ7CnZhciBkdnJJUAoKdmFyIGNvbmZpZ01lbnVfdHVuZXIgPSBuZXcgT2JqZWN0KCk7CmNvbmZpZ01lbnVfdHVuZXJbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X3R1bmVyWyJfbWVudVR5cGUiXSAgICAgPSAic2luZ2xlSW5wdXQiOwpjb25maWdNZW51X3R1bmVyWyJfY29uZmlnS2V5Il0gICAgPSAidHVuZXIiOwpjb25maWdNZW51X3R1bmVyWyJfbGFiZWwiXSAgICAgICAgPSAiQXZhaWxhYmxlIHR1bmVycyI7CmNvbmZpZ01lbnVfdHVuZXJbIm5hbWUiXSAgICAgICAgICA9ICJ0dW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbImlkIl0gICAgICAgICAgICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbInBsYWNlaG9sZGVyIl0gICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbIl91c2FnZSJdICAgICAgICA9ICJUaGlzIHNldHRpbmcgaXMgb25seSB1c2VkIGJ5IFBsZXggYW5kIEVtYnkuPGJyPlRoZSBudW1iZXIgb2YgY29uY3VycmVudCBzdHJlYW1zIGFsbG93ZWQgYnkgdGhlIElQVFYgcHJvdmlkZXIuIgoKCnZhciBvcHRpb25WYWx1ZXMgPSBuZXcgQXJyYXkoKTsKZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICBvcHRpb25WYWx1ZXMucHVzaChpKQp9CmNvbmZpZ01lbnVfdHVuZXJbIl9vcHRpb25WYWx1ZXMiXSA9IG9wdGlvblZhbHVlczsKCnZhciBjb25maWdNZW51X2VwZyA9IG5ldyBPYmplY3QoKTsKY29uZmlnTWVudV9lcGdbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X2VwZ1siX21lbnVUeXBlIl0gICAgID0gInNpbmdsZUlucHV0IjsKY29uZmlnTWVudV9lcGdbIl9jb25maWdLZXkiXSAgICA9ICJlcGdTb3VyY2UiOwpjb25maWdNZW51X2VwZ1siX2xhYmVsIl0gICAgICAgID0gIlNlbGVjdGlvbiBvZiB0aGUgRVBHIHNvdXJjZSI7CmNvbmZpZ01lbnVfZXBnWyJuYW1lIl0gICAgICAgICAgPSAiZXBnU291cmNlIjsKY29uZmlnTWVudV9lcGdbImlkIl0gICAgICAgICAgICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbInBsYWNlaG9sZGVyIl0gICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbIl9vcHRpb25WYWx1ZXMiXSA9IG5ldyBBcnJheSgiUE1TIiwgIlhFUEciKTsKY29uZmlnTWVudV9lcGdbIl91c2FnZSJdICAgICAgICA9ICJQTVM6ICAgVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5PGJyPlhFUEc6ICBVc2Ugb2YgZXh0ZXJuYWwgRVBHIGRhdGEgKFhNTFRWKTxicj4gICAgICAgU2V2ZXJhbCBYTUxUViBzb3VyY2VzIHBvc3NpYmxlPGJyPiAgICAgICBBbGxvd3MgZWRpdGluZyBhbmQgb3JkZXIgY2hhbm5lbHM8YnI+ICAgICAgIE0zVSAvIFhNTFRWIGV4cG9ydCAoSFRUUCBsaW5rIGZvciBJUFRWIGFwcHMpIgoKdmFyIGNvbmZpZ01lbnVfbTN1ID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X20zdVsiX2VsZW1lbnQiXSAgICAgICAgPSAiSU5QVVQiOwpjb25maWdNZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CmNvbmZpZ01lbnVfbTN1WyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9tM3VbIl9sYWJlbCJdICAgICAgICAgID0gIk0zVSBGaWxlOiBsb2NhbCBvciByZW1vdGUiOwpjb25maWdNZW51X20zdVsibmFtZSJdICAgICAgICAgICAgPSAiZmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJpZCJdICAgICAgICAgICAgICA9ICJtM3UiOwpjb25maWdNZW51X20zdVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfbTN1WyJwbGFjZWhvbGRlciJdICAgICA9ICJNM1UgRmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJfdXNhZ2UiXSAgICAgICAgICA9ICJSZW1vdGUgcGxheWxpc3Q6IGh0dHA6Ly95b3VyLnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1IgoKCmNvbmZpZ01lbnVfbTN1WyJ2YWx1ZSJdICAgICAgICAgICA9ICJodHRwOi8vd2Vic3J2LmxvY2FsOjgwODAva2FiZWwubTN1IjsKCnZhciBjb25maWdNZW51X2NvbXBsZXRlID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X2NvbXBsZXRlWyJfZWxlbWVudCJdICAgICAgICA9ICJIMiI7CmNvbmZpZ01lbnVfY29tcGxldGVbIl9tZW51VHlwZSJdICAgICAgID0gImlucHV0QXJyYXkiOwpjb25maWdNZW51X2NvbXBsZXRlWyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsiX3RleHQiXSAgICAgICAgICAgPSAieFRlVmUgd2FzIHN1Y2Nlc3NmdWxseSBzZXQgdXAiOwpjb25maWdNZW51X2NvbXBsZXRlWyJuYW1lIl0gICAgICAgICAgICA9ICJjb21wbGV0ZSI7CmNvbmZpZ01lbnVfY29tcGxldGVbImlkIl0gICAgICAgICAgICAgID0gImNvbXBsZXRlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfY29tcGxldGVbImNsYXNzIl0gICAgICAgICAgID0gImNlbnRlciI7Cgpjb25maWdNZW51WyJ0dW5lciJdICAgICA9IGNvbmZpZ01lbnVfdHVuZXI7CmNvbmZpZ01lbnVbImVwZ1NvdXJjZSJdID0gY29uZmlnTWVudV9lcGc7CmNvbmZpZ01lbnVbIm0zdSJdICAgICAgID0gY29uZmlnTWVudV9tM3U7CmNvbmZpZ01lbnVbImNvbXBsZXRlIl0gID0gY29uZmlnTWVudV9jb21wbGV0ZTsKCmZ1bmN0aW9uIHJlYWR5Rm9yQ29uZmlndXJhdGlvbigpIHsKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICBkYXRhWyJjbWQiXSA9ICJnZXRTZXJ2ZXJDb25maWciOwogIHhUZVZlKGRhdGEpOwogIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsKfQoKZnVuY3Rpb24gY3JlYXRlQ29uZmlndXJhdGlvbihlbG0pIHsKCiAgYWN0aXZlV2l6YXJkID0gZWxtOwogIHZhciBpdGVtICA9IGNvbmZpZ01lbnVbZWxtXTsKCiAgdmFyIGRpdiAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKTsKICBkaXYuaW5uZXJIVE1MID0gIiI7CiAgZGl2LnNldEF0dHJpYnV0ZSgiZGF0YS1jb25maWdLZXkiLCBpdGVtWyJfY29uZmlnS2V5Il0pOwogIGRpdi5zZXRBdHRyaWJ1dGUoImRhdGEtbWVudVR5cGUiLCBpdGVtWyJfbWVudVR5cGUiXSk7CiAgCiAgc3dpdGNoKGl0ZW0uaGFzT3duUHJvcGVydHkoIl9sYWJlbCIpKSB7CiAgICBjYXNlIHRydWU6CiAgICAgIHZhciBuZXdJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdJdGVtWyJfZWxlbWVudCJdID0gIkxBQkVMIjsKICAgICAgbmV3SXRlbVsiX3RleHQiXSAgICA9IGl0ZW1bIl9sYWJlbCJdOyAKICAgICAgbmV3SXRlbVsiZm9yIl0gICAgICA9IGl0ZW1bImlkIl07CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0l0ZW0pKTsKICAgICAgYnJlYWsKICB9CgogIHN3aXRjaChpdGVtWyJfZWxlbWVudCJdKSB7CiAgICBjYXNlICJTRUxFQ1QiOgogICAgICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChpdGVtKSk7CiAgICAgIHZhciBzZWxlY3RFbGVtZW50ID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJTRUxFQ1QiKVswXTsKICAgICAgdmFyIHZhbHVlcyA9IGl0ZW1bIl9vcHRpb25WYWx1ZXMiXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICB2Line truncated
|
||||
|
||||
}
|
||||
|
||||
+66
-29
@@ -10,11 +10,19 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"../src/internal/authentication"
|
||||
"xteve/src/internal/authentication"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var wsUpgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 4096,
|
||||
WriteBufferSize: 4096,
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
// StartWebserver : Startet den Webserver
|
||||
func StartWebserver() (err error) {
|
||||
|
||||
@@ -30,6 +38,7 @@ func StartWebserver() (err error) {
|
||||
http.HandleFunc("/api/", API)
|
||||
http.HandleFunc("/images/", Images)
|
||||
http.HandleFunc("/data_images/", DataImages)
|
||||
|
||||
//http.HandleFunc("/auto/", Auto)
|
||||
|
||||
showInfo("DVR IP:" + System.IPAddress + ":" + Settings.Port)
|
||||
@@ -129,20 +138,37 @@ func Stream(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
|
||||
err = errors.New("RTSP and RTP streams are not supported")
|
||||
ShowError(err, 2004)
|
||||
|
||||
showInfo("Streaming URL:" + streamInfo.URL)
|
||||
http.Redirect(w, r, streamInfo.URL, 302)
|
||||
|
||||
showInfo("Streaming Info:URL was passed to the client")
|
||||
return
|
||||
// If an UDPxy host is set, and the stream URL is multicast (i.e. starts with 'udp://@'),
|
||||
// then streamInfo.URL needs to be rewritten to point to UDPxy.
|
||||
if Settings.UDPxy != "" && strings.HasPrefix(streamInfo.URL, "udp://@") {
|
||||
streamInfo.URL = fmt.Sprintf("http://%s/udp/%s/", Settings.UDPxy, strings.TrimPrefix(streamInfo.URL, "udp://@"))
|
||||
}
|
||||
|
||||
showInfo(fmt.Sprintf("Buffer:%t", Settings.Buffer))
|
||||
switch Settings.Buffer {
|
||||
|
||||
if Settings.Buffer == true {
|
||||
case "-":
|
||||
showInfo(fmt.Sprintf("Buffer:false [%s]", Settings.Buffer))
|
||||
|
||||
case "xteve":
|
||||
if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
|
||||
err = errors.New("RTSP and RTP streams are not supported")
|
||||
ShowError(err, 2004)
|
||||
|
||||
showInfo("Streaming URL:" + streamInfo.URL)
|
||||
http.Redirect(w, r, streamInfo.URL, 302)
|
||||
|
||||
showInfo("Streaming Info:URL was passed to the client")
|
||||
return
|
||||
}
|
||||
|
||||
showInfo(fmt.Sprintf("Buffer:true [%s]", Settings.Buffer))
|
||||
|
||||
default:
|
||||
showInfo(fmt.Sprintf("Buffer:true [%s]", Settings.Buffer))
|
||||
|
||||
}
|
||||
|
||||
if Settings.Buffer != "-" {
|
||||
showInfo(fmt.Sprintf("Buffer Size:%d KB", Settings.BufferSize))
|
||||
}
|
||||
|
||||
@@ -152,16 +178,16 @@ func Stream(w http.ResponseWriter, r *http.Request) {
|
||||
// Prüfen ob der Buffer verwendet werden soll
|
||||
switch Settings.Buffer {
|
||||
|
||||
case true:
|
||||
bufferingStream(streamInfo.PlaylistID, streamInfo.URL, streamInfo.Name, w, r)
|
||||
|
||||
case false:
|
||||
case "-":
|
||||
showInfo("Streaming URL:" + streamInfo.URL)
|
||||
http.Redirect(w, r, streamInfo.URL, 302)
|
||||
|
||||
showInfo("Streaming Info:URL was passed to the client.")
|
||||
showInfo("Streaming Info:xTeVe is no longer involved, the client connects directly to the streaming server.")
|
||||
|
||||
default:
|
||||
bufferingStream(streamInfo.PlaylistID, streamInfo.URL, streamInfo.Name, w, r)
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
@@ -195,7 +221,7 @@ func Auto(w http.ResponseWriter, r *http.Request) {
|
||||
// xTeVe : Web Server /xmltv/ und /m3u/
|
||||
func xTeVe(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var requestType, groupTitle, file, content string
|
||||
var requestType, groupTitle, file, content, contentType string
|
||||
var err error
|
||||
var path = strings.TrimPrefix(r.URL.Path, "/")
|
||||
var groups = []string{}
|
||||
@@ -205,7 +231,6 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
|
||||
// XMLTV Datei
|
||||
if strings.Contains(path, "xmltv/") {
|
||||
|
||||
w.Header().Set("Content-Type", "application/xml")
|
||||
requestType = "xml"
|
||||
|
||||
file = System.Folder.Data + getFilenameFromPath(path)
|
||||
@@ -249,6 +274,13 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
contentType = http.DetectContentType([]byte(content))
|
||||
if strings.Contains(strings.ToLower(contentType), "xml") {
|
||||
contentType = "application/xml; charset=utf-8"
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
if err == nil {
|
||||
w.Write([]byte(content))
|
||||
}
|
||||
@@ -305,15 +337,18 @@ func WS(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var newToken string
|
||||
|
||||
if r.Header.Get("Origin") != "http://"+r.Host {
|
||||
httpStatusError(w, r, 403)
|
||||
return
|
||||
}
|
||||
/*
|
||||
if r.Header.Get("Origin") != "http://"+r.Host {
|
||||
httpStatusError(w, r, 403)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
setGlobalDomain(r.Host)
|
||||
@@ -531,7 +566,7 @@ func WS(w http.ResponseWriter, r *http.Request) {
|
||||
default:
|
||||
fmt.Println("+ + + + + + + + + + +", request.Cmd)
|
||||
|
||||
var requestMap = make(map[string]interface{}) // Debug
|
||||
var requestMap = make(map[string]any) // Debug
|
||||
_ = requestMap
|
||||
if System.Dev == true {
|
||||
fmt.Println(mapToJSON(requestMap))
|
||||
@@ -564,7 +599,7 @@ func WS(w http.ResponseWriter, r *http.Request) {
|
||||
// Web : Web Server /web/
|
||||
func Web(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var lang = make(map[string]interface{})
|
||||
var lang = make(map[string]any)
|
||||
var err error
|
||||
|
||||
var requestFile = strings.Replace(r.URL.Path, "/web", "html", -1)
|
||||
@@ -572,6 +607,8 @@ func Web(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var language LanguageUI
|
||||
|
||||
setGlobalDomain(r.Host)
|
||||
|
||||
if System.Dev == true {
|
||||
|
||||
lang, err = loadJSONFileToMap(fmt.Sprintf("html/lang/%s.json", Settings.Language))
|
||||
@@ -600,7 +637,7 @@ func Web(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if System.ScanInProgress == 0 {
|
||||
|
||||
if len(Settings.Files.M3U) == 0 && len(Settings.Files.HDHR) == 0 {
|
||||
if Settings.WizardCompleted == false && len(Settings.Files.M3U) == 0 && len(Settings.Files.HDHR) == 0 {
|
||||
System.ConfigurationWizard = true
|
||||
}
|
||||
|
||||
@@ -999,7 +1036,7 @@ func setDefaultResponseData(response ResponseStruct, data bool) (defaults Respon
|
||||
|
||||
defaults.ClientInfo.XEPGCount = Data.XEPG.XEPGCount
|
||||
|
||||
var XEPG = make(map[string]interface{})
|
||||
var XEPG = make(map[string]any)
|
||||
|
||||
if len(Data.Streams.Active) > 0 {
|
||||
|
||||
@@ -1008,8 +1045,8 @@ func setDefaultResponseData(response ResponseStruct, data bool) (defaults Respon
|
||||
|
||||
} else {
|
||||
|
||||
XEPG["epgMapping"] = make(map[string]interface{})
|
||||
XEPG["xmltvMap"] = make(map[string]interface{})
|
||||
XEPG["epgMapping"] = make(map[string]any)
|
||||
XEPG["xmltvMap"] = make(map[string]any)
|
||||
|
||||
}
|
||||
|
||||
|
||||
+407
-76
@@ -8,10 +8,16 @@ import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"runtime"
|
||||
"sort"
|
||||
"unicode"
|
||||
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"xteve/src/internal/imgcache"
|
||||
)
|
||||
|
||||
// Provider XMLTV Datei überprüfen
|
||||
@@ -42,6 +48,13 @@ func buildXEPG(background bool) {
|
||||
|
||||
System.ScanInProgress = 1
|
||||
|
||||
var err error
|
||||
|
||||
Data.Cache.Images, err = imgcache.New(System.Folder.ImagesCache, fmt.Sprintf("%s://%s/images/", System.ServerProtocol.WEB, System.Domain), Settings.CacheImages)
|
||||
if err != nil {
|
||||
ShowError(err, 0)
|
||||
}
|
||||
|
||||
if Settings.EpgSource == "XEPG" {
|
||||
|
||||
switch background {
|
||||
@@ -56,10 +69,31 @@ func buildXEPG(background bool) {
|
||||
cleanupXEPG()
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
go cachingImages()
|
||||
queuePlexGuideRefresh("xepg rebuild")
|
||||
|
||||
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
||||
|
||||
if Settings.CacheImages == true && System.ImageCachingInProgress == 0 {
|
||||
|
||||
go func() {
|
||||
|
||||
System.ImageCachingInProgress = 1
|
||||
showInfo(fmt.Sprintf("Image Caching:Images are cached (%d)", len(Data.Cache.Images.Queue)))
|
||||
|
||||
Data.Cache.Images.Image.Caching()
|
||||
Data.Cache.Images.Image.Remove()
|
||||
showInfo("Image Caching:Done")
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
queuePlexGuideRefresh("xepg image cache refresh")
|
||||
|
||||
System.ImageCachingInProgress = 0
|
||||
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
System.ScanInProgress = 0
|
||||
|
||||
// Cache löschen
|
||||
@@ -82,7 +116,29 @@ func buildXEPG(background bool) {
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
go cachingImages()
|
||||
queuePlexGuideRefresh("xepg rebuild")
|
||||
|
||||
if Settings.CacheImages == true && System.ImageCachingInProgress == 0 {
|
||||
|
||||
go func() {
|
||||
|
||||
System.ImageCachingInProgress = 1
|
||||
showInfo(fmt.Sprintf("Image Caching:Images are cached (%d)", len(Data.Cache.Images.Queue)))
|
||||
|
||||
Data.Cache.Images.Image.Caching()
|
||||
Data.Cache.Images.Image.Remove()
|
||||
showInfo("Image Caching:Done")
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
queuePlexGuideRefresh("xepg image cache refresh")
|
||||
|
||||
System.ImageCachingInProgress = 0
|
||||
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
||||
|
||||
System.ScanInProgress = 0
|
||||
@@ -128,6 +184,7 @@ func updateXEPG(background bool) {
|
||||
|
||||
createXMLTVFile()
|
||||
createM3UFile()
|
||||
queuePlexGuideRefresh("xepg update")
|
||||
showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
|
||||
|
||||
System.ScanInProgress = 0
|
||||
@@ -156,9 +213,9 @@ func updateXEPG(background bool) {
|
||||
func createXEPGMapping() {
|
||||
|
||||
Data.XMLTV.Files = getLocalProviderFiles("xmltv")
|
||||
Data.XMLTV.Mapping = make(map[string]interface{})
|
||||
Data.XMLTV.Mapping = make(map[string]any)
|
||||
|
||||
var tmpMap = make(map[string]interface{})
|
||||
var tmpMap = make(map[string]any)
|
||||
|
||||
var friendlyDisplayName = func(channel Channel) (displayName string) {
|
||||
var dn = channel.DisplayName
|
||||
@@ -199,10 +256,10 @@ func createXEPGMapping() {
|
||||
if err == nil {
|
||||
|
||||
// Daten aus der XML Datei in eine temporäre Map schreiben
|
||||
var xmltvMap = make(map[string]interface{})
|
||||
var xmltvMap = make(map[string]any)
|
||||
|
||||
for _, c := range xmltv.Channel {
|
||||
var channel = make(map[string]interface{})
|
||||
var channel = make(map[string]any)
|
||||
|
||||
channel["id"] = c.ID
|
||||
channel["display-name"] = friendlyDisplayName(*c)
|
||||
@@ -220,7 +277,7 @@ func createXEPGMapping() {
|
||||
}
|
||||
|
||||
Data.XMLTV.Mapping = tmpMap
|
||||
tmpMap = make(map[string]interface{})
|
||||
tmpMap = make(map[string]any)
|
||||
|
||||
} else {
|
||||
|
||||
@@ -231,8 +288,8 @@ func createXEPGMapping() {
|
||||
}
|
||||
|
||||
// Auswahl für den Dummy erstellen
|
||||
var dummy = make(map[string]interface{})
|
||||
var times = []string{"30", "60", "90", "120"}
|
||||
var dummy = make(map[string]any)
|
||||
var times = []string{"30", "60", "90", "120", "180", "240", "360"}
|
||||
|
||||
for _, i := range times {
|
||||
|
||||
@@ -253,8 +310,9 @@ func createXEPGMapping() {
|
||||
// XEPG Datenbank erstellen / aktualisieren
|
||||
func createXEPGDatabase() (err error) {
|
||||
|
||||
var allChannelNumbers []float64
|
||||
Data.Cache.Streams.Active = []string{}
|
||||
var allChannelNumbers = make([]float64, 0, System.UnfilteredChannelLimit)
|
||||
Data.Cache.Streams.Active = make([]string, 0, System.UnfilteredChannelLimit)
|
||||
Data.XEPG.Channels = make(map[string]any, System.UnfilteredChannelLimit)
|
||||
|
||||
Data.XEPG.Channels, err = loadJSONFileToMap(System.File.XEPG)
|
||||
if err != nil {
|
||||
@@ -279,24 +337,33 @@ func createXEPGDatabase() (err error) {
|
||||
|
||||
var getFreeChannelNumber = func() (xChannelID string) {
|
||||
|
||||
sort.Float64s(allChannelNumbers)
|
||||
|
||||
var firstFreeNumber float64 = Settings.MappingFirstChannel
|
||||
|
||||
newNumber:
|
||||
for {
|
||||
|
||||
if indexOfFloat64(firstFreeNumber, allChannelNumbers) == -1 {
|
||||
xChannelID = fmt.Sprintf("%g", firstFreeNumber)
|
||||
allChannelNumbers = append(allChannelNumbers, firstFreeNumber)
|
||||
return
|
||||
}
|
||||
|
||||
if indexOfFloat64(firstFreeNumber, allChannelNumbers) == -1 {
|
||||
xChannelID = fmt.Sprintf("%g", firstFreeNumber)
|
||||
allChannelNumbers = append(allChannelNumbers, firstFreeNumber)
|
||||
} else {
|
||||
firstFreeNumber++
|
||||
goto newNumber
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var generateHashForChannel = func(m3uID string, groupTitle string, tvgID string, tvgName string, uuidKey string, uuidValue string) string {
|
||||
hash := md5.Sum([]byte(m3uID + groupTitle + tvgID + tvgName + uuidKey + uuidValue))
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
showInfo("XEPG:" + "Update database")
|
||||
|
||||
// Kanal mit fehlenden Kanalnummern löschen
|
||||
// Kanal mit fehlenden Kanalnummern löschen. Delete channel with missing channel numbers
|
||||
for id, dxc := range Data.XEPG.Channels {
|
||||
|
||||
var xepgChannel XEPGChannelStruct
|
||||
@@ -315,17 +382,24 @@ func createXEPGDatabase() (err error) {
|
||||
|
||||
}
|
||||
|
||||
var xepgChannels = make(map[string]interface{})
|
||||
|
||||
for k, v := range Data.XEPG.Channels {
|
||||
xepgChannels[k] = v
|
||||
// Make a map of the db channels based on their previously downloaded attributes -- filename, group, title, etc
|
||||
var xepgChannelsValuesMap = make(map[string]XEPGChannelStruct, System.UnfilteredChannelLimit)
|
||||
for _, v := range Data.XEPG.Channels {
|
||||
var channel XEPGChannelStruct
|
||||
err = json.Unmarshal([]byte(mapToJSON(v)), &channel)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
channelHash := generateHashForChannel(channel.FileM3UID, channel.GroupTitle, channel.TvgID, channel.TvgName, channel.UUIDKey, channel.UUIDValue)
|
||||
xepgChannelsValuesMap[channelHash] = channel
|
||||
}
|
||||
|
||||
for _, dsa := range Data.Streams.Active {
|
||||
|
||||
var channelExists = false // Entscheidet ob ein Kanal neu zu Datenbank hinzugefügt werden soll.
|
||||
var channelHasUUID = false // Überprüft, ob der Kanal (Stream) eindeutige ID's besitzt
|
||||
var currentXEPGID string // Aktuelle Datenbank ID (XEPG). Wird verwendet, um den Kanal in der Datenbank mit dem Stream der M3u zu aktualisieren
|
||||
var channelExists = false // Entscheidet ob ein Kanal neu zu Datenbank hinzugefügt werden soll. Decides whether a channel should be added to the database
|
||||
var channelHasUUID = false // Überprüft, ob der Kanal (Stream) eindeutige ID's besitzt. Checks whether the channel (stream) has unique IDs
|
||||
var currentXEPGID string // Aktuelle Datenbank ID (XEPG). Wird verwendet, um den Kanal in der Datenbank mit dem Stream der M3u zu aktualisieren. Current database ID (XEPG) Used to update the channel in the database with the stream of the M3u
|
||||
|
||||
var m3uChannel M3UChannelStructXEPG
|
||||
|
||||
err = json.Unmarshal([]byte(mapToJSON(dsa)), &m3uChannel)
|
||||
@@ -333,44 +407,53 @@ func createXEPGDatabase() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
Data.Cache.Streams.Active = append(Data.Cache.Streams.Active, m3uChannel.Name)
|
||||
Data.Cache.Streams.Active = append(Data.Cache.Streams.Active, m3uChannel.Name+m3uChannel.FileM3UID)
|
||||
|
||||
// XEPG Datenbank durchlaufen um nach dem Kanal zu suchen.
|
||||
for xepg, dxc := range xepgChannels {
|
||||
|
||||
var xepgChannel XEPGChannelStruct
|
||||
err = json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
|
||||
if err != nil {
|
||||
return
|
||||
// Try to find the channel based on matching all known values. If that fails, then move to full channel scan
|
||||
m3uChannelHash := generateHashForChannel(m3uChannel.FileM3UID, m3uChannel.GroupTitle, m3uChannel.TvgID, m3uChannel.TvgName, m3uChannel.UUIDKey, m3uChannel.UUIDValue)
|
||||
if val, ok := xepgChannelsValuesMap[m3uChannelHash]; ok {
|
||||
channelExists = true
|
||||
currentXEPGID = val.XEPG
|
||||
if len(m3uChannel.UUIDValue) > 0 {
|
||||
channelHasUUID = true
|
||||
}
|
||||
} else {
|
||||
|
||||
// Vergleichen des Streams anhand einer UUID in der M3U mit dem Kanal in der Databank
|
||||
if len(xepgChannel.UUIDValue) > 0 && len(m3uChannel.UUIDValue) > 0 {
|
||||
// XEPG Datenbank durchlaufen um nach dem Kanal zu suchen. Run through the XEPG database to search for the channel (full scan)
|
||||
for _, dxc := range xepgChannelsValuesMap {
|
||||
|
||||
if xepgChannel.UUIDValue == m3uChannel.UUIDValue && xepgChannel.UUIDKey == m3uChannel.UUIDKey {
|
||||
if m3uChannel.FileM3UID == dxc.FileM3UID {
|
||||
|
||||
channelExists = true
|
||||
channelHasUUID = true
|
||||
currentXEPGID = xepg
|
||||
break
|
||||
dxc.FileM3UID = m3uChannel.FileM3UID
|
||||
dxc.FileM3UName = m3uChannel.FileM3UName
|
||||
|
||||
// Vergleichen des Streams anhand einer UUID in der M3U mit dem Kanal in der Databank. Compare the stream using a UUID in the M3U with the channel in the database
|
||||
if len(dxc.UUIDValue) > 0 && len(m3uChannel.UUIDValue) > 0 {
|
||||
|
||||
if dxc.UUIDValue == m3uChannel.UUIDValue && dxc.UUIDKey == m3uChannel.UUIDKey {
|
||||
|
||||
channelExists = true
|
||||
channelHasUUID = true
|
||||
currentXEPGID = dxc.XEPG
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// Vergleichen des Streams mit dem Kanal in der Databank anhand des Kanalnamens. Compare the stream to the channel in the database using the channel name
|
||||
if dxc.Name == m3uChannel.Name {
|
||||
channelExists = true
|
||||
currentXEPGID = dxc.XEPG
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// Vergleichen des Streams mit dem Kanal in der Databank anhand des Kanalnamens
|
||||
//fmt.Println(xepgChannel.Name, xepgChannel.UUIDKey, xepgChannel.UUIDValue)
|
||||
if xepgChannel.Name == m3uChannel.Name {
|
||||
channelExists = true
|
||||
currentXEPGID = xepg
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//os.Exit(0)
|
||||
|
||||
switch channelExists {
|
||||
|
||||
case true:
|
||||
@@ -435,7 +518,7 @@ func createXEPGDatabase() (err error) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
showInfo("XEPG:" + "Save DB file")
|
||||
err = saveMapToJSONFile(System.File.XEPG, Data.XEPG.Channels)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -444,10 +527,132 @@ func createXEPGDatabase() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func normalizeXEPGMatchValue(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
if len(value) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.Map(func(r rune) rune {
|
||||
switch {
|
||||
case unicode.IsLetter(r):
|
||||
return unicode.ToLower(r)
|
||||
case unicode.IsDigit(r):
|
||||
return r
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}, value)
|
||||
}
|
||||
|
||||
func appendXEPGIssueSample(samples map[string]struct{}, value string) {
|
||||
value = strings.TrimSpace(value)
|
||||
if len(value) == 0 {
|
||||
return
|
||||
}
|
||||
samples[value] = struct{}{}
|
||||
}
|
||||
|
||||
func xepgIssueSampleText(samples map[string]struct{}, max int) string {
|
||||
if len(samples) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
list := make([]string, 0, len(samples))
|
||||
for name := range samples {
|
||||
list = append(list, name)
|
||||
}
|
||||
sort.Strings(list)
|
||||
|
||||
if len(list) > max {
|
||||
return strings.Join(list[:max], ", ") + ", ..."
|
||||
}
|
||||
|
||||
return strings.Join(list, ", ")
|
||||
}
|
||||
|
||||
func findXEPGReplacementChannel(xmltvChannels map[string]any, xepgChannel XEPGChannelStruct) (channelID string, channel map[string]any, ok bool) {
|
||||
var candidateValues = map[string]struct{}{}
|
||||
|
||||
addCandidate := func(value string) {
|
||||
normalized := normalizeXEPGMatchValue(value)
|
||||
if len(normalized) == 0 {
|
||||
return
|
||||
}
|
||||
candidateValues[normalized] = struct{}{}
|
||||
}
|
||||
|
||||
addCandidate(xepgChannel.XName)
|
||||
addCandidate(xepgChannel.Name)
|
||||
addCandidate(xepgChannel.TvgName)
|
||||
addCandidate(xepgChannel.TvgID)
|
||||
|
||||
if len(candidateValues) == 0 {
|
||||
return "", nil, false
|
||||
}
|
||||
|
||||
if _, exists := candidateValues[normalizeXEPGMatchValue(xepgChannel.TvgID)]; exists {
|
||||
if direct, found := xmltvChannels[xepgChannel.TvgID].(map[string]any); found {
|
||||
return xepgChannel.TvgID, direct, true
|
||||
}
|
||||
}
|
||||
|
||||
var matches []struct {
|
||||
id string
|
||||
channel map[string]any
|
||||
}
|
||||
|
||||
for id, data := range xmltvChannels {
|
||||
xmltvChannel, castOK := data.(map[string]any)
|
||||
if castOK == false {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, match := candidateValues[normalizeXEPGMatchValue(id)]; match {
|
||||
matches = append(matches, struct {
|
||||
id string
|
||||
channel map[string]any
|
||||
}{id: id, channel: xmltvChannel})
|
||||
continue
|
||||
}
|
||||
|
||||
displayName, hasDisplayName := xmltvChannel["display-name"].(string)
|
||||
if hasDisplayName == false {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, match := candidateValues[normalizeXEPGMatchValue(displayName)]; match {
|
||||
matches = append(matches, struct {
|
||||
id string
|
||||
channel map[string]any
|
||||
}{id: id, channel: xmltvChannel})
|
||||
}
|
||||
}
|
||||
|
||||
if len(matches) != 1 {
|
||||
return "", nil, false
|
||||
}
|
||||
|
||||
return matches[0].id, matches[0].channel, true
|
||||
}
|
||||
|
||||
// Kanäle automatisch zuordnen und das Mapping überprüfen
|
||||
func mapping() (err error) {
|
||||
showInfo("XEPG:" + "Map channels")
|
||||
|
||||
strictMissingEPGMode := Settings.XepgMissingEPGMode != "relaxed"
|
||||
|
||||
missingEPGCount := 0
|
||||
missingXMLTVCount := 0
|
||||
autoRemapCount := 0
|
||||
relaxedKeepCount := 0
|
||||
relaxedDummyCount := 0
|
||||
missingEPGSamples := map[string]struct{}{}
|
||||
missingXMLTVSamples := map[string]struct{}{}
|
||||
autoRemapSamples := map[string]struct{}{}
|
||||
relaxedKeepSamples := map[string]struct{}{}
|
||||
relaxedDummySamples := map[string]struct{}{}
|
||||
|
||||
for xepg, dxc := range Data.XEPG.Channels {
|
||||
|
||||
var xepgChannel XEPGChannelStruct
|
||||
@@ -460,7 +665,7 @@ func mapping() (err error) {
|
||||
if xepgChannel.XActive == false {
|
||||
|
||||
// Werte kann "-" sein, deswegen len < 1
|
||||
if len(xepgChannel.XmltvFile) < 1 && len(xepgChannel.XmltvFile) < 1 {
|
||||
if len(xepgChannel.XmltvFile) < 1 && len(xepgChannel.XMapping) < 1 {
|
||||
|
||||
var tvgID = xepgChannel.TvgID
|
||||
|
||||
@@ -472,16 +677,16 @@ func mapping() (err error) {
|
||||
|
||||
for file, xmltvChannels := range Data.XMLTV.Mapping {
|
||||
|
||||
if channel, ok := xmltvChannels.(map[string]interface{})[tvgID]; ok {
|
||||
if channel, ok := xmltvChannels.(map[string]any)[tvgID]; ok {
|
||||
|
||||
if channelID, ok := channel.(map[string]interface{})["id"].(string); ok {
|
||||
if channelID, ok := channel.(map[string]any)["id"].(string); ok {
|
||||
|
||||
xepgChannel.XmltvFile = file
|
||||
xepgChannel.XMapping = channelID
|
||||
xepgChannel.XActive = true
|
||||
|
||||
// Falls in der XMLTV Datei ein Logo existiert, wird dieses verwendet. Falls nicht, dann das Logo aus der M3U Datei
|
||||
if icon, ok := channel.(map[string]interface{})["icon"].(string); ok {
|
||||
if icon, ok := channel.(map[string]any)["icon"].(string); ok {
|
||||
if len(icon) > 0 {
|
||||
xepgChannel.TvgLogo = icon
|
||||
}
|
||||
@@ -508,9 +713,9 @@ func mapping() (err error) {
|
||||
|
||||
if file != "xTeVe Dummy" {
|
||||
|
||||
if value, ok := Data.XMLTV.Mapping[file].(map[string]interface{}); ok {
|
||||
if value, ok := Data.XMLTV.Mapping[file].(map[string]any); ok {
|
||||
|
||||
if channel, ok := value[mapping].(map[string]interface{}); ok {
|
||||
if channel, ok := value[mapping].(map[string]any); ok {
|
||||
|
||||
// Kanallogo aktualisieren
|
||||
if logo, ok := channel["icon"].(string); ok {
|
||||
@@ -522,20 +727,68 @@ func mapping() (err error) {
|
||||
}
|
||||
|
||||
} else {
|
||||
if channelID, replacementChannel, remapOK := findXEPGReplacementChannel(value, xepgChannel); remapOK {
|
||||
xepgChannel.XMapping = channelID
|
||||
|
||||
ShowError(fmt.Errorf(fmt.Sprintf("Missing EPG data: %s", xepgChannel.Name)), 0)
|
||||
showWarning(2302)
|
||||
xepgChannel.XActive = false
|
||||
if logo, ok := replacementChannel["icon"].(string); ok {
|
||||
if xepgChannel.XUpdateChannelIcon == true && len(logo) > 0 {
|
||||
xepgChannel.TvgLogo = logo
|
||||
}
|
||||
}
|
||||
|
||||
autoRemapCount++
|
||||
name := strings.TrimSpace(xepgChannel.Name)
|
||||
if len(name) == 0 {
|
||||
name = strings.TrimSpace(xepgChannel.XName)
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = xepg
|
||||
}
|
||||
appendXEPGIssueSample(autoRemapSamples, name)
|
||||
} else {
|
||||
name := strings.TrimSpace(xepgChannel.Name)
|
||||
if len(name) == 0 {
|
||||
name = strings.TrimSpace(xepgChannel.XName)
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = xepg
|
||||
}
|
||||
|
||||
if strictMissingEPGMode == true {
|
||||
missingEPGCount++
|
||||
appendXEPGIssueSample(missingEPGSamples, name)
|
||||
xepgChannel.XActive = false
|
||||
} else {
|
||||
relaxedKeepCount++
|
||||
appendXEPGIssueSample(relaxedKeepSamples, name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
var fileID = strings.TrimSuffix(getFilenameFromPath(file), path.Ext(getFilenameFromPath(file)))
|
||||
providerName := getProviderParameter(fileID, "xmltv", "name")
|
||||
if len(strings.TrimSpace(providerName)) == 0 {
|
||||
providerName = file
|
||||
}
|
||||
|
||||
ShowError(fmt.Errorf("Missing XMLTV file: %s", getProviderParameter(fileID, "xmltv", "name")), 0)
|
||||
showWarning(2301)
|
||||
xepgChannel.XActive = false
|
||||
if strictMissingEPGMode == true {
|
||||
missingXMLTVCount++
|
||||
appendXEPGIssueSample(missingXMLTVSamples, providerName)
|
||||
xepgChannel.XActive = false
|
||||
} else {
|
||||
relaxedDummyCount++
|
||||
name := strings.TrimSpace(xepgChannel.Name)
|
||||
if len(name) == 0 {
|
||||
name = strings.TrimSpace(xepgChannel.XName)
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = xepg
|
||||
}
|
||||
appendXEPGIssueSample(relaxedDummySamples, name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -557,6 +810,28 @@ func mapping() (err error) {
|
||||
|
||||
}
|
||||
|
||||
if autoRemapCount > 0 {
|
||||
showInfo(fmt.Sprintf("XEPG:%d channel mappings were auto-remapped (examples: %s)", autoRemapCount, xepgIssueSampleText(autoRemapSamples, 8)))
|
||||
}
|
||||
|
||||
if missingEPGCount > 0 {
|
||||
showWarning(2302)
|
||||
showInfo(fmt.Sprintf("XEPG:%d channels have missing EPG mappings and were deactivated (examples: %s)", missingEPGCount, xepgIssueSampleText(missingEPGSamples, 8)))
|
||||
}
|
||||
|
||||
if missingXMLTVCount > 0 {
|
||||
showWarning(2301)
|
||||
showInfo(fmt.Sprintf("XEPG:%d channels reference missing XMLTV files and were deactivated (sources: %s)", missingXMLTVCount, xepgIssueSampleText(missingXMLTVSamples, 5)))
|
||||
}
|
||||
|
||||
if relaxedKeepCount > 0 {
|
||||
showInfo(fmt.Sprintf("XEPG:%d channels kept active in relaxed mode despite missing EPG mappings (examples: %s)", relaxedKeepCount, xepgIssueSampleText(relaxedKeepSamples, 8)))
|
||||
}
|
||||
|
||||
if relaxedDummyCount > 0 {
|
||||
showInfo(fmt.Sprintf("XEPG:%d channels will use xTeVe Dummy guide in relaxed mode because XMLTV sources were unavailable (examples: %s)", relaxedDummyCount, xepgIssueSampleText(relaxedDummySamples, 8)))
|
||||
}
|
||||
|
||||
err = saveMapToJSONFile(System.File.XEPG, Data.XEPG.Channels)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -568,6 +843,10 @@ func mapping() (err error) {
|
||||
// XMLTV Datei erstellen
|
||||
func createXMLTVFile() (err error) {
|
||||
|
||||
// Image Cache
|
||||
// 4edd81ab7c368208cc6448b615051b37.jpg
|
||||
var imgc = Data.Cache.Images
|
||||
|
||||
Data.Cache.ImagesFiles = []string{}
|
||||
Data.Cache.ImagesURLS = []string{}
|
||||
Data.Cache.ImagesCache = []string{}
|
||||
@@ -586,7 +865,7 @@ func createXMLTVFile() (err error) {
|
||||
}
|
||||
|
||||
if len(Data.XMLTV.Files) == 0 && len(Data.Streams.Active) == 0 {
|
||||
Data.XEPG.Channels = make(map[string]interface{})
|
||||
Data.XEPG.Channels = make(map[string]any)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -615,7 +894,7 @@ func createXMLTVFile() (err error) {
|
||||
// Kanäle
|
||||
var channel Channel
|
||||
channel.ID = xepgChannel.XChannelID
|
||||
channel.Icon = Icon{Src: getCacheImageURL(xepgChannel.TvgLogo)}
|
||||
channel.Icon = Icon{Src: imgc.Image.GetURL(xepgChannel.TvgLogo)}
|
||||
channel.DisplayName = append(channel.DisplayName, DisplayName{Value: xepgChannel.XName})
|
||||
|
||||
xepgXML.Channel = append(xepgXML.Channel, &channel)
|
||||
@@ -641,9 +920,10 @@ func createXMLTVFile() (err error) {
|
||||
var xmlOutput = []byte(xml.Header + string(content))
|
||||
writeByteToFile(System.File.XML, xmlOutput)
|
||||
|
||||
xepgXML = XMLTV{}
|
||||
showInfo("XEPG:" + fmt.Sprintf("Compress XMLTV file (%s)", System.Compressed.GZxml))
|
||||
err = compressGZIP(&xmlOutput, System.Compressed.GZxml)
|
||||
|
||||
//saveMapToJSONFile(System.File.Images, Data.Cache.ImageCache)
|
||||
xepgXML = XMLTV{}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -653,6 +933,13 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
|
||||
|
||||
var xmltvFile = System.Folder.Data + xepgChannel.XmltvFile
|
||||
var channelID = xepgChannel.XMapping
|
||||
relaxedMissingEPGMode := Settings.XepgMissingEPGMode == "relaxed"
|
||||
fallbackToDummy := func() {
|
||||
dummyChannel := xepgChannel
|
||||
dummyChannel.XmltvFile = "xTeVe Dummy"
|
||||
dummyChannel.XMapping = "240_Minutes"
|
||||
xepgXML = createDummyProgram(dummyChannel)
|
||||
}
|
||||
|
||||
var xmltv XMLTV
|
||||
|
||||
@@ -662,6 +949,10 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
|
||||
|
||||
err = getLocalXMLTV(xmltvFile, &xmltv)
|
||||
if err != nil {
|
||||
if relaxedMissingEPGMode == true {
|
||||
fallbackToDummy()
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -690,6 +981,15 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
|
||||
// Category (Kategorie)
|
||||
getCategory(program, xmltvProgram, xepgChannel)
|
||||
|
||||
// Credits : (Credits)
|
||||
program.Credits = xmltvProgram.Credits
|
||||
|
||||
// Rating (Bewertung)
|
||||
program.Rating = xmltvProgram.Rating
|
||||
|
||||
// StarRating (Bewertung / Kritiken)
|
||||
program.StarRating = xmltvProgram.StarRating
|
||||
|
||||
// Country (Länder)
|
||||
program.Country = xmltvProgram.Country
|
||||
|
||||
@@ -717,25 +1017,33 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
|
||||
// Live
|
||||
program.Live = xmltvProgram.Live
|
||||
|
||||
// Premiere
|
||||
program.Premiere = xmltvProgram.Premiere
|
||||
|
||||
xepgXML.Program = append(xepgXML.Program, program)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(xepgXML.Program) == 0 && relaxedMissingEPGMode == true && xmltvFile != System.Folder.Data+"xTeVe Dummy" {
|
||||
fallbackToDummy()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Dummy Daten erstellen (createXMLTVFile)
|
||||
func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
|
||||
|
||||
var imgc = Data.Cache.Images
|
||||
var currentTime = time.Now()
|
||||
var dateArray = strings.Fields(currentTime.String())
|
||||
var offset = " " + dateArray[2]
|
||||
var currentDay = currentTime.Format("20060102")
|
||||
var startTime, _ = time.Parse("20060102150405", currentDay+"000000")
|
||||
|
||||
showInfo("Create Dummy Guide:" + "Time offset" + offset + " - " + xepgChannel.XName)
|
||||
showDebug("Create Dummy Guide:"+"Time offset"+offset+" - "+xepgChannel.XName, 2)
|
||||
|
||||
var dl = strings.Split(xepgChannel.XMapping, "_")
|
||||
dummyLength, err := strconv.Atoi(dl[0])
|
||||
@@ -744,7 +1052,7 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
|
||||
return
|
||||
}
|
||||
|
||||
for d := 0; d < 4; d++ {
|
||||
for d := range 4 {
|
||||
|
||||
var epgStartTime = startTime.Add(time.Hour * time.Duration(d*24))
|
||||
|
||||
@@ -759,10 +1067,15 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
|
||||
epg.Start = epgStartTime.Format("20060102150405") + offset
|
||||
epg.Stop = epgStopTime.Format("20060102150405") + offset
|
||||
epg.Title = append(epg.Title, &Title{Value: xepgChannel.XName + " (" + epgStartTime.Weekday().String()[0:2] + ". " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04") + ")", Lang: "en"})
|
||||
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
|
||||
|
||||
if len(xepgChannel.XDescription) == 0 {
|
||||
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
|
||||
} else {
|
||||
epg.Desc = append(epg.Desc, &Desc{Value: xepgChannel.XDescription, Lang: "en"})
|
||||
}
|
||||
|
||||
if Settings.XepgReplaceMissingImages == true {
|
||||
poster.Src = getCacheImageURL(xepgChannel.TvgLogo)
|
||||
poster.Src = imgc.Image.GetURL(xepgChannel.TvgLogo)
|
||||
epg.Poster = append(epg.Poster, poster)
|
||||
}
|
||||
|
||||
@@ -809,8 +1122,10 @@ func getCategory(program *Program, xmltvProgram *Program, xepgChannel XEPGChanne
|
||||
// Programm Poster Cover aus der XMLTV Datei laden
|
||||
func getPoster(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelStruct) {
|
||||
|
||||
var imgc = Data.Cache.Images
|
||||
|
||||
for _, poster := range xmltvProgram.Poster {
|
||||
poster.Src = getCacheImageURL(poster.Src)
|
||||
poster.Src = imgc.Image.GetURL(poster.Src)
|
||||
program.Poster = append(program.Poster, poster)
|
||||
}
|
||||
|
||||
@@ -818,7 +1133,7 @@ func getPoster(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelS
|
||||
|
||||
if len(xmltvProgram.Poster) == 0 {
|
||||
var poster Poster
|
||||
poster.Src = getCacheImageURL(xepgChannel.TvgLogo)
|
||||
poster.Src = imgc.Image.GetURL(poster.Src)
|
||||
program.Poster = append(program.Poster, poster)
|
||||
}
|
||||
|
||||
@@ -929,6 +1244,18 @@ func createM3UFile() {
|
||||
// XEPG Datenbank bereinigen
|
||||
func cleanupXEPG() {
|
||||
|
||||
//fmt.Println(Settings.Files.M3U)
|
||||
|
||||
var sourceIDs []string
|
||||
|
||||
for source := range Settings.Files.M3U {
|
||||
sourceIDs = append(sourceIDs, source)
|
||||
}
|
||||
|
||||
for source := range Settings.Files.HDHR {
|
||||
sourceIDs = append(sourceIDs, source)
|
||||
}
|
||||
|
||||
showInfo("XEPG:" + fmt.Sprintf("Cleanup database"))
|
||||
Data.XEPG.XEPGCount = 0
|
||||
|
||||
@@ -938,7 +1265,7 @@ func cleanupXEPG() {
|
||||
err := json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
|
||||
if err == nil {
|
||||
|
||||
if indexOfString(xepgChannel.Name, Data.Cache.Streams.Active) == -1 {
|
||||
if indexOfString(xepgChannel.Name+xepgChannel.FileM3UID, Data.Cache.Streams.Active) == -1 {
|
||||
delete(Data.XEPG.Channels, id)
|
||||
} else {
|
||||
if xepgChannel.XActive == true {
|
||||
@@ -946,6 +1273,10 @@ func cleanupXEPG() {
|
||||
}
|
||||
}
|
||||
|
||||
if indexOfString(xepgChannel.FileM3UID, sourceIDs) == -1 {
|
||||
delete(Data.XEPG.Channels, id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ function login() {
|
||||
if (value.length == 0) {
|
||||
inputs[i].style.borderColor = "red"
|
||||
err = true
|
||||
} else {
|
||||
inputs[i].style.borderColor = ""
|
||||
}
|
||||
|
||||
data[key] = value
|
||||
@@ -30,7 +32,6 @@ function login() {
|
||||
if (data.hasOwnProperty("confirm")) {
|
||||
|
||||
if (data["confirm"] != data["password"]) {
|
||||
alert("sdafsd")
|
||||
document.getElementById('password').style.borderColor = "red"
|
||||
document.getElementById('confirm').style.borderColor = "red"
|
||||
|
||||
@@ -44,4 +45,4 @@ function login() {
|
||||
|
||||
form.submit();
|
||||
|
||||
}
|
||||
}
|
||||
+127
-22
@@ -5,6 +5,8 @@ var SEARCH_MAPPING = new Object()
|
||||
var UNDO = new Object()
|
||||
var SERVER_CONNECTION = false
|
||||
var WS_AVAILABLE = false
|
||||
var ACTIVE_MENU_ID:string = ""
|
||||
var LAST_BULK_CHECKBOX:HTMLInputElement = null
|
||||
|
||||
|
||||
// Menü
|
||||
@@ -21,9 +23,8 @@ menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.p
|
||||
|
||||
// Kategorien für die Einstellungen
|
||||
var settingsCategory = new Array()
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api,use_plexAPI,plex.url,plex.token"));settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.missing.epg.mode,xepg.replace.missing.images"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"))
|
||||
|
||||
@@ -52,7 +53,44 @@ function showElement(elmID, type) {
|
||||
case false: cssClass = "none"; break;
|
||||
}
|
||||
|
||||
document.getElementById(elmID).className = cssClass;
|
||||
var element = document.getElementById(elmID)
|
||||
if (element == null) {
|
||||
return
|
||||
}
|
||||
|
||||
element.className = cssClass;
|
||||
}
|
||||
|
||||
function setConnectionState(state:string, text:string = "") {
|
||||
|
||||
var label:string = text
|
||||
if (label == undefined || label.length == 0) {
|
||||
switch (state) {
|
||||
case "online":
|
||||
label = "Connected"
|
||||
break
|
||||
|
||||
case "busy":
|
||||
label = "Syncing"
|
||||
break
|
||||
|
||||
case "offline":
|
||||
label = "Offline"
|
||||
break
|
||||
|
||||
default:
|
||||
label = "Connecting"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var indicator = document.getElementById("connection-indicator")
|
||||
if (indicator == null) {
|
||||
return
|
||||
}
|
||||
|
||||
indicator.className = "status-" + state
|
||||
indicator.innerText = label
|
||||
}
|
||||
|
||||
function changeButtonAction(element, buttonID, attribute) {
|
||||
@@ -145,6 +183,59 @@ function getAllSelectedChannels():string[] {
|
||||
return channels
|
||||
}
|
||||
|
||||
function scheduleChannelRangeSelection(checkbox:HTMLInputElement, event:MouseEvent) {
|
||||
|
||||
var shiftPressed = false
|
||||
if (event != undefined && event.shiftKey == true) {
|
||||
shiftPressed = true
|
||||
}
|
||||
|
||||
// Run after the native checkbox toggle so we copy the final checked state.
|
||||
setTimeout(function() {
|
||||
selectChannelRange(checkbox, shiftPressed)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function selectChannelRange(checkbox:HTMLInputElement, shiftPressed:boolean) {
|
||||
|
||||
if (BULK_EDIT == false || checkbox == undefined || checkbox == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var table = document.getElementById("content_table")
|
||||
if (table == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var trs = table.getElementsByTagName("TR")
|
||||
var visibleCheckboxes:HTMLInputElement[] = new Array()
|
||||
|
||||
for (var i = 1; i < trs.length; i++) {
|
||||
if ((trs[i] as HTMLElement).style.display != "none") {
|
||||
var bulkCheckbox = (trs[i] as HTMLTableRowElement).querySelector("input.bulk") as HTMLInputElement
|
||||
if (bulkCheckbox != null) {
|
||||
visibleCheckboxes.push(bulkCheckbox)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var currentIndex = visibleCheckboxes.indexOf(checkbox)
|
||||
var previousIndex = -1
|
||||
if (LAST_BULK_CHECKBOX != null) {
|
||||
previousIndex = visibleCheckboxes.indexOf(LAST_BULK_CHECKBOX)
|
||||
}
|
||||
|
||||
if (shiftPressed == true && previousIndex > -1 && currentIndex > -1) {
|
||||
var start = Math.min(previousIndex, currentIndex)
|
||||
var end = Math.max(previousIndex, currentIndex)
|
||||
for (var i = start; i <= end; i++) {
|
||||
visibleCheckboxes[i].checked = checkbox.checked
|
||||
}
|
||||
}
|
||||
|
||||
LAST_BULK_CHECKBOX = checkbox
|
||||
}
|
||||
|
||||
function selectAllChannels() {
|
||||
|
||||
var bulk:Boolean = false
|
||||
@@ -174,6 +265,7 @@ function selectAllChannels() {
|
||||
|
||||
}
|
||||
|
||||
LAST_BULK_CHECKBOX = null
|
||||
return
|
||||
}
|
||||
|
||||
@@ -198,6 +290,7 @@ function bulkEdit() {
|
||||
(rows[i] as HTMLInputElement).checked = false
|
||||
}
|
||||
|
||||
LAST_BULK_CHECKBOX = null
|
||||
return
|
||||
}
|
||||
|
||||
@@ -310,7 +403,7 @@ function createSearchObj() {
|
||||
var data = SERVER["xepg"]["epgMapping"]
|
||||
var channels = getObjKeys(data)
|
||||
|
||||
var channelKeys:string[] = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title"]
|
||||
var channelKeys:string[] = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"]
|
||||
|
||||
channels.forEach(id => {
|
||||
|
||||
@@ -331,7 +424,17 @@ function createSearchObj() {
|
||||
|
||||
} else {
|
||||
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " "
|
||||
if (key == "x-xmltv-file") {
|
||||
var xmltvFile = getValueFromProviderFile(data[id][key], "xmltv", "name")
|
||||
|
||||
if (xmltvFile != undefined) {
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + xmltvFile + " "
|
||||
}
|
||||
|
||||
} else {
|
||||
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " "
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -370,17 +473,19 @@ function searchInMapping() {
|
||||
|
||||
function calculateWrapperHeight() {
|
||||
|
||||
if (document.getElementById("box-wrapper")){
|
||||
var elm = document.getElementById("box-wrapper");
|
||||
var content = document.getElementById("content");
|
||||
|
||||
var elm = document.getElementById("box-wrapper");
|
||||
if (elm != null && content != null){
|
||||
|
||||
var divs = new Array("myStreamsBox", "clientInfo", "content");
|
||||
var elementsHeight = 0 - elm.offsetHeight;
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
elementsHeight = elementsHeight + document.getElementById(divs[i]).offsetHeight;
|
||||
var contentTop = content.getBoundingClientRect().top
|
||||
var freeSpace = window.innerHeight - contentTop - 26
|
||||
|
||||
if (freeSpace < 180) {
|
||||
freeSpace = 180
|
||||
}
|
||||
|
||||
elm.style.height = window.innerHeight - elementsHeight + "px";
|
||||
elm.style.height = freeSpace + "px";
|
||||
|
||||
}
|
||||
|
||||
@@ -409,7 +514,7 @@ function changeChannelNumber(element) {
|
||||
})
|
||||
|
||||
for (var i = 0; i < channelNumbers.length; i++) {
|
||||
|
||||
|
||||
if (channelNumbers.indexOf(newNumber) == -1) {
|
||||
break
|
||||
}
|
||||
@@ -423,7 +528,7 @@ function changeChannelNumber(element) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
data[dbID]["x-channelID"] = newNumber.toString()
|
||||
element.value = newNumber
|
||||
|
||||
@@ -462,7 +567,7 @@ function toggleChannelStatus(id:string) {
|
||||
var checkbox = (document.getElementById("active") as HTMLInputElement)
|
||||
status = (checkbox).checked
|
||||
}
|
||||
|
||||
|
||||
|
||||
var ids:string[] = getAllSelectedChannels()
|
||||
if (ids.length == 0) {
|
||||
@@ -483,9 +588,9 @@ function toggleChannelStatus(id:string) {
|
||||
alert(channel["x-name"] + ": Missing XMLTV file / channel")
|
||||
checkbox.checked = false
|
||||
}
|
||||
|
||||
|
||||
channel["x-active"] = false
|
||||
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
@@ -622,9 +727,9 @@ function checkUndo(key:string) {
|
||||
UNDO[key] = JSON.parse(JSON.stringify(SERVER["xepg"][key]));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -647,9 +752,9 @@ function sortSelect(elem) {
|
||||
|
||||
elem.options[i] = tmpAry[i];
|
||||
if(elem.options[i].value == selectedValue) newSelectedIndex = i;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
|
||||
return;
|
||||
}
|
||||
|
||||
+11
-3
@@ -29,9 +29,18 @@ function showLogs(bottom:boolean) {
|
||||
|
||||
var logs = SERVER["log"]["log"]
|
||||
var div = document.getElementById("content_log")
|
||||
var wrapper = document.getElementById("box-wrapper") as HTMLElement
|
||||
var shouldStickToBottom:boolean = bottom
|
||||
|
||||
div.innerHTML = ""
|
||||
|
||||
if (wrapper != null && shouldStickToBottom == false) {
|
||||
var distanceToBottom:number = wrapper.scrollHeight - wrapper.scrollTop - wrapper.clientHeight
|
||||
if (distanceToBottom < 80) {
|
||||
shouldStickToBottom = true
|
||||
}
|
||||
}
|
||||
|
||||
var keys = getObjKeys(logs)
|
||||
|
||||
keys.forEach(logID => {
|
||||
@@ -44,9 +53,8 @@ function showLogs(bottom:boolean) {
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
if (bottom == true) {
|
||||
if (shouldStickToBottom == true && wrapper != null) {
|
||||
|
||||
var wrapper = document.getElementById("box-wrapper");
|
||||
wrapper.scrollTop = wrapper.scrollHeight;
|
||||
|
||||
}
|
||||
@@ -62,4 +70,4 @@ function resetLogs() {
|
||||
var server:Server = new Server(cmd)
|
||||
server.request(data)
|
||||
|
||||
}
|
||||
}
|
||||
+302
-34
@@ -37,6 +37,7 @@ class MainMenuItem extends MainMenu {
|
||||
var item = document.createElement("LI")
|
||||
item.setAttribute("onclick", "javascript: openThisMenu(this)")
|
||||
item.setAttribute("id", this.id)
|
||||
item.setAttribute("data-menu", this.menuKey)
|
||||
var img = this.createIMG(this.imgSrc)
|
||||
var value = this.createValue(this.value)
|
||||
|
||||
@@ -64,7 +65,7 @@ class MainMenuItem extends MainMenu {
|
||||
break
|
||||
|
||||
case "mapping":
|
||||
this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}"]
|
||||
this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}", "{{.mapping.table.edit}}"]
|
||||
break
|
||||
|
||||
}
|
||||
@@ -147,7 +148,7 @@ class Content {
|
||||
var cell:Cell = new Cell()
|
||||
cell.child = true
|
||||
cell.childType = "P"
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
cell.value = data[key]["tuner"]
|
||||
} else {
|
||||
cell.value = "-"
|
||||
@@ -424,11 +425,7 @@ class Content {
|
||||
cell.child = true
|
||||
cell.childType = "IMG"
|
||||
cell.imageURL = data[key]["tvg-logo"]
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
|
||||
tr.appendChild(td)
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
// Kanalname
|
||||
var cell:Cell = new Cell()
|
||||
@@ -436,10 +433,7 @@ class Content {
|
||||
cell.childType = "P"
|
||||
cell.className = data[key]["x-category"]
|
||||
cell.value = data[key]["x-name"]
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
tr.appendChild(td)
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
|
||||
// Playlist
|
||||
@@ -448,10 +442,7 @@ class Content {
|
||||
cell.childType = "P"
|
||||
//cell.value = data[key]["_file.m3u.name"]
|
||||
cell.value = getValueFromProviderFile(data[key]["_file.m3u.id"], "m3u", "name")
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
tr.appendChild(td)
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
|
||||
// Gruppe (group-title)
|
||||
@@ -459,10 +450,7 @@ class Content {
|
||||
cell.child = true
|
||||
cell.childType = "P"
|
||||
cell.value = data[key]["x-group-title"]
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
tr.appendChild(td)
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
// XMLTV Datei
|
||||
var cell:Cell = new Cell()
|
||||
@@ -475,10 +463,7 @@ class Content {
|
||||
cell.value = data[key]["x-xmltv-file"]
|
||||
}
|
||||
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
tr.appendChild(td)
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
// XMLTV Kanal
|
||||
var cell:Cell = new Cell()
|
||||
@@ -490,11 +475,18 @@ class Content {
|
||||
value = data[key]["x-mapping"].substring(0, 20) + "..."
|
||||
}
|
||||
cell.value = value
|
||||
var td = cell.createCell()
|
||||
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
td.id = key
|
||||
tr.appendChild(cell.createCell())
|
||||
|
||||
tr.appendChild(td)
|
||||
var cell:Cell = new Cell()
|
||||
cell.child = true
|
||||
cell.childType = "EDIT"
|
||||
cell.value = "{{.button.edit}}"
|
||||
var editTd = cell.createCell()
|
||||
var editButton = (editTd.firstChild as HTMLInputElement)
|
||||
editButton.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
|
||||
editButton.setAttribute("id", key)
|
||||
editButton.setAttribute("aria-label", "Edit " + data[key]["x-name"])
|
||||
tr.appendChild(editTd)
|
||||
|
||||
rows.push(tr)
|
||||
});
|
||||
@@ -561,6 +553,9 @@ class Cell {
|
||||
(element as HTMLInputElement).checked = this.value;
|
||||
(element as HTMLInputElement).type = "checkbox";
|
||||
(element as HTMLInputElement).className = "bulk hideBulk";
|
||||
(element as HTMLInputElement).addEventListener("click", function(event) {
|
||||
scheduleChannelRangeSelection((element as HTMLInputElement), (event as MouseEvent))
|
||||
})
|
||||
break
|
||||
|
||||
case "BULK_HEAD":
|
||||
@@ -578,6 +573,14 @@ class Cell {
|
||||
element.setAttribute("onerror", "javascript: this.onerror=null;this.src=''" )
|
||||
//onerror="this.onerror=null;this.src='missing.gif';"
|
||||
}
|
||||
break
|
||||
|
||||
case "EDIT":
|
||||
element = document.createElement("INPUT");
|
||||
(element as HTMLInputElement).type = "button";
|
||||
(element as HTMLInputElement).value = this.value;
|
||||
(element as HTMLInputElement).className = "mapping-edit-button";
|
||||
break
|
||||
}
|
||||
|
||||
td.appendChild(element)
|
||||
@@ -683,7 +686,7 @@ class ShowContent extends Content {
|
||||
input.setAttribute("id", "searchMapping")
|
||||
input.setAttribute("placeholder", "{{.button.search}}")
|
||||
input.className = "search"
|
||||
input.setAttribute("onchange", 'javascript: searchInMapping()')
|
||||
input.setAttribute("oninput", 'javascript: searchInMapping()')
|
||||
interaction.appendChild(input)
|
||||
break;
|
||||
|
||||
@@ -824,16 +827,227 @@ class ShowContent extends Content {
|
||||
|
||||
}
|
||||
|
||||
var SHELL_LAYOUT_READY:boolean = false
|
||||
|
||||
function setLayoutMenuState(open:boolean) {
|
||||
if (document.body == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (open == true) {
|
||||
document.body.classList.add("menu-open")
|
||||
} else {
|
||||
document.body.classList.remove("menu-open")
|
||||
}
|
||||
}
|
||||
|
||||
function toggleLayoutMenu() {
|
||||
if (document.body == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var isOpen:boolean = document.body.classList.contains("menu-open")
|
||||
setLayoutMenuState(!isOpen)
|
||||
}
|
||||
|
||||
function closeLayoutMenuIfMobile() {
|
||||
if (window.innerWidth <= 900) {
|
||||
setLayoutMenuState(false)
|
||||
}
|
||||
}
|
||||
|
||||
function setActiveMenu(menuID:string) {
|
||||
|
||||
ACTIVE_MENU_ID = menuID.toString()
|
||||
var menu = document.getElementById("main-menu")
|
||||
if (menu == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var items = menu.getElementsByTagName("LI")
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].classList.remove("menu-active")
|
||||
}
|
||||
|
||||
var activeItem = document.getElementById(ACTIVE_MENU_ID)
|
||||
var activeMenuKey:string = ""
|
||||
if (activeItem != null) {
|
||||
activeItem.classList.add("menu-active")
|
||||
var menuKeyValue = activeItem.getAttribute("data-menu")
|
||||
if (menuKeyValue != null) {
|
||||
activeMenuKey = menuKeyValue
|
||||
}
|
||||
}
|
||||
|
||||
if (document.body != null) {
|
||||
if (activeMenuKey.length > 0) {
|
||||
document.body.setAttribute("data-active-menu", activeMenuKey)
|
||||
} else {
|
||||
document.body.removeAttribute("data-active-menu")
|
||||
}
|
||||
|
||||
if (activeMenuKey == "log") {
|
||||
document.body.classList.add("menu-log-focus")
|
||||
} else {
|
||||
document.body.classList.remove("menu-log-focus")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderStatusCards() {
|
||||
var wrapper = document.getElementById("status-cards")
|
||||
if (wrapper == null || SERVER.hasOwnProperty("clientInfo") == false) {
|
||||
return
|
||||
}
|
||||
|
||||
var info = SERVER["clientInfo"]
|
||||
var errors:number = parseInt(info["errors"], 10)
|
||||
var warnings:number = parseInt(info["warnings"], 10)
|
||||
var cards:any[] = [
|
||||
{label: "Streams", value: info["streams"], tone: "ok"},
|
||||
{label: "EPG Source", value: info["epgSource"], tone: "neutral"},
|
||||
{label: "XEPG Channels", value: info["xepg"], tone: "ok"},
|
||||
{label: "Errors", value: info["errors"], tone: errors > 0 ? "error" : "ok"},
|
||||
{label: "Warnings", value: info["warnings"], tone: warnings > 0 ? "warn" : "ok"},
|
||||
{label: "DVR", value: info["DVR"], tone: "neutral"},
|
||||
]
|
||||
|
||||
wrapper.innerHTML = ""
|
||||
cards.forEach(card => {
|
||||
|
||||
var box = document.createElement("DIV")
|
||||
box.className = "status-card status-card-" + card.tone
|
||||
|
||||
var label = document.createElement("P")
|
||||
label.className = "status-card-label"
|
||||
label.innerText = card.label
|
||||
|
||||
var value = document.createElement("P")
|
||||
value.className = "status-card-value"
|
||||
if (card.value == undefined || card.value == "") {
|
||||
value.innerText = "-"
|
||||
} else {
|
||||
value.innerText = card.value
|
||||
}
|
||||
|
||||
box.appendChild(label)
|
||||
box.appendChild(value)
|
||||
wrapper.appendChild(box)
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function initShellLayout() {
|
||||
|
||||
if (SHELL_LAYOUT_READY == true) {
|
||||
return
|
||||
}
|
||||
|
||||
var toggle = document.getElementById("menu-toggle")
|
||||
if (toggle != null) {
|
||||
toggle.onclick = function() {
|
||||
toggleLayoutMenu()
|
||||
}
|
||||
}
|
||||
|
||||
var overlay = document.getElementById("layout-overlay")
|
||||
if (overlay != null) {
|
||||
overlay.onclick = function() {
|
||||
setLayoutMenuState(false)
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", function(event) {
|
||||
|
||||
if (event.key == "Escape") {
|
||||
setLayoutMenuState(false)
|
||||
showElement("popup", false)
|
||||
return
|
||||
}
|
||||
|
||||
if (event.key == "/") {
|
||||
var target = event.target as HTMLElement
|
||||
var onInput = target.tagName == "INPUT" || target.tagName == "TEXTAREA" || target.tagName == "SELECT"
|
||||
|
||||
if (onInput == true) {
|
||||
return
|
||||
}
|
||||
|
||||
var search = document.getElementById("searchMapping")
|
||||
if (search != null) {
|
||||
event.preventDefault()
|
||||
(search as HTMLInputElement).focus()
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setConnectionState("idle")
|
||||
SHELL_LAYOUT_READY = true
|
||||
}
|
||||
|
||||
function shouldPollLogs():boolean {
|
||||
if (document.hidden == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (document.getElementById("content_log") == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (ACTIVE_MENU_ID.length < 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
var activeItem = document.getElementById(ACTIVE_MENU_ID)
|
||||
if (activeItem == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return activeItem.getAttribute("data-menu") == "log"
|
||||
}
|
||||
|
||||
function PageReady() {
|
||||
|
||||
initShellLayout()
|
||||
|
||||
var server:Server = new Server("getServerConfig")
|
||||
server.request(new Object())
|
||||
|
||||
var bootstrapAttempts:number = 0
|
||||
var maxBootstrapAttempts:number = 5
|
||||
var bootstrapTimer:number = window.setInterval(function() {
|
||||
|
||||
if (SERVER.hasOwnProperty("clientInfo") == true) {
|
||||
window.clearInterval(bootstrapTimer)
|
||||
return
|
||||
}
|
||||
|
||||
if (SERVER_CONNECTION == true) {
|
||||
return
|
||||
}
|
||||
|
||||
bootstrapAttempts++
|
||||
var retryServer:Server = new Server("getServerConfig")
|
||||
retryServer.request(new Object())
|
||||
|
||||
if (bootstrapAttempts >= maxBootstrapAttempts) {
|
||||
window.clearInterval(bootstrapTimer)
|
||||
}
|
||||
|
||||
}, 3000)
|
||||
|
||||
window.addEventListener("resize", function(){
|
||||
if (window.innerWidth > 900) {
|
||||
setLayoutMenuState(false)
|
||||
}
|
||||
calculateWrapperHeight();
|
||||
}, true);
|
||||
|
||||
setInterval(function(){
|
||||
if (shouldPollLogs() == false) {
|
||||
return
|
||||
}
|
||||
updateLog()
|
||||
}, 10000);
|
||||
|
||||
@@ -841,6 +1055,35 @@ function PageReady() {
|
||||
return
|
||||
}
|
||||
|
||||
function isClientInfoHttpURL(value:string):boolean {
|
||||
return /^https?:\/\//i.test(value)
|
||||
}
|
||||
|
||||
function setClientInfoValue(key:string, value:any) {
|
||||
var element = document.getElementById(key)
|
||||
if (element == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var textValue = ""
|
||||
if (value != undefined && value != null) {
|
||||
textValue = String(value)
|
||||
}
|
||||
|
||||
if ((key == "m3u-url" || key == "xepg-url") && isClientInfoHttpURL(textValue)) {
|
||||
element.innerHTML = ""
|
||||
var anchor = document.createElement("A")
|
||||
anchor.href = textValue
|
||||
anchor.target = "_blank"
|
||||
anchor.rel = "noopener noreferrer"
|
||||
anchor.textContent = textValue
|
||||
element.appendChild(anchor)
|
||||
return
|
||||
}
|
||||
|
||||
element.innerHTML = textValue
|
||||
}
|
||||
|
||||
function createLayout() {
|
||||
|
||||
// Client Info
|
||||
@@ -848,11 +1091,10 @@ function createLayout() {
|
||||
var keys = getObjKeys(obj);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
|
||||
if (document.getElementById(keys[i])) {
|
||||
document.getElementById(keys[i]).innerHTML = obj[keys[i]];
|
||||
}
|
||||
setClientInfoValue(keys[i], obj[keys[i]])
|
||||
|
||||
}
|
||||
renderStatusCards()
|
||||
|
||||
if (!document.getElementById("main-menu")) {
|
||||
return
|
||||
@@ -889,13 +1131,32 @@ function createLayout() {
|
||||
|
||||
}
|
||||
|
||||
if (ACTIVE_MENU_ID.length > 0 && document.getElementById(ACTIVE_MENU_ID)) {
|
||||
setActiveMenu(ACTIVE_MENU_ID)
|
||||
}
|
||||
|
||||
var content = document.getElementById("content")
|
||||
var menu = document.getElementById("main-menu")
|
||||
if (ACTIVE_MENU_ID.length == 0 && content != null && menu != null) {
|
||||
|
||||
if (content.innerHTML.replace(/\\s/g, "").length == 0) {
|
||||
var firstItem = menu.getElementsByTagName("LI")[0]
|
||||
if (firstItem != undefined) {
|
||||
firstItem.click()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
function openThisMenu(element) {
|
||||
var id = element.id
|
||||
var content:ShowContent = new ShowContent(id)
|
||||
setActiveMenu(id)
|
||||
content.show()
|
||||
closeLayoutMenuIfMobile()
|
||||
calculateWrapperHeight()
|
||||
|
||||
return
|
||||
@@ -1113,7 +1374,7 @@ function openPopUp(dataType, element) {
|
||||
content.appendRow("{{.playlist.fileM3U.title}}", input)
|
||||
|
||||
// Tuner
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
var text:string[] = new Array()
|
||||
var values:string[] = new Array()
|
||||
|
||||
@@ -1192,7 +1453,7 @@ function openPopUp(dataType, element) {
|
||||
content.appendRow("{{.playlist.fileHDHR.title}}", input)
|
||||
|
||||
// Tuner
|
||||
if (SERVER["settings"]["buffer"] == true) {
|
||||
if (SERVER["settings"]["buffer"] != "-") {
|
||||
var text:string[] = new Array()
|
||||
var values:string[] = new Array()
|
||||
|
||||
@@ -1532,6 +1793,13 @@ function openPopUp(dataType, element) {
|
||||
|
||||
content.description(data["name"])
|
||||
|
||||
// Beschreibung
|
||||
var dbKey:string = "x-description"
|
||||
var input = content.createInput("text", dbKey, data[dbKey])
|
||||
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
content.appendRow("{{.mapping.description.title}}", input)
|
||||
|
||||
// Aktualisierung des Kanalnamens
|
||||
if (data.hasOwnProperty("_uuid.key")) {
|
||||
if (data["_uuid.key"] != "") {
|
||||
@@ -1561,7 +1829,7 @@ function openPopUp(dataType, element) {
|
||||
// Erweitern der EPG Kategorie
|
||||
var dbKey:string = "x-category"
|
||||
var text:string[] = ["-", "Kids (Emby only)", "News", "Movie", "Series", "Sports"]
|
||||
var values:string[] = ["-", "Kids", "News", "Movie", "Series", "Sports"]
|
||||
var values:string[] = ["", "Kids", "News", "Movie", "Series", "Sports"]
|
||||
var select = content.createSelect(text, values, data[dbKey], dbKey)
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
content.appendRow("{{.mapping.epgCategory.title}}", select)
|
||||
|
||||
+80
-7
@@ -18,6 +18,7 @@ class Server {
|
||||
if (this.cmd != "updateLog") {
|
||||
showElement("loading", true)
|
||||
UNDO = new Object()
|
||||
setConnectionState("busy")
|
||||
}
|
||||
|
||||
switch(window.location.protocol) {
|
||||
@@ -29,13 +30,67 @@ class Server {
|
||||
break
|
||||
}
|
||||
|
||||
var url = this.protocol + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token")
|
||||
var wsHost:string = window.location.host
|
||||
if (wsHost == undefined || wsHost.length < 1) {
|
||||
wsHost = window.location.hostname
|
||||
}
|
||||
var url = this.protocol + wsHost + "/data/" + "?Token=" + getCookie("Token")
|
||||
|
||||
data["cmd"] = this.cmd
|
||||
var requestCmd:string = data["cmd"]
|
||||
var ws = new WebSocket(url)
|
||||
var isLogUpdate:boolean = data["cmd"] == "updateLog"
|
||||
var responseReceived:boolean = false
|
||||
var requestFinished:boolean = false
|
||||
var timeoutMs:number = 12000
|
||||
var requestTimeout:number
|
||||
|
||||
var finishRequest = function(state:string, responseSuccess:boolean = false):void {
|
||||
if (requestFinished == true) {
|
||||
return
|
||||
}
|
||||
|
||||
requestFinished = true
|
||||
SERVER_CONNECTION = false
|
||||
window.clearTimeout(requestTimeout)
|
||||
|
||||
if (responseSuccess == true) {
|
||||
if (state == "online") {
|
||||
WS_FAILURE_COUNT = 0
|
||||
}
|
||||
} else {
|
||||
WS_FAILURE_COUNT++
|
||||
}
|
||||
|
||||
if (isLogUpdate == false) {
|
||||
showElement("loading", false)
|
||||
}
|
||||
|
||||
if (state != "") {
|
||||
setConnectionState(state)
|
||||
}
|
||||
}
|
||||
|
||||
requestTimeout = window.setTimeout(function() {
|
||||
console.log("Websocket request timed out.")
|
||||
var timeoutState:string = "offline"
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
timeoutState = "idle"
|
||||
}
|
||||
finishRequest(timeoutState, false)
|
||||
try {
|
||||
ws.close()
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}, timeoutMs)
|
||||
|
||||
ws.onopen = function() {
|
||||
|
||||
WS_AVAILABLE = true
|
||||
if (data["cmd"] != "updateLog") {
|
||||
setConnectionState("busy")
|
||||
}
|
||||
|
||||
console.log("REQUEST (JS):");
|
||||
console.log(data)
|
||||
@@ -50,9 +105,13 @@ class Server {
|
||||
ws.onerror = function(e) {
|
||||
|
||||
console.log("No websocket connection to xTeVe could be established. Check your network configuration.")
|
||||
SERVER_CONNECTION = false
|
||||
var errorState:string = "offline"
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
errorState = "idle"
|
||||
}
|
||||
finishRequest(errorState, false)
|
||||
|
||||
if (WS_AVAILABLE == false) {
|
||||
if (WS_AVAILABLE == false && isLogUpdate == false && requestCmd != "getServerConfig") {
|
||||
alert("No websocket connection to xTeVe could be established. Check your network configuration.")
|
||||
}
|
||||
|
||||
@@ -60,9 +119,8 @@ class Server {
|
||||
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
|
||||
SERVER_CONNECTION = false
|
||||
showElement("loading", false)
|
||||
responseReceived = true
|
||||
finishRequest("online", true)
|
||||
|
||||
console.log("RESPONSE:");
|
||||
var response = JSON.parse(e.data);
|
||||
@@ -74,6 +132,7 @@ class Server {
|
||||
}
|
||||
|
||||
if (response["status"] == false) {
|
||||
setConnectionState("offline")
|
||||
|
||||
alert(response["err"])
|
||||
|
||||
@@ -135,13 +194,27 @@ class Server {
|
||||
createLayout()
|
||||
|
||||
}
|
||||
|
||||
ws.onclose = function() {
|
||||
if (responseReceived == true) {
|
||||
return
|
||||
}
|
||||
|
||||
var closeState:string = "offline"
|
||||
if (isLogUpdate == true && WS_FAILURE_COUNT < 2) {
|
||||
closeState = "idle"
|
||||
}
|
||||
finishRequest(closeState, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var WS_FAILURE_COUNT:number = 0
|
||||
|
||||
function getCookie(name) {
|
||||
var value = "; " + document.cookie;
|
||||
var parts = value.split("; " + name + "=");
|
||||
if (parts.length == 2) return parts.pop().split(";").shift();
|
||||
}
|
||||
}
|
||||
+196
-28
@@ -75,6 +75,35 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "plex.url":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.plexURL.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "plex.url", data)
|
||||
input.setAttribute("placeholder", "{{.settings.plexURL.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "plex.token":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.plexToken.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("password", "plex.token", data)
|
||||
input.setAttribute("placeholder", "{{.settings.plexToken.placeholder}}")
|
||||
input.setAttribute("autocomplete", "off")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "buffer.timeout":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.bufferTimeout.title}}" + ":"
|
||||
@@ -89,6 +118,62 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "ffmpeg.path":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.ffmpegPath.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "ffmpeg.path", data)
|
||||
input.setAttribute("placeholder", "{{.settings.ffmpegPath.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "ffmpeg.options":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.ffmpegOptions.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "ffmpeg.options", data)
|
||||
input.setAttribute("placeholder", "{{.settings.ffmpegOptions.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "vlc.path":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.vlcPath.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "vlc.path", data)
|
||||
input.setAttribute("placeholder", "{{.settings.vlcPath.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "vlc.options":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.vlcOptions.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "vlc.options", data)
|
||||
input.setAttribute("placeholder", "{{.settings.vlcOptions.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
// Checkboxen
|
||||
case "authentication.web":
|
||||
var tdLeft = document.createElement("TD")
|
||||
@@ -216,20 +301,6 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "buffer":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.streamBuffering.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createCheckbox(settingsKey)
|
||||
input.checked = data
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "api":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.api.title}}" + ":"
|
||||
@@ -244,10 +315,40 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
// Select
|
||||
case "tuner":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.tuner.title}}" + ":"
|
||||
case "use_plexAPI":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.usePlexAPI.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createCheckbox(settingsKey)
|
||||
input.checked = data
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
// Select
|
||||
case "xepg.missing.epg.mode":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.xepgMissingEPGMode.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var text:any[] = ["{{.settings.xepgMissingEPGMode.info_strict}}", "{{.settings.xepgMissingEPGMode.info_relaxed}}"]
|
||||
var values:any[] = ["strict", "relaxed"]
|
||||
|
||||
var select = content.createSelect(text, values, data, settingsKey)
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(select)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "tuner":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.tuner.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var text = new Array()
|
||||
@@ -314,19 +415,50 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "buffer":
|
||||
var tdLeft = document.createElement("TD")
|
||||
tdLeft.innerHTML = "{{.settings.streamBuffering.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var text:any[] = ["{{.settings.streamBuffering.info_false}}", "xTeVe: ({{.settings.streamBuffering.info_xteve}})", "FFmpeg: ({{.settings.streamBuffering.info_ffmpeg}})", "VLC: ({{.settings.streamBuffering.info_vlc}})"]
|
||||
var values:any[] = ["-", "xteve", "ffmpeg", "vlc"]
|
||||
|
||||
var select = content.createSelect(text, values, data, settingsKey)
|
||||
select.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(select)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "udpxy":
|
||||
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.udpxy.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "udpxy", data)
|
||||
input.setAttribute("placeholder", "{{.settings.udpxy.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
return setting
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
createDescription(settingsKey:string):any {
|
||||
|
||||
var description = document.createElement("TR")
|
||||
var text:string
|
||||
switch (settingsKey) {
|
||||
|
||||
|
||||
case "authentication.web":
|
||||
text = "{{.settings.authenticationWEB.description}}"
|
||||
break
|
||||
@@ -381,6 +513,30 @@ class SettingsCategory {
|
||||
text = "{{.settings.userAgent.description}}"
|
||||
break
|
||||
|
||||
case "plex.url":
|
||||
text = "{{.settings.plexURL.description}}"
|
||||
break
|
||||
|
||||
case "plex.token":
|
||||
text = "{{.settings.plexToken.description}}"
|
||||
break
|
||||
|
||||
case "ffmpeg.path":
|
||||
text = "{{.settings.ffmpegPath.description}}"
|
||||
break
|
||||
|
||||
case "ffmpeg.options":
|
||||
text = "{{.settings.ffmpegOptions.description}}"
|
||||
break
|
||||
|
||||
case "vlc.path":
|
||||
text = "{{.settings.vlcPath.description}}"
|
||||
break
|
||||
|
||||
case "vlc.options":
|
||||
text = "{{.settings.vlcOptions.description}}"
|
||||
break
|
||||
|
||||
case "epgSource":
|
||||
text = "{{.settings.epgSource.description}}"
|
||||
break
|
||||
@@ -397,6 +553,10 @@ class SettingsCategory {
|
||||
text = "{{.settings.api.description}}"
|
||||
break
|
||||
|
||||
case "use_plexAPI":
|
||||
text = "{{.settings.usePlexAPI.description}}"
|
||||
break
|
||||
|
||||
case "files.update":
|
||||
text = "{{.settings.filesUpdate.description}}"
|
||||
break
|
||||
@@ -405,14 +565,22 @@ class SettingsCategory {
|
||||
text = "{{.settings.cacheImages.description}}"
|
||||
break
|
||||
|
||||
case "xepg.replace.missing.images":
|
||||
text = "{{.settings.replaceEmptyImages.description}}"
|
||||
case "xepg.replace.missing.images":
|
||||
text = "{{.settings.replaceEmptyImages.description}}"
|
||||
break
|
||||
|
||||
case "xepg.missing.epg.mode":
|
||||
text = "{{.settings.xepgMissingEPGMode.description}}"
|
||||
break
|
||||
|
||||
case "udpxy":
|
||||
text = "{{.settings.udpxy.description}}"
|
||||
break
|
||||
|
||||
default:
|
||||
text = ""
|
||||
break
|
||||
|
||||
|
||||
}
|
||||
|
||||
var tdLeft = document.createElement("TD")
|
||||
@@ -425,7 +593,7 @@ class SettingsCategory {
|
||||
|
||||
description.appendChild(tdLeft)
|
||||
description.appendChild(tdRight)
|
||||
|
||||
|
||||
return description
|
||||
|
||||
}
|
||||
@@ -445,12 +613,12 @@ class SettingsCategoryItem extends SettingsCategory {
|
||||
createCategory():void {
|
||||
var headline = this.createCategoryHeadline(this.headline)
|
||||
var settingsKeys = this.settingsKeys
|
||||
|
||||
|
||||
var doc = document.getElementById(this.DocumentID)
|
||||
doc.appendChild(headline)
|
||||
|
||||
// Tabelle für die Kategorie erstellen
|
||||
|
||||
|
||||
var table = document.createElement("TABLE")
|
||||
|
||||
var keys = settingsKeys.split(",")
|
||||
@@ -491,7 +659,7 @@ function showSettings() {
|
||||
for (let i = 0; i < settingsCategory.length; i++) {
|
||||
settingsCategory[i].createCategory()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
@@ -553,7 +721,7 @@ function saveSettings() {
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
var data = new Object()
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"./src"
|
||||
"xteve/src"
|
||||
)
|
||||
|
||||
// GitHubStruct : GitHub Account. Über diesen Account werden die Updates veröffentlicht
|
||||
@@ -35,21 +35,19 @@ var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-
|
||||
Update: Automatic updates from the GitHub repository [true|false]
|
||||
*/
|
||||
|
||||
// Name : Programname
|
||||
// Name : Programmname
|
||||
const Name = "xTeVe"
|
||||
|
||||
// Version : Version, die Build Nummer wird in der main func geparst.
|
||||
const Version = "2.0.3.0030"
|
||||
// Can be overwritten at build time: -ldflags "-X main.Version=..."
|
||||
var Version = "2.2.0.0200"
|
||||
|
||||
// DBVersion : Datanbank Version
|
||||
const DBVersion = "2.0.0"
|
||||
const DBVersion = "2.1.0"
|
||||
|
||||
// APIVersion : API Version
|
||||
const APIVersion = "1.1.0"
|
||||
|
||||
// Dev : Aktiviert den Entwicklungsmodus. Für den Webserver werden dann die lokalen Dateien verwendet.
|
||||
const Dev = false
|
||||
|
||||
var homeDirectory = fmt.Sprintf("%s%s.%s%s", src.GetUserHomeDirectory(), string(os.PathSeparator), strings.ToLower(Name), string(os.PathSeparator))
|
||||
var samplePath = fmt.Sprintf("%spath%sto%sxteve%s", string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator))
|
||||
var sampleRestore = fmt.Sprintf("%spath%sto%sfile%s", string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator))
|
||||
@@ -63,6 +61,9 @@ var debug = flag.Int("debug", 0, ": Debug level [0 - 3] (default: 0)")
|
||||
var info = flag.Bool("info", false, ": Show system info")
|
||||
var h = flag.Bool("h", false, ": Show help")
|
||||
|
||||
// Aktiviert den Entwicklungsmodus. Für den Webserver werden dann die lokalen Dateien verwendet.
|
||||
var dev = flag.Bool("dev", false, ": Activates the developer mode, the source code must be available. The local files for the web interface are used.")
|
||||
|
||||
func main() {
|
||||
|
||||
// Build-Nummer von der Versionsnummer trennen
|
||||
@@ -73,7 +74,6 @@ func main() {
|
||||
system.Branch = GitHub.Branch
|
||||
system.Build = build[len(build)-1:][0]
|
||||
system.DBVersion = DBVersion
|
||||
system.Dev = Dev
|
||||
system.GitHub = GitHub
|
||||
system.Name = Name
|
||||
system.Version = strings.Join(build[0:len(build)-1], ".")
|
||||
@@ -122,6 +122,8 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
system.Dev = *dev
|
||||
|
||||
// Systeminformationen anzeigen
|
||||
if *info {
|
||||
|
||||
@@ -189,7 +191,6 @@ func main() {
|
||||
err = src.BinaryUpdate()
|
||||
if err != nil {
|
||||
src.ShowError(err, 0)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
err = src.StartSystem(false)
|
||||
|
||||
Reference in new issue
Block a user