Compare commits
No commits in common. "main" and "main" have entirely different histories.
@ -1,3 +1,4 @@
|
|||||||
.git
|
.svn
|
||||||
db.sqlite*
|
db.sqlite
|
||||||
out/
|
out/**/*.o
|
||||||
|
out/**/*.d
|
||||||
|
@ -6,51 +6,15 @@ jobs:
|
|||||||
Build-All:
|
Build-All:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: node:23-bookworm-slim
|
valid_volumes: ['/opt/keys']
|
||||||
valid_volumes:
|
|
||||||
- '/opt/keys'
|
|
||||||
- '/opt/deps'
|
|
||||||
volumes:
|
volumes:
|
||||||
- /opt/keys:/opt/keys
|
- /opt/keys:/opt/keys
|
||||||
- /opt/deps:/opt/deps
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install build dependencies
|
- name: check out code
|
||||||
run: >
|
|
||||||
apt update && apt install -y \
|
|
||||||
build-essential \
|
|
||||||
clang-19 \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
docker.io \
|
|
||||||
doxygen \
|
|
||||||
file \
|
|
||||||
gcc-aarch64-linux-gnu \
|
|
||||||
git \
|
|
||||||
graphviz \
|
|
||||||
libgpgme11 \
|
|
||||||
libssl-dev \
|
|
||||||
mingw-w64 \
|
|
||||||
rsync \
|
|
||||||
unzip \
|
|
||||||
zip \
|
|
||||||
zlib1g-dev
|
|
||||||
- name: Get code
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup environment
|
- run: ln -s /opt/keys .keys
|
||||||
run: |
|
|
||||||
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100
|
|
||||||
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100
|
|
||||||
ln -s /opt/keys .keys
|
|
||||||
ln -sf /opt/deps/ios_toolchain deps/
|
|
||||||
ln -sf /opt/deps/macos_toolchain deps/
|
|
||||||
- name: Build documentation
|
|
||||||
run: |
|
|
||||||
mkdir -p out/html/ ~/.ssh/
|
|
||||||
make docs
|
|
||||||
echo 'pildefriends ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKD3Kde5vDO0TrMBDK0IGGeNGe/XinWAZkSQ/rXxwUjt' >> ~/.ssh/known_hosts
|
|
||||||
rsync -avP --delete -e "ssh -i /opt/keys/ssh.ed25519" out/html/ tfdocs@pildefriends:docs/html/
|
|
||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
@ -60,12 +24,14 @@ jobs:
|
|||||||
uses: android-actions/setup-android@v3
|
uses: android-actions/setup-android@v3
|
||||||
with:
|
with:
|
||||||
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
|
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
|
||||||
- name: Docker build
|
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 gcc-aarch64-linux-gnu
|
||||||
run: DOCKER_BUILDKIT=1 docker build .
|
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
|
||||||
- name: Build
|
- run: docker build .
|
||||||
run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all dist docs
|
- uses: actions/upload-artifact@v3
|
||||||
- name: Upload artifacts
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
with:
|
||||||
name: dist
|
path: |
|
||||||
path: dist/*
|
out/TildeFriends-release.fdroid.apk
|
||||||
|
out/winrelease/tildefriends.exe
|
||||||
|
out/tildefriends-x86_64.AppImage
|
||||||
|
out/release/tildefriends.standalone
|
||||||
|
out/armrelease/tildefriends.standalone
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,13 +1,11 @@
|
|||||||
build/
|
build/
|
||||||
*.core
|
*.core
|
||||||
db.*
|
db.*
|
||||||
deps/ios_toolchain
|
deps/ios_toolchain/
|
||||||
deps/macos_toolchain
|
|
||||||
deps/openssl/
|
deps/openssl/
|
||||||
dist/
|
dist/
|
||||||
.flatpak-builder
|
.flatpak-builder
|
||||||
.keys
|
.keys
|
||||||
**/.DS_Store
|
|
||||||
logs/
|
logs/
|
||||||
**/node_modules
|
**/node_modules
|
||||||
out
|
out
|
||||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -26,6 +26,6 @@
|
|||||||
[submodule "deps/c-ares"]
|
[submodule "deps/c-ares"]
|
||||||
path = deps/c-ares
|
path = deps/c-ares
|
||||||
url = https://github.com/c-ares/c-ares.git
|
url = https://github.com/c-ares/c-ares.git
|
||||||
[submodule "deps/zsign"]
|
[submodule "docs"]
|
||||||
path = deps/zsign
|
path = docs
|
||||||
url = https://github.com/zhlynn/zsign.git
|
url = https://dev.tildefriends.net/cory/tildefriends.wiki.git
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
FROM bitnami/minideb:bookworm AS build
|
FROM bitnami/minideb:bullseye AS build
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
gcc \
|
gcc \
|
||||||
libc6-dev \
|
libc6-dev \
|
||||||
perl \
|
libssl-dev \
|
||||||
make
|
make
|
||||||
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
RUN make -C /app -j $(nproc) release
|
RUN make -C /app -j $(nproc) release
|
||||||
|
|
||||||
FROM bitnami/minideb:bookworm
|
FROM bitnami/minideb:bullseye
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
libssl1.1
|
||||||
|
|
||||||
COPY --from=build /app/out/release/tildefriends /app/out/release/tildefriends
|
COPY --from=build /app/out/release/tildefriends /app/out/release/tildefriends
|
||||||
COPY --from=build /app/apps /app/apps
|
COPY --from=build /app/apps /app/apps
|
||||||
|
14
Doxyfile
14
Doxyfile
@ -943,9 +943,7 @@ WARN_LOGFILE =
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = README.md \
|
INPUT = src/
|
||||||
docs/ \
|
|
||||||
src/
|
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
@ -1112,7 +1110,7 @@ FILTER_SOURCE_PATTERNS =
|
|||||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||||
# and want to reuse the introduction page also for the doxygen output.
|
# and want to reuse the introduction page also for the doxygen output.
|
||||||
|
|
||||||
USE_MDFILE_AS_MAINPAGE = README.md
|
USE_MDFILE_AS_MAINPAGE =
|
||||||
|
|
||||||
# The Fortran standard specifies that for fixed formatted Fortran code all
|
# The Fortran standard specifies that for fixed formatted Fortran code all
|
||||||
# characters from position 72 are to be considered as comment. A common
|
# characters from position 72 are to be considered as comment. A common
|
||||||
@ -1682,7 +1680,7 @@ DISABLE_INDEX = NO
|
|||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_TREEVIEW = YES
|
GENERATE_TREEVIEW = NO
|
||||||
|
|
||||||
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
|
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
|
||||||
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
|
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
|
||||||
@ -2270,7 +2268,7 @@ GENERATE_AUTOGEN_DEF = NO
|
|||||||
# database with symbols found by doxygen stored in tables.
|
# database with symbols found by doxygen stored in tables.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
#GENERATE_SQLITE3 = NO
|
GENERATE_SQLITE3 = NO
|
||||||
|
|
||||||
# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be
|
# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be
|
||||||
# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put
|
# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put
|
||||||
@ -2278,7 +2276,7 @@ GENERATE_AUTOGEN_DEF = NO
|
|||||||
# The default directory is: sqlite3.
|
# The default directory is: sqlite3.
|
||||||
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
||||||
|
|
||||||
#SQLITE3_OUTPUT = sqlite3
|
SQLITE3_OUTPUT = sqlite3
|
||||||
|
|
||||||
# The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db
|
# The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db
|
||||||
# database file will be recreated with each doxygen run. If set to NO, doxygen
|
# database file will be recreated with each doxygen run. If set to NO, doxygen
|
||||||
@ -2286,7 +2284,7 @@ GENERATE_AUTOGEN_DEF = NO
|
|||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
||||||
|
|
||||||
#SQLITE3_RECREATE_DB = YES
|
SQLITE3_RECREATE_DB = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the Perl module output
|
# Configuration options related to the Perl module output
|
||||||
|
370
GNUmakefile
370
GNUmakefile
@ -16,14 +16,11 @@ MAKEFLAGS += --no-builtin-rules
|
|||||||
## LD := Linker.
|
## LD := Linker.
|
||||||
## ANDROID_SDK := Path to the Android SDK.
|
## ANDROID_SDK := Path to the Android SDK.
|
||||||
|
|
||||||
VERSION_CODE := 35
|
VERSION_CODE := 32
|
||||||
VERSION_CODE_IOS := 12
|
VERSION_NUMBER := 0.0.27-wip
|
||||||
VERSION_NUMBER := 0.0.30-wip
|
|
||||||
VERSION_NAME := This program kills fascists.
|
VERSION_NAME := This program kills fascists.
|
||||||
|
|
||||||
IPHONEOS_VERSION_MIN=14.0
|
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip
|
||||||
|
|
||||||
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3490100.zip
|
|
||||||
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
|
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
|
||||||
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||||
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
|
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
|
||||||
@ -36,27 +33,21 @@ UNAME_M := $(shell uname -m)
|
|||||||
ANDROID_SDK ?= ~/Android/Sdk
|
ANDROID_SDK ?= ~/Android/Sdk
|
||||||
BUNDLETOOL = out/bundletool.jar
|
BUNDLETOOL = out/bundletool.jar
|
||||||
|
|
||||||
HAVE_WIN :=
|
HAVE_WIN := 0
|
||||||
HAVE_CROSS_AARCH64 :=
|
HAVE_CROSS_AARCH64 := 0
|
||||||
USE_SYSTEM_SSL :=
|
|
||||||
|
|
||||||
export SOURCE_DATE_EPOCH=1
|
export SOURCE_DATE_EPOCH=1
|
||||||
export TZ=UTC
|
export TZ=UTC
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
BUILD_TYPES := debug release iosdebug iosrelease iossimdebug iossimrelease
|
BUILD_TYPES := macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease
|
||||||
HAVE_ANDROID = 0
|
|
||||||
HAVE_LINUX_IOS = 0
|
|
||||||
HAVE_LINUX_MACOS = 0
|
|
||||||
HAVE_WIN = 0
|
|
||||||
else ifeq ($(UNAME_S),Linux)
|
else ifeq ($(UNAME_S),Linux)
|
||||||
BUILD_TYPES := debug release
|
BUILD_TYPES := debug release
|
||||||
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1)
|
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1,0)
|
||||||
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1)
|
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1,0)
|
||||||
HAVE_LINUX_MACOS = $(if $(shell which deps/macos_toolchain/bin/oa64-clang),1)
|
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1,0)
|
||||||
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1)
|
|
||||||
ifneq ($(UNAME_M),aarch64)
|
ifneq ($(UNAME_M),aarch64)
|
||||||
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1)
|
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1,0)
|
||||||
endif
|
endif
|
||||||
else ifeq ($(UNAME_S),Haiku)
|
else ifeq ($(UNAME_S),Haiku)
|
||||||
BUILD_TYPES := debug release
|
BUILD_TYPES := debug release
|
||||||
@ -65,11 +56,6 @@ LDFLAGS += \
|
|||||||
-lbsd \
|
-lbsd \
|
||||||
-lnetwork \
|
-lnetwork \
|
||||||
-Wno-stringop-overflow
|
-Wno-stringop-overflow
|
||||||
USE_SYSTEM_SSL := 1
|
|
||||||
HAVE_ANDROID = 0
|
|
||||||
HAVE_LINUX_IOS = 0
|
|
||||||
HAVE_LINUX_MACOS = 0
|
|
||||||
HAVE_WIN = 0
|
|
||||||
else ifeq ($(UNAME_S),OpenBSD)
|
else ifeq ($(UNAME_S),OpenBSD)
|
||||||
BUILD_TYPES := debug release
|
BUILD_TYPES := debug release
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
@ -77,24 +63,18 @@ CFLAGS += \
|
|||||||
LDFLAGS += \
|
LDFLAGS += \
|
||||||
-lexecinfo \
|
-lexecinfo \
|
||||||
-lc++abi
|
-lc++abi
|
||||||
HAVE_ANDROID :=
|
HAVE_ANDROID := 0
|
||||||
HAVE_LINUX_IOS :=
|
HAVE_LINUX_IOS := 0
|
||||||
HAVE_LINUX_MACOS :=
|
|
||||||
USE_SYSTEM_SSL := 1
|
|
||||||
else
|
else
|
||||||
$(error Unexpected host platform $(UNAME_S).)
|
$(error Unexpected host platform $(UNAME_S).)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Everything is set above.
|
|
||||||
$(info Building Tilde Friends $(VERSION_NUMBER) android=$(if $(HAVE_ANDROID),1,0) win=$(if $(HAVE_WIN),1,0) cross_aarch64=$(if $(HAVE_CROSS_AARCH64),1,0) cross_ios=$(if $(HAVE_LINUX_IOS),1,0) cross_macos=$(if $(HAVE_LINUX_MACOS),1,0) system_ssl=$(if $(USE_SYSTEM_SSL),1,0))
|
|
||||||
|
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-std=gnu11 \
|
-std=gnu11 \
|
||||||
-Wall \
|
-Wall \
|
||||||
-Wextra \
|
-Wextra \
|
||||||
-Wno-cast-function-type-mismatch \
|
|
||||||
-Wno-unknown-warning-option \
|
|
||||||
-Wno-unused-parameter \
|
-Wno-unused-parameter \
|
||||||
|
-Wno-unknown-warning-option \
|
||||||
-MMD \
|
-MMD \
|
||||||
-MP \
|
-MP \
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
@ -103,7 +83,8 @@ CFLAGS += \
|
|||||||
-g
|
-g
|
||||||
LDFLAGS += \
|
LDFLAGS += \
|
||||||
-Wno-attributes \
|
-Wno-attributes \
|
||||||
-Wno-aggressive-loop-optimizations
|
-Wno-aggressive-loop-optimizations \
|
||||||
|
-flto=auto
|
||||||
|
|
||||||
ANDROID_MIN_SDK_VERSION := 24
|
ANDROID_MIN_SDK_VERSION := 24
|
||||||
ANDROID_TARGET_SDK_VERSION := 34
|
ANDROID_TARGET_SDK_VERSION := 34
|
||||||
@ -146,7 +127,6 @@ WINDOWS_TARGETS := \
|
|||||||
out/winrelease/tildefriends.exe
|
out/winrelease/tildefriends.exe
|
||||||
ifeq ($(HAVE_WIN),1)
|
ifeq ($(HAVE_WIN),1)
|
||||||
BUILD_TYPES += windebug winrelease
|
BUILD_TYPES += windebug winrelease
|
||||||
all: out/windebug/tildefriends.standalone.exe out/winrelease/tildefriends.standalone.exe
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
AARCH64_TARGETS := \
|
AARCH64_TARGETS := \
|
||||||
@ -156,28 +136,12 @@ ifeq ($(HAVE_CROSS_AARCH64),1)
|
|||||||
BUILD_TYPES += armdebug armrelease
|
BUILD_TYPES += armdebug armrelease
|
||||||
endif
|
endif
|
||||||
|
|
||||||
HOST_TARGETS := \
|
LINUX_TARGETS := \
|
||||||
out/debug/tildefriends \
|
out/debug/tildefriends \
|
||||||
out/release/tildefriends
|
out/release/tildefriends
|
||||||
ifeq ($(UNAME_S),Darwin)
|
|
||||||
MACOS_TARGETS := \
|
MACOS_TARGETS := \
|
||||||
out/debug/tildefriends \
|
out/macosdebug/tildefriends \
|
||||||
out/release/tildefriends
|
out/macosrelease/tildefriends
|
||||||
else ifeq ($(UNAME_S),Linux)
|
|
||||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
|
||||||
MACOS_TARGETS := \
|
|
||||||
out/macosdebug-arm/tildefriends \
|
|
||||||
out/macosrelease-arm/tildefriends \
|
|
||||||
out/macosdebug-x86_64/tildefriends \
|
|
||||||
out/macosrelease-x86_64/tildefriends
|
|
||||||
all: out/macosdebug/tildefriends.standalone
|
|
||||||
all: out/macosrelease/tildefriends.standalone
|
|
||||||
else
|
|
||||||
MACOS_TARGETS :=
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
MACOS_TARGETS :=
|
|
||||||
endif
|
|
||||||
IOS_TARGETS := \
|
IOS_TARGETS := \
|
||||||
out/iosdebug/tildefriends \
|
out/iosdebug/tildefriends \
|
||||||
out/iosrelease/tildefriends
|
out/iosrelease/tildefriends
|
||||||
@ -191,14 +155,6 @@ ifeq ($(HAVE_LINUX_IOS),1)
|
|||||||
BUILD_TYPES += iosdebug iosrelease
|
BUILD_TYPES += iosdebug iosrelease
|
||||||
all: $(IOS_APPS)
|
all: $(IOS_APPS)
|
||||||
endif
|
endif
|
||||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
|
||||||
BUILD_TYPES += \
|
|
||||||
macosdebug-arm \
|
|
||||||
macosrelease-arm \
|
|
||||||
macosdebug-x86_64 \
|
|
||||||
macosrelease-x86_64
|
|
||||||
all: $(IOS_APPS)
|
|
||||||
endif
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
all: $(IOS_APPS) \
|
all: $(IOS_APPS) \
|
||||||
out/tildefriends-iossimdebug.app/tildefriends \
|
out/tildefriends-iossimdebug.app/tildefriends \
|
||||||
@ -213,38 +169,35 @@ DEBUG_TARGETS := \
|
|||||||
out/windebug/tildefriends.exe \
|
out/windebug/tildefriends.exe \
|
||||||
out/iosdebug/tildefriends \
|
out/iosdebug/tildefriends \
|
||||||
out/iossimdebug/tildefriends \
|
out/iossimdebug/tildefriends \
|
||||||
|
out/macosdebug/tildefriends \
|
||||||
out/androiddebug/tildefriends \
|
out/androiddebug/tildefriends \
|
||||||
out/androiddebug-armv7a/tildefriends \
|
out/androiddebug-armv7a/tildefriends \
|
||||||
out/androiddebug-x86_64/tildefriends \
|
out/androiddebug-x86_64/tildefriends \
|
||||||
out/androiddebug-x86/tildefriends \
|
out/androiddebug-x86/tildefriends \
|
||||||
out/armdebug/tildefriends \
|
out/armdebug/tildefriends
|
||||||
out/macosdebug-arm/tildefriends \
|
|
||||||
out/macosdebug-x86_64/tildefriends
|
|
||||||
RELEASE_TARGETS := \
|
RELEASE_TARGETS := \
|
||||||
out/release/tildefriends \
|
out/release/tildefriends \
|
||||||
out/winrelease/tildefriends.exe \
|
out/winrelease/tildefriends.exe \
|
||||||
out/iosrelease/tildefriends \
|
out/iosrelease/tildefriends \
|
||||||
out/iossimrelease/tildefriends \
|
out/iossimrelease/tildefriends \
|
||||||
|
out/macosrelease/tildefriends \
|
||||||
out/androidrelease/tildefriends \
|
out/androidrelease/tildefriends \
|
||||||
out/androidrelease-armv7a/tildefriends \
|
out/androidrelease-armv7a/tildefriends \
|
||||||
out/androidrelease-x86_64/tildefriends \
|
out/androidrelease-x86_64/tildefriends \
|
||||||
out/androidrelease-x86/tildefriends \
|
out/androidrelease-x86/tildefriends \
|
||||||
out/armrelease/tildefriends \
|
out/armrelease/tildefriends
|
||||||
out/macosrelease-arm/tildefriends \
|
|
||||||
out/macosrelease-x86_64/tildefriends
|
|
||||||
ALL_TARGETS = $(DEBUG_TARGETS) $(RELEASE_TARGETS)
|
ALL_TARGETS = $(DEBUG_TARGETS) $(RELEASE_TARGETS)
|
||||||
ANDROID_RELEASE_TARGETS := $(filter-out $(DEBUG_TARGETS),$(ANDROID_TARGETS))
|
ANDROID_RELEASE_TARGETS := $(filter-out $(DEBUG_TARGETS),$(ANDROID_TARGETS))
|
||||||
NONANDROID_RELEASE_TARGETS := $(filter-out $(ANDROID_ARM64_TARGETS),$(RELEASE_TARGETS))
|
NONANDROID_RELEASE_TARGETS := $(filter-out $(ANDROID_ARM64_TARGETS),$(RELEASE_TARGETS))
|
||||||
NONANDROID_TARGETS := $(filter-out $(ANDROID_TARGETS),$(ALL_TARGETS))
|
NONANDROID_TARGETS := $(filter-out $(ANDROID_TARGETS),$(ALL_TARGETS))
|
||||||
NONMACOS_TARGETS := $(filter-out $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS),$(ALL_TARGETS))
|
NONMACOS_TARGETS := $(filter-out $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS),$(ALL_TARGETS))
|
||||||
|
DEADSTRIP_TARGETS := $(filter-out $(ANDROID_TARGETS),$(NONMACOS_TARGETS))
|
||||||
ifneq ($(UNAME_S),OpenBSD)
|
ifneq ($(UNAME_S),OpenBSD)
|
||||||
$(NONMACOS_TARGETS): LDFLAGS += -static-libgcc
|
$(NONMACOS_TARGETS): LDFLAGS += -static-libgcc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(NONANDROID_TARGETS): CFLAGS += -fno-omit-frame-pointer
|
$(NONANDROID_TARGETS): CFLAGS += -fno-omit-frame-pointer
|
||||||
$(filter-out $(WINDOWS_TARGETS),$(ALL_TARGETS)): LDFLAGS += \
|
$(filter-out $(WINDOWS_TARGETS),$(ALL_TARGETS)): LDFLAGS += -rdynamic
|
||||||
-rdynamic \
|
|
||||||
-gz=zlib
|
|
||||||
$(ANDROID_TARGETS): CFLAGS += \
|
$(ANDROID_TARGETS): CFLAGS += \
|
||||||
--sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot \
|
--sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/sysroot \
|
||||||
-fPIC \
|
-fPIC \
|
||||||
@ -257,7 +210,8 @@ $(ANDROID_TARGETS): LDFLAGS += --sysroot $(ANDROID_NDK)/toolchains/llvm/prebuilt
|
|||||||
$(DEBUG_TARGETS): CFLAGS += -DDEBUG -Og
|
$(DEBUG_TARGETS): CFLAGS += -DDEBUG -Og
|
||||||
$(DEBUG_TARGETS): LDFLAGS += -Og
|
$(DEBUG_TARGETS): LDFLAGS += -Og
|
||||||
$(RELEASE_TARGETS): CFLAGS += \
|
$(RELEASE_TARGETS): CFLAGS += \
|
||||||
-DNDEBUG
|
-DNDEBUG \
|
||||||
|
-flto
|
||||||
$(ANDROID_RELEASE_TARGETS): CFLAGS += -Oz
|
$(ANDROID_RELEASE_TARGETS): CFLAGS += -Oz
|
||||||
$(ANDROID_RELEASE_TARGETS): LDFLAGS += -Oz
|
$(ANDROID_RELEASE_TARGETS): LDFLAGS += -Oz
|
||||||
$(NONANDROID_RELEASE_TARGETS): CFLAGS += -Os
|
$(NONANDROID_RELEASE_TARGETS): CFLAGS += -Os
|
||||||
@ -268,29 +222,25 @@ $(WINDOWS_TARGETS): CFLAGS += \
|
|||||||
-D_WIN32_WINNT=0x0A00 \
|
-D_WIN32_WINNT=0x0A00 \
|
||||||
-DWINVER=0x0A00 \
|
-DWINVER=0x0A00 \
|
||||||
-DNTDDI_VERSION=NTDDI_WIN10 \
|
-DNTDDI_VERSION=NTDDI_WIN10 \
|
||||||
-Iout/openssl/$(UNAME_S)/mingw64/usr/local/include
|
-Ideps/openssl/mingw64/usr/local/include
|
||||||
$(WINDOWS_TARGETS): LDFLAGS += \
|
$(WINDOWS_TARGETS): LDFLAGS += \
|
||||||
-static \
|
-static \
|
||||||
-lm \
|
-lm \
|
||||||
-Lout/openssl/$(UNAME_S)/mingw64/usr/local/lib
|
-Ldeps/openssl/mingw64/usr/local/lib
|
||||||
$(AARCH64_TARGETS): CC = aarch64-linux-gnu-gcc
|
$(AARCH64_TARGETS): CC = aarch64-linux-gnu-gcc
|
||||||
$(AARCH64_TARGETS): AS = $(CC)
|
$(AARCH64_TARGETS): AS = $(CC)
|
||||||
$(AARCH64_TARGETS): CFLAGS += -Iout/openssl/Linux/aarch64/usr/local/include
|
$(AARCH64_TARGETS): CFLAGS += -Ideps/openssl/Linux/aarch64/usr/local/include
|
||||||
$(AARCH64_TARGETS): LDFLAGS += -Lout/openssl/Linux/aarch64/usr/local/lib
|
$(AARCH64_TARGETS): LDFLAGS += -Ldeps/openssl/Linux/aarch64/usr/local/lib
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
$(HOST_TARGETS): CC = xcrun clang
|
$(MACOS_TARGETS): CC = xcrun clang
|
||||||
$(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
|
$(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
|
||||||
$(IOS_TARGETS): CC = xcrun --sdk iphoneos clang -isysroot $(IOS_SYSROOT) -arch arm64
|
$(IOS_TARGETS): CC = xcrun --sdk iphoneos clang -isysroot $(IOS_SYSROOT) -arch arm64
|
||||||
$(IOSSIM_TARGETS): IOSSIM_SYSROOT := $(shell xcrun --sdk iphonesimulator --show-sdk-path)
|
$(IOSSIM_TARGETS): IOSSIM_SYSROOT := $(shell xcrun --sdk iphonesimulator --show-sdk-path)
|
||||||
$(IOSSIM_TARGETS): CC = xcrun --sdk iphonesimulator clang -isysroot $(IOSSIM_SYSROOT) -arch x86_64
|
$(IOSSIM_TARGETS): CC = xcrun --sdk iphonesimulator clang -isysroot $(IOSSIM_SYSROOT) -arch x86_64
|
||||||
else ifeq ($(UNAME_S),Linux)
|
else ifeq ($(UNAME_S),Linux)
|
||||||
$(IOS_TARGETS): CFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk -arch arm64 -DTARGET_OS_IPHONE=1
|
$(IOS_TARGETS): CFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk -arch arm64
|
||||||
$(IOS_TARGETS): LDFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk
|
$(IOS_TARGETS): LDFLAGS += -isysroot deps/ios_toolchain/target/SDKs/iPhoneOS18.2.sdk
|
||||||
$(IOS_TARGETS): CC = PATH=$$PATH:deps/ios_toolchain/target/bin LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/ios_toolchain/target/lib deps/ios_toolchain/target/bin/arm-apple-darwin11-clang
|
$(IOS_TARGETS): CC = PATH=$$PATH:deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang
|
||||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/o64-clang
|
|
||||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/oa64-clang
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/o64-clang
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): CC = PATH=deps/macos_toolchain/bin:$$PATH LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:deps/macos_toolchain/lib deps/macos_toolchain/bin/oa64-clang
|
|
||||||
endif
|
endif
|
||||||
$(ANDROID_X86_64_TARGETS): ANDROID_NDK_TARGET_TRIPLE := x86_64-linux-android
|
$(ANDROID_X86_64_TARGETS): ANDROID_NDK_TARGET_TRIPLE := x86_64-linux-android
|
||||||
$(ANDROID_X86_TARGETS): ANDROID_NDK_TARGET_TRIPLE := i686-linux-android
|
$(ANDROID_X86_TARGETS): ANDROID_NDK_TARGET_TRIPLE := i686-linux-android
|
||||||
@ -301,39 +251,30 @@ $(ANDROID_TARGETS): AS = $(CC)
|
|||||||
$(ANDROID_TARGETS): CFLAGS += \
|
$(ANDROID_TARGETS): CFLAGS += \
|
||||||
-target $(ANDROID_NDK_TARGET_TRIPLE)$(ANDROID_MIN_SDK_VERSION) \
|
-target $(ANDROID_NDK_TARGET_TRIPLE)$(ANDROID_MIN_SDK_VERSION) \
|
||||||
-Wno-unknown-warning-option
|
-Wno-unknown-warning-option
|
||||||
$(ANDROID_ARMV7A_TARGETS): CFLAGS += -Iout/openssl/android/armeabi-v7a/usr/local/include
|
$(ANDROID_ARMV7A_TARGETS): CFLAGS += -Ideps/openssl/android/armeabi-v7a/usr/local/include
|
||||||
$(ANDROID_ARMV7A_TARGETS): LDFLAGS += -Lout/openssl/android/armeabi-v7a/usr/local/lib
|
$(ANDROID_ARMV7A_TARGETS): LDFLAGS += -Ldeps/openssl/android/armeabi-v7a/usr/local/lib
|
||||||
$(ANDROID_ARM64_TARGETS): CFLAGS += -Iout/openssl/android/arm64-v8a/usr/local/include
|
$(ANDROID_ARM64_TARGETS): CFLAGS += -Ideps/openssl/android/arm64-v8a/usr/local/include
|
||||||
$(ANDROID_ARM64_TARGETS): LDFLAGS += -Lout/openssl/android/arm64-v8a/usr/local/lib
|
$(ANDROID_ARM64_TARGETS): LDFLAGS += -Ldeps/openssl/android/arm64-v8a/usr/local/lib
|
||||||
$(ANDROID_X86_TARGETS): CFLAGS += -Iout/openssl/android/x86/usr/local/include
|
$(ANDROID_X86_TARGETS): CFLAGS += -Ideps/openssl/android/x86/usr/local/include
|
||||||
$(ANDROID_X86_TARGETS): CFLAGS += -Wno-atomic-alignment
|
$(ANDROID_X86_TARGETS): CFLAGS += -Wno-atomic-alignment
|
||||||
$(ANDROID_X86_TARGETS): LDFLAGS += -Lout/openssl/android/x86/usr/local/lib
|
$(ANDROID_X86_TARGETS): LDFLAGS += -Ldeps/openssl/android/x86/usr/local/lib
|
||||||
$(ANDROID_X86_64_TARGETS): CFLAGS += -Iout/openssl/android/x86_64/usr/local/include
|
$(ANDROID_X86_64_TARGETS): CFLAGS += -Ideps/openssl/android/x86_64/usr/local/include
|
||||||
$(ANDROID_X86_64_TARGETS): LDFLAGS += -Lout/openssl/android/x86_64/usr/local/lib
|
$(ANDROID_X86_64_TARGETS): LDFLAGS += -Ldeps/openssl/android/x86_64/usr/local/lib
|
||||||
$(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type
|
$(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type
|
||||||
$(MACOS_TARGETS): LDFLAGS += -Wl,-dead_strip
|
$(DEADSTRIP_TARGETS): LDFLAGS += -Wl,--gc-sections
|
||||||
$(NONMACOS_TARGETS): LDFLAGS += -Wl,--gc-sections -Wl,--as-needed
|
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0
|
||||||
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
|
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0
|
||||||
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
$(IOS_TARGETS): CFLAGS += -Iout/openssl/ios/ios64-xcrun/usr/local/include
|
$(IOS_TARGETS): CFLAGS += -Ideps/openssl/ios/ios64-xcrun/usr/local/include
|
||||||
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/ios/ios64-xcrun/usr/local/lib
|
$(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
|
||||||
else
|
else
|
||||||
$(IOS_TARGETS): CFLAGS += -Iout/openssl/$(UNAME_S)/ios64-cross/usr/local/include
|
$(IOS_TARGETS): CFLAGS += -Ideps/openssl/$(UNAME_S)/ios64-cross/usr/local/include
|
||||||
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/$(UNAME_S)/ios64-cross/usr/local/lib
|
$(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/ios64-cross/usr/local/lib
|
||||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-x86_64/usr/local/include
|
|
||||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-arm/usr/local/include
|
|
||||||
$(filter $(BUILD_DIR)/macosdebug-x86_64/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib
|
|
||||||
$(filter $(BUILD_DIR)/macosdebug-arm/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-arm/usr/local/lib
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-x86_64/usr/local/include
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): CFLAGS += -Iout/openssl/$(UNAME_S)/macos-arm/usr/local/include
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-arm/%,$(ALL_TARGETS)): LDFLAGS += -Lout/openssl/$(UNAME_S)/macos-arm/usr/local/lib
|
|
||||||
endif
|
endif
|
||||||
$(IOSSIM_TARGETS): CFLAGS += -Iout/openssl/ios/iossimulator-xcrun/usr/local/include
|
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
|
||||||
$(IOSSIM_TARGETS): LDFLAGS += -Lout/openssl/ios/iossimulator-xcrun/usr/local/lib
|
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
|
||||||
$(HOST_TARGETS): CFLAGS += -Iout/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
|
$(LINUX_TARGETS) $(MACOS_TARGETS): CFLAGS += -Ideps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
|
||||||
$(HOST_TARGETS): LDFLAGS += -Lout/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
|
$(LINUX_TARGETS) $(MACOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
|
||||||
|
|
||||||
ifeq ($(UNAME_M),x86_64)
|
ifeq ($(UNAME_M),x86_64)
|
||||||
ifeq ($(UNAME_S),Linux)
|
ifeq ($(UNAME_S),Linux)
|
||||||
@ -352,14 +293,13 @@ endif
|
|||||||
|
|
||||||
get_objs = \
|
get_objs = \
|
||||||
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
|
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
|
||||||
|
$(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||||
$(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \
|
$(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \
|
||||||
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \
|
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androiddebug-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \
|
||||||
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||||
|
$(foreach build_type,macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos))))) \
|
||||||
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_ios))))) \
|
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_ios))))) \
|
||||||
$(foreach build_type,iosdebug iosrelease iossimdebug iossimrelease macosdebug-arm macosrelease-arm macosdebug-x86_64 macosrelease-x86_64,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos))))) \
|
$(foreach build_type,androiddebug-x86 androidrelease-x86,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_x86)))))
|
||||||
$(foreach build_type,androiddebug-x86 androidrelease-x86,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_x86))))) \
|
|
||||||
$(if $(findstring Darwin,$(UNAME_S)),$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_macos)))))) \
|
|
||||||
$(if $(findstring Darwin,$(UNAME_S)),,$(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))))
|
|
||||||
|
|
||||||
APP_SOURCES := $(wildcard src/*.c)
|
APP_SOURCES := $(wildcard src/*.c)
|
||||||
APP_SOURCES_ios := $(wildcard src/*.m)
|
APP_SOURCES_ios := $(wildcard src/*.m)
|
||||||
@ -381,12 +321,10 @@ $(APP_OBJS): CFLAGS += \
|
|||||||
-Ideps/valgrind \
|
-Ideps/valgrind \
|
||||||
-Wdouble-promotion \
|
-Wdouble-promotion \
|
||||||
-Werror
|
-Werror
|
||||||
ifneq ($(UNAME_S),Darwin)
|
|
||||||
ifeq ($(UNAME_M),x86_64)
|
ifeq ($(UNAME_M),x86_64)
|
||||||
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/ios% $(BUILD_DIR)/macos%,$(APP_OBJS)): CFLAGS += \
|
$(filter-out $(BUILD_DIR)/android% $(BUILD_DIR)/macos% $(BUILD_DIR)/ios%,$(APP_OBJS)): CFLAGS += \
|
||||||
-fanalyzer
|
-fanalyzer
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ARES_SOURCES := \
|
ARES_SOURCES := \
|
||||||
deps/c-ares/src/lib/ares_addrinfo2hostent.c \
|
deps/c-ares/src/lib/ares_addrinfo2hostent.c \
|
||||||
@ -623,6 +561,7 @@ $(UV_OBJS): CFLAGS += \
|
|||||||
-Wno-unused-result \
|
-Wno-unused-result \
|
||||||
-Wno-unused-variable \
|
-Wno-unused-variable \
|
||||||
-Wno-nonnull
|
-Wno-nonnull
|
||||||
|
$(UV_OBJS): CFLAGS += -fno-lto
|
||||||
$(filter out/win%,$(UV_OBJS)): \
|
$(filter out/win%,$(UV_OBJS)): \
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-Wno-cast-function-type \
|
-Wno-cast-function-type \
|
||||||
@ -718,12 +657,12 @@ $(SQLITE_OBJS): CFLAGS += \
|
|||||||
-DSQLITE_MAX_COMPOUND_SELECT=300 \
|
-DSQLITE_MAX_COMPOUND_SELECT=300 \
|
||||||
-DSQLITE_MAX_EXPR_DEPTH=40 \
|
-DSQLITE_MAX_EXPR_DEPTH=40 \
|
||||||
-DSQLITE_MAX_FUNCTION_ARG=8 \
|
-DSQLITE_MAX_FUNCTION_ARG=8 \
|
||||||
-DSQLITE_MAX_LENGTH=10485760 \
|
-DSQLITE_MAX_LENGTH=5242880 \
|
||||||
-DSQLITE_MAX_LIKE_PATTERN_LENGTH=50 \
|
-DSQLITE_MAX_LIKE_PATTERN_LENGTH=50 \
|
||||||
-DSQLITE_MAX_SQL_LENGTH=100000 \
|
-DSQLITE_MAX_SQL_LENGTH=100000 \
|
||||||
-DSQLITE_MAX_TRIGGER_DEPTH=10 \
|
-DSQLITE_MAX_TRIGGER_DEPTH=10 \
|
||||||
-DSQLITE_MAX_VARIABLE_NUMBER=100 \
|
-DSQLITE_MAX_VARIABLE_NUMBER=100 \
|
||||||
-DSQLITE_MAX_VDBE_OP=50000 \
|
-DSQLITE_MAX_VDBE_OP=25000 \
|
||||||
-DSQLITE_OMIT_DEPRECATED \
|
-DSQLITE_OMIT_DEPRECATED \
|
||||||
-DSQLITE_OMIT_DESERIALIZE \
|
-DSQLITE_OMIT_DESERIALIZE \
|
||||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||||
@ -819,12 +758,12 @@ $(MINIUNZIP_OBJS): CFLAGS += \
|
|||||||
LDFLAGS += \
|
LDFLAGS += \
|
||||||
-pthread \
|
-pthread \
|
||||||
-lm
|
-lm
|
||||||
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS) $(filter-out $(HOST_TARGETS),$(MACOS_TARGETS)): LDFLAGS += \
|
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
|
||||||
-lssl \
|
-lssl \
|
||||||
-lcrypto
|
-lcrypto
|
||||||
ifneq ($(UNAME_S),Haiku)
|
ifneq ($(UNAME_S),Haiku)
|
||||||
ifneq ($(UNAME_S),OpenBSD)
|
ifneq ($(UNAME_S),OpenBSD)
|
||||||
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
|
debug release $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
|
||||||
-ldl
|
-ldl
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -857,15 +796,27 @@ $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
|
|||||||
##
|
##
|
||||||
## Common targets:
|
## Common targets:
|
||||||
##
|
##
|
||||||
all: $(BUILD_TYPES) ## Build all targets that appear possible to build on this machine.
|
debug: ## Build a debug executable for the current platform.
|
||||||
debug: ## Build a debug executable for the current host platform.
|
release: ## Build a release executable for the current platform.
|
||||||
release: ## Build a release executable for the current host platform.
|
|
||||||
armdebug: ## Cross-compile aarch64 debug on Linux.
|
armdebug: ## Cross-compile aarch64 debug on Linux.
|
||||||
armrelease: ## Cross-compile aarch64 release on Linux.
|
armrelease: ## Cross-compile aarch64 release on Linux.
|
||||||
windebug: ## Cross-compile a debug win32 executable on Linux.
|
all: $(BUILD_TYPES) ## Build all targets that appear possible to build on this machine.
|
||||||
winrelease: ## Cross-compile a release win32 executable on Linux.
|
unix: debug release ## Build all UNIX targets.
|
||||||
|
win: windebug winrelease ## Build all Windows targets.
|
||||||
.PHONY: all win unix
|
.PHONY: all win unix
|
||||||
|
|
||||||
|
##
|
||||||
|
## Windows targets:
|
||||||
|
##
|
||||||
|
windebug: ## Build a debug win32 executable.
|
||||||
|
winrelease: ## Build a release win32 executable.
|
||||||
|
|
||||||
|
##
|
||||||
|
## MacOS targets:
|
||||||
|
##
|
||||||
|
macosdebug: ## Build a MacOS debug executable.
|
||||||
|
macosrelease: ## Build a MacOS release executable.
|
||||||
|
|
||||||
ALL_APP_OBJS := \
|
ALL_APP_OBJS := \
|
||||||
$(APP_OBJS) \
|
$(APP_OBJS) \
|
||||||
$(ARES_OBJS) \
|
$(ARES_OBJS) \
|
||||||
@ -921,17 +872,6 @@ src/android/AndroidManifest.xml : $(firstword $(MAKEFILE_LIST))
|
|||||||
-e 's/android:targetSdkVersion="[[:digit:]]*"/android:targetSdkVersion="$(ANDROID_TARGET_SDK_VERSION)"/' \
|
-e 's/android:targetSdkVersion="[[:digit:]]*"/android:targetSdkVersion="$(ANDROID_TARGET_SDK_VERSION)"/' \
|
||||||
$@
|
$@
|
||||||
|
|
||||||
src/ios/Info.plist : $(firstword $(MAKEFILE_LIST))
|
|
||||||
@echo "[ios_version] $@"
|
|
||||||
@cat $@ | \
|
|
||||||
tr '\n' '^' | \
|
|
||||||
sed -r \
|
|
||||||
-e 's@(<key>CFBundleShortVersionString</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(VERSION_NUMBER:%-wip=%)\2@' \
|
|
||||||
-e 's@(<key>CFBundleVersion</key>\^[[:space:]]*<string>)[[:digit:]]+(</string>)@\1$(VERSION_CODE_IOS)\2@' \
|
|
||||||
-e 's@(<key>MinimumOSVersion</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(IPHONEOS_VERSION_MIN)\2@' | \
|
|
||||||
tr '^' '\n' > \
|
|
||||||
$@.tmp && mv $@.tmp $@ || rm -f $@.tmp
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Android targets:
|
## Android targets:
|
||||||
##
|
##
|
||||||
@ -949,30 +889,29 @@ out/res/layout_activity_main.xml.flat: src/android/res/layout/activity_main.xml
|
|||||||
@echo "[aapt2] $@"
|
@echo "[aapt2] $@"
|
||||||
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ src/android/res/layout/activity_main.xml
|
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ src/android/res/layout/activity_main.xml
|
||||||
|
|
||||||
out/res/drawable_%.xml.flat: src/android/res/drawable/%.xml
|
out/res/drawable_icon.xml.flat: src/android/res/drawable/icon.xml
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
@echo "[aapt2] $@"
|
@echo "[aapt2] $@"
|
||||||
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ $(<)
|
@$(ANDROID_BUILD_TOOLS)/aapt2 compile -o out/res/ src/android/res/drawable/icon.xml
|
||||||
|
|
||||||
out/apk/res.apk out/gen/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat out/res/drawable_logo.xml.flat src/android/AndroidManifest.xml
|
out/apk/res.apk out/gen/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat src/android/AndroidManifest.xml
|
||||||
@echo [aapt2 link] res.apk
|
@echo [aapt2 link] res.apk
|
||||||
@mkdir -p out/apk/
|
@mkdir -p out/apk/
|
||||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat out/res/drawable_logo.xml.flat \
|
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat \
|
||||||
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
||||||
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
||||||
--manifest src/android/AndroidManifest.xml \
|
--manifest src/android/AndroidManifest.xml \
|
||||||
-o out/apk/res.apk \
|
-o out/apk/res.apk \
|
||||||
--java out/gen/
|
--java out/gen/
|
||||||
|
|
||||||
out/apk/res.fdroid.apk out/gen_fdroid/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon_fdroid.xml.flat out/res/drawable_logo.xml.flat src/android/AndroidManifest.xml
|
out/apk/res.fdroid.apk out/gen_fdroid/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat src/android/AndroidManifest.xml
|
||||||
@echo [aapt2 link] res.fdroid.apk
|
@echo [aapt2 link] res.fdroid.apk
|
||||||
@mkdir -p out/apk/
|
@mkdir -p out/apk/
|
||||||
@sed -e 's@drawable/icon@drawable/icon_fdroid@' src/android/AndroidManifest.xml > out/apk/AndroidManifest.fdroid.xml
|
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat \
|
||||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon_fdroid.xml.flat out/res/drawable_logo.xml.flat \
|
|
||||||
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
--min-sdk-version $(ANDROID_MIN_SDK_VERSION) \
|
||||||
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
--target-sdk-version $(ANDROID_TARGET_SDK_VERSION) \
|
||||||
--rename-manifest-package com.unprompted.tildefriends.fdroid \
|
--rename-manifest-package com.unprompted.tildefriends.fdroid \
|
||||||
--manifest out/apk/AndroidManifest.fdroid.xml \
|
--manifest src/android/AndroidManifest.xml \
|
||||||
-o out/apk/res.fdroid.apk \
|
-o out/apk/res.fdroid.apk \
|
||||||
--java out/gen_fdroid/
|
--java out/gen_fdroid/
|
||||||
|
|
||||||
@ -989,12 +928,11 @@ out/apk/classes.dex: $(CLASS_FILES)
|
|||||||
@$(ANDROID_BUILD_TOOLS)/d8 --lib $(ANDROID_PLATFORM)/android.jar --output $(dir $@) out/classes/com/unprompted/tildefriends/*.class
|
@$(ANDROID_BUILD_TOOLS)/d8 --lib $(ANDROID_PLATFORM)/android.jar --output $(dir $@) out/classes/com/unprompted/tildefriends/*.class
|
||||||
|
|
||||||
PACKAGE_DIRS := \
|
PACKAGE_DIRS := \
|
||||||
apps \
|
apps/ \
|
||||||
core \
|
core/ \
|
||||||
deps/codemirror \
|
deps/codemirror/ \
|
||||||
deps/prettier \
|
deps/prettier/ \
|
||||||
deps/lit \
|
deps/lit/
|
||||||
deps/speedscope
|
|
||||||
|
|
||||||
RAW_FILES := $(sort $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f -not -name '.*')))
|
RAW_FILES := $(sort $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f -not -name '.*')))
|
||||||
|
|
||||||
@ -1024,7 +962,6 @@ out/TildeFriends.aab: out/apk/classes.dex $(filter-out %debug%, $(ANDROID_TARGET
|
|||||||
--manifest src/android/AndroidManifest.xml \
|
--manifest src/android/AndroidManifest.xml \
|
||||||
-R out/res/layout_activity_main.xml.flat \
|
-R out/res/layout_activity_main.xml.flat \
|
||||||
-R out/res/drawable_icon.xml.flat \
|
-R out/res/drawable_icon.xml.flat \
|
||||||
-R out/res/drawable_logo.xml.flat \
|
|
||||||
--auto-add-overlay
|
--auto-add-overlay
|
||||||
@unzip out/aab/temporary.apk -d out/aab/staging/
|
@unzip out/aab/temporary.apk -d out/aab/staging/
|
||||||
@mkdir -p out/aab/staging/root/deps
|
@mkdir -p out/aab/staging/root/deps
|
||||||
@ -1051,7 +988,7 @@ out/TildeFriends.aab: out/apk/classes.dex $(filter-out %debug%, $(ANDROID_TARGET
|
|||||||
@cp -r deps/codemirror/ out/aab/staging/root/deps/
|
@cp -r deps/codemirror/ out/aab/staging/root/deps/
|
||||||
@cd out/aab/staging/; zip -r ../base.zip *; cd ../../../
|
@cd out/aab/staging/; zip -r ../base.zip *; cd ../../../
|
||||||
@java -jar $(BUNDLETOOL) build-bundle --overwrite --config=src/android/BundleConfig.json --modules=out/aab/base.zip --output=$@
|
@java -jar $(BUNDLETOOL) build-bundle --overwrite --config=src/android/BundleConfig.json --modules=out/aab/base.zip --output=$@
|
||||||
@$(ANDROID_BUILD_TOOLS)/apksigner sign -ks .keys/android.jks --ks-key-alias androidKey -ks-pass pass:android --min-sdk-version=$(ANDROID_MIN_SDK_VERSION) $@
|
@jarsigner -keystore .keys/android.jks $@ androidKey -storepass android
|
||||||
|
|
||||||
aab: out/TildeFriends.aab ## Build an Android App Bundle.
|
aab: out/TildeFriends.aab ## Build an Android App Bundle.
|
||||||
.PHONY: aab
|
.PHONY: aab
|
||||||
@ -1154,27 +1091,14 @@ out/%.app/tildefriends.png: src/ios/tildefriends.png
|
|||||||
@cp -v $< $@
|
@cp -v $< $@
|
||||||
|
|
||||||
out/data.zip: $(RAW_FILES)
|
out/data.zip: $(RAW_FILES)
|
||||||
@echo [zip] $@
|
|
||||||
@zip -u $@ -q -9 $(RAW_FILES)
|
@zip -u $@ -q -9 $(RAW_FILES)
|
||||||
|
|
||||||
out/zsign_build/zsign: $(wildcard deps/zsign/*.cpp deps/zsign/*.h deps/zsign/*.txt deps/zsign/common/*)
|
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/data.zip
|
||||||
@+echo [cmake] $@
|
|
||||||
@cmake -B out/zsign_build deps/zsign
|
|
||||||
@cmake --build out/zsign_build -- COLOR=0 VERBOSE=0 MAKESILENT=-s
|
|
||||||
|
|
||||||
ifeq ($(HAVE_LINUX_IOS),1)
|
|
||||||
ZSIGN_DEP = out/zsign_build/zsign
|
|
||||||
else
|
|
||||||
ZSIGN_DEP =
|
|
||||||
endif
|
|
||||||
|
|
||||||
out/tildefriends-%.app/tildefriends: out/%/tildefriends out/tildefriends-%.app/Info.plist out/tildefriends-%.app/tildefriends.png out/data.zip $(ZSIGN_DEP)
|
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
@cp -v $(filter-out out/zsign%,$<) $@
|
@cp -v $< $@
|
||||||
@cp -v out/data.zip $(@D)/
|
@cp -v out/data.zip $(@D)/
|
||||||
ifeq ($(HAVE_LINUX_IOS),1)
|
ifeq ($(HAVE_LINUX_IOS),1)
|
||||||
@mkdir -p $(realpath $(dir $@))/_CodeSignature
|
@zsign -q -k .keys/apple.p12 -f -m src/ios/embedded.mobileprovision $(realpath $(dir $@))
|
||||||
@out/zsign_build/zsign -q -k .keys/apple.p12 -f -m src/ios/embedded.mobileprovision $(realpath $(dir $@))
|
|
||||||
endif
|
endif
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
out/tildefriends-%.ipa: out/tildefriends-ios%.app/tildefriends
|
out/tildefriends-%.ipa: out/tildefriends-ios%.app/tildefriends
|
||||||
@ -1212,34 +1136,26 @@ iossimdebuggo: out/tildefriends-iossimdebug.app/tildefriends ## Build, install,
|
|||||||
xcrun simctl launch booted com.unprompted.tildefriends
|
xcrun simctl launch booted com.unprompted.tildefriends
|
||||||
.PHONY: iossimdebuggo
|
.PHONY: iossimdebuggo
|
||||||
|
|
||||||
ANDROID_DEPS := out/openssl/android/arm64-v8a/usr/local/lib/libssl.a
|
ANDROID_DEPS := deps/openssl/android/arm64-v8a/usr/local/lib/libssl.a
|
||||||
$(ANDROID_DEPS):
|
$(ANDROID_DEPS):
|
||||||
+@export ANDROID_NDK_ROOT=$(ANDROID_NDK)
|
+@ANDROID_NDK_ROOT=$(ANDROID_NDK) tools/ssl-android
|
||||||
+@export BUILD_PLATFORM=android
|
|
||||||
+@export TOOLCHAIN=$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64
|
|
||||||
+@PATH="$$TOOLCHAIN/x86_64-linux-android/bin:$$TOOLCHAIN/bin:$$PATH" BUILD_TARGET=x86_64 SSL_TARGET=android-x86_64 OPTIONS="-D__ANDROID_API__=$(ANDROID_MIN_SDK_VERSION) -Wno-macro-redefined" tools/ssl-local
|
|
||||||
+@PATH="$$TOOLCHAIN/i686-linux-android/bin:$$TOOLCHAIN/bin:$$PATH" BUILD_TARGET=x86 SSL_TARGET=android-x86 OPTIONS="-D__ANDROID_API__=$(ANDROID_MIN_SDK_VERSION) -Wno-macro-redefined" tools/ssl-local
|
|
||||||
+@PATH="$$TOOLCHAIN/arm-linux-androideabi/bin:$$TOOLCHAIN/bin:$$PATH" BUILD_TARGET=armeabi-v7a SSL_TARGET=android-arm OPTIONS="--target=armv7a-linux-androideabi -Wl,--fix-cortex-a8 -D__ANDROID_API__=$(ANDROID_MIN_SDK_VERSION) -Wno-macro-redefined" tools/ssl-local
|
|
||||||
+@PATH="$$TOOLCHAIN/aarch64-linux-android/bin:$$TOOLCHAIN/bin:$$PATH" BUILD_TARGET=arm64-v8a SSL_TARGET=android-arm64 OPTIONS="-D__ANDROID_API__=$(ANDROID_MIN_SDK_VERSION) -Wno-macro-redefined" tools/ssl-local
|
|
||||||
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
|
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Linux)
|
ifeq ($(UNAME_S),Linux)
|
||||||
ifneq ($(USE_SYSTEM_SSL),1)
|
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
|
||||||
$(LOCAL_DEPS):
|
$(LOCAL_DEPS):
|
||||||
+@tools/ssl-local
|
+@OPTIONS=-flto tools/ssl-local
|
||||||
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
ifeq ($(HAVE_CROSS_AARCH64),1)
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
|
LOCAL_DEPS := deps/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
|
||||||
$(LOCAL_DEPS):
|
$(LOCAL_DEPS):
|
||||||
+@OPTIONS="--cross-compile-prefix=aarch64-linux-gnu-" BUILD_TARGET=aarch64 SSL_TARGET=linux-aarch64 tools/ssl-local
|
+@OPTIONS="--cross-compile-prefix=aarch64-linux-gnu- -flto" BUILD_TARGET=aarch64 tools/ssl-local
|
||||||
$(filter $(BUILD_DIR)/armdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/armrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
$(filter $(BUILD_DIR)/armdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/armrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(HAVE_LINUX_IOS),1)
|
ifeq ($(HAVE_LINUX_IOS),1)
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/ios64-cross/usr/local/lib/libssl.a
|
LOCAL_DEPS := deps/openssl/$(UNAME_S)/ios64-cross/usr/local/lib/libssl.a
|
||||||
$(LOCAL_DEPS):
|
$(LOCAL_DEPS):
|
||||||
+@PATH=deps/ios_toolchain/target/bin:$$PATH \
|
+@PATH=deps/ios_toolchain/target/bin:$$PATH \
|
||||||
BUILD_TARGET=ios64-cross \
|
BUILD_TARGET=ios64-cross \
|
||||||
@ -1248,63 +1164,33 @@ $(LOCAL_DEPS):
|
|||||||
CROSS_TOP=../../deps/ios_toolchain/target \
|
CROSS_TOP=../../deps/ios_toolchain/target \
|
||||||
CROSS_SDK=iPhoneOS18.2.sdk \
|
CROSS_SDK=iPhoneOS18.2.sdk \
|
||||||
CC=clang \
|
CC=clang \
|
||||||
OPTIONS=-miphoneos-version-min=$(IPHONEOS_VERSION_MIN) \
|
OPTIONS=-miphoneos-version-min=9.0 \
|
||||||
tools/ssl-local
|
tools/ssl-local
|
||||||
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/macos-arm/usr/local/lib/libssl.a
|
|
||||||
$(LOCAL_DEPS):
|
|
||||||
+@PATH=../../deps/macos_toolchain/bin:$$PATH \
|
|
||||||
BUILD_TARGET=macos-arm \
|
|
||||||
SSL_TARGET=darwin64-arm64 \
|
|
||||||
CC=../../deps/macos_toolchain/bin/oa64-clang \
|
|
||||||
RANLIB=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ranlib \
|
|
||||||
AR=../../deps/macos_toolchain/bin/arm64-apple-darwin24-ar \
|
|
||||||
tools/ssl-local
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-arm/% $(BUILD_DIR)/macosdebug-arm/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
|
||||||
|
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/macos-x86_64/usr/local/lib/libssl.a
|
|
||||||
$(LOCAL_DEPS):
|
|
||||||
+@PATH=../../deps/macos_toolchain/bin:$$PATH \
|
|
||||||
BUILD_TARGET=macos-x86_64 \
|
|
||||||
SSL_TARGET=darwin64-x86_64 \
|
|
||||||
CC=../../deps/macos_toolchain/bin/o64-clang \
|
|
||||||
RANLIB=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ranlib \
|
|
||||||
AR=../../deps/macos_toolchain/bin/x86_64-apple-darwin24-ar \
|
|
||||||
tools/ssl-local
|
|
||||||
$(filter $(BUILD_DIR)/macosrelease-x86_64/% $(BUILD_DIR)/macosdebug-x86_64/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
LOCAL_DEPS := out/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
|
||||||
$(LOCAL_DEPS):
|
$(LOCAL_DEPS):
|
||||||
+@tools/ssl-local
|
+@OPTIONS=-flto tools/ssl-local
|
||||||
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
$(filter $(BUILD_DIR)/macosdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/macosrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(HAVE_WIN),1)
|
ifeq ($(HAVE_WIN),1)
|
||||||
WINDOWS_DEPS := out/openssl/$(UNAME_S)/mingw64/usr/local/lib/libssl.a
|
WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a
|
||||||
$(WINDOWS_DEPS):
|
$(WINDOWS_DEPS):
|
||||||
+@BUILD_TARGET=mingw64 SSL_TARGET=mingw64 OPTIONS="--cross-compile-prefix=x86_64-w64-mingw32-" tools/ssl-local
|
+@tools/ssl-mingw64
|
||||||
$(filter $(BUILD_DIR)/win%,$(APP_OBJS)): | $(WINDOWS_DEPS)
|
$(filter $(BUILD_DIR)/win%,$(APP_OBJS)): | $(WINDOWS_DEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
IOS_DEPS := out/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
|
IOS_DEPS := deps/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
|
||||||
$(IOS_DEPS):
|
$(IOS_DEPS):
|
||||||
+@BUILD_PLATFORM=ios BUILD_TARGET=ios64-xcrun SSL_TARGET=ios64-xcrun OPTIONS="-fPIC -Wno-macro-redefined -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)" tools/ssl-local
|
+@tools/ssl-ios
|
||||||
+@BUILD_PLATFORM=ios BUILD_TARGET=iossimulator-xcrun SSL_TARGET=iossimulator-xcrun OPTIONS="-fPIC -Wno-macro-redefined" tools/ssl-local
|
|
||||||
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
|
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
out/macos%/tildefriends: out/macos%-arm/tildefriends out/macos%-x86_64/tildefriends
|
|
||||||
@echo [lipo] $@
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
@deps/macos_toolchain/bin/lipo -create -output $@ $^
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Linux package targets:
|
## Linux package targets:
|
||||||
##
|
##
|
||||||
@ -1332,8 +1218,7 @@ appimage: out/tildefriends-x86_64.AppImage ## Build an AppImage.
|
|||||||
.PHONY: appimage
|
.PHONY: appimage
|
||||||
|
|
||||||
flatpak: out/ ## Build a flatpak.
|
flatpak: out/ ## Build a flatpak.
|
||||||
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
flatpak-builder --force-clean --user --install-deps-from=flathub --install --repo=out/flatpak-repo out/flatpak src/com.unprompted.tildefriends.yml
|
||||||
flatpak-builder --user --disable-rofiles-fuse --install-deps-from=flathub --install --repo=out/flatpak-repo out/flatpak src/com.unprompted.tildefriends.yml
|
|
||||||
flatpak build-bundle out/flatpak-repo out/tildefriends.flatpak com.unprompted.tildefriends
|
flatpak build-bundle out/flatpak-repo out/tildefriends.flatpak com.unprompted.tildefriends
|
||||||
.PHONY: flatpak
|
.PHONY: flatpak
|
||||||
|
|
||||||
@ -1373,6 +1258,7 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
|
|||||||
--exclude=deps/libsodium/test \
|
--exclude=deps/libsodium/test \
|
||||||
--exclude=deps/libuv/docs \
|
--exclude=deps/libuv/docs \
|
||||||
--exclude=deps/libuv/test \
|
--exclude=deps/libuv/test \
|
||||||
|
--exclude=deps/openssl \
|
||||||
--exclude=deps/speedscope/*.map \
|
--exclude=deps/speedscope/*.map \
|
||||||
--exclude=deps/sqlite/shell.c \
|
--exclude=deps/sqlite/shell.c \
|
||||||
--exclude=deps/zlib/contrib/vstudio \
|
--exclude=deps/zlib/contrib/vstudio \
|
||||||
@ -1383,20 +1269,7 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
|
|||||||
.PHONY: tarball
|
.PHONY: tarball
|
||||||
|
|
||||||
dist: ## Build versions of all distributables for release.
|
dist: ## Build versions of all distributables for release.
|
||||||
dist: release-apk aab out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone
|
dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone $(if $(HAVE_CROSS_AARCH64), out/armrelease/tildefriends.standalone)
|
||||||
ifeq ($(HAVE_LINUX_IOS),1)
|
|
||||||
dist: iosrelease-ipa
|
|
||||||
endif
|
|
||||||
ifeq ($(HAVE_LINUX_MACOS),1)
|
|
||||||
dist: out/macosrelease/tildefriends.standalone
|
|
||||||
endif
|
|
||||||
ifeq ($(HAVE_WIN),1)
|
|
||||||
dist: out/winrelease/tildefriends.standalone.exe
|
|
||||||
endif
|
|
||||||
ifeq ($(HAVE_CROSS_AARCH64),1)
|
|
||||||
dist: out/armrelease/tildefriends.standalone
|
|
||||||
endif
|
|
||||||
dist:
|
|
||||||
@mkdir -p dist/
|
@mkdir -p dist/
|
||||||
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
|
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
|
||||||
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
|
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
|
||||||
@ -1404,10 +1277,8 @@ dist:
|
|||||||
@cp out/TildeFriends-x86-release.zopfli.apk dist/TildeFriends-x86-$(VERSION_NUMBER).apk
|
@cp out/TildeFriends-x86-release.zopfli.apk dist/TildeFriends-x86-$(VERSION_NUMBER).apk
|
||||||
@echo "[cp] TildeFriends-arm-$(VERSION_NUMBER).apk"
|
@echo "[cp] TildeFriends-arm-$(VERSION_NUMBER).apk"
|
||||||
@cp out/TildeFriends-arm-release.zopfli.apk dist/TildeFriends-arm-$(VERSION_NUMBER).apk
|
@cp out/TildeFriends-arm-release.zopfli.apk dist/TildeFriends-arm-$(VERSION_NUMBER).apk
|
||||||
@test $(HAVE_LINUX_IOS) && echo "[cp] TildeFriends-$(VERSION_NUMBER).ipa"
|
@echo "[cp] TildeFriends-$(VERSION_NUMBER).ipa"
|
||||||
@test $(HAVE_LINUX_IOS) && cp out/tildefriends-release.ipa dist/TildeFriends-$(VERSION_NUMBER).ipa
|
@cp out/tildefriends-release.ipa dist/TildeFriends-$(VERSION_NUMBER).ipa
|
||||||
@test $(HAVE_LINUX_MACOS) && echo "[cp] tildefriends-macos-$(VERSION_NUMBER)"
|
|
||||||
@test $(HAVE_LINUX_MACOS) && cp out/macosrelease/tildefriends.standalone dist/tildefriends-macos-$(VERSION_NUMBER)
|
|
||||||
@test $(HAVE_WIN) && echo "[cp] tildefriends-$(VERSION_NUMBER).exe"
|
@test $(HAVE_WIN) && echo "[cp] tildefriends-$(VERSION_NUMBER).exe"
|
||||||
@test $(HAVE_WIN) && cp out/winrelease/tildefriends.standalone.exe dist/tildefriends-$(VERSION_NUMBER).exe
|
@test $(HAVE_WIN) && cp out/winrelease/tildefriends.standalone.exe dist/tildefriends-$(VERSION_NUMBER).exe
|
||||||
@echo "[cp] TildeFriends-$(VERSION_NUMBER).aab"
|
@echo "[cp] TildeFriends-$(VERSION_NUMBER).aab"
|
||||||
@ -1429,17 +1300,6 @@ dist-test: dist ## Exercise some built distributable files, making sure they wor
|
|||||||
@rm -rf tildefriends-$(VERSION_NUMBER)
|
@rm -rf tildefriends-$(VERSION_NUMBER)
|
||||||
.PHONY: dist-test
|
.PHONY: dist-test
|
||||||
|
|
||||||
dist-ios: iosrelease-app
|
|
||||||
rm -rfv out/Payload out/tildefriends.ipa
|
|
||||||
mkdir -p out/Payload/tildefriends.app
|
|
||||||
cp -avR out/tildefriends-iosrelease.app/* out/Payload/tildefriends.app/
|
|
||||||
cp src/ios/tildefriends.png out/Payload/tildefriends.app/
|
|
||||||
xcrun -sdk iphoneos actool --compile out/Payload/tildefriends.app/ --platform iphoneos --minimum-deployment-target $(IPHONEOS_VERSION_MIN) --app-icon AppIcon src/ios/icons/Assets.xcassets src/ios/icons/*.png --output-partial-info-plist out/actool.plist
|
|
||||||
cp src/ios/distribution.mobileprovision out/Payload/tildefriends.app/embedded.mobileprovision
|
|
||||||
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/Payload/tildefriends.app
|
|
||||||
cd out; zip -r tildefriends.ipa Payload; cd ..
|
|
||||||
xcrun -sdk iphoneos altool --upload-app -f out/tildefriends.ipa -t ios -u $$(cat .keys/altool-user) -p $$(cat .keys/altool-password)
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Targets for tidying up:
|
## Targets for tidying up:
|
||||||
##
|
##
|
||||||
|
27
README.md
27
README.md
@ -1,16 +1,18 @@
|
|||||||
# Tilde Friends
|
# Tilde Friends
|
||||||
|
|
||||||
Tilde Friends participates in the Secure Scuttlebutt decentralized social
|
Tilde Friends is a tool for making and sharing.
|
||||||
network while also functioning as a platform for making, sharing, and running
|
|
||||||
web applications.
|
|
||||||
|
|
||||||
A public instance lives at https://www.tildefriends.net/.
|
A public instance lives at https://www.tildefriends.net/.
|
||||||
|
|
||||||
|
It is both a peer-to-peer social network client, participating in Secure
|
||||||
|
Scuttlebutt, as well as a platform for writing and running web applications.
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
1. Be the fanciest, best-maintained Secure Scuttlebutt client in town.
|
1. Make it easy and fun to run all sorts of web applications.
|
||||||
1. Make it easy to make, share, and run all sorts of applications while
|
2. Provide security that is easy to understand and protects your data.
|
||||||
respecting the privacy and safety of your data.
|
3. Make creating and sharing web applications accessible to anyone with a
|
||||||
|
browser.
|
||||||
|
|
||||||
## Getting the Source
|
## Getting the Source
|
||||||
|
|
||||||
@ -38,7 +40,8 @@ dependencies in the right places.
|
|||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
System OpenSSL libraries are assumed to be available on Haiku and OpenBSD.
|
On Linux only, system OpenSSL libraries (`libssl-dev`, in debian-speak) are
|
||||||
|
assumed to be available.
|
||||||
|
|
||||||
On MacOS, Xcode's command-line tools are expected to be available.
|
On MacOS, Xcode's command-line tools are expected to be available.
|
||||||
|
|
||||||
@ -55,16 +58,18 @@ standard.
|
|||||||
## Running
|
## Running
|
||||||
|
|
||||||
By default, running the built `out/debug/tildefriends` executable will start a
|
By default, running the built `out/debug/tildefriends` executable will start a
|
||||||
web server at <http://localhost:12345/>. `tildefriends -h` lists further
|
web server at <http://localhost:12345/>. It expects to be run with the
|
||||||
options.
|
repository root as the current working directory. `tildefriends -h` lists
|
||||||
|
further options.
|
||||||
|
|
||||||
The first user to create an account and log in will be granted administrative
|
The first user to create an account and log in will be granted administrative
|
||||||
privileges. Further administration can be done in the `admin` app at
|
privileges. Further administration can be done at
|
||||||
<http://localhost:12345/~core/admin/>.
|
<http://localhost:12345/~core/admin/>.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Docs live here: <https://docs.tildefriends.net/>.
|
Docs are a work in progress:
|
||||||
|
<https://dev.tildefriends.net/cory/tildefriends/wiki>.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "🎛",
|
"emoji": "🎛",
|
||||||
"previous": "&kmKNyb/uaXNb24gCinJtfS8iWx4cLUWdtl0y2DwEUas=.sha256"
|
"previous": "&R49FywYF8CXPhoSEydLbSCgvCddeyTiBwGuDU/gqY+M=.sha256"
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ ${description.value}</textarea
|
|||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
`;
|
`;
|
||||||
} else if (description.type != 'hidden') {
|
} else {
|
||||||
return html`
|
return html`
|
||||||
<li class="w3-row">
|
<li class="w3-row">
|
||||||
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>
|
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||||
@ -108,10 +108,6 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
||||||
@ -153,9 +149,9 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
.w3-hover-none:hover{box-shadow:none!important}
|
||||||
/* Colors */
|
/* Colors */
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
||||||
@ -170,24 +166,15 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
||||||
|
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "💻",
|
"emoji": "💻",
|
||||||
"previous": "&sFRTDn/RpxP1NJeECXHrXKwCRUJsEOEDVaCMPl50zpM=.sha256"
|
"previous": "&icsPplXHgmpkbNWyo/WTvRdT/A8BXxW4lJixOtP4ueQ=.sha256"
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@ async function fetch_info(apps) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
async function fetch_shared_apps() {
|
async function fetch_shared_apps() {
|
||||||
let messages = {};
|
let messages = {};
|
||||||
|
|
||||||
@ -65,17 +69,17 @@ async function main() {
|
|||||||
const stylesheet = `
|
const stylesheet = `
|
||||||
body {
|
body {
|
||||||
color: whitesmoke;
|
color: whitesmoke;
|
||||||
margin: 8px;
|
font-family: sans-serif;
|
||||||
|
margin: 16px;
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
.iconbox {
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
|
grid-template-columns: repeat(auto-fill, 64px);
|
||||||
}
|
gap: 1em;
|
||||||
|
justify-content: space-around;
|
||||||
.iconbox::after {
|
background-color: #ffffff10;
|
||||||
content: "";
|
border: 2px solid #073642;
|
||||||
flex: auto;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app {
|
.app {
|
||||||
@ -97,28 +101,16 @@ async function main() {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const body = `
|
const body = `
|
||||||
<h1>Welcome to Tilde Friends</h1>
|
<h1 style="text-shadow: #808080 0 0 10px;">Welcome to Tilde Friends.</h1>
|
||||||
|
|
||||||
<div class="w3-card-4 w3-margin-top">
|
<h2>your apps</h2>
|
||||||
<header class="w3-container w3-light-blue">
|
<div id="apps" class="container"></div>
|
||||||
<h2>Your Apps</h2>
|
|
||||||
</header>
|
|
||||||
<div id="apps" class="w3-indigo iconbox"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w3-card-4 w3-margin-top">
|
<h2>shared apps</h2>
|
||||||
<header class="w3-container w3-light-blue">
|
<div id="shared_apps" class="container"></div>
|
||||||
<h2>Shared Apps</h2>
|
|
||||||
</header>
|
|
||||||
<div id="shared_apps" class="w3-indigo iconbox"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w3-card-4 w3-margin-top">
|
<h2>core apps</h2>
|
||||||
<header class="w3-container w3-light-blue">
|
<div id="core_apps" class="container"></div>
|
||||||
<h2>Core Apps</h2>
|
|
||||||
</header>
|
|
||||||
<div id="core_apps" class="w3-indigo iconbox"></div>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const script = `
|
const script = `
|
||||||
@ -134,13 +126,9 @@ async function main() {
|
|||||||
|
|
||||||
// For each app in the provided list
|
// For each app in the provided list
|
||||||
for (let app of Object.keys(apps).sort()) {
|
for (let app of Object.keys(apps).sort()) {
|
||||||
|
|
||||||
// Create the item
|
// Create the item
|
||||||
let inline = document.createElement('div');
|
let div = list.appendChild(document.createElement('div'));
|
||||||
inline.style.display = 'inline-block';
|
|
||||||
inline.classList.add('w3-button');
|
|
||||||
list.appendChild(inline);
|
|
||||||
let div = document.createElement('div');
|
|
||||||
inline.appendChild(div);
|
|
||||||
div.classList.add('app');
|
div.classList.add('app');
|
||||||
|
|
||||||
// The app's icon
|
// The app's icon
|
||||||
@ -173,13 +161,12 @@ async function main() {
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link type="text/css" rel="stylesheet" href="w3.css"></link>
|
|
||||||
<style>
|
<style>
|
||||||
${stylesheet}
|
${stylesheet}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="w3-darkgray">
|
<body>
|
||||||
${body}
|
${body}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
248
apps/apps/w3.css
248
apps/apps/w3.css
@ -1,248 +0,0 @@
|
|||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
|
||||||
article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item}
|
|
||||||
audio,canvas,progress,video{display:inline-block}progress{vertical-align:baseline}
|
|
||||||
audio:not([controls]){display:none;height:0}[hidden],template{display:none}
|
|
||||||
a{background-color:transparent}a:active,a:hover{outline-width:0}
|
|
||||||
abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}
|
|
||||||
b,strong{font-weight:bolder}dfn{font-style:italic}mark{background:#ff0;color:#000}
|
|
||||||
small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
|
||||||
sub{bottom:-0.25em}sup{top:-0.5em}figure{margin:1em 40px}img{border-style:none}
|
|
||||||
code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}hr{box-sizing:content-box;height:0;overflow:visible}
|
|
||||||
button,input,select,textarea,optgroup{font:inherit;margin:0}optgroup{font-weight:bold}
|
|
||||||
button,input{overflow:visible}button,select{text-transform:none}
|
|
||||||
button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}
|
|
||||||
button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}
|
|
||||||
button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}
|
|
||||||
fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}
|
|
||||||
legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}
|
|
||||||
[type=checkbox],[type=radio]{padding:0}
|
|
||||||
[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}
|
|
||||||
[type=search]{-webkit-appearance:textfield;outline-offset:-2px}
|
|
||||||
[type=search]::-webkit-search-decoration{-webkit-appearance:none}
|
|
||||||
::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
|
|
||||||
/* End extract */
|
|
||||||
html,body{font-family:Verdana,sans-serif;font-size:15px;line-height:1.5}html{overflow-x:hidden}
|
|
||||||
h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px}
|
|
||||||
.w3-serif{font-family:serif}.w3-sans-serif{font-family:sans-serif}.w3-cursive{font-family:cursive}.w3-monospace{font-family:monospace}
|
|
||||||
h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin:10px 0}.w3-wide{letter-spacing:4px}
|
|
||||||
hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|
||||||
.w3-image{max-width:100%;height:auto}img{vertical-align:middle}a{color:inherit}
|
|
||||||
.w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table}.w3-table-all{border:1px solid #ccc}
|
|
||||||
.w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1}
|
|
||||||
.w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1}
|
|
||||||
.w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center}
|
|
||||||
.w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top}
|
|
||||||
.w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:16px}
|
|
||||||
.w3-btn,.w3-button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap}
|
|
||||||
.w3-btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}
|
|
||||||
.w3-btn,.w3-button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
|
||||||
.w3-disabled,.w3-btn:disabled,.w3-button:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none}
|
|
||||||
.w3-btn.w3-disabled:hover,.w3-btn:disabled:hover{box-shadow:none}
|
|
||||||
.w3-badge,.w3-tag{background-color:#000;color:#fff;display:inline-block;padding-left:8px;padding-right:8px;text-align:center}.w3-badge{border-radius:50%}
|
|
||||||
.w3-ul{list-style-type:none;padding:0;margin:0}.w3-ul li{padding:8px 16px;border-bottom:1px solid #ddd}.w3-ul li:last-child{border-bottom:none}
|
|
||||||
.w3-tooltip,.w3-display-container{position:relative}.w3-tooltip .w3-text{display:none}.w3-tooltip:hover .w3-text{display:inline-block}
|
|
||||||
.w3-ripple:active{opacity:0.5}.w3-ripple{transition:opacity 0s}
|
|
||||||
.w3-input{padding:8px;display:block;border:none;border-bottom:1px solid #ccc;width:100%}
|
|
||||||
.w3-select{padding:9px 0;width:100%;border:none;border-bottom:1px solid #ccc}
|
|
||||||
.w3-dropdown-click,.w3-dropdown-hover{position:relative;display:inline-block;cursor:pointer}
|
|
||||||
.w3-dropdown-hover:hover .w3-dropdown-content{display:block}
|
|
||||||
.w3-dropdown-hover:first-child,.w3-dropdown-click:hover{background-color:#ccc;color:#000}
|
|
||||||
.w3-dropdown-hover:hover > .w3-button:first-child,.w3-dropdown-click:hover > .w3-button:first-child{background-color:#ccc;color:#000}
|
|
||||||
.w3-dropdown-content{cursor:auto;color:#000;background-color:#fff;display:none;position:absolute;min-width:160px;margin:0;padding:0;z-index:1}
|
|
||||||
.w3-check,.w3-radio{width:24px;height:24px;position:relative;top:6px}
|
|
||||||
.w3-sidebar{height:100%;width:200px;background-color:#fff;position:fixed!important;z-index:1;overflow:auto}
|
|
||||||
.w3-bar-block .w3-dropdown-hover,.w3-bar-block .w3-dropdown-click{width:100%}
|
|
||||||
.w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%}
|
|
||||||
.w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px}
|
|
||||||
.w3-main,#main{transition:margin-left .4s}
|
|
||||||
.w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)}
|
|
||||||
.w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px}
|
|
||||||
.w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto}
|
|
||||||
.w3-bar .w3-bar-item{padding:8px 16px;float:left;width:auto;border:none;display:block;outline:0}
|
|
||||||
.w3-bar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left}
|
|
||||||
.w3-bar .w3-button{white-space:normal}
|
|
||||||
.w3-bar-block .w3-bar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none;outline:0}
|
|
||||||
.w3-bar-block.w3-center .w3-bar-item{text-align:center}.w3-block{display:block;width:100%}
|
|
||||||
.w3-responsive{display:block;overflow-x:auto}
|
|
||||||
.w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before,
|
|
||||||
.w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both}
|
|
||||||
.w3-col,.w3-half,.w3-third,.w3-twothird,.w3-threequarter,.w3-quarter{float:left;width:100%}
|
|
||||||
.w3-col.s1{width:8.33333%}.w3-col.s2{width:16.66666%}.w3-col.s3{width:24.99999%}.w3-col.s4{width:33.33333%}
|
|
||||||
.w3-col.s5{width:41.66666%}.w3-col.s6{width:49.99999%}.w3-col.s7{width:58.33333%}.w3-col.s8{width:66.66666%}
|
|
||||||
.w3-col.s9{width:74.99999%}.w3-col.s10{width:83.33333%}.w3-col.s11{width:91.66666%}.w3-col.s12{width:99.99999%}
|
|
||||||
@media (min-width:601px){.w3-col.m1{width:8.33333%}.w3-col.m2{width:16.66666%}.w3-col.m3,.w3-quarter{width:24.99999%}.w3-col.m4,.w3-third{width:33.33333%}
|
|
||||||
.w3-col.m5{width:41.66666%}.w3-col.m6,.w3-half{width:49.99999%}.w3-col.m7{width:58.33333%}.w3-col.m8,.w3-twothird{width:66.66666%}
|
|
||||||
.w3-col.m9,.w3-threequarter{width:74.99999%}.w3-col.m10{width:83.33333%}.w3-col.m11{width:91.66666%}.w3-col.m12{width:99.99999%}}
|
|
||||||
@media (min-width:993px){.w3-col.l1{width:8.33333%}.w3-col.l2{width:16.66666%}.w3-col.l3{width:24.99999%}.w3-col.l4{width:33.33333%}
|
|
||||||
.w3-col.l5{width:41.66666%}.w3-col.l6{width:49.99999%}.w3-col.l7{width:58.33333%}.w3-col.l8{width:66.66666%}
|
|
||||||
.w3-col.l9{width:74.99999%}.w3-col.l10{width:83.33333%}.w3-col.l11{width:91.66666%}.w3-col.l12{width:99.99999%}}
|
|
||||||
.w3-rest{overflow:hidden}.w3-stretch{margin-left:-16px;margin-right:-16px}
|
|
||||||
.w3-content,.w3-auto{margin-left:auto;margin-right:auto}.w3-content{max-width:980px}.w3-auto{max-width:1140px}
|
|
||||||
.w3-cell-row{display:table;width:100%}.w3-cell{display:table-cell}
|
|
||||||
.w3-cell-top{vertical-align:top}.w3-cell-middle{vertical-align:middle}.w3-cell-bottom{vertical-align:bottom}
|
|
||||||
.w3-hide{display:none!important}.w3-show-block,.w3-show{display:block!important}.w3-show-inline-block{display:inline-block!important}
|
|
||||||
@media (max-width:1205px){.w3-auto{max-width:95%}}
|
|
||||||
@media (max-width:600px){.w3-modal-content{margin:0 10px;width:auto!important}.w3-modal{padding-top:30px}
|
|
||||||
.w3-dropdown-hover.w3-mobile .w3-dropdown-content,.w3-dropdown-click.w3-mobile .w3-dropdown-content{position:relative}
|
|
||||||
.w3-hide-small{display:none!important}.w3-mobile{display:block;width:100%!important}.w3-bar-item.w3-mobile,.w3-dropdown-hover.w3-mobile,.w3-dropdown-click.w3-mobile{text-align:center}
|
|
||||||
.w3-dropdown-hover.w3-mobile,.w3-dropdown-hover.w3-mobile .w3-btn,.w3-dropdown-hover.w3-mobile .w3-button,.w3-dropdown-click.w3-mobile,.w3-dropdown-click.w3-mobile .w3-btn,.w3-dropdown-click.w3-mobile .w3-button{width:100%}}
|
|
||||||
@media (max-width:768px){.w3-modal-content{width:500px}.w3-modal{padding-top:50px}}
|
|
||||||
@media (min-width:993px){.w3-modal-content{width:900px}.w3-hide-large{display:none!important}.w3-sidebar.w3-collapse{display:block!important}}
|
|
||||||
@media (max-width:992px) and (min-width:601px){.w3-hide-medium{display:none!important}}
|
|
||||||
@media (max-width:992px){.w3-sidebar.w3-collapse{display:none}.w3-main{margin-left:0!important;margin-right:0!important}.w3-auto{max-width:100%}}
|
|
||||||
.w3-top,.w3-bottom{position:fixed;width:100%;z-index:1}.w3-top{top:0}.w3-bottom{bottom:0}
|
|
||||||
.w3-overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2}
|
|
||||||
.w3-display-topleft{position:absolute;left:0;top:0}.w3-display-topright{position:absolute;right:0;top:0}
|
|
||||||
.w3-display-bottomleft{position:absolute;left:0;bottom:0}.w3-display-bottomright{position:absolute;right:0;bottom:0}
|
|
||||||
.w3-display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)}
|
|
||||||
.w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)}
|
|
||||||
.w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)}
|
|
||||||
.w3-display-topmiddle{position:absolute;left:50%;top:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}
|
|
||||||
.w3-display-bottommiddle{position:absolute;left:50%;bottom:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}
|
|
||||||
.w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none}
|
|
||||||
.w3-display-position{position:absolute}
|
|
||||||
.w3-circle{border-radius:50%}
|
|
||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
|
||||||
.w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}
|
|
||||||
.w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)}
|
|
||||||
.w3-spin{animation:w3-spin 2s infinite linear}@keyframes w3-spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}
|
|
||||||
.w3-animate-fading{animation:fading 10s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}}
|
|
||||||
.w3-animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}}
|
|
||||||
.w3-animate-top{position:relative;animation:animatetop 0.4s}@keyframes animatetop{from{top:-300px;opacity:0} to{top:0;opacity:1}}
|
|
||||||
.w3-animate-left{position:relative;animation:animateleft 0.4s}@keyframes animateleft{from{left:-300px;opacity:0} to{left:0;opacity:1}}
|
|
||||||
.w3-animate-right{position:relative;animation:animateright 0.4s}@keyframes animateright{from{right:-300px;opacity:0} to{right:0;opacity:1}}
|
|
||||||
.w3-animate-bottom{position:relative;animation:animatebottom 0.4s}@keyframes animatebottom{from{bottom:-300px;opacity:0} to{bottom:0;opacity:1}}
|
|
||||||
.w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}}
|
|
||||||
.w3-animate-input{transition:width 0.4s ease-in-out}.w3-animate-input:focus{width:100%!important}
|
|
||||||
.w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1}
|
|
||||||
.w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75}
|
|
||||||
.w3-greyscale-max,.w3-grayscale-max,.w3-hover-greyscale:hover,.w3-hover-grayscale:hover{filter:grayscale(100%)}
|
|
||||||
.w3-greyscale,.w3-grayscale{filter:grayscale(75%)}.w3-greyscale-min,.w3-grayscale-min{filter:grayscale(50%)}
|
|
||||||
.w3-sepia{filter:sepia(75%)}.w3-sepia-max,.w3-hover-sepia:hover{filter:sepia(100%)}.w3-sepia-min{filter:sepia(50%)}
|
|
||||||
.w3-tiny{font-size:10px!important}.w3-small{font-size:12px!important}.w3-medium{font-size:15px!important}.w3-large{font-size:18px!important}
|
|
||||||
.w3-xlarge{font-size:24px!important}.w3-xxlarge{font-size:36px!important}.w3-xxxlarge{font-size:48px!important}.w3-jumbo{font-size:64px!important}
|
|
||||||
.w3-left-align{text-align:left!important}.w3-right-align{text-align:right!important}.w3-justify{text-align:justify!important}.w3-center{text-align:center!important}
|
|
||||||
.w3-border-0{border:0!important}.w3-border{border:1px solid #ccc!important}
|
|
||||||
.w3-border-top{border-top:1px solid #ccc!important}.w3-border-bottom{border-bottom:1px solid #ccc!important}
|
|
||||||
.w3-border-left{border-left:1px solid #ccc!important}.w3-border-right{border-right:1px solid #ccc!important}
|
|
||||||
.w3-topbar{border-top:6px solid #ccc!important}.w3-bottombar{border-bottom:6px solid #ccc!important}
|
|
||||||
.w3-leftbar{border-left:6px solid #ccc!important}.w3-rightbar{border-right:6px solid #ccc!important}
|
|
||||||
.w3-section,.w3-code{margin-top:16px!important;margin-bottom:16px!important}
|
|
||||||
.w3-margin{margin:16px!important}.w3-margin-top{margin-top:16px!important}.w3-margin-bottom{margin-bottom:16px!important}
|
|
||||||
.w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important}
|
|
||||||
.w3-padding-small{padding:4px 8px!important}.w3-padding{padding:8px 16px!important}.w3-padding-large{padding:12px 24px!important}
|
|
||||||
.w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}.w3-padding-24{padding-top:24px!important;padding-bottom:24px!important}
|
|
||||||
.w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}.w3-padding-48{padding-top:48px!important;padding-bottom:48px!important}
|
|
||||||
.w3-padding-64{padding-top:64px!important;padding-bottom:64px!important}
|
|
||||||
.w3-padding-top-64{padding-top:64px!important}.w3-padding-top-48{padding-top:48px!important}
|
|
||||||
.w3-padding-top-32{padding-top:32px!important}.w3-padding-top-24{padding-top:24px!important}
|
|
||||||
.w3-left{float:left!important}.w3-right{float:right!important}
|
|
||||||
.w3-button:hover{color:#000!important;background-color:#ccc!important}
|
|
||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
|
||||||
/* Colors */
|
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
|
||||||
.w3-blue-grey,.w3-hover-blue-grey:hover,.w3-blue-gray,.w3-hover-blue-gray:hover{color:#fff!important;background-color:#607d8b!important}
|
|
||||||
.w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important}
|
|
||||||
.w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important}
|
|
||||||
.w3-indigo,.w3-hover-indigo:hover{color:#fff!important;background-color:#3f51b5!important}
|
|
||||||
.w3-khaki,.w3-hover-khaki:hover{color:#000!important;background-color:#f0e68c!important}
|
|
||||||
.w3-lime,.w3-hover-lime:hover{color:#000!important;background-color:#cddc39!important}
|
|
||||||
.w3-orange,.w3-hover-orange:hover{color:#000!important;background-color:#ff9800!important}
|
|
||||||
.w3-deep-orange,.w3-hover-deep-orange:hover{color:#fff!important;background-color:#ff5722!important}
|
|
||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
|
||||||
|
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
|
||||||
.w3-pale-blue,.w3-hover-pale-blue:hover{color:#000!important;background-color:#ddffff!important}
|
|
||||||
.w3-text-amber,.w3-hover-text-amber:hover{color:#ffc107!important}
|
|
||||||
.w3-text-aqua,.w3-hover-text-aqua:hover{color:#00ffff!important}
|
|
||||||
.w3-text-blue,.w3-hover-text-blue:hover{color:#2196F3!important}
|
|
||||||
.w3-text-light-blue,.w3-hover-text-light-blue:hover{color:#87CEEB!important}
|
|
||||||
.w3-text-brown,.w3-hover-text-brown:hover{color:#795548!important}
|
|
||||||
.w3-text-cyan,.w3-hover-text-cyan:hover{color:#00bcd4!important}
|
|
||||||
.w3-text-blue-grey,.w3-hover-text-blue-grey:hover,.w3-text-blue-gray,.w3-hover-text-blue-gray:hover{color:#607d8b!important}
|
|
||||||
.w3-text-green,.w3-hover-text-green:hover{color:#4CAF50!important}
|
|
||||||
.w3-text-light-green,.w3-hover-text-light-green:hover{color:#8bc34a!important}
|
|
||||||
.w3-text-indigo,.w3-hover-text-indigo:hover{color:#3f51b5!important}
|
|
||||||
.w3-text-khaki,.w3-hover-text-khaki:hover{color:#b4aa50!important}
|
|
||||||
.w3-text-lime,.w3-hover-text-lime:hover{color:#cddc39!important}
|
|
||||||
.w3-text-orange,.w3-hover-text-orange:hover{color:#ff9800!important}
|
|
||||||
.w3-text-deep-orange,.w3-hover-text-deep-orange:hover{color:#ff5722!important}
|
|
||||||
.w3-text-pink,.w3-hover-text-pink:hover{color:#e91e63!important}
|
|
||||||
.w3-text-purple,.w3-hover-text-purple:hover{color:#9c27b0!important}
|
|
||||||
.w3-text-deep-purple,.w3-hover-text-deep-purple:hover{color:#673ab7!important}
|
|
||||||
.w3-text-red,.w3-hover-text-red:hover{color:#f44336!important}
|
|
||||||
.w3-text-sand,.w3-hover-text-sand:hover{color:#fdf5e6!important}
|
|
||||||
.w3-text-teal,.w3-hover-text-teal:hover{color:#009688!important}
|
|
||||||
.w3-text-yellow,.w3-hover-text-yellow:hover{color:#d2be0e!important}
|
|
||||||
.w3-text-white,.w3-hover-text-white:hover{color:#fff!important}
|
|
||||||
.w3-text-black,.w3-hover-text-black:hover{color:#000!important}
|
|
||||||
.w3-text-grey,.w3-hover-text-grey:hover,.w3-text-gray,.w3-hover-text-gray:hover{color:#757575!important}
|
|
||||||
.w3-text-light-grey,.w3-hover-text-light-grey:hover,.w3-text-light-gray,.w3-hover-text-light-gray:hover{color:#f1f1f1!important}
|
|
||||||
.w3-text-dark-grey,.w3-hover-text-dark-grey:hover,.w3-text-dark-gray,.w3-hover-text-dark-gray:hover{color:#3a3a3a!important}
|
|
||||||
.w3-border-amber,.w3-hover-border-amber:hover{border-color:#ffc107!important}
|
|
||||||
.w3-border-aqua,.w3-hover-border-aqua:hover{border-color:#00ffff!important}
|
|
||||||
.w3-border-blue,.w3-hover-border-blue:hover{border-color:#2196F3!important}
|
|
||||||
.w3-border-light-blue,.w3-hover-border-light-blue:hover{border-color:#87CEEB!important}
|
|
||||||
.w3-border-brown,.w3-hover-border-brown:hover{border-color:#795548!important}
|
|
||||||
.w3-border-cyan,.w3-hover-border-cyan:hover{border-color:#00bcd4!important}
|
|
||||||
.w3-border-blue-grey,.w3-hover-border-blue-grey:hover,.w3-border-blue-gray,.w3-hover-border-blue-gray:hover{border-color:#607d8b!important}
|
|
||||||
.w3-border-green,.w3-hover-border-green:hover{border-color:#4CAF50!important}
|
|
||||||
.w3-border-light-green,.w3-hover-border-light-green:hover{border-color:#8bc34a!important}
|
|
||||||
.w3-border-indigo,.w3-hover-border-indigo:hover{border-color:#3f51b5!important}
|
|
||||||
.w3-border-khaki,.w3-hover-border-khaki:hover{border-color:#f0e68c!important}
|
|
||||||
.w3-border-lime,.w3-hover-border-lime:hover{border-color:#cddc39!important}
|
|
||||||
.w3-border-orange,.w3-hover-border-orange:hover{border-color:#ff9800!important}
|
|
||||||
.w3-border-deep-orange,.w3-hover-border-deep-orange:hover{border-color:#ff5722!important}
|
|
||||||
.w3-border-pink,.w3-hover-border-pink:hover{border-color:#e91e63!important}
|
|
||||||
.w3-border-purple,.w3-hover-border-purple:hover{border-color:#9c27b0!important}
|
|
||||||
.w3-border-deep-purple,.w3-hover-border-deep-purple:hover{border-color:#673ab7!important}
|
|
||||||
.w3-border-red,.w3-hover-border-red:hover{border-color:#f44336!important}
|
|
||||||
.w3-border-sand,.w3-hover-border-sand:hover{border-color:#fdf5e6!important}
|
|
||||||
.w3-border-teal,.w3-hover-border-teal:hover{border-color:#009688!important}
|
|
||||||
.w3-border-yellow,.w3-hover-border-yellow:hover{border-color:#ffeb3b!important}
|
|
||||||
.w3-border-white,.w3-hover-border-white:hover{border-color:#fff!important}
|
|
||||||
.w3-border-black,.w3-hover-border-black:hover{border-color:#000!important}
|
|
||||||
.w3-border-grey,.w3-hover-border-grey:hover,.w3-border-gray,.w3-hover-border-gray:hover{border-color:#9e9e9e!important}
|
|
||||||
.w3-border-light-grey,.w3-hover-border-light-grey:hover,.w3-border-light-gray,.w3-hover-border-light-gray:hover{border-color:#f1f1f1!important}
|
|
||||||
.w3-border-dark-grey,.w3-hover-border-dark-grey:hover,.w3-border-dark-gray,.w3-hover-border-dark-gray:hover{border-color:#616161!important}
|
|
||||||
.w3-border-pale-red,.w3-hover-border-pale-red:hover{border-color:#ffe7e7!important}.w3-border-pale-green,.w3-hover-border-pale-green:hover{border-color:#e7ffe7!important}
|
|
||||||
.w3-border-pale-yellow,.w3-hover-border-pale-yellow:hover{border-color:#ffffcc!important}.w3-border-pale-blue,.w3-hover-border-pale-blue:hover{border-color:#e7ffff!important}
|
|
42
apps/blog/lit-all.min.js
vendored
42
apps/blog/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "➡️",
|
"emoji": "➡️"
|
||||||
"previous": "&YDDSzbRD8NFAykYlZnk4r4hAK5qXjT5LmKE6rhS1s+A=.sha256"
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ async function contacts_internal(id, last_row_id, following, max_row_id) {
|
|||||||
result.blocking = result.blocking || {};
|
result.blocking = result.blocking || {};
|
||||||
let contacts = await query(
|
let contacts = await query(
|
||||||
`
|
`
|
||||||
SELECT json(content) AS content FROM messages
|
SELECT content FROM messages
|
||||||
WHERE author = ? AND
|
WHERE author = ? AND
|
||||||
rowid > ? AND
|
rowid > ? AND
|
||||||
rowid <= ? AND
|
rowid <= ? AND
|
||||||
@ -189,6 +189,50 @@ async function fetch_about(db, ids, users) {
|
|||||||
return Object.assign({}, users);
|
return Object.assign({}, users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAbout(db, id) {
|
||||||
|
if (g_about_cache[id]) {
|
||||||
|
return g_about_cache[id];
|
||||||
|
}
|
||||||
|
let o = await db.get(id + ':about');
|
||||||
|
const k_version = 4;
|
||||||
|
let f = o ? JSON.parse(o) : o;
|
||||||
|
if (!f || f.version != k_version) {
|
||||||
|
f = {about: {}, sequence: 0, version: k_version};
|
||||||
|
}
|
||||||
|
await ssb.sqlAsync(
|
||||||
|
'SELECT ' +
|
||||||
|
' sequence, ' +
|
||||||
|
' content ' +
|
||||||
|
'FROM messages ' +
|
||||||
|
'WHERE ' +
|
||||||
|
' author = ?1 AND ' +
|
||||||
|
' sequence > ?2 AND ' +
|
||||||
|
" json_extract(content, '$.type') = 'about' AND " +
|
||||||
|
" json_extract(content, '$.about') = ?1 " +
|
||||||
|
'UNION SELECT MAX(sequence) as sequence, NULL FROM messages WHERE author = ?1 ' +
|
||||||
|
'ORDER BY sequence',
|
||||||
|
[id, f.sequence],
|
||||||
|
function (row) {
|
||||||
|
f.sequence = row.sequence;
|
||||||
|
if (row.content) {
|
||||||
|
let about = {};
|
||||||
|
try {
|
||||||
|
about = JSON.parse(row.content);
|
||||||
|
} catch {}
|
||||||
|
delete about.about;
|
||||||
|
delete about.type;
|
||||||
|
f.about = Object.assign(f.about, about);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let j = JSON.stringify(f);
|
||||||
|
if (o != j) {
|
||||||
|
await db.set(id + ':about', j);
|
||||||
|
}
|
||||||
|
g_about_cache[id] = f.about;
|
||||||
|
return f.about;
|
||||||
|
}
|
||||||
|
|
||||||
async function getSize(db, id) {
|
async function getSize(db, id) {
|
||||||
let size = 0;
|
let size = 0;
|
||||||
await ssb.sqlAsync(
|
await ssb.sqlAsync(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||||
@ -108,10 +108,6 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
||||||
@ -153,9 +149,9 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
.w3-hover-none:hover{box-shadow:none!important}
|
||||||
/* Colors */
|
/* Colors */
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
||||||
@ -170,24 +166,15 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
||||||
|
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
||||||
|
42
apps/issues/lit-all.min.js
vendored
42
apps/issues/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
42
apps/journal/lit-all.min.js
vendored
42
apps/journal/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,9 +1,7 @@
|
|||||||
async function main() {
|
async function main() {
|
||||||
print(core.url);
|
let host = core.url.match(/.*\/\/(.*?)\//)[1];
|
||||||
let host = core.url.match(/.*?\/\/([^:/]*)/)[1];
|
|
||||||
let port = await ssb.port();
|
|
||||||
let id = (await ssb.getServerIdentity()).substring(1);
|
let id = (await ssb.getServerIdentity()).substring(1);
|
||||||
let room = `net:${host}:${port}~shs:${id}:SSB+Room+SK3TLYC2T86EHQCUHBUHASCASE18JBV24=`;
|
let room = `net:${host}:${ssb.port}~shs:${id}:SSB+Room+SK3TLYC2T86EHQCUHBUHASCASE18JBV24=`;
|
||||||
await app.setDocument(`
|
await app.setDocument(`
|
||||||
<body style="color: #fff">
|
<body style="color: #fff">
|
||||||
<h1>Server</h1>
|
<h1>Server</h1>
|
||||||
|
42
apps/sneaker/lit-all.min.js
vendored
42
apps/sneaker/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "🦀",
|
"emoji": "🦀",
|
||||||
"previous": "&Zv/eOewtUPxYuALmYV8v+JDKwH4+aN8zCTYFwB7oYEw=.sha256"
|
"previous": "&bBoMW+AjErDfa483Mg3+h1L25xfDDeVSpcfD9WAwL3U=.sha256"
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ tfrpc.register(async function createIdentity() {
|
|||||||
tfrpc.register(async function getServerIdentity() {
|
tfrpc.register(async function getServerIdentity() {
|
||||||
return ssb.getServerIdentity();
|
return ssb.getServerIdentity();
|
||||||
});
|
});
|
||||||
|
tfrpc.register(async function setServerFollowingMe(id, following) {
|
||||||
|
return ssb.setServerFollowingMe(id, following);
|
||||||
|
});
|
||||||
tfrpc.register(async function getIdentities() {
|
tfrpc.register(async function getIdentities() {
|
||||||
return ssb.getIdentities();
|
return ssb.getIdentities();
|
||||||
});
|
});
|
||||||
@ -103,10 +106,6 @@ tfrpc.register(async function getActiveIdentity() {
|
|||||||
tfrpc.register(async function sync() {
|
tfrpc.register(async function sync() {
|
||||||
return await ssb.sync();
|
return await ssb.sync();
|
||||||
});
|
});
|
||||||
tfrpc.register(async function url() {
|
|
||||||
return core.url;
|
|
||||||
});
|
|
||||||
|
|
||||||
core.register('onBroadcastsChanged', async function () {
|
core.register('onBroadcastsChanged', async function () {
|
||||||
await tfrpc.rpc.set('broadcasts', await ssb.getBroadcasts());
|
await tfrpc.rpc.set('broadcasts', await ssb.getBroadcasts());
|
||||||
});
|
});
|
||||||
|
@ -7,7 +7,7 @@ function textNode(text) {
|
|||||||
function linkNode(text, link) {
|
function linkNode(text, link) {
|
||||||
const linkNode = new commonmark.Node('link', undefined);
|
const linkNode = new commonmark.Node('link', undefined);
|
||||||
if (link.startsWith('#')) {
|
if (link.startsWith('#')) {
|
||||||
linkNode.destination = `#${encodeURIComponent(link)}`;
|
linkNode.destination = `#${encodeURIComponent('#' + link)}`;
|
||||||
} else {
|
} else {
|
||||||
linkNode.destination = link;
|
linkNode.destination = link;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ export async function picker(callback, anchor, author) {
|
|||||||
<div class="w3-modal-content w3-card-4">
|
<div class="w3-modal-content w3-card-4">
|
||||||
<div
|
<div
|
||||||
class="w3-content w3-theme-d1"
|
class="w3-content w3-theme-d1"
|
||||||
style="display: flex; flex-direction: column; max-height: 80vh"
|
style="display: flex; flex-direction: column; max-height: 50vh"
|
||||||
>
|
>
|
||||||
<header class="w3-container" style="flex: 0 0">
|
<header class="w3-container" style="flex: 0 0">
|
||||||
<h1>Choose a Reaction</h1>
|
<h1>Choose a Reaction</h1>
|
||||||
|
42
apps/ssb/lit-all.min.js
vendored
42
apps/ssb/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -18,9 +18,6 @@ class TfElement extends LitElement {
|
|||||||
channels: {type: Array},
|
channels: {type: Array},
|
||||||
channels_unread: {type: Object},
|
channels_unread: {type: Object},
|
||||||
channels_latest: {type: Object},
|
channels_latest: {type: Object},
|
||||||
guest: {type: Boolean},
|
|
||||||
url: {type: String},
|
|
||||||
private_messages: {type: Array},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,8 +36,8 @@ class TfElement extends LitElement {
|
|||||||
this.channels = [];
|
this.channels = [];
|
||||||
this.channels_unread = {};
|
this.channels_unread = {};
|
||||||
this.channels_latest = {};
|
this.channels_latest = {};
|
||||||
this.loading_latest = 0;
|
this.loading_channels_latest = 0;
|
||||||
this.loading_latest_scheduled = 0;
|
this.loading_channels_latest_scheduled = 0;
|
||||||
tfrpc.rpc.getBroadcasts().then((b) => {
|
tfrpc.rpc.getBroadcasts().then((b) => {
|
||||||
self.broadcasts = b || [];
|
self.broadcasts = b || [];
|
||||||
});
|
});
|
||||||
@ -69,9 +66,7 @@ class TfElement extends LitElement {
|
|||||||
async initial_load() {
|
async initial_load() {
|
||||||
let whoami = await tfrpc.rpc.getActiveIdentity();
|
let whoami = await tfrpc.rpc.getActiveIdentity();
|
||||||
let ids = (await tfrpc.rpc.getIdentities()) || [];
|
let ids = (await tfrpc.rpc.getIdentities()) || [];
|
||||||
this.url = await tfrpc.rpc.url();
|
|
||||||
this.whoami = whoami ?? (ids.length ? ids[0] : undefined);
|
this.whoami = whoami ?? (ids.length ? ids[0] : undefined);
|
||||||
this.guest = !this.whoami?.length;
|
|
||||||
this.ids = ids;
|
this.ids = ids;
|
||||||
await this.load_channels();
|
await this.load_channels();
|
||||||
}
|
}
|
||||||
@ -148,8 +143,7 @@ class TfElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch_about(following, users) {
|
async fetch_about(ids, users) {
|
||||||
let ids = Object.keys(following).sort();
|
|
||||||
const k_cache_version = 1;
|
const k_cache_version = 1;
|
||||||
let cache = await tfrpc.rpc.databaseGet('about');
|
let cache = await tfrpc.rpc.databaseGet('about');
|
||||||
let original_cache = cache;
|
let original_cache = cache;
|
||||||
@ -175,55 +169,37 @@ class TfElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const k_chunk_size = 1024;
|
|
||||||
let min_row_id = 0;
|
|
||||||
console.log(
|
|
||||||
'loading about for',
|
|
||||||
ids.length,
|
|
||||||
'accounts',
|
|
||||||
cache.last_row_id,
|
|
||||||
'=>',
|
|
||||||
max_row_id
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
while (true) {
|
|
||||||
let abouts = await tfrpc.rpc.query(
|
let abouts = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
SELECT * FROM (
|
|
||||||
SELECT
|
SELECT
|
||||||
messages.rowid AS rowid, messages.author, json(messages.content) AS content, messages.sequence
|
messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
FROM
|
FROM
|
||||||
messages,
|
messages,
|
||||||
json_each(?1) AS following
|
json_each(?1) AS following
|
||||||
WHERE
|
WHERE
|
||||||
messages.author = following.value AND
|
messages.author = following.value AND
|
||||||
messages.content ->> 'type' = 'about' AND
|
|
||||||
messages.rowid > ?3 AND
|
messages.rowid > ?3 AND
|
||||||
messages.rowid <= ?4
|
messages.rowid <= ?4 AND
|
||||||
|
json_extract(messages.content, '$.type') = 'about'
|
||||||
UNION
|
UNION
|
||||||
SELECT
|
SELECT
|
||||||
messages.rowid AS rowid, messages.author, json(messages.content) AS content, messages.sequence
|
messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
FROM
|
FROM
|
||||||
messages,
|
messages,
|
||||||
json_each(?2) AS following
|
json_each(?2) AS following
|
||||||
WHERE
|
WHERE
|
||||||
messages.author = following.value AND
|
messages.author = following.value AND
|
||||||
messages.content ->> 'type' = 'about' AND
|
messages.rowid <= ?4 AND
|
||||||
messages.rowid > ?6 AND
|
json_extract(messages.content, '$.type') = 'about'
|
||||||
messages.rowid <= ?4
|
ORDER BY messages.author, messages.sequence
|
||||||
)
|
|
||||||
ORDER BY rowid LIMIT ?5
|
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
JSON.stringify(ids.filter((id) => cache.about[id])),
|
JSON.stringify(ids.filter((id) => cache.about[id])),
|
||||||
JSON.stringify(ids.filter((id) => !cache.about[id])),
|
JSON.stringify(ids.filter((id) => !cache.about[id])),
|
||||||
cache.last_row_id,
|
cache.last_row_id,
|
||||||
max_row_id,
|
max_row_id,
|
||||||
k_chunk_size,
|
|
||||||
min_row_id,
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
let max_seen;
|
|
||||||
for (let about of abouts) {
|
for (let about of abouts) {
|
||||||
let content = JSON.parse(about.content);
|
let content = JSON.parse(about.content);
|
||||||
if (content.about === about.author) {
|
if (content.about === about.author) {
|
||||||
@ -234,18 +210,8 @@ class TfElement extends LitElement {
|
|||||||
content
|
content
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
max_seen = about.rowid;
|
|
||||||
}
|
}
|
||||||
console.log(
|
cache.last_row_id = max_row_id;
|
||||||
'cache =',
|
|
||||||
cache.last_row_id,
|
|
||||||
'seen =',
|
|
||||||
max_seen,
|
|
||||||
'max =',
|
|
||||||
max_row_id
|
|
||||||
);
|
|
||||||
cache.last_row_id = Math.max(cache.last_row_id, max_seen ?? max_row_id);
|
|
||||||
min_row_id = Math.max(min_row_id, max_seen ?? max_row_id);
|
|
||||||
let new_cache = JSON.stringify(cache);
|
let new_cache = JSON.stringify(cache);
|
||||||
if (new_cache !== original_cache) {
|
if (new_cache !== original_cache) {
|
||||||
let start_time = new Date();
|
let start_time = new Date();
|
||||||
@ -255,18 +221,7 @@ class TfElement extends LitElement {
|
|||||||
}
|
}
|
||||||
users = users || {};
|
users = users || {};
|
||||||
for (let id of Object.keys(cache.about)) {
|
for (let id of Object.keys(cache.about)) {
|
||||||
users[id] = Object.assign(
|
users[id] = Object.assign(users[id] || {}, cache.about[id]);
|
||||||
{follow_depth: following[id]?.d},
|
|
||||||
users[id] || {},
|
|
||||||
cache.about[id]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (cache.last_row_id >= max_row_id) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
}
|
||||||
return Object.assign({}, users);
|
return Object.assign({}, users);
|
||||||
}
|
}
|
||||||
@ -289,7 +244,7 @@ class TfElement extends LitElement {
|
|||||||
this.load_channels();
|
this.load_channels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.schedule_load_latest();
|
this.schedule_load_channels_latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handle_whoami_changed(event) {
|
async _handle_whoami_changed(event) {
|
||||||
@ -304,76 +259,47 @@ class TfElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async get_latest_private(following) {
|
async create_identity() {
|
||||||
const k_version = 1;
|
if (confirm('Are you sure you want to create a new identity?')) {
|
||||||
// { "version": 1, "range": [1234, 5678], messages: [ "%1.sha256", "%2.sha256", ... ], latest: rowid }
|
await tfrpc.rpc.createIdentity();
|
||||||
let cache = JSON.parse(
|
this.ids = (await tfrpc.rpc.getIdentities()) || [];
|
||||||
(await tfrpc.rpc.databaseGet(`private:${this.whoami}`)) ?? '{}'
|
if (this.ids && !this.whoami) {
|
||||||
);
|
this.whoami = this.ids[0];
|
||||||
if (cache.version !== k_version) {
|
|
||||||
cache = {
|
|
||||||
version: k_version,
|
|
||||||
messages: [],
|
|
||||||
range: [],
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_latest_private(following) {
|
||||||
let latest = (
|
let latest = (
|
||||||
await tfrpc.rpc.query('SELECT MAX(rowid) AS latest FROM messages')
|
await tfrpc.rpc.query('SELECT MAX(rowid) AS latest FROM messages')
|
||||||
)[0].latest;
|
)[0].latest;
|
||||||
let ranges = [];
|
const k_chunk_count = 256;
|
||||||
const k_chunk_size = 512;
|
while (latest - k_chunk_count >= 0) {
|
||||||
if (cache.range.length) {
|
|
||||||
for (let i = cache.range[1]; i < latest; i += k_chunk_size) {
|
|
||||||
ranges.push([i, Math.min(i + k_chunk_size, latest), true]);
|
|
||||||
}
|
|
||||||
for (let i = cache.range[0]; i >= 0; i -= k_chunk_size) {
|
|
||||||
ranges.push([
|
|
||||||
Math.max(i - k_chunk_size, 0),
|
|
||||||
Math.min(cache.range[0], i + k_chunk_size),
|
|
||||||
false,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < latest; i += k_chunk_size) {
|
|
||||||
ranges.push([i, Math.min(i + k_chunk_size, latest), true]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let range of ranges) {
|
|
||||||
let messages = await tfrpc.rpc.query(
|
let messages = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
SELECT messages.rowid, messages.id, json(content) AS content
|
SELECT messages.rowid, messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
FROM messages
|
FROM messages
|
||||||
|
JOIN json_each(?1) AS following ON messages.author = following.value
|
||||||
WHERE
|
WHERE
|
||||||
messages.rowid > ?1 AND
|
messages.rowid > ?2 AND
|
||||||
messages.rowid <= ?2 AND
|
messages.rowid <= ?3 AND
|
||||||
json(messages.content) LIKE '"%'
|
json(messages.content) LIKE '"%'
|
||||||
ORDER BY sequence DESC
|
ORDER BY sequence DESC
|
||||||
`,
|
`,
|
||||||
[range[0], range[1]]
|
[JSON.stringify(following), latest - k_chunk_count, latest]
|
||||||
);
|
);
|
||||||
messages = (await this.decrypt(messages)).filter((x) => x.decrypted);
|
messages = (await this.decrypt(messages)).filter((x) => x.decrypted);
|
||||||
if (messages.length) {
|
if (messages.length) {
|
||||||
cache.latest = Math.max(
|
return Math.max(...messages.map((x) => x.rowid));
|
||||||
cache.latest ?? 0,
|
|
||||||
...messages.map((x) => x.rowid)
|
|
||||||
);
|
|
||||||
if (range[2]) {
|
|
||||||
cache.messages = [...cache.messages, ...messages.map((x) => x.id)];
|
|
||||||
} else {
|
|
||||||
cache.messages = [...messages.map((x) => x.id), ...cache.messages];
|
|
||||||
}
|
}
|
||||||
|
latest -= k_chunk_count;
|
||||||
}
|
}
|
||||||
cache.range[0] = Math.min(cache.range[0] ?? range[0], range[0]);
|
return -1;
|
||||||
cache.range[1] = Math.max(cache.range[1] ?? range[1], range[1]);
|
|
||||||
await tfrpc.rpc.databaseSet(
|
|
||||||
`private:${this.whoami}`,
|
|
||||||
JSON.stringify(cache)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return [cache.latest, cache.messages];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async load_channels_latest(following) {
|
async load_channels_latest(following) {
|
||||||
|
this.loading_channels_latest++;
|
||||||
|
try {
|
||||||
let start_time = new Date();
|
let start_time = new Date();
|
||||||
let latest_private = this.get_latest_private(following);
|
let latest_private = this.get_latest_private(following);
|
||||||
let channels = await tfrpc.rpc.query(
|
let channels = await tfrpc.rpc.query(
|
||||||
@ -409,52 +335,37 @@ class TfElement extends LitElement {
|
|||||||
this.channels_latest = Object.fromEntries(
|
this.channels_latest = Object.fromEntries(
|
||||||
channels.map((x) => [x.channel, x.rowid])
|
channels.map((x) => [x.channel, x.rowid])
|
||||||
);
|
);
|
||||||
|
console.log('latest', this.channels_latest);
|
||||||
|
console.log('unread', this.channels_unread);
|
||||||
console.log('channels took', (new Date() - start_time) / 1000.0);
|
console.log('channels took', (new Date() - start_time) / 1000.0);
|
||||||
let self = this;
|
let self = this;
|
||||||
start_time = new Date();
|
|
||||||
latest_private.then(function (latest) {
|
latest_private.then(function (latest) {
|
||||||
self.channels_latest = Object.assign({}, self.channels_latest, {
|
self.channels_latest = Object.assign({}, self.channels_latest, {
|
||||||
'🔐': latest[0],
|
'🔐': latest,
|
||||||
});
|
});
|
||||||
console.log('private took', (new Date() - start_time) / 1000.0);
|
console.log('private took', (new Date() - start_time) / 1000.0);
|
||||||
self.private_messages = latest[1];
|
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
this.loading_channels_latest--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_schedule_load_latest_timer() {
|
_schedule_load_channels_latest_timer() {
|
||||||
--this.loading_latest_scheduled;
|
--this.loading_channels_latest_scheduled;
|
||||||
this.schedule_load_latest();
|
this.schedule_load_channels_latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_load_latest() {
|
schedule_load_channels_latest() {
|
||||||
if (!this.loading_latest) {
|
if (!this.loading_channels_latest) {
|
||||||
this.shadowRoot.getElementById('tf-tab-news')?.load_latest();
|
this.shadowRoot.getElementById('tf-tab-news')?.load_latest();
|
||||||
this.load();
|
this.load_channels_latest(this.following);
|
||||||
} else if (!this.loading_latest_scheduled) {
|
} else if (!this.loading_channels_latest_scheduled) {
|
||||||
this.loading_latest_scheduled++;
|
this.loading_channels_latest_scheduled++;
|
||||||
setTimeout(this._schedule_load_latest_timer.bind(this), 5000);
|
setTimeout(this._schedule_load_channels_latest_timer.bind(this), 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch_user_info(users) {
|
|
||||||
let info = await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
SELECT messages_stats.author, messages_stats.max_sequence, messages_stats.max_timestamp AS max_ts FROM messages_stats
|
|
||||||
JOIN json_each(?) AS following
|
|
||||||
ON messages_stats.author = following.value
|
|
||||||
`,
|
|
||||||
[JSON.stringify(Object.keys(users))]
|
|
||||||
);
|
|
||||||
for (let row of info) {
|
|
||||||
users[row.author].seq = row.max_seq;
|
|
||||||
users[row.author].ts = row.max_ts;
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
this.loading_latest = true;
|
|
||||||
try {
|
|
||||||
let start_time = new Date();
|
let start_time = new Date();
|
||||||
let whoami = this.whoami;
|
let whoami = this.whoami;
|
||||||
let following = await tfrpc.rpc.following([whoami], 2);
|
let following = await tfrpc.rpc.following([whoami], 2);
|
||||||
@ -473,32 +384,19 @@ class TfElement extends LitElement {
|
|||||||
this.channels_unread = JSON.parse(
|
this.channels_unread = JSON.parse(
|
||||||
(await tfrpc.rpc.databaseGet('unread')) ?? '{}'
|
(await tfrpc.rpc.databaseGet('unread')) ?? '{}'
|
||||||
);
|
);
|
||||||
this.following = Object.keys(following);
|
users = await this.fetch_about(Object.keys(following).sort(), users);
|
||||||
let about_start_time = new Date();
|
|
||||||
users = await this.fetch_about(following, users);
|
|
||||||
console.log(
|
console.log(
|
||||||
'about took',
|
'about took',
|
||||||
(new Date() - about_start_time) / 1000.0,
|
(new Date() - start_time) / 1000.0,
|
||||||
'seconds for',
|
'seconds for',
|
||||||
Object.keys(users).length,
|
Object.keys(users).length,
|
||||||
'users'
|
'users'
|
||||||
);
|
);
|
||||||
start_time = new Date();
|
this.following = Object.keys(following);
|
||||||
users = await this.fetch_user_info(users);
|
|
||||||
console.log(
|
|
||||||
'user info took',
|
|
||||||
(new Date() - start_time) / 1000.0,
|
|
||||||
'seconds'
|
|
||||||
);
|
|
||||||
this.users = users;
|
this.users = users;
|
||||||
console.log(
|
console.log(`load finished ${whoami} => ${this.whoami} in ${(new Date() - start_time) / 1000}`);
|
||||||
`load finished ${whoami} => ${this.whoami} in ${(new Date() - start_time) / 1000}`
|
|
||||||
);
|
|
||||||
this.whoami = whoami;
|
this.whoami = whoami;
|
||||||
this.loaded = whoami;
|
this.loaded = whoami;
|
||||||
} finally {
|
|
||||||
this.loading_latest = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_set_unread(event) {
|
channel_set_unread(event) {
|
||||||
@ -550,7 +448,6 @@ class TfElement extends LitElement {
|
|||||||
.channels_unread=${this.channels_unread}
|
.channels_unread=${this.channels_unread}
|
||||||
@channelsetunread=${this.channel_set_unread}
|
@channelsetunread=${this.channel_set_unread}
|
||||||
.connections=${this.connections}
|
.connections=${this.connections}
|
||||||
.private_messages=${this.private_messages}
|
|
||||||
></tf-tab-news>
|
></tf-tab-news>
|
||||||
`;
|
`;
|
||||||
} else if (this.tab === 'connections') {
|
} else if (this.tab === 'connections') {
|
||||||
@ -624,9 +521,7 @@ class TfElement extends LitElement {
|
|||||||
style="position: static; top: 0; z-index: 10"
|
style="position: static; top: 0; z-index: 10"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class=${'w3-bar-item w3-button w3-circle w3-ripple' +
|
class="w3-bar-item w3-button w3-circle w3-ripple"
|
||||||
(this.connections?.some((x) => x.flags.one_shot) ? ' w3-spin' : '')}
|
|
||||||
style="width: 1.5em; height: 1.5em; padding: 8px"
|
|
||||||
@click=${this.refresh}
|
@click=${this.refresh}
|
||||||
>
|
>
|
||||||
↻
|
↻
|
||||||
@ -649,20 +544,8 @@ class TfElement extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
let contents = this.guest
|
let contents =
|
||||||
? html`<div
|
!this.loaded || this.loading
|
||||||
class="w3-display-middle w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge w3-xlarge w3-container"
|
|
||||||
>
|
|
||||||
<p>⚠️🦀 Must be logged in to Tilde Friends to scuttle here. 🦀⚠️</p>
|
|
||||||
<footer class="w3-center">
|
|
||||||
<a
|
|
||||||
class="w3-button w3-theme-d1"
|
|
||||||
href=${`/login?return=${encodeURIComponent(this.url)}`}
|
|
||||||
>Login</a
|
|
||||||
>
|
|
||||||
</footer>
|
|
||||||
</div>`
|
|
||||||
: !this.loaded || this.loading
|
|
||||||
? html`<div
|
? html`<div
|
||||||
class="w3-display-middle w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge w3-xlarge"
|
class="w3-display-middle w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge w3-xlarge"
|
||||||
>
|
>
|
||||||
@ -676,7 +559,7 @@ class TfElement extends LitElement {
|
|||||||
class="w3-theme-dark"
|
class="w3-theme-dark"
|
||||||
>
|
>
|
||||||
<div style="flex: 0 0">${tabs}</div>
|
<div style="flex: 0 0">${tabs}</div>
|
||||||
<div style="flex: 1 1; overflow: auto; contain: layout">
|
<div style="flex: 1 1; overflow: scroll; contain: layout">
|
||||||
${contents}
|
${contents}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -255,12 +255,10 @@ class TfComposeElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
let input = document.createElement('input');
|
let input = document.createElement('input');
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.addEventListener('change', function (event) {
|
input.onchange = function (event) {
|
||||||
input.parentNode.removeChild(input);
|
|
||||||
let file = event.target.files[0];
|
let file = event.target.files[0];
|
||||||
self.add_file(file);
|
self.add_file(file);
|
||||||
});
|
};
|
||||||
document.body.appendChild(input);
|
|
||||||
input.click();
|
input.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +357,7 @@ class TfComposeElement extends LitElement {
|
|||||||
remove_mention(id) {
|
remove_mention(id) {
|
||||||
let draft = this.get_draft();
|
let draft = this.get_draft();
|
||||||
delete draft.mentions[id];
|
delete draft.mentions[id];
|
||||||
setTimeout(() => this.notify(draft), 0);
|
setTimeout(() => this.notify(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_mention(mention) {
|
render_mention(mention) {
|
||||||
@ -596,7 +594,7 @@ class TfComposeElement extends LitElement {
|
|||||||
.innerText=${live(draft.text ?? '')}
|
.innerText=${live(draft.text ?? '')}
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-half w3-container">
|
<div class="w3-half">
|
||||||
${content_warning}
|
${content_warning}
|
||||||
<p id="preview"></p>
|
<p id="preview"></p>
|
||||||
</div>
|
</div>
|
||||||
@ -607,11 +605,7 @@ class TfComposeElement extends LitElement {
|
|||||||
<footer class="w3-container">
|
<footer class="w3-container">
|
||||||
${this.render_attach_app()} ${this.render_content_warning()}
|
${this.render_attach_app()} ${this.render_content_warning()}
|
||||||
${this.render_new_thread()}
|
${this.render_new_thread()}
|
||||||
<button
|
<button class="w3-button w3-theme-d1" id="submit" @click=${this.submit}>
|
||||||
class="w3-button w3-theme-d1"
|
|
||||||
id="submit"
|
|
||||||
@click=${this.submit}
|
|
||||||
>
|
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<button class="w3-button w3-theme-d1" @click=${this.attach}>
|
<button class="w3-button w3-theme-d1" @click=${this.attach}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {LitElement, html, repeat, render, unsafeHTML} from './lit-all.min.js';
|
import {LitElement, html, render, unsafeHTML} from './lit-all.min.js';
|
||||||
import * as tfrpc from '/static/tfrpc.js';
|
import * as tfrpc from '/static/tfrpc.js';
|
||||||
import * as tfutils from './tf-utils.js';
|
import * as tfutils from './tf-utils.js';
|
||||||
import * as emojis from './emojis.js';
|
import * as emojis from './emojis.js';
|
||||||
@ -33,25 +33,6 @@ class TfMessageElement extends LitElement {
|
|||||||
this.channel_unread = -1;
|
this.channel_unread = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
this._click_callback = this.document_click.bind(this);
|
|
||||||
document.body.addEventListener('mouseup', this._click_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
super.disconnectedCallback();
|
|
||||||
document.body.removeEventListener('mouseup', this._click_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
document_click(event) {
|
|
||||||
let content = this.renderRoot.querySelector('.w3-dropdown-content');
|
|
||||||
let target = event.target;
|
|
||||||
if (content && !content.contains(target)) {
|
|
||||||
content.classList.remove('w3-show');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show_reply() {
|
show_reply() {
|
||||||
let event = new CustomEvent('tf-draft', {
|
let event = new CustomEvent('tf-draft', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
@ -116,13 +97,6 @@ class TfMessageElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_json(value) {
|
|
||||||
let json = JSON.stringify(value, null, 2);
|
|
||||||
return html`
|
|
||||||
<pre style="white-space: pre-wrap; overflow-wrap: anywhere">${json}</pre>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render_raw() {
|
render_raw() {
|
||||||
let raw = {
|
let raw = {
|
||||||
id: this.message?.id,
|
id: this.message?.id,
|
||||||
@ -134,12 +108,23 @@ class TfMessageElement extends LitElement {
|
|||||||
content: this.message?.content,
|
content: this.message?.content,
|
||||||
signature: this.message?.signature,
|
signature: this.message?.signature,
|
||||||
};
|
};
|
||||||
return this.render_json(raw);
|
return html`<div style="white-space: pre-wrap">
|
||||||
|
${JSON.stringify(raw, null, 2)}
|
||||||
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
vote(emoji) {
|
vote(emoji) {
|
||||||
let reaction = emoji;
|
let reaction = emoji;
|
||||||
let message = this.message.id;
|
let message = this.message.id;
|
||||||
|
if (
|
||||||
|
confirm(
|
||||||
|
'Are you sure you want to react with ' +
|
||||||
|
reaction +
|
||||||
|
' to ' +
|
||||||
|
message +
|
||||||
|
'?'
|
||||||
|
)
|
||||||
|
) {
|
||||||
tfrpc.rpc
|
tfrpc.rpc
|
||||||
.appendMessage(this.whoami, {
|
.appendMessage(this.whoami, {
|
||||||
type: 'vote',
|
type: 'vote',
|
||||||
@ -153,6 +138,7 @@ class TfMessageElement extends LitElement {
|
|||||||
alert(error?.message);
|
alert(error?.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
react(event) {
|
react(event) {
|
||||||
emojis.picker((x) => this.vote(x), null, this.whoami);
|
emojis.picker((x) => this.vote(x), null, this.whoami);
|
||||||
@ -204,7 +190,7 @@ class TfMessageElement extends LitElement {
|
|||||||
|
|
||||||
render_mention(mention) {
|
render_mention(mention) {
|
||||||
if (!mention?.link || typeof mention.link != 'string') {
|
if (!mention?.link || typeof mention.link != 'string') {
|
||||||
return this.render_json(mention);
|
return html` <pre>${JSON.stringify(mention)}</pre>`;
|
||||||
} else if (
|
} else if (
|
||||||
mention?.link?.startsWith('&') &&
|
mention?.link?.startsWith('&') &&
|
||||||
mention?.type?.startsWith('image/')
|
mention?.type?.startsWith('image/')
|
||||||
@ -255,17 +241,16 @@ class TfMessageElement extends LitElement {
|
|||||||
) {
|
) {
|
||||||
return html` <a href=${`/${mention.link}/view`}>${mention.name}</a>`;
|
return html` <a href=${`/${mention.link}/view`}>${mention.name}</a>`;
|
||||||
} else {
|
} else {
|
||||||
return this.render_json(mention);
|
return html` <pre style="white-space: pre-wrap">
|
||||||
|
${JSON.stringify(mention, null, 2)}</pre
|
||||||
|
>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_mentions() {
|
render_mentions() {
|
||||||
let mentions = this.message?.content?.mentions || [];
|
let mentions = this.message?.content?.mentions || [];
|
||||||
mentions = mentions.filter(
|
mentions = mentions.filter(
|
||||||
(x) =>
|
(x) => this.message?.content?.text?.indexOf(x.link) === -1
|
||||||
this.message?.content?.text?.indexOf(
|
|
||||||
typeof x === 'string' ? x : x.link
|
|
||||||
) === -1
|
|
||||||
);
|
);
|
||||||
if (mentions.length) {
|
if (mentions.length) {
|
||||||
let self = this;
|
let self = this;
|
||||||
@ -310,20 +295,19 @@ class TfMessageElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
if (this.message.child_messages?.length) {
|
if (this.message.child_messages?.length) {
|
||||||
if (!this.expanded[this.message.id]) {
|
if (!this.expanded[this.message.id]) {
|
||||||
return html`
|
return html`<button
|
||||||
<button
|
class="w3-button w3-theme-d1"
|
||||||
class="w3-button w3-theme-d1 w3-block w3-bar"
|
|
||||||
style="box-sizing: border-box"
|
|
||||||
@click=${() => self.set_expanded(true)}
|
@click=${() => self.set_expanded(true)}
|
||||||
>
|
>
|
||||||
+ ${this.total_child_messages(this.message) + ' More'}
|
+ ${this.total_child_messages(this.message) + ' More'}
|
||||||
</button>
|
</button>`;
|
||||||
`;
|
|
||||||
} else {
|
} else {
|
||||||
return html` <div class="w3-container w3-margin-bottom">
|
return html`<button
|
||||||
${repeat(
|
class="w3-button w3-theme-d1"
|
||||||
this.message.child_messages || [],
|
@click=${() => self.set_expanded(false)}
|
||||||
(x) => x.id,
|
>
|
||||||
|
Collapse</button
|
||||||
|
>${(this.message.child_messages || []).map(
|
||||||
(x) =>
|
(x) =>
|
||||||
html`<tf-message
|
html`<tf-message
|
||||||
.message=${x}
|
.message=${x}
|
||||||
@ -334,15 +318,7 @@ class TfMessageElement extends LitElement {
|
|||||||
channel=${this.channel}
|
channel=${this.channel}
|
||||||
channel_unread=${this.channel_unread}
|
channel_unread=${this.channel_unread}
|
||||||
></tf-message>`
|
></tf-message>`
|
||||||
)}
|
)}`;
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="w3-button w3-theme-d1 w3-block w3-bar"
|
|
||||||
style="box-sizing: border-box"
|
|
||||||
@click=${() => self.set_expanded(false)}
|
|
||||||
>
|
|
||||||
Collapse
|
|
||||||
</button>`;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -381,143 +357,85 @@ class TfMessageElement extends LitElement {
|
|||||||
return channels.map((x) => html`<tf-tag tag=${x}></tf-tag>`);
|
return channels.map((x) => html`<tf-tag tag=${x}></tf-tag>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
class_background() {
|
render() {
|
||||||
return this.message?.decrypted
|
|
||||||
? 'w3-pale-red'
|
|
||||||
: this.message?.rowid >= this.channel_unread
|
|
||||||
? 'w3-theme-d2'
|
|
||||||
: 'w3-theme-d4';
|
|
||||||
}
|
|
||||||
|
|
||||||
get_content() {
|
|
||||||
let content = this.message?.content;
|
let content = this.message?.content;
|
||||||
if (this.message?.decrypted?.type == 'post') {
|
if (this.message?.decrypted?.type == 'post') {
|
||||||
content = this.message.decrypted;
|
content = this.message.decrypted;
|
||||||
}
|
}
|
||||||
return content;
|
let class_background = this.message?.decrypted
|
||||||
}
|
? 'w3-pale-red'
|
||||||
|
: this.message?.rowid >= this.channel_unread
|
||||||
copy_id(event) {
|
? 'w3-theme-d2'
|
||||||
navigator.clipboard.writeText(this.message?.id);
|
: 'w3-theme-d4';
|
||||||
}
|
|
||||||
|
|
||||||
toggle_menu(event) {
|
|
||||||
event.srcElement.parentNode
|
|
||||||
.querySelector('.w3-dropdown-content')
|
|
||||||
.classList.toggle('w3-show');
|
|
||||||
}
|
|
||||||
|
|
||||||
render_menu() {
|
|
||||||
let content = this.get_content();
|
|
||||||
let formats = [['message', 'Message']];
|
|
||||||
if (content?.type == 'post' || content?.type == 'blog') {
|
|
||||||
formats.push(['md', 'Markdown']);
|
|
||||||
}
|
|
||||||
if (this.message?.decrypted) {
|
|
||||||
formats.push(['decrypted', 'Decrypted']);
|
|
||||||
}
|
|
||||||
formats.push(['raw', 'Raw']);
|
|
||||||
return html`
|
|
||||||
<div class="w3-bar-item w3-right">
|
|
||||||
<button class="w3-button w3-theme-d1" @click=${this.toggle_menu}>
|
|
||||||
%
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
class="w3-dropdown-content w3-bar-block w3-card-4 w3-theme-l1"
|
|
||||||
style="right: 48px"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
target="_top"
|
|
||||||
class="w3-button w3-bar-item"
|
|
||||||
href=${'#' + encodeURIComponent(this.message?.id)}
|
|
||||||
>View Message</a
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="w3-button w3-bar-item w3-border-bottom"
|
|
||||||
@click=${this.copy_id}
|
|
||||||
>
|
|
||||||
Copy ID
|
|
||||||
</button>
|
|
||||||
${this.drafts[this.message?.id] === undefined
|
|
||||||
? html`
|
|
||||||
<button class="w3-button w3-bar-item" @click=${this.show_reply}>
|
|
||||||
⮢ Reply
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
: undefined}
|
|
||||||
<button
|
|
||||||
class="w3-button w3-bar-item w3-border-bottom"
|
|
||||||
@click=${this.react}
|
|
||||||
>
|
|
||||||
👍 React
|
|
||||||
</button>
|
|
||||||
${formats.map(
|
|
||||||
([format, name]) => html`
|
|
||||||
<button
|
|
||||||
class="w3-button w3-bar-item"
|
|
||||||
style=${format == this.format ? 'font-weight: bold' : ''}
|
|
||||||
@click=${() => (this.format = format)}
|
|
||||||
>
|
|
||||||
${name}
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render_header() {
|
|
||||||
let is_encrypted = this.message?.decrypted
|
|
||||||
? html`<span class="w3-bar-item">🔓</span>`
|
|
||||||
: typeof this.message?.content == 'string'
|
|
||||||
? html`<span class="w3-bar-item">🔒</span>`
|
|
||||||
: undefined;
|
|
||||||
return html`
|
|
||||||
<header class="w3-bar">
|
|
||||||
<span class="w3-bar-item">
|
|
||||||
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
|
||||||
</span>
|
|
||||||
${is_encrypted} ${this.render_menu()}
|
|
||||||
<div class="w3-bar-item w3-right" style="text-wrap: nowrap">
|
|
||||||
${new Date(this.message.timestamp).toLocaleString()}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render_frame(inner) {
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
code {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div
|
|
||||||
class="w3-card-4 ${this.class_background()} w3-border-theme w3-margin-top"
|
|
||||||
style="overflow: auto; overflow-wrap: anywhere; display: block; max-width: 100%"
|
|
||||||
>
|
|
||||||
${inner}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render_small_frame(inner) {
|
|
||||||
let self = this;
|
let self = this;
|
||||||
return this.render_frame(html`
|
let raw_button;
|
||||||
${self.render_header()}
|
switch (this.format) {
|
||||||
${self.format == 'raw'
|
case 'raw':
|
||||||
? html`<div class="w3-container">${self.render_raw()}</div>`
|
if (content?.type == 'post' || content?.type == 'blog') {
|
||||||
: inner}
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'md')}
|
||||||
|
>
|
||||||
|
Markdown
|
||||||
|
</button>`;
|
||||||
|
} else {
|
||||||
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'message')}
|
||||||
|
>
|
||||||
|
Message
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'md':
|
||||||
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'message')}
|
||||||
|
>
|
||||||
|
Message
|
||||||
|
</button>`;
|
||||||
|
break;
|
||||||
|
case 'decrypted':
|
||||||
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'raw')}
|
||||||
|
>
|
||||||
|
Raw
|
||||||
|
</button>`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (this.message.decrypted) {
|
||||||
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'decrypted')}
|
||||||
|
>
|
||||||
|
Decrypted
|
||||||
|
</button>`;
|
||||||
|
} else {
|
||||||
|
raw_button = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => (self.format = 'raw')}
|
||||||
|
>
|
||||||
|
Raw
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
function small_frame(inner) {
|
||||||
|
let body;
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
|
style="margin-top: 8px; padding: 16px; display: inline-block; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
|
<tf-user id=${self.message.author} .users=${self.users}></tf-user>
|
||||||
|
<span style="padding-right: 8px; text-wrap: nowrap"
|
||||||
|
><a tfarget="_top" href=${'#' + encodeURIComponent(self.message.id)}
|
||||||
|
>%</a
|
||||||
|
>
|
||||||
|
${new Date(self.message.timestamp).toLocaleString()}</span
|
||||||
|
>
|
||||||
|
${raw_button} ${self.format == 'raw' ? self.render_raw() : inner}
|
||||||
${self.render_votes()}
|
${self.render_votes()}
|
||||||
${(self.message.child_messages || []).map(
|
${(self.message.child_messages || []).map(
|
||||||
(x) => html`
|
(x) => html`
|
||||||
@ -532,41 +450,15 @@ class TfMessageElement extends LitElement {
|
|||||||
></tf-message>
|
></tf-message>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
`);
|
</div>
|
||||||
}
|
|
||||||
|
|
||||||
render_actions() {
|
|
||||||
let content = this.get_content();
|
|
||||||
let reply =
|
|
||||||
this.drafts[this.message?.id] !== undefined
|
|
||||||
? html`
|
|
||||||
<tf-compose
|
|
||||||
whoami=${this.whoami}
|
|
||||||
.users=${this.users}
|
|
||||||
root=${content.root || this.message.id}
|
|
||||||
branch=${this.message.id}
|
|
||||||
.drafts=${this.drafts}
|
|
||||||
@tf-discard=${this.discard_reply}
|
|
||||||
author=${this.message.author}
|
|
||||||
></tf-compose>
|
|
||||||
`
|
|
||||||
: undefined;
|
|
||||||
return html`
|
|
||||||
<div class="w3-section w3-container">${reply}</div>
|
|
||||||
<footer>${this.render_children()}</footer>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
let content = this.message?.content;
|
|
||||||
if (this.message?.decrypted?.type == 'post') {
|
|
||||||
content = this.message.decrypted;
|
|
||||||
}
|
|
||||||
let class_background = this.class_background();
|
|
||||||
let self = this;
|
|
||||||
if (this.message?.type === 'contact_group') {
|
if (this.message?.type === 'contact_group') {
|
||||||
return this.render_frame(
|
return html` <div
|
||||||
html` ${this.message.messages.map(
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
|
style="margin-top: 8px; padding: 16px; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
|
${this.message.messages.map(
|
||||||
(x) =>
|
(x) =>
|
||||||
html`<tf-message
|
html`<tf-message
|
||||||
.message=${x}
|
.message=${x}
|
||||||
@ -577,17 +469,17 @@ class TfMessageElement extends LitElement {
|
|||||||
channel=${this.channel}
|
channel=${this.channel}
|
||||||
channel_unread=${this.channel_unread}
|
channel_unread=${this.channel_unread}
|
||||||
></tf-message>`
|
></tf-message>`
|
||||||
)}`
|
)}
|
||||||
);
|
</div>`;
|
||||||
} else if (this.message.placeholder) {
|
} else if (this.message.placeholder) {
|
||||||
return this.render_frame(
|
return html` <div
|
||||||
html`<div class="w3-padding">
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
<p>
|
style="margin-top: 8px; padding: 16px; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
<a target="_top" href=${'#' + encodeURIComponent(this.message.id)}
|
<a target="_top" href=${'#' + encodeURIComponent(this.message.id)}
|
||||||
>${this.message.id}</a
|
>${this.message.id}</a
|
||||||
>
|
>
|
||||||
(placeholder)
|
(placeholder)
|
||||||
</p>
|
|
||||||
<div>${this.render_votes()}</div>
|
<div>${this.render_votes()}</div>
|
||||||
${(this.message.child_messages || []).map(
|
${(this.message.child_messages || []).map(
|
||||||
(x) => html`
|
(x) => html`
|
||||||
@ -602,9 +494,8 @@ class TfMessageElement extends LitElement {
|
|||||||
></tf-message>
|
></tf-message>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</div>`
|
</div>`;
|
||||||
);
|
} else if (typeof (content?.type === 'string')) {
|
||||||
} else if (typeof content?.type === 'string') {
|
|
||||||
if (content.type == 'about') {
|
if (content.type == 'about') {
|
||||||
let name;
|
let name;
|
||||||
let image;
|
let image;
|
||||||
@ -631,14 +522,10 @@ class TfMessageElement extends LitElement {
|
|||||||
Updated profile for
|
Updated profile for
|
||||||
<tf-user id=${content.about} .users=${this.users}></tf-user>.
|
<tf-user id=${content.about} .users=${this.users}></tf-user>.
|
||||||
</div>`;
|
</div>`;
|
||||||
return this.render_small_frame(html`
|
return small_frame(html` ${update} ${name} ${image} ${description} `);
|
||||||
<div class="w3-container">
|
|
||||||
<p>${update} ${name} ${image} ${description}</p>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
} else if (content.type == 'contact') {
|
} else if (content.type == 'contact') {
|
||||||
return html`
|
return html`
|
||||||
<div class="w3-padding">
|
<div>
|
||||||
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
||||||
is
|
is
|
||||||
${content.blocking === true
|
${content.blocking === true
|
||||||
@ -657,6 +544,24 @@ class TfMessageElement extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
} else if (content.type == 'post') {
|
} else if (content.type == 'post') {
|
||||||
|
let reply =
|
||||||
|
this.drafts[this.message?.id] !== undefined
|
||||||
|
? html`
|
||||||
|
<tf-compose
|
||||||
|
whoami=${this.whoami}
|
||||||
|
.users=${this.users}
|
||||||
|
root=${content.root || this.message.id}
|
||||||
|
branch=${this.message.id}
|
||||||
|
.drafts=${this.drafts}
|
||||||
|
@tf-discard=${this.discard_reply}
|
||||||
|
author=${this.message.author}
|
||||||
|
></tf-compose>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<button class="w3-button w3-theme-d1" @click=${this.show_reply}>
|
||||||
|
Reply
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
let self = this;
|
let self = this;
|
||||||
let body;
|
let body;
|
||||||
switch (this.format) {
|
switch (this.format) {
|
||||||
@ -673,7 +578,11 @@ class TfMessageElement extends LitElement {
|
|||||||
body = unsafeHTML(tfutils.markdown(content.text));
|
body = unsafeHTML(tfutils.markdown(content.text));
|
||||||
break;
|
break;
|
||||||
case 'decrypted':
|
case 'decrypted':
|
||||||
body = this.render_json(content);
|
body = html`<pre
|
||||||
|
style="white-space: pre-wrap; overflow-wrap: anywhere"
|
||||||
|
>
|
||||||
|
${JSON.stringify(content, null, 2)}</pre
|
||||||
|
>`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let content_warning = html`
|
let content_warning = html`
|
||||||
@ -695,22 +604,108 @@ class TfMessageElement extends LitElement {
|
|||||||
? html` ${content_warning} ${content_html} `
|
? html` ${content_warning} ${content_html} `
|
||||||
: content_warning
|
: content_warning
|
||||||
: content_html;
|
: content_html;
|
||||||
return this.render_frame(html`
|
let is_encrypted = this.message?.decrypted
|
||||||
${this.render_header()}
|
? html`<span style="align-self: center">🔓</span>`
|
||||||
<div class="w3-container">${payload}</div>
|
: undefined;
|
||||||
${this.render_votes()} ${this.render_actions()}
|
return html`
|
||||||
|
<style>
|
||||||
|
code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div
|
||||||
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
|
style="margin-top: 8px; padding: 16px; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
|
<div style="display: flex; flex-direction: row">
|
||||||
|
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
||||||
|
${is_encrypted}
|
||||||
|
<span style="flex: 1"></span>
|
||||||
|
<span style="padding-right: 8px; text-wrap: nowrap"
|
||||||
|
><a
|
||||||
|
target="_top"
|
||||||
|
href=${'#' + encodeURIComponent(self.message.id)}
|
||||||
|
>%</a
|
||||||
|
>
|
||||||
|
${new Date(this.message.timestamp).toLocaleString()}</span
|
||||||
|
>
|
||||||
|
<span>${raw_button}</span>
|
||||||
</div>
|
</div>
|
||||||
`);
|
${payload} ${this.render_votes()}
|
||||||
|
<footer class="w3-container">
|
||||||
|
${reply}
|
||||||
|
<button class="w3-button w3-theme-d1" @click=${this.react}>
|
||||||
|
React
|
||||||
|
</button>
|
||||||
|
${!content.root && this.message.rowid < this.channel_unread
|
||||||
|
? html`
|
||||||
|
<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${this.mark_unread}
|
||||||
|
>
|
||||||
|
Mark Unread
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
: undefined}
|
||||||
|
${this.render_children()}
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
} else if (content.type === 'issue') {
|
} else if (content.type === 'issue') {
|
||||||
return this.render_frame(html`
|
let is_encrypted = this.message?.decrypted
|
||||||
${this.render_header()} ${content.text} ${this.render_votes()}
|
? html`<span style="align-self: center">🔓</span>`
|
||||||
|
: undefined;
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div
|
||||||
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
|
style="margin-top: 8px; padding: 16px; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
|
<div style="display: flex; flex-direction: row">
|
||||||
|
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
||||||
|
${is_encrypted}
|
||||||
|
<span style="flex: 1"></span>
|
||||||
|
<span style="padding-right: 8px; text-wrap: nowrap"
|
||||||
|
><a
|
||||||
|
target="_top"
|
||||||
|
href=${'#' + encodeURIComponent(self.message.id)}
|
||||||
|
>%</a
|
||||||
|
>
|
||||||
|
${new Date(this.message.timestamp).toLocaleString()}</span
|
||||||
|
>
|
||||||
|
<span>${raw_button}</span>
|
||||||
|
</div>
|
||||||
|
${content.text} ${this.render_votes()}
|
||||||
<footer class="w3-container">
|
<footer class="w3-container">
|
||||||
<button class="w3-button w3-theme-d1" @click=${this.react}>
|
<button class="w3-button w3-theme-d1" @click=${this.react}>
|
||||||
React
|
React
|
||||||
</button>
|
</button>
|
||||||
${this.render_children()}
|
${this.render_children()}
|
||||||
</footer>
|
</footer>
|
||||||
`);
|
</div>
|
||||||
|
`;
|
||||||
} else if (content.type === 'blog') {
|
} else if (content.type === 'blog') {
|
||||||
let self = this;
|
let self = this;
|
||||||
tfrpc.rpc.get_blob(content.blog).then(function (data) {
|
tfrpc.rpc.get_blob(content.blog).then(function (data) {
|
||||||
@ -746,20 +741,77 @@ class TfMessageElement extends LitElement {
|
|||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return this.render_frame(html`
|
let reply =
|
||||||
${this.render_header()}
|
this.drafts[this.message?.id] !== undefined
|
||||||
|
? html`
|
||||||
|
<tf-compose
|
||||||
|
whoami=${this.whoami}
|
||||||
|
.users=${this.users}
|
||||||
|
root=${content.root || this.message.id}
|
||||||
|
branch=${this.message.id}
|
||||||
|
.drafts=${this.drafts}
|
||||||
|
@tf-discard=${this.discard_reply}
|
||||||
|
author=${this.message.author}
|
||||||
|
></tf-compose>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<button class="w3-button w3-theme-d1" @click=${this.show_reply}>
|
||||||
|
Reply
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div
|
||||||
|
class="w3-card-4 ${class_background} w3-border-theme"
|
||||||
|
style="margin-top: 8px; padding: 16px; overflow: scroll; overflow-wrap: anywhere; display: block; max-width: 100%"
|
||||||
|
>
|
||||||
|
<div style="display: flex; flex-direction: row">
|
||||||
|
<tf-user id=${this.message.author} .users=${this.users}></tf-user>
|
||||||
|
<span style="flex: 1"></span>
|
||||||
|
<span style="padding-right: 8px; text-wrap: nowrap"
|
||||||
|
><a
|
||||||
|
target="_top"
|
||||||
|
href=${'#' + encodeURIComponent(self.message.id)}
|
||||||
|
>%</a
|
||||||
|
>
|
||||||
|
${new Date(this.message.timestamp).toLocaleString()}</span
|
||||||
|
>
|
||||||
|
<span>${raw_button}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>${body}</div>
|
<div>${body}</div>
|
||||||
${this.render_mentions()} ${this.render_votes()}
|
${this.render_mentions()}
|
||||||
${this.render_actions()}
|
${this.render_votes()}
|
||||||
`);
|
<footer class="w3-content">
|
||||||
|
${reply}
|
||||||
|
<button class="w3-button w3-theme-d1" @click=${this.react}>
|
||||||
|
React
|
||||||
|
</button>
|
||||||
|
${this.render_children()}
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
} else if (content.type === 'pub') {
|
} else if (content.type === 'pub') {
|
||||||
return this.render_small_frame(
|
return small_frame(
|
||||||
html` <style>
|
html` <style>
|
||||||
span {
|
span {
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="w3-padding">
|
<span>
|
||||||
<div>
|
<div>
|
||||||
🍻
|
🍻
|
||||||
<tf-user
|
<tf-user
|
||||||
@ -768,47 +820,38 @@ class TfMessageElement extends LitElement {
|
|||||||
></tf-user>
|
></tf-user>
|
||||||
</div>
|
</div>
|
||||||
<pre>${content.address.host}:${content.address.port}</pre>
|
<pre>${content.address.host}:${content.address.port}</pre>
|
||||||
</div>`
|
</span>`
|
||||||
);
|
);
|
||||||
} else if (content.type === 'channel') {
|
} else if (content.type === 'channel') {
|
||||||
return this.render_small_frame(html`
|
return small_frame(html`
|
||||||
<div class="w3-container">
|
<div>
|
||||||
<p>
|
|
||||||
${content.subscribed ? 'subscribed to' : 'unsubscribed from'}
|
${content.subscribed ? 'subscribed to' : 'unsubscribed from'}
|
||||||
<a href=${'#' + encodeURIComponent('#' + content.channel)}
|
<a href=${'#' + encodeURIComponent('#' + content.channel)}
|
||||||
>#${content.channel}</a
|
>#${content.channel}</a
|
||||||
>
|
>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
} else if (typeof this.message.content == 'string') {
|
} else if (typeof this.message.content == 'string') {
|
||||||
if (this.message?.decrypted) {
|
if (this.message?.decrypted) {
|
||||||
if (this.format == 'decrypted') {
|
if (this.format == 'decrypted') {
|
||||||
return this.render_small_frame(
|
return small_frame(
|
||||||
html`<span class="w3-container">🔓</span> ${this.render_json(
|
html`<span>🔓</span>
|
||||||
this.message.decrypted
|
<pre>${JSON.stringify(this.message.decrypted, null, 2)}</pre>`
|
||||||
)}`
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return this.render_small_frame(
|
return small_frame(
|
||||||
html`<span class="w3-container">🔓</span>
|
html`<span>🔓</span>
|
||||||
<div class="w3-container">${this.message.decrypted.type}</div>`
|
<div>${this.message.decrypted.type}</div>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return this.render_small_frame();
|
return small_frame(html`<span>🔒</span>`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return this.render_small_frame(
|
return small_frame(html`<div><b>type</b>: ${content.type}</div>`);
|
||||||
html`<div class="w3-container">
|
|
||||||
<p><b>type</b>: ${content.type}</p>
|
|
||||||
</div>`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (typeof this.message.content == 'string') {
|
|
||||||
return this.render_small_frame();
|
|
||||||
} else {
|
} else {
|
||||||
return this.render_small_frame(this.render_raw());
|
return small_frame(this.render_raw());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {LitElement, html, unsafeHTML, repeat, until} from './lit-all.min.js';
|
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
|
||||||
import * as tfrpc from '/static/tfrpc.js';
|
import * as tfrpc from '/static/tfrpc.js';
|
||||||
import {styles} from './tf-styles.js';
|
import {styles} from './tf-styles.js';
|
||||||
|
|
||||||
@ -198,9 +198,7 @@ class TfNewsElement extends LitElement {
|
|||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
<div>
|
<div>
|
||||||
${repeat(
|
${final_messages.map(
|
||||||
final_messages,
|
|
||||||
(x) => x.id,
|
|
||||||
(x) => html`
|
(x) => html`
|
||||||
<tf-message
|
<tf-message
|
||||||
.message=${x}
|
.message=${x}
|
||||||
|
@ -11,7 +11,7 @@ class TfProfileElement extends LitElement {
|
|||||||
id: {type: String},
|
id: {type: String},
|
||||||
users: {type: Object},
|
users: {type: Object},
|
||||||
size: {type: Number},
|
size: {type: Number},
|
||||||
sequence: {type: Number},
|
server_follows_me: {type: Boolean},
|
||||||
following: {type: Boolean},
|
following: {type: Boolean},
|
||||||
blocking: {type: Boolean},
|
blocking: {type: Boolean},
|
||||||
};
|
};
|
||||||
@ -27,7 +27,7 @@ class TfProfileElement extends LitElement {
|
|||||||
this.id = null;
|
this.id = null;
|
||||||
this.users = {};
|
this.users = {};
|
||||||
this.size = 0;
|
this.size = 0;
|
||||||
this.sequence = 0;
|
this.server_follows_me = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
@ -63,8 +63,27 @@ class TfProfileElement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async initial_load() {
|
||||||
|
this.server_follows_me = undefined;
|
||||||
|
let server_id = await tfrpc.rpc.getServerIdentity();
|
||||||
|
let followed = await tfrpc.rpc.query(
|
||||||
|
`
|
||||||
|
SELECT json_extract(content, '$.following') AS following
|
||||||
|
FROM messages
|
||||||
|
WHERE author = ? AND
|
||||||
|
json_extract(content, '$.type') = 'contact' AND
|
||||||
|
json_extract(content, '$.contact') = ? ORDER BY sequence DESC LIMIT 1
|
||||||
|
`,
|
||||||
|
[server_id, this.whoami]
|
||||||
|
);
|
||||||
|
let is_followed = false;
|
||||||
|
for (let row of followed) {
|
||||||
|
is_followed = row.following != 0;
|
||||||
|
}
|
||||||
|
this.server_follows_me = is_followed;
|
||||||
|
}
|
||||||
|
|
||||||
modify(change) {
|
modify(change) {
|
||||||
let self = this;
|
|
||||||
tfrpc.rpc
|
tfrpc.rpc
|
||||||
.appendMessage(
|
.appendMessage(
|
||||||
this.whoami,
|
this.whoami,
|
||||||
@ -76,10 +95,6 @@ class TfProfileElement extends LitElement {
|
|||||||
change
|
change
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(function () {
|
|
||||||
self._follow_whoami = undefined;
|
|
||||||
self.load();
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
alert(error?.message);
|
alert(error?.message);
|
||||||
});
|
});
|
||||||
@ -141,8 +156,7 @@ class TfProfileElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
let input = document.createElement('input');
|
let input = document.createElement('input');
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.addEventListener('change', function (event) {
|
input.onchange = function (event) {
|
||||||
input.parentNode.removeChild(input);
|
|
||||||
let file = event.target.files[0];
|
let file = event.target.files[0];
|
||||||
file
|
file
|
||||||
.arrayBuffer()
|
.arrayBuffer()
|
||||||
@ -157,33 +171,67 @@ class TfProfileElement extends LitElement {
|
|||||||
.catch(function (e) {
|
.catch(function (e) {
|
||||||
alert(e.message);
|
alert(e.message);
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
document.body.appendChild(input);
|
|
||||||
input.click();
|
input.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async server_follow_me(follow) {
|
||||||
|
try {
|
||||||
|
await tfrpc.rpc.setServerFollowingMe(this.whoami, follow);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.initial_load();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
copy_id() {
|
copy_id() {
|
||||||
navigator.clipboard.writeText(this.id);
|
navigator.clipboard.writeText(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (
|
||||||
|
this.id == this.whoami &&
|
||||||
|
this.editing &&
|
||||||
|
this.server_follows_me === undefined
|
||||||
|
) {
|
||||||
|
this.initial_load();
|
||||||
|
}
|
||||||
this.load();
|
this.load();
|
||||||
let self = this;
|
let self = this;
|
||||||
let profile = this.users[this.id] || {};
|
let profile = this.users[this.id] || {};
|
||||||
tfrpc.rpc
|
tfrpc.rpc
|
||||||
.query(
|
.query(
|
||||||
`SELECT SUM(LENGTH(content)) AS size, MAX(sequence) AS sequence FROM messages WHERE author = ?`,
|
`SELECT SUM(LENGTH(content)) AS size FROM messages WHERE author = ?`,
|
||||||
[this.id]
|
[this.id]
|
||||||
)
|
)
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
self.size = result[0].size;
|
self.size = result[0].size;
|
||||||
self.sequence = result[0].sequence;
|
|
||||||
});
|
});
|
||||||
let edit;
|
let edit;
|
||||||
let follow;
|
let follow;
|
||||||
let block;
|
let block;
|
||||||
if (this.id === this.whoami) {
|
if (this.id === this.whoami) {
|
||||||
if (this.editing) {
|
if (this.editing) {
|
||||||
|
let server_follow;
|
||||||
|
if (this.server_follows_me === true) {
|
||||||
|
server_follow = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => this.server_follow_me(false)}
|
||||||
|
>
|
||||||
|
Server, Stop Following Me
|
||||||
|
</button>`;
|
||||||
|
} else if (this.server_follows_me === false) {
|
||||||
|
server_follow = html`<button
|
||||||
|
class="w3-button w3-theme-d1"
|
||||||
|
@click=${() => this.server_follow_me(true)}
|
||||||
|
>
|
||||||
|
Server, Follow Me
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
edit = html`
|
edit = html`
|
||||||
<button
|
<button
|
||||||
id="save_profile"
|
id="save_profile"
|
||||||
@ -195,6 +243,7 @@ class TfProfileElement extends LitElement {
|
|||||||
<button class="w3-button w3-theme-d1" @click=${this.discard_edits}>
|
<button class="w3-button w3-theme-d1" @click=${this.discard_edits}>
|
||||||
Discard
|
Discard
|
||||||
</button>
|
</button>
|
||||||
|
${server_follow}
|
||||||
`;
|
`;
|
||||||
} else {
|
} else {
|
||||||
edit = html`<button
|
edit = html`<button
|
||||||
@ -227,12 +276,13 @@ class TfProfileElement extends LitElement {
|
|||||||
let edit_profile = this.editing
|
let edit_profile = this.editing
|
||||||
? html`
|
? html`
|
||||||
<div style="flex: 1 0 50%; display: flex; flex-direction: column; gap: 8px">
|
<div style="flex: 1 0 50%; display: flex; flex-direction: column; gap: 8px">
|
||||||
|
<div class="w3-container">
|
||||||
<div>
|
<div>
|
||||||
<label for="name">Name:</label>
|
<label for="name">Name:</label>
|
||||||
<input class="w3-input w3-theme-d1" type="text" id="name" value=${this.editing.name} @input=${(event) => (this.editing = Object.assign({}, this.editing, {name: event.srcElement.value}))} placeholder="Choose a name"></input>
|
<input class="w3-input w3-theme-d1" type="text" id="name" value=${this.editing.name} @input=${(event) => (this.editing = Object.assign({}, this.editing, {name: event.srcElement.value}))}></input>
|
||||||
</div>
|
</div>
|
||||||
<div><label for="description">Description:</label></div>
|
<div><label for="description">Description:</label></div>
|
||||||
<textarea class="w3-input w3-theme-d1" style="resize: vertical" rows="8" id="description" @input=${(event) => (this.editing = Object.assign({}, this.editing, {description: event.srcElement.value}))} placeholder="Tell people a little bit about yourself here, if you like.">${this.editing.description}</textarea>
|
<textarea class="w3-input w3-theme-d1" style="resize: vertical" rows="8" id="description" @input=${(event) => (this.editing = Object.assign({}, this.editing, {description: event.srcElement.value}))}>${this.editing.description}</textarea>
|
||||||
<div>
|
<div>
|
||||||
<label for="public_web_hosting">Public Web Hosting:</label>
|
<label for="public_web_hosting">Public Web Hosting:</label>
|
||||||
<input class="w3-check w3-theme-d1" type="checkbox" id="public_web_hosting" ?checked=${this.editing.publicWebHosting} @input=${(event) => (self.editing = Object.assign({}, self.editing, {publicWebHosting: event.srcElement.checked}))}></input>
|
<input class="w3-check w3-theme-d1" type="checkbox" id="public_web_hosting" ?checked=${this.editing.publicWebHosting} @input=${(event) => (self.editing = Object.assign({}, self.editing, {publicWebHosting: event.srcElement.checked}))}></input>
|
||||||
@ -240,6 +290,7 @@ class TfProfileElement extends LitElement {
|
|||||||
<div>
|
<div>
|
||||||
<button class="w3-button w3-theme-d1" @click=${this.attach_image}>Attach Image</button>
|
<button class="w3-button w3-theme-d1" @click=${this.attach_image}>Attach Image</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
: null;
|
: null;
|
||||||
let image =
|
let image =
|
||||||
@ -248,24 +299,15 @@ class TfProfileElement extends LitElement {
|
|||||||
let description = this.editing?.description ?? profile.description;
|
let description = this.editing?.description ?? profile.description;
|
||||||
return html`<div class="w3-card-4 w3-container w3-theme-d3" style="box-sizing: border-box">
|
return html`<div class="w3-card-4 w3-container w3-theme-d3" style="box-sizing: border-box">
|
||||||
<header class="w3-container">
|
<header class="w3-container">
|
||||||
<p><tf-user id=${this.id} .users=${this.users}></tf-user> (${tfutils.human_readable_size(this.size)} in ${this.sequence} messages)</p>
|
<p><tf-user id=${this.id} .users=${this.users}></tf-user> (${tfutils.human_readable_size(this.size)})</p>
|
||||||
</header>
|
</header>
|
||||||
<div class="w3-container">
|
<div class="w3-container">
|
||||||
<div class="w3-margin-bottom" style="display: flex; flex-direction: row">
|
<input type="text" class="w3-input w3-border w3-theme-d1" readonly value=${this.id}></input>
|
||||||
<input type="text" class="w3-input w3-border w3-theme-d1" style="display: flex 1 1" readonly value=${this.id}></input>
|
<button class="w3-button w3-theme-d1 w3-ripple" @click=${this.copy_id}>Copy</button>
|
||||||
<button class="w3-button w3-theme-d1 w3-ripple" style="flex: 0 0 auto" @click=${this.copy_id}>Copy</button>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; flex-direction: row; gap: 1em">
|
<div style="display: flex; flex-direction: row; gap: 1em">
|
||||||
${edit_profile}
|
${edit_profile}
|
||||||
<div style="flex: 1 0 50%">
|
<div style="flex: 1 0 50%">
|
||||||
${
|
<div><img src=${'/' + image + '/view'} style="width: 256px; height: auto"></img></div>
|
||||||
image
|
|
||||||
? html`<div><img src=${'/' + image + '/view'} style="width: 256px; height: auto"></img></div>`
|
|
||||||
: html`<div>
|
|
||||||
<div class="w3-jumbo">😎</div>
|
|
||||||
<div><i>Profile image not set.</i></div>
|
|
||||||
</div>`
|
|
||||||
}
|
|
||||||
<div>${unsafeHTML(tfutils.markdown(description))}</div>
|
<div>${unsafeHTML(tfutils.markdown(description))}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,21 +41,18 @@ class TfReactionsModalElement extends LitElement {
|
|||||||
>
|
>
|
||||||
</header>
|
</header>
|
||||||
<ul class="w3-theme-dark w3-container w3-ul">
|
<ul class="w3-theme-dark w3-container w3-ul">
|
||||||
${this.votes
|
${this.votes.map(
|
||||||
.sort((x, y) => y.timestamp - x.timestamp)
|
|
||||||
.map(
|
|
||||||
(x) => html`
|
(x) => html`
|
||||||
<li style="display: flex; flex-direction: row; gap: 4px">
|
<li class="w3-bar">
|
||||||
<span style="flex-basis: 3em"
|
<span class="w3-bar-item"
|
||||||
>${x?.content?.vote?.expression}</span
|
>${x?.content?.vote?.expression}</span
|
||||||
>
|
>
|
||||||
<tf-user
|
<tf-user
|
||||||
style="flex: 1 1"
|
class="w3-bar-item"
|
||||||
id=${x.author}
|
id=${x.author}
|
||||||
.users=${this.users}
|
.users=${this.users}
|
||||||
></tf-user>
|
></tf-user>
|
||||||
<span
|
<span class="w3-bar-item w3-right"
|
||||||
style="flex-shrink: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis"
|
|
||||||
>${new Date(x?.timestamp).toLocaleString()}</span
|
>${new Date(x?.timestamp).toLocaleString()}</span
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
@ -48,7 +48,7 @@ const tf = css`
|
|||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const w3 = css`
|
const w3 = css`
|
||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||||
@ -158,10 +158,6 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
||||||
@ -203,9 +199,9 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
.w3-hover-none:hover{box-shadow:none!important}
|
||||||
/* Colors */
|
/* Colors */
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
||||||
@ -220,24 +216,15 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
||||||
|
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
||||||
@ -409,9 +396,9 @@ function is_dark(hex, value) {
|
|||||||
function generated() {
|
function generated() {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
let k_color = rgb_to_hex([
|
let k_color = rgb_to_hex([
|
||||||
(now.getDay() * 128) / 6,
|
now.getDay() * 255 / 6,
|
||||||
(now.getHours() * 128) / 23,
|
now.getHours() * 255 / 23,
|
||||||
(now.getSeconds() * 128) / 59,
|
now.getSeconds() * 255 / 59,
|
||||||
]);
|
]);
|
||||||
//let k_color = '#034f84';
|
//let k_color = '#034f84';
|
||||||
//let k_color = rgb_to_hex([Math.random() * 256, Math.random() * 256, Math.random() * 256]);
|
//let k_color = rgb_to_hex([Math.random() * 256, Math.random() * 256, Math.random() * 256]);
|
||||||
|
@ -103,23 +103,6 @@ class TfTabConnectionsElement extends LitElement {
|
|||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
render_progress(name, value, max) {
|
|
||||||
if (max && value != max) {
|
|
||||||
return html`
|
|
||||||
<div class="w3-theme-d1 w3-small">
|
|
||||||
<div
|
|
||||||
class="w3-container w3-theme-l1"
|
|
||||||
style="width: ${Math.floor(
|
|
||||||
(100.0 * value) / max
|
|
||||||
)}%; text-wrap: nowrap"
|
|
||||||
>
|
|
||||||
${name} ${value} / ${max} (${Math.round((100.0 * value) / max)}%)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render_broadcast(connection) {
|
render_broadcast(connection) {
|
||||||
let self = this;
|
let self = this;
|
||||||
return html`
|
return html`
|
||||||
@ -159,28 +142,14 @@ class TfTabConnectionsElement extends LitElement {
|
|||||||
}, {})
|
}, {})
|
||||||
);
|
);
|
||||||
return html`
|
return html`
|
||||||
${connection.connected
|
|
||||||
? html`
|
|
||||||
<button
|
<button
|
||||||
class="w3-button w3-theme-d1"
|
class="w3-button w3-theme-d1"
|
||||||
@click=${() => tfrpc.rpc.closeConnection(connection.id)}
|
@click=${() => tfrpc.rpc.closeConnection(connection.id)}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
`
|
|
||||||
: undefined}
|
|
||||||
${connection.flags.one_shot ? '🔃' : undefined}
|
${connection.flags.one_shot ? '🔃' : undefined}
|
||||||
<tf-user id=${connection.id} .users=${this.users}></tf-user>
|
<tf-user id=${connection.id} .users=${this.users}></tf-user>
|
||||||
${this.render_progress(
|
|
||||||
'recv',
|
|
||||||
connection.progress.in.total - connection.progress.in.current,
|
|
||||||
connection.progress.in.total
|
|
||||||
)}
|
|
||||||
${this.render_progress(
|
|
||||||
'send',
|
|
||||||
connection.progress.out.total - connection.progress.out.current,
|
|
||||||
connection.progress.out.total
|
|
||||||
)}
|
|
||||||
${connection.tunnel !== undefined
|
${connection.tunnel !== undefined
|
||||||
? '🚇'
|
? '🚇'
|
||||||
: html`(${connection.host}:${connection.port})`}
|
: html`(${connection.host}:${connection.port})`}
|
||||||
@ -233,21 +202,6 @@ class TfTabConnectionsElement extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle_accordian(id) {
|
|
||||||
let element = this.renderRoot.getElementById(id);
|
|
||||||
element.classList.toggle('w3-hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_connections() {
|
|
||||||
return this.connections.filter((x) => x.tunnel === undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_broadcasts() {
|
|
||||||
return this.broadcasts
|
|
||||||
.filter((x) => x.address)
|
|
||||||
.filter((x) => this.connections.map((c) => c.id).indexOf(x.pubkey) == -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let self = this;
|
let self = this;
|
||||||
return html`
|
return html`
|
||||||
@ -262,33 +216,27 @@ class TfTabConnectionsElement extends LitElement {
|
|||||||
>
|
>
|
||||||
Connect
|
Connect
|
||||||
</button>
|
</button>
|
||||||
<h2
|
<h2>Broadcasts</h2>
|
||||||
class="w3-button w3-block w3-theme-d1"
|
<ul class="w3-ul w3-border">
|
||||||
@click=${() => self.toggle_accordian('connections')}
|
${this.broadcasts
|
||||||
>
|
.filter((x) => x.address)
|
||||||
Connections (${this.valid_connections().length})
|
.filter(
|
||||||
</h2>
|
(x) => self.connections.map((c) => c.id).indexOf(x.pubkey) == -1
|
||||||
<ul class="w3-ul w3-border" id="connections">
|
)
|
||||||
${this.valid_connections().map(
|
.map((x) => self.render_broadcast(x))}
|
||||||
(x) => html` <li class="w3-bar">${this.render_connection(x)}</li> `
|
</ul>
|
||||||
|
<h2>Connections</h2>
|
||||||
|
<ul class="w3-ul w3-border">
|
||||||
|
${this.connections
|
||||||
|
.filter((x) => x.tunnel === undefined)
|
||||||
|
.map(
|
||||||
|
(x) => html`
|
||||||
|
<li class="w3-bar">${this.render_connection(x)}</li>
|
||||||
|
`
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
<h2
|
<h2>Stored Connections</h2>
|
||||||
class="w3-button w3-block w3-theme-d1"
|
<ul class="w3-ul w3-border">
|
||||||
@click=${() => self.toggle_accordian('broadcasts')}
|
|
||||||
>
|
|
||||||
Broadcasts (${this.valid_broadcasts().length})
|
|
||||||
</h2>
|
|
||||||
<ul class="w3-ul w3-border w3-hide" id="broadcasts">
|
|
||||||
${this.valid_broadcasts().map((x) => self.render_broadcast(x))}
|
|
||||||
</ul>
|
|
||||||
<h2
|
|
||||||
class="w3-button w3-block w3-theme-d1"
|
|
||||||
@click=${() => self.toggle_accordian('stored_connections')}
|
|
||||||
>
|
|
||||||
Stored Connections (${this.stored_connections.length})
|
|
||||||
</h2>
|
|
||||||
<ul class="w3-ul w3-border w3-hide" id="stored_connections">
|
|
||||||
${this.stored_connections.map(
|
${this.stored_connections.map(
|
||||||
(x) => html`
|
(x) => html`
|
||||||
<li>
|
<li>
|
||||||
@ -315,33 +263,25 @@ class TfTabConnectionsElement extends LitElement {
|
|||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
<h2
|
<h2>Local Accounts</h2>
|
||||||
class="w3-button w3-block w3-theme-d1"
|
<ul class="w3-ul w3-border">
|
||||||
@click=${() => self.toggle_accordian('local_accounts')}
|
|
||||||
>
|
|
||||||
Local Accounts (${this.identities.length})
|
|
||||||
</h2>
|
|
||||||
<div class="w3-container w3-hide" id="local_accounts">
|
|
||||||
${this.identities.map(
|
${this.identities.map(
|
||||||
(x) =>
|
(x) =>
|
||||||
html`<div
|
html`<li class="w3-bar">
|
||||||
class="w3-tag w3-round w3-theme-l3"
|
|
||||||
style="padding: 4px; margin: 2px; max-width: 100%; text-wrap: nowrap; overflow: hidden"
|
|
||||||
>
|
|
||||||
${x == this.server_identity
|
${x == this.server_identity
|
||||||
? html`<div class="w3-tag w3-medium w3-round w3-theme-l1">
|
? html`<span class="w3-tag w3-medium w3-round w3-theme-l1"
|
||||||
🖥 local server
|
>🖥 local server</span
|
||||||
</div>`
|
>`
|
||||||
: undefined}
|
: undefined}
|
||||||
${this.my_identities.indexOf(x) != -1
|
${this.my_identities.indexOf(x) != -1
|
||||||
? html`<div class="w3-tag w3-medium w3-round w3-theme-d1">
|
? html`<span class="w3-tag w3-medium w3-round w3-theme-d1"
|
||||||
😎 you
|
>😎 you</span
|
||||||
</div>`
|
>`
|
||||||
: undefined}
|
: undefined}
|
||||||
<tf-user id=${x} .users=${this.users}></tf-user>
|
<tf-user id=${x} .users=${this.users}></tf-user>
|
||||||
</div>`
|
</li>`
|
||||||
)}
|
)}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {LitElement, cache, html, unsafeHTML, until} from './lit-all.min.js';
|
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
|
||||||
import * as tfrpc from '/static/tfrpc.js';
|
import * as tfrpc from '/static/tfrpc.js';
|
||||||
import {styles} from './tf-styles.js';
|
import {styles} from './tf-styles.js';
|
||||||
|
|
||||||
@ -17,7 +17,6 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
loading: {type: Number},
|
loading: {type: Number},
|
||||||
time_range: {type: Array},
|
time_range: {type: Array},
|
||||||
time_loading: {type: Array},
|
time_loading: {type: Array},
|
||||||
private_messages: {type: Array},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,63 +45,6 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
: this.hash.substring(1);
|
: this.hash.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _fetch_related_messages(messages) {
|
|
||||||
let refs = await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
WITH
|
|
||||||
news AS (
|
|
||||||
SELECT value AS id FROM json_each(?)
|
|
||||||
)
|
|
||||||
SELECT refs_out.ref AS ref FROM messages_refs refs_out JOIN news ON refs_out.message = news.id
|
|
||||||
UNION
|
|
||||||
SELECT refs_in.message AS ref FROM messages_refs refs_in JOIN news ON refs_in.ref = news.id
|
|
||||||
`,
|
|
||||||
[JSON.stringify(messages.map((x) => x.id))]
|
|
||||||
);
|
|
||||||
let related_messages = await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
|
||||||
FROM messages
|
|
||||||
JOIN json_each(?2) refs ON messages.id = refs.value
|
|
||||||
JOIN json_each(?1) AS following ON messages.author = following.value
|
|
||||||
`,
|
|
||||||
[JSON.stringify(this.following), JSON.stringify(refs.map((x) => x.ref))]
|
|
||||||
);
|
|
||||||
let combined = [].concat(messages, related_messages);
|
|
||||||
let refs2 = await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
WITH
|
|
||||||
news AS (
|
|
||||||
SELECT value AS id FROM json_each(?)
|
|
||||||
)
|
|
||||||
SELECT refs_out.ref AS ref FROM messages_refs refs_out JOIN news ON refs_out.message = news.id
|
|
||||||
UNION
|
|
||||||
SELECT refs_in.message AS ref FROM messages_refs refs_in JOIN news ON refs_in.ref = news.id
|
|
||||||
`,
|
|
||||||
[JSON.stringify(combined.map((x) => x.id))]
|
|
||||||
);
|
|
||||||
let t0 = new Date();
|
|
||||||
let result = [].concat(
|
|
||||||
combined,
|
|
||||||
await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
|
||||||
FROM json_each(?2) refs
|
|
||||||
JOIN messages ON messages.id = refs.value
|
|
||||||
JOIN json_each(?1) following ON messages.author = following.value
|
|
||||||
WHERE messages.content ->> 'type' != 'post'
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
JSON.stringify(this.following),
|
|
||||||
JSON.stringify(refs2.map((x) => x.ref)),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
let t1 = new Date();
|
|
||||||
console.log((t1 - t0) / 1000);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetch_messages(start_time, end_time) {
|
async fetch_messages(start_time, end_time) {
|
||||||
this.time_loading = [start_time, end_time];
|
this.time_loading = [start_time, end_time];
|
||||||
let result;
|
let result;
|
||||||
@ -115,14 +57,15 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
JOIN json_each(?2) AS following ON messages.author = following.value
|
JOIN json_each(?2) AS following ON messages.author = following.value
|
||||||
WHERE
|
WHERE
|
||||||
messages.author != ?1 AND
|
messages.author != ?1 AND
|
||||||
(?3 IS NULL OR messages.timestamp >= ?3) AND messages.timestamp < ?4
|
messages.timestamp >= ?3 AND
|
||||||
|
messages.timestamp < ?4
|
||||||
ORDER BY timestamp DESC limit 20)
|
ORDER BY timestamp DESC limit 20)
|
||||||
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
FROM mentions
|
FROM mentions
|
||||||
JOIN messages_refs ON mentions.id = messages_refs.ref
|
JOIN messages_refs ON mentions.id = messages_refs.ref
|
||||||
JOIN messages ON messages_refs.message = messages.id
|
JOIN messages ON messages_refs.message = messages.id
|
||||||
UNION
|
UNION
|
||||||
SELECT TRUE AS is_primary, * FROM mentions
|
SELECT * FROM mentions
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
'"' + this.whoami.replace('"', '""') + '"',
|
'"' + this.whoami.replace('"', '""') + '"',
|
||||||
@ -134,29 +77,33 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
} else if (this.hash.startsWith('#@')) {
|
} else if (this.hash.startsWith('#@')) {
|
||||||
result = await tfrpc.rpc.query(
|
result = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
WITH
|
WITH mine AS (SELECT rowid, id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
selected AS (SELECT rowid, id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
|
||||||
FROM messages
|
FROM messages
|
||||||
WHERE messages.author = ?1 AND (?2 IS NULL OR messages.timestamp >= 2) AND messages.timestamp < ?3
|
WHERE messages.author = ?
|
||||||
ORDER BY sequence DESC LIMIT 20
|
ORDER BY sequence DESC)
|
||||||
)
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
FROM mine
|
||||||
FROM selected
|
JOIN messages_refs ON mine.id = messages_refs.ref
|
||||||
JOIN messages_refs ON selected.id = messages_refs.ref
|
|
||||||
JOIN messages ON messages_refs.message = messages.id
|
JOIN messages ON messages_refs.message = messages.id
|
||||||
|
WHERE
|
||||||
|
mine.timestamp >= ?2 AND
|
||||||
|
mine.timestamp < ?3
|
||||||
UNION
|
UNION
|
||||||
SELECT TRUE AS is_primary, * FROM selected
|
SELECT * FROM mine
|
||||||
|
WHERE
|
||||||
|
mine.timestamp >= ?2 AND
|
||||||
|
mine.timestamp < ?3
|
||||||
`,
|
`,
|
||||||
[this.hash.substring(1), start_time, end_time]
|
[this.hash.substring(1), start_time, end_time]
|
||||||
);
|
);
|
||||||
} else if (this.hash.startsWith('#%')) {
|
} else if (this.hash.startsWith('#%')) {
|
||||||
result = await tfrpc.rpc.query(
|
result = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
SELECT TRUE AS is_primary, id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
SELECT id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
FROM messages
|
FROM messages
|
||||||
WHERE messages.id = ?1
|
WHERE id = ?1
|
||||||
UNION
|
UNION
|
||||||
SELECT FALSE AS is_primary, id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
SELECT id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
FROM messages JOIN messages_refs
|
FROM messages JOIN messages_refs
|
||||||
ON messages.id = messages_refs.message
|
ON messages.id = messages_refs.message
|
||||||
WHERE messages_refs.ref = ?1
|
WHERE messages_refs.ref = ?1
|
||||||
@ -164,92 +111,112 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
[this.hash.substring(1)]
|
[this.hash.substring(1)]
|
||||||
);
|
);
|
||||||
} else if (this.hash.startsWith('##')) {
|
} else if (this.hash.startsWith('##')) {
|
||||||
let t0 = new Date();
|
let promises = [];
|
||||||
let initial_messages = await tfrpc.rpc.query(
|
const k_following_limit = 256;
|
||||||
|
for (let i = 0; i < this.following.length; i += k_following_limit) {
|
||||||
|
promises.push(
|
||||||
|
tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
WITH
|
WITH news AS (SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
all_news AS (
|
|
||||||
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
|
||||||
FROM messages
|
FROM messages
|
||||||
JOIN json_each(?) AS following ON messages.author = following.value
|
JOIN json_each(?) AS following ON messages.author = following.value
|
||||||
WHERE messages.content ->> 'channel' = ?4
|
WHERE
|
||||||
|
messages.timestamp >= ? AND
|
||||||
|
messages.timestamp < ? AND
|
||||||
|
messages.content ->> 'channel' = ?
|
||||||
|
ORDER BY messages.timestamp DESC)
|
||||||
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
|
FROM news
|
||||||
|
JOIN messages_refs ON news.id = messages_refs.ref
|
||||||
|
JOIN messages ON messages_refs.message = messages.id
|
||||||
|
UNION
|
||||||
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
|
FROM news
|
||||||
|
JOIN messages_refs ON news.id = messages_refs.message
|
||||||
|
JOIN messages ON messages_refs.ref = messages.id
|
||||||
UNION
|
UNION
|
||||||
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
FROM messages_fts(?5)
|
FROM messages_fts(?5)
|
||||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||||
JOIN json_each(?1) AS following ON messages.author = following.value
|
JOIN json_each(?1) AS following ON messages.author = following.value
|
||||||
JOIN json_tree(messages.content, '$.mentions') AS mention ON mention.value = '#' || ?4
|
JOIN json_tree(messages.content, '$.mentions') AS mention ON mention.value = '#' || ?4
|
||||||
)
|
WHERE
|
||||||
SELECT TRUE AS is_primary, all_news.* FROM all_news
|
messages.timestamp >= ?2 AND
|
||||||
WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3
|
messages.timestamp < ?3
|
||||||
ORDER BY all_news.timestamp DESC LIMIT 20
|
UNION
|
||||||
|
SELECT news.* FROM news
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
JSON.stringify(this.following),
|
JSON.stringify(this.following.slice(i, i + k_following_limit)),
|
||||||
start_time,
|
start_time,
|
||||||
end_time,
|
end_time,
|
||||||
this.hash.substring(2),
|
this.hash.substring(2),
|
||||||
'"#' + this.hash.substring(2).replace('"', '""') + '"',
|
'"#' + this.hash.substring(2).replace('"', '""') + '"',
|
||||||
]
|
]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let t1 = new Date();
|
}
|
||||||
result = await this._fetch_related_messages(initial_messages);
|
result = [].concat(...(await Promise.all(promises)));
|
||||||
let t2 = new Date();
|
|
||||||
console.log(
|
|
||||||
`load of ${result.length} rows took ${(t2 - t0) / 1000} (${(t1 - t0) / 1000} to find ${initial_messages.length} initial messages, ${(t2 - t1) / 1000} to find ${result.length} total messages) following=${this.following.length} st=${start_time} et=${end_time}`
|
|
||||||
);
|
|
||||||
} else if (this.hash == '#🔐') {
|
} else if (this.hash == '#🔐') {
|
||||||
result = await tfrpc.rpc.query(
|
result = await tfrpc.rpc.query(
|
||||||
`
|
`
|
||||||
SELECT TRUE AS is_primary, messages.rowid, messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
SELECT messages.rowid, messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||||
FROM messages
|
FROM messages
|
||||||
JOIN json_each(?1) AS private_messages ON messages.id = private_messages.value
|
JOIN json_each(?1) AS following ON messages.author = following.value
|
||||||
WHERE
|
WHERE
|
||||||
(?2 IS NULL OR (messages.timestamp >= ?2)) AND messages.timestamp < ?3 AND
|
messages.timestamp >= ?2 AND
|
||||||
|
messages.timestamp < ?3 AND
|
||||||
json(messages.content) LIKE '"%'
|
json(messages.content) LIKE '"%'
|
||||||
ORDER BY messages.sequence DESC LIMIT 20
|
ORDER BY sequence DESC
|
||||||
`,
|
|
||||||
[JSON.stringify(this.private_messages), start_time, end_time]
|
|
||||||
);
|
|
||||||
result = (await this.decrypt(result)).filter((x) => x.decrypted);
|
|
||||||
} else {
|
|
||||||
let t0 = new Date();
|
|
||||||
let initial_messages = await tfrpc.rpc.query(
|
|
||||||
`
|
|
||||||
WITH
|
|
||||||
all_news AS (
|
|
||||||
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
|
||||||
FROM messages
|
|
||||||
JOIN json_each(?) AS following ON messages.author = following.value
|
|
||||||
),
|
|
||||||
news AS (
|
|
||||||
SELECT * FROM all_news
|
|
||||||
WHERE all_news.timestamp < ?3 AND (?2 IS NULL OR all_news.timestamp >= ?2)
|
|
||||||
ORDER BY timestamp DESC LIMIT 20
|
|
||||||
)
|
|
||||||
SELECT TRUE AS is_primary, news.* FROM news
|
|
||||||
`,
|
`,
|
||||||
[JSON.stringify(this.following), start_time, end_time]
|
[JSON.stringify(this.following), start_time, end_time]
|
||||||
);
|
);
|
||||||
let t1 = new Date();
|
result = (await this.decrypt(result)).filter((x) => x.decrypted);
|
||||||
result = await this._fetch_related_messages(initial_messages);
|
} else {
|
||||||
let t2 = new Date();
|
let promises = [];
|
||||||
console.log(
|
const k_following_limit = 256;
|
||||||
`load of ${result.length} rows took ${(t2 - t0) / 1000} (${(t1 - t0) / 1000} to find ${initial_messages.length} initial messages, ${(t2 - t1) / 1000} to find ${result.length} total messages) following=${this.following.length} st=${start_time} et=${end_time}`
|
for (let i = 0; i < this.following.length; i += k_following_limit) {
|
||||||
|
promises.push(
|
||||||
|
tfrpc.rpc.query(
|
||||||
|
`
|
||||||
|
WITH news AS (SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
|
FROM messages
|
||||||
|
JOIN json_each(?) AS following ON messages.author = following.value
|
||||||
|
WHERE messages.timestamp >= ? AND messages.timestamp < ?
|
||||||
|
ORDER BY messages.timestamp DESC)
|
||||||
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
|
FROM news
|
||||||
|
JOIN messages_refs ON news.id = messages_refs.ref
|
||||||
|
JOIN messages ON messages_refs.message = messages.id
|
||||||
|
UNION
|
||||||
|
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||||
|
FROM news
|
||||||
|
JOIN messages_refs ON news.id = messages_refs.message
|
||||||
|
JOIN messages ON messages_refs.ref = messages.id
|
||||||
|
UNION
|
||||||
|
SELECT news.* FROM news
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
JSON.stringify(this.following.slice(i, i + k_following_limit)),
|
||||||
|
start_time,
|
||||||
|
end_time,
|
||||||
|
]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
result = [].concat(...(await Promise.all(promises)));
|
||||||
|
}
|
||||||
this.time_loading = undefined;
|
this.time_loading = undefined;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_time_range_from_messages(messages) {
|
update_time_range_from_messages(messages) {
|
||||||
let only_primary = messages.filter((x) => x.is_primary);
|
|
||||||
this.time_range = [
|
this.time_range = [
|
||||||
only_primary.reduce(
|
messages.reduce(
|
||||||
(accumulator, current) => Math.min(accumulator, current.timestamp),
|
(accumulator, current) => Math.min(accumulator, current.timestamp),
|
||||||
this.time_range[0]
|
this.time_range[0]
|
||||||
),
|
),
|
||||||
only_primary.reduce(
|
messages.reduce(
|
||||||
(accumulator, current) => Math.max(accumulator, current.timestamp),
|
(accumulator, current) => Math.max(accumulator, current.timestamp),
|
||||||
this.time_range[1]
|
this.time_range[1]
|
||||||
),
|
),
|
||||||
@ -261,15 +228,17 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
this.loading_canceled = false;
|
this.loading_canceled = false;
|
||||||
try {
|
try {
|
||||||
let more = [];
|
let more = [];
|
||||||
let last_start_time = this.time_range[0];
|
while (!more.length && !this.loading_canceled) {
|
||||||
try {
|
let last_start_time = this.start_time;
|
||||||
more = await this.fetch_messages(null, last_start_time);
|
this.start_time = last_start_time - 7 * 24 * 60 * 60 * 1000;
|
||||||
} catch (e) {
|
more = await this.fetch_messages(this.start_time, last_start_time);
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
this.update_time_range_from_messages(
|
this.update_time_range_from_messages(
|
||||||
more.filter((x) => x.timestamp < last_start_time)
|
more.filter(
|
||||||
|
(x) =>
|
||||||
|
x.timestamp >= this.start_time && x.timestamp < last_start_time
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
this.messages = await this.decrypt([...more, ...this.messages]);
|
this.messages = await this.decrypt([...more, ...this.messages]);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading--;
|
this.loading--;
|
||||||
@ -305,69 +274,80 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_messages(old_messages, new_messages) {
|
|
||||||
let old_by_id = Object.fromEntries(old_messages.map((x) => [x.id, x]));
|
|
||||||
return new_messages.map((x) => (old_by_id[x.id] ? old_by_id[x.id] : x));
|
|
||||||
}
|
|
||||||
|
|
||||||
async load_latest() {
|
async load_latest() {
|
||||||
this.loading++;
|
this.loading++;
|
||||||
let now = new Date().valueOf();
|
let now = new Date().valueOf();
|
||||||
let end_time = now + 24 * 60 * 60 * 1000;
|
let end_time = now + 24 * 60 * 60 * 1000;
|
||||||
let messages = [];
|
let messages = [];
|
||||||
try {
|
try {
|
||||||
messages = await this.fetch_messages(this.time_range[0], end_time);
|
messages = await this.fetch_messages(
|
||||||
|
this.time_range[1] - 24 * 60 * 60 * 1000,
|
||||||
|
end_time
|
||||||
|
);
|
||||||
messages = await this.decrypt(messages);
|
messages = await this.decrypt(messages);
|
||||||
this.update_time_range_from_messages(
|
this.update_time_range_from_messages(
|
||||||
messages.filter(
|
messages.filter(
|
||||||
(x) => x.timestamp >= this.time_range[0] && x.timestamp < end_time
|
(x) => x.timestamp >= this.time_range[1] && x.timestamp < end_time
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading--;
|
this.loading--;
|
||||||
}
|
}
|
||||||
this.messages = this.merge_messages(
|
this.messages = Object.values(
|
||||||
this.messages,
|
|
||||||
Object.values(
|
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
[...this.messages, ...messages]
|
[...this.messages, ...messages]
|
||||||
.sort((x, y) => x.timestamp - y.timestamp)
|
.sort((x, y) => x.timestamp - y.timestamp)
|
||||||
.slice(-1024)
|
.slice(-1024)
|
||||||
.map((x) => [x.id, x])
|
.map((x) => [x.id, x])
|
||||||
)
|
)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
console.log('done loading latest messages.');
|
console.log('done loading latest messages.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async load_messages() {
|
async load_messages() {
|
||||||
let start_time = new Date();
|
|
||||||
let self = this;
|
let self = this;
|
||||||
this.loading++;
|
this.loading++;
|
||||||
let messages = [];
|
let messages = [];
|
||||||
try {
|
try {
|
||||||
if (this._messages_hash !== this.hash) {
|
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
this._messages_hash = this.hash;
|
this._messages_hash = this.hash;
|
||||||
}
|
|
||||||
this._messages_following = this.following;
|
this._messages_following = this.following;
|
||||||
let now = new Date().valueOf();
|
let now = new Date().valueOf();
|
||||||
let start_time = now - 24 * 60 * 60 * 1000;
|
let start_time = now - 24 * 60 * 60 * 1000;
|
||||||
this.start_time = start_time;
|
this.start_time = start_time;
|
||||||
this.time_range = [now + 24 * 60 * 60 * 1000, now + 24 * 60 * 60 * 1000];
|
this.time_range = [this.start_time, now + 24 * 60 * 60 * 1000];
|
||||||
messages = await this.fetch_messages(null, this.time_range[1]);
|
messages = await this.fetch_messages(
|
||||||
|
this.time_range[0],
|
||||||
|
this.time_range[1]
|
||||||
|
);
|
||||||
this.update_time_range_from_messages(
|
this.update_time_range_from_messages(
|
||||||
messages.filter((x) => x.timestamp < this.time_range[1])
|
messages.filter(
|
||||||
|
(x) =>
|
||||||
|
x.timestamp >= this.time_range[0] &&
|
||||||
|
x.timestamp < this.time_range[1]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
messages = await this.decrypt(messages);
|
messages = await this.decrypt(messages);
|
||||||
|
if (!messages.length) {
|
||||||
|
let more = [];
|
||||||
|
while (!more.length && start_time >= 0) {
|
||||||
|
let last_start_time = start_time;
|
||||||
|
start_time = last_start_time - 7 * 24 * 60 * 60 * 1000;
|
||||||
|
more = await this.fetch_messages(start_time, last_start_time);
|
||||||
|
this.update_time_range_from_messages(
|
||||||
|
more.filter(
|
||||||
|
(x) => x.timestamp >= start_time && x.timestamp < last_start_time
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
messages = await this.decrypt([...more, ...this.messages]);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.loading--;
|
this.loading--;
|
||||||
}
|
}
|
||||||
this.messages = this.merge_messages(this.messages, messages);
|
this.messages = messages;
|
||||||
this.time_loading = undefined;
|
this.time_loading = undefined;
|
||||||
console.log(
|
console.log(`loading messages done for ${self.whoami}`);
|
||||||
`loading ${messages.length} messages done for ${self.whoami} in ${(new Date() - start_time) / 1000}s`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_all_read() {
|
mark_all_read() {
|
||||||
@ -393,8 +373,7 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
if (
|
if (
|
||||||
!this.messages ||
|
!this.messages ||
|
||||||
this._messages_hash !== this.hash ||
|
this._messages_hash !== this.hash ||
|
||||||
JSON.stringify(this._messages_following) !==
|
this._messages_following !== this.following
|
||||||
JSON.stringify(this.following)
|
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
`loading messages for ${this.whoami} (following ${this.following.length})`
|
`loading messages for ${this.whoami} (following ${this.following.length})`
|
||||||
@ -438,7 +417,7 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
return cache(html`
|
return html`
|
||||||
<button class="w3-button w3-theme-d1" @click=${this.mark_all_read}>
|
<button class="w3-button w3-theme-d1" @click=${this.mark_all_read}>
|
||||||
Mark All Read
|
Mark All Read
|
||||||
</button>
|
</button>
|
||||||
@ -454,7 +433,7 @@ class TfTabNewsFeedElement extends LitElement {
|
|||||||
channel_unread=${this.channels_unread?.[this.channel()]}
|
channel_unread=${this.channels_unread?.[this.channel()]}
|
||||||
></tf-news>
|
></tf-news>
|
||||||
${more}
|
${more}
|
||||||
`);
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import {
|
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
|
||||||
LitElement,
|
|
||||||
cache,
|
|
||||||
keyed,
|
|
||||||
html,
|
|
||||||
unsafeHTML,
|
|
||||||
until,
|
|
||||||
} from './lit-all.min.js';
|
|
||||||
import * as tfrpc from '/static/tfrpc.js';
|
import * as tfrpc from '/static/tfrpc.js';
|
||||||
import {styles} from './tf-styles.js';
|
import {styles} from './tf-styles.js';
|
||||||
|
|
||||||
@ -23,7 +16,6 @@ class TfTabNewsElement extends LitElement {
|
|||||||
channels_unread: {type: Object},
|
channels_unread: {type: Object},
|
||||||
channels_latest: {type: Object},
|
channels_latest: {type: Object},
|
||||||
connections: {type: Array},
|
connections: {type: Array},
|
||||||
private_messages: {type: Array},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,26 +128,6 @@ class TfTabNewsElement extends LitElement {
|
|||||||
return this.hash.startsWith('##') ? this.hash.substring(2) : undefined;
|
return this.hash.startsWith('##') ? this.hash.substring(2) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
compare_follows() {
|
|
||||||
const now = new Date().valueOf();
|
|
||||||
return function (a, b) {
|
|
||||||
return (b[1].ts > now ? -1 : b[1].ts) - (a[1].ts > now ? -1 : a[1].ts);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
suggested_follows() {
|
|
||||||
/*
|
|
||||||
** Filter out people who have used future timestamps so that they aren't
|
|
||||||
** pinned at the top.
|
|
||||||
*/
|
|
||||||
let self = this;
|
|
||||||
return Object.entries(this.users)
|
|
||||||
.filter((x) => x[1].follow_depth > 1)
|
|
||||||
.sort(self.compare_follows())
|
|
||||||
.slice(0, 8)
|
|
||||||
.map((x) => x[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
render_sidebar() {
|
render_sidebar() {
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
@ -181,7 +153,7 @@ class TfTabNewsElement extends LitElement {
|
|||||||
>
|
>
|
||||||
`
|
`
|
||||||
: undefined}
|
: undefined}
|
||||||
<h4 class="w3-bar-item w3-theme-d2">Channels</h4>
|
<div class="w3-bar-item w3-theme-d2">Channels</div>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="w3-bar-item w3-button"
|
class="w3-bar-item w3-button"
|
||||||
@ -223,31 +195,10 @@ class TfTabNewsElement extends LitElement {
|
|||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<h4 class="w3-bar-item w3-theme-d2">Connections</h4>
|
<div class="w3-bar-item w3-theme-d2">Connections</div>
|
||||||
${this.connections
|
${this.connections.map((x) => (html`
|
||||||
.filter((x) => x.id && !x.destroy_reason)
|
<tf-user class="w3-bar-item" style="max-width: 100%" id=${x.id} .users=${this.users}></tf-user>
|
||||||
.map(
|
`))}
|
||||||
(x) => html`
|
|
||||||
<tf-user
|
|
||||||
class="w3-bar-item"
|
|
||||||
style="max-width: 100%"
|
|
||||||
id=${x.id}
|
|
||||||
fallback_name=${x.host}
|
|
||||||
.users=${this.users}
|
|
||||||
></tf-user>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
<h4 class="w3-bar-item w3-theme-d2">Suggested Follows</h4>
|
|
||||||
${this.suggested_follows().map(
|
|
||||||
(x) => html`
|
|
||||||
<tf-user
|
|
||||||
class="w3-bar-item"
|
|
||||||
style="max-width: 100%"
|
|
||||||
id=${x}
|
|
||||||
.users=${this.users}
|
|
||||||
></tf-user>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="w3-overlay"
|
class="w3-overlay"
|
||||||
@ -260,15 +211,12 @@ class TfTabNewsElement extends LitElement {
|
|||||||
render() {
|
render() {
|
||||||
let profile =
|
let profile =
|
||||||
this.hash.startsWith('#@') && this.hash != '#@'
|
this.hash.startsWith('#@') && this.hash != '#@'
|
||||||
? keyed(
|
? html`<tf-profile
|
||||||
this.hash.substring(1),
|
|
||||||
html`<tf-profile
|
|
||||||
class="tf-profile"
|
class="tf-profile"
|
||||||
id=${this.hash.substring(1)}
|
id=${this.hash.substring(1)}
|
||||||
whoami=${this.whoami}
|
whoami=${this.whoami}
|
||||||
.users=${this.users}
|
.users=${this.users}
|
||||||
></tf-profile>`
|
></tf-profile>`
|
||||||
)
|
|
||||||
: undefined;
|
: undefined;
|
||||||
let edit_profile;
|
let edit_profile;
|
||||||
if (
|
if (
|
||||||
@ -283,10 +231,10 @@ class TfTabNewsElement extends LitElement {
|
|||||||
name.
|
name.
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
return cache(html`
|
return html`
|
||||||
${this.render_sidebar()}
|
${this.render_sidebar()}
|
||||||
<div
|
<div
|
||||||
style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: auto; contain: layout"
|
style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: scroll"
|
||||||
id="main"
|
id="main"
|
||||||
class="w3-main"
|
class="w3-main"
|
||||||
>
|
>
|
||||||
@ -339,11 +287,10 @@ class TfTabNewsElement extends LitElement {
|
|||||||
@tf-expand=${this.on_expand}
|
@tf-expand=${this.on_expand}
|
||||||
.channels_unread=${this.channels_unread}
|
.channels_unread=${this.channels_unread}
|
||||||
.channels_latest=${this.channels_latest}
|
.channels_latest=${this.channels_latest}
|
||||||
.private_messages=${this.private_messages}
|
|
||||||
></tf-tab-news-feed>
|
></tf-tab-news-feed>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ class TfTagElement extends LitElement {
|
|||||||
let number = this.count ? html` (${this.count})` : undefined;
|
let number = this.count ? html` (${this.count})` : undefined;
|
||||||
return html`<a
|
return html`<a
|
||||||
href=${'#' + encodeURIComponent(this.tag)}
|
href=${'#' + encodeURIComponent(this.tag)}
|
||||||
class="w3-tag w3-theme-d1 w3-round-4 w3-button"
|
style="display: inline-block; margin: 3px; border: 1px solid black; background-color: #444; padding: 4px; border-radius: 3px"
|
||||||
>${this.tag}${number}</a
|
>${this.tag}${number}</a
|
||||||
> `;
|
>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ class TfUserElement extends LitElement {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
id: {type: String},
|
id: {type: String},
|
||||||
fallback_name: {type: String},
|
|
||||||
users: {type: Object},
|
users: {type: Object},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -16,41 +15,31 @@ class TfUserElement extends LitElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.fallback_name = null;
|
|
||||||
this.users = {};
|
this.users = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let user = this.users[this.id];
|
|
||||||
let shape =
|
|
||||||
user?.follow_depth === undefined || user.follow_depth >= 2
|
|
||||||
? 'w3-circle'
|
|
||||||
: 'w3-round';
|
|
||||||
let image = html`<span
|
let image = html`<span
|
||||||
class=${'w3-theme-l4 ' + shape}
|
class="w3-theme-light w3-circle"
|
||||||
style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"
|
style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"
|
||||||
>😎</span
|
>?</span
|
||||||
>`;
|
>`;
|
||||||
let name = this.users?.[this.id]?.name;
|
let name = this.users?.[this.id]?.name;
|
||||||
name = html`<a target="_top" href=${'#' + this.id}
|
name = html`<a target="_top" href=${'#' + this.id}>${name !== undefined ? name : this.id}</a>`
|
||||||
>${name ?? this.fallback_name ?? this.id}</a
|
|
||||||
>`;
|
|
||||||
|
|
||||||
if (user) {
|
if (this.users[this.id]) {
|
||||||
let image_link = user.image;
|
let image_link = this.users[this.id].image;
|
||||||
image_link =
|
image_link =
|
||||||
typeof image_link == 'string' ? image_link : image_link?.link;
|
typeof image_link == 'string' ? image_link : image_link?.link;
|
||||||
if (image_link !== undefined) {
|
if (image_link !== undefined) {
|
||||||
image = html`<img
|
image = html`<img
|
||||||
class=${'w3-theme-l4 ' + shape}
|
class="w3-circle"
|
||||||
style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover"
|
style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover"
|
||||||
src="/${image_link}/view"
|
src="/${image_link}/view"
|
||||||
/>`;
|
/>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return html` <div
|
return html` <div style="display: inline-block; vertical-align: middle; font-weight: bold; text-wrap: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis">
|
||||||
style="display: inline-block; vertical-align: middle; font-weight: bold; text-wrap: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis"
|
|
||||||
>
|
|
||||||
${image} ${name}
|
${image} ${name}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "💾",
|
"emoji": "💾",
|
||||||
"previous": "&tzZFIe7Y54O4sx1QtAPdemkXh+p5qHXSG/dlS7NP6OQ=.sha256"
|
"previous": "&mvGTlWKFR5QM/3nb4fJ2WQq0n/gNKvBmhGDkAvb8ki8=.sha256"
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ async function query(sql, args) {
|
|||||||
|
|
||||||
async function get_biggest() {
|
async function get_biggest() {
|
||||||
return query(`
|
return query(`
|
||||||
select author, size from messages_stats group by author order by size desc limit 10;
|
select author, sum(length(content)) as size from messages group by author order by size desc limit 10;
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +62,15 @@ function nice_size(bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await app.setDocument('<p style="color: #fff">Analyzing feeds...</p>');
|
await app.setDocument(
|
||||||
let most_follows = get_most_follows();
|
'<p style="color: #fff">Finding the top 10 largest feeds...</p>'
|
||||||
|
);
|
||||||
|
let most_follows = await get_most_follows();
|
||||||
let total = await get_total();
|
let total = await get_total();
|
||||||
let identities = await ssb.getAllIdentities();
|
let identities = await ssb.getAllIdentities();
|
||||||
let following1 = await ssb.following(identities, 1);
|
let following1 = await ssb.following(identities, 1);
|
||||||
let following2 = await ssb.following(identities, 2);
|
let following2 = await ssb.following(identities, 2);
|
||||||
let biggest = await get_biggest();
|
let biggest = await get_biggest();
|
||||||
most_follows = await most_follows;
|
|
||||||
let names = await get_names(
|
let names = await get_names(
|
||||||
[].concat(
|
[].concat(
|
||||||
biggest.map((x) => x.author),
|
biggest.map((x) => x.author),
|
||||||
@ -93,7 +94,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
let html = `<body style="color: #000; background-color: #ddd">\n
|
let html = `<body style="color: #000; background-color: #ddd">\n
|
||||||
<h1>Storage Summary</h1>
|
<h1>Storage Summary</h1>
|
||||||
<h2>Top Accounts by Size</h2>
|
<h2>Top 10 Accounts by Size</h2>
|
||||||
<ol>`;
|
<ol>`;
|
||||||
for (let item of biggest) {
|
for (let item of biggest) {
|
||||||
html += `<li>
|
html += `<li>
|
||||||
@ -104,7 +105,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
html += `
|
html += `
|
||||||
</ol>
|
</ol>
|
||||||
<h2>Top Accounts by Follows</h2>
|
<h2>Top 10 Accounts by Follows</h2>
|
||||||
<ol>`;
|
<ol>`;
|
||||||
for (let item of most_follows) {
|
for (let item of most_follows) {
|
||||||
html += `<li>
|
html += `<li>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "tildefriends-app",
|
|
||||||
"emoji": "🕸",
|
|
||||||
"previous": "&n7hu5b8/TsfiG6FDlCRG5nPCrIdCr96+xpIJ/aQT/uM=.sha256"
|
|
||||||
}
|
|
100
apps/web/app.js
100
apps/web/app.js
@ -1,100 +0,0 @@
|
|||||||
let g_hash;
|
|
||||||
|
|
||||||
async function query(sql, params) {
|
|
||||||
let results = [];
|
|
||||||
await ssb.sqlAsync(sql, params, function (row) {
|
|
||||||
results.push(row);
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function resolve(id) {
|
|
||||||
try {
|
|
||||||
let blob = await ssb.blobGet(id);
|
|
||||||
if (blob) {
|
|
||||||
let json;
|
|
||||||
try {
|
|
||||||
json = JSON.parse(utf8Decode(blob));
|
|
||||||
} catch {
|
|
||||||
return {id: utf8Decode(blob)};
|
|
||||||
}
|
|
||||||
if (json?.links) {
|
|
||||||
for (let [key, value] of Object.entries(json.links)) {
|
|
||||||
json.links[key] = await resolve(value);
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
} else {
|
|
||||||
return 'huh?' + json;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return `missing<${id}>`;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return id + ': ' + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function get_names(identities) {
|
|
||||||
return Object.fromEntries(
|
|
||||||
(
|
|
||||||
await query(
|
|
||||||
`
|
|
||||||
SELECT author, name FROM (
|
|
||||||
SELECT
|
|
||||||
messages.author,
|
|
||||||
RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
|
|
||||||
messages.content ->> 'name' AS name
|
|
||||||
FROM messages
|
|
||||||
JOIN json_each(?) AS identities ON identities.value = messages.author
|
|
||||||
WHERE
|
|
||||||
json_extract(messages.content, '$.type') = 'about' AND
|
|
||||||
content ->> 'about' = messages.author AND name IS NOT NULL)
|
|
||||||
WHERE author_rank = 1
|
|
||||||
`,
|
|
||||||
[JSON.stringify(identities)]
|
|
||||||
)
|
|
||||||
).map((x) => [x.author, x.name])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function render(hash) {
|
|
||||||
g_hash = hash;
|
|
||||||
if (!hash) {
|
|
||||||
let sites = await query(
|
|
||||||
`
|
|
||||||
SELECT site.author, site.id
|
|
||||||
FROM messages site
|
|
||||||
WHERE site.content ->> 'type' = 'web-init'
|
|
||||||
`,
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
let names = await get_names(sites.map((x) => x.author));
|
|
||||||
if (hash === g_hash) {
|
|
||||||
await app.setDocument(
|
|
||||||
`<ul style="background-color: #ddd">${sites.map((x) => `<li><a target="_top" href="#${encodeURIComponent(x.id)}">${names[x.author] ?? x.author} - ${x.id}</a></li>`).join('\n')}</ul>`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let site_id =
|
|
||||||
hash.charAt(0) == '#'
|
|
||||||
? decodeURIComponent(hash.substring(1))
|
|
||||||
: decodeURIComponent(hash);
|
|
||||||
await app.setDocument(`<html style="margin: 0; padding: 0; width: 100vw; height: 100vh; margin: 0; padding: 0">
|
|
||||||
<body style="display: flex; flex-direction: column; width: 100vw; height: 100vh">
|
|
||||||
<iframe src="${encodeURIComponent(site_id)}/index.html" style="flex: 1 1; border: 0; background-color: #fff"></iframe>
|
|
||||||
</body>
|
|
||||||
</html>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
core.register('message', async function message_handler(message) {
|
|
||||||
if (message.event == 'hashChange') {
|
|
||||||
await render(message.hash);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
render(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
@ -1,63 +0,0 @@
|
|||||||
async function query(sql, params) {
|
|
||||||
let results = [];
|
|
||||||
await ssb.sqlAsync(sql, params, function (row) {
|
|
||||||
results.push(row);
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
function guess_content_type(name) {
|
|
||||||
if (name.endsWith('.html')) {
|
|
||||||
return 'text/html; charset=UTF-8';
|
|
||||||
} else if (name.endsWith('.js') || name.endsWith('.mjs')) {
|
|
||||||
return 'text/javascript; charset=UTF-8';
|
|
||||||
} else if (name.endsWith('.css')) {
|
|
||||||
return 'text/stylesheet; charset=UTF-8';
|
|
||||||
} else {
|
|
||||||
return 'application/binary';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
let path = request.path.replaceAll(/(%[0-9a-fA-F]{2})/g, (x) =>
|
|
||||||
String.fromCharCode(parseInt(x.substring(1), 16))
|
|
||||||
);
|
|
||||||
let match = path.match(/^(%.{44}\.sha256)(?:\/)?(.*)$/);
|
|
||||||
|
|
||||||
let content_type = guess_content_type(request.path);
|
|
||||||
let root = await query(
|
|
||||||
`
|
|
||||||
SELECT root.content ->> 'root' AS root
|
|
||||||
FROM messages site
|
|
||||||
JOIN messages root
|
|
||||||
ON site.id = ? AND root.author = site.author AND root.content ->> 'site' = site.id
|
|
||||||
ORDER BY root.sequence DESC LIMIT 1
|
|
||||||
`,
|
|
||||||
[match[1]]
|
|
||||||
);
|
|
||||||
let root_id = root[0]['root'];
|
|
||||||
let last_id = root_id;
|
|
||||||
let blob = await ssb.blobGet(root_id);
|
|
||||||
try {
|
|
||||||
for (let part of match[2]?.split('/')) {
|
|
||||||
let dir = JSON.parse(utf8Decode(blob));
|
|
||||||
last_id = dir?.links[part];
|
|
||||||
blob = await ssb.blobGet(dir?.links[part]);
|
|
||||||
content_type = guess_content_type(part);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
respond({
|
|
||||||
status_code: 200,
|
|
||||||
data: blob ? utf8Decode(blob) : `${last_id} not found`,
|
|
||||||
content_type: content_type,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(function (e) {
|
|
||||||
respond({
|
|
||||||
status_code: 200,
|
|
||||||
data: `${e.message}\n${e.stack}`,
|
|
||||||
content_type: 'text/plain',
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "👋",
|
"emoji": "👋",
|
||||||
"previous": "&wAb7J6E35xEXpiXsQ6t1RaWTGIvlatUnyH8ipF6pVic=.sha256"
|
"previous": "&7gFmLW5zSMhmxWWY1+jeRcHdullgujSqGJg94lVgr1k=.sha256"
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,17 @@
|
|||||||
<link rel="stylesheet" href="brands.min.css" />
|
<link rel="stylesheet" href="brands.min.css" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
body,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5 {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
img {
|
img {
|
||||||
margin-bottom: -8px;
|
margin-bottom: -8px;
|
||||||
}
|
}
|
||||||
@ -28,14 +39,11 @@
|
|||||||
<b>😎 Tilde Friends</b>
|
<b>😎 Tilde Friends</b>
|
||||||
</h1>
|
</h1>
|
||||||
<h1 class="w3-xxlarge w3-text-green">
|
<h1 class="w3-xxlarge w3-text-green">
|
||||||
<b
|
<b>Make apps and friends from the comfort of your web browser.</b>
|
||||||
>the Secure Scuttlebutt decentralized social network client that's
|
|
||||||
<i>fancy🎩</i></b
|
|
||||||
>
|
|
||||||
</h1>
|
</h1>
|
||||||
<p>
|
<p>
|
||||||
In addition to participating in Secure Scuttlebutt, Tilde Friends is
|
Tilde Friends is a platform for building, running, and sharing web
|
||||||
a platform for building, running, and sharing applications.
|
applications.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Available for lots of devices:
|
Available for lots of devices:
|
||||||
@ -52,7 +60,7 @@
|
|||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="w3-button w3-black w3-padding-large"
|
class="w3-button w3-black w3-padding-large"
|
||||||
href="https://www.tildefriends.net/~core/ssb/"
|
href="https://www.tildefriends.net/~cory/apps/"
|
||||||
><i class="fa fa-link"></i> Try It</a
|
><i class="fa fa-link"></i> Try It</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
@ -60,11 +68,6 @@
|
|||||||
href="https://dev.tildefriends.net/"
|
href="https://dev.tildefriends.net/"
|
||||||
><i class="fa fa-mug-hot"></i> Development</a
|
><i class="fa fa-mug-hot"></i> Development</a
|
||||||
>
|
>
|
||||||
<a
|
|
||||||
class="w3-button w3-black w3-padding-large"
|
|
||||||
href="https://docs.tildefriends.net/"
|
|
||||||
><i class="fa fa-book"></i> Documentation</a
|
|
||||||
>
|
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="w3-button w3-round-large w3-padding w3-blue-gray w3-margin-top"
|
class="w3-button w3-round-large w3-padding w3-blue-gray w3-margin-top"
|
||||||
@ -220,15 +223,16 @@
|
|||||||
|
|
||||||
<!-- Technlology Section -->
|
<!-- Technlology Section -->
|
||||||
<div class="w3-container w3-padding-64 w3-light-grey w3-center">
|
<div class="w3-container w3-padding-64 w3-light-grey w3-center">
|
||||||
<h1 class="w3-jumbo"><b>Built the Old Fashioned Way</b></h1>
|
<h1 class="w3-jumbo"><b>Boring Technology</b></h1>
|
||||||
<p>
|
<p>
|
||||||
Tilde Friends strives to use only simple and widely adopted dependencies
|
Tilde Friends is built using boring, trusted tech. Unless a better
|
||||||
in order to keep it easy to build for all sorts of platforms and
|
reason presents itself, it strives to use only simple and widely adopted
|
||||||
maintainable for a very long time.
|
dependencies in order to keep it easy to build for all sorts of
|
||||||
|
platforms and maintainable for a very long time.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Though of course for building Tilde Friends apps, you are free to use
|
Though of course for building Tilde Friends apps, you are free to use
|
||||||
whatever fits on top.
|
whatever fits.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="w3-row" style="margin-top: 64px">
|
<div class="w3-row" style="margin-top: 64px">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||||
@ -108,10 +108,6 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
||||||
@ -153,9 +149,9 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
.w3-hover-none:hover{box-shadow:none!important}
|
||||||
/* Colors */
|
/* Colors */
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
||||||
@ -170,24 +166,15 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
||||||
|
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
||||||
|
42
apps/wiki/lit-all.min.js
vendored
42
apps/wiki/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
113
core/app.js
113
core/app.js
@ -1,26 +1,53 @@
|
|||||||
import * as core from './core.js';
|
import * as core from './core.js';
|
||||||
|
|
||||||
|
let g_next_id = 1;
|
||||||
|
let g_calls = {};
|
||||||
|
|
||||||
let gSessionIndex = 0;
|
let gSessionIndex = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function makeSessionId() {
|
||||||
|
return 'session_' + (gSessionIndex++).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function App() {
|
function App() {
|
||||||
|
this._on_output = null;
|
||||||
this._send_queue = [];
|
this._send_queue = [];
|
||||||
this.calls = {};
|
|
||||||
this._next_call_id = 1;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} callback
|
||||||
|
*/
|
||||||
|
App.prototype.readOutput = function (callback) {
|
||||||
|
this._on_output = callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} api
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
App.prototype.makeFunction = function (api) {
|
App.prototype.makeFunction = function (api) {
|
||||||
let self = this;
|
let self = this;
|
||||||
let result = function () {
|
let result = function () {
|
||||||
let id = self._next_call_id++;
|
let id = g_next_id++;
|
||||||
while (!id || self.calls[id]) {
|
while (!id || g_calls[id]) {
|
||||||
id = self._next_call_id++;
|
id = g_next_id++;
|
||||||
}
|
}
|
||||||
let promise = new Promise(function (resolve, reject) {
|
let promise = new Promise(function (resolve, reject) {
|
||||||
self.calls[id] = {resolve: resolve, reject: reject};
|
g_calls[id] = {resolve: resolve, reject: reject};
|
||||||
});
|
});
|
||||||
let message = {
|
let message = {
|
||||||
action: 'tfrpc',
|
message: 'tfrpc',
|
||||||
method: api[0],
|
method: api[0],
|
||||||
params: [...arguments],
|
params: [...arguments],
|
||||||
id: id,
|
id: id,
|
||||||
@ -32,6 +59,10 @@ App.prototype.makeFunction = function (api) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} message
|
||||||
|
*/
|
||||||
App.prototype.send = function (message) {
|
App.prototype.send = function (message) {
|
||||||
if (this._send_queue) {
|
if (this._send_queue) {
|
||||||
if (this._on_output) {
|
if (this._on_output) {
|
||||||
@ -46,7 +77,13 @@ App.prototype.send = function (message) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.app_socket = async function socket(request, response) {
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} request
|
||||||
|
* @param {*} response
|
||||||
|
* @param {*} client
|
||||||
|
*/
|
||||||
|
async function socket(request, response, client) {
|
||||||
let process;
|
let process;
|
||||||
let options = {};
|
let options = {};
|
||||||
let credentials = await httpd.auth_query(request.headers);
|
let credentials = await httpd.auth_query(request.headers);
|
||||||
@ -66,16 +103,10 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
try {
|
try {
|
||||||
message = JSON.parse(event.data);
|
message = JSON.parse(event.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
print(
|
print('ERROR', error, event.data, event.data.length, event.opCode);
|
||||||
'WebSocket error:',
|
|
||||||
error,
|
|
||||||
event.data,
|
|
||||||
event.data.length,
|
|
||||||
event.opCode
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!process && message.action == 'hello') {
|
if (message.action == 'hello') {
|
||||||
let packageOwner;
|
let packageOwner;
|
||||||
let packageName;
|
let packageName;
|
||||||
let blobId;
|
let blobId;
|
||||||
@ -92,7 +123,7 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
if (!blobId) {
|
if (!blobId) {
|
||||||
response.send(
|
response.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
action: 'tfrpc',
|
message: 'tfrpc',
|
||||||
method: 'error',
|
method: 'error',
|
||||||
params: [message.path + ' not found'],
|
params: [message.path + ' not found'],
|
||||||
id: -1,
|
id: -1,
|
||||||
@ -133,7 +164,7 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
options.packageOwner = packageOwner;
|
options.packageOwner = packageOwner;
|
||||||
options.packageName = packageName;
|
options.packageName = packageName;
|
||||||
options.url = message.url;
|
options.url = message.url;
|
||||||
let sessionId = 'session_' + (gSessionIndex++).toString();
|
let sessionId = makeSessionId();
|
||||||
if (blobId) {
|
if (blobId) {
|
||||||
if (message.edit_only) {
|
if (message.edit_only) {
|
||||||
response.send(
|
response.send(
|
||||||
@ -145,24 +176,9 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (process) {
|
if (process) {
|
||||||
process.client_api.tfrpc = function (message) {
|
process.app.readOutput(function (message) {
|
||||||
if (message.id) {
|
|
||||||
let calls = process?.app?.calls;
|
|
||||||
if (calls) {
|
|
||||||
let call = calls[message.id];
|
|
||||||
if (call) {
|
|
||||||
if (message.error !== undefined) {
|
|
||||||
call.reject(message.error);
|
|
||||||
} else {
|
|
||||||
call.resolve(message.result);
|
|
||||||
}
|
|
||||||
delete calls[message.id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
process.app._on_output = (message) =>
|
|
||||||
response.send(JSON.stringify(message), 0x1);
|
response.send(JSON.stringify(message), 0x1);
|
||||||
|
});
|
||||||
process.app.send();
|
process.app.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,13 +207,26 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
if (process && process.timeout > 0) {
|
if (process && process.timeout > 0) {
|
||||||
setTimeout(ping, process.timeout);
|
setTimeout(ping, process.timeout);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (message.action == 'resetPermission') {
|
||||||
if (process) {
|
if (process) {
|
||||||
if (process.client_api[message.action]) {
|
process.resetPermission(message.permission);
|
||||||
process.client_api[message.action](message);
|
|
||||||
} else if (process.eventHandlers['message']) {
|
|
||||||
await core.invoke(process.eventHandlers['message'], [message]);
|
|
||||||
}
|
}
|
||||||
|
} else if (message.action == 'setActiveIdentity') {
|
||||||
|
process.setActiveIdentity(message.identity);
|
||||||
|
} else if (message.action == 'createIdentity') {
|
||||||
|
await process.createIdentity();
|
||||||
|
} else if (message.message == 'tfrpc') {
|
||||||
|
if (message.id && g_calls[message.id]) {
|
||||||
|
if (message.error !== undefined) {
|
||||||
|
g_calls[message.id].reject(message.error);
|
||||||
|
} else {
|
||||||
|
g_calls[message.id].resolve(message.result);
|
||||||
|
}
|
||||||
|
delete g_calls[message.id];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (process && process.eventHandlers['message']) {
|
||||||
|
await core.invoke(process.eventHandlers['message'], [message]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.opCode == 0x8) {
|
} else if (event.opCode == 0x8) {
|
||||||
@ -216,6 +245,6 @@ exports.app_socket = async function socket(request, response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
response.upgrade(100, {});
|
response.upgrade(100, {});
|
||||||
};
|
}
|
||||||
|
|
||||||
export {App};
|
export {socket, App};
|
||||||
|
@ -149,7 +149,7 @@ class TfNavigationElement extends LitElement {
|
|||||||
<link type="text/css" rel="stylesheet" href="/static/w3.css" />
|
<link type="text/css" rel="stylesheet" href="/static/w3.css" />
|
||||||
<div class="w3-dropdown-click w3-right" style="max-width: 100%">
|
<div class="w3-dropdown-click w3-right" style="max-width: 100%">
|
||||||
<button
|
<button
|
||||||
class="w3-button w3-rest"
|
class="w3-button w3-rest w3-cyan"
|
||||||
style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 100%"
|
style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 100%"
|
||||||
id="identity"
|
id="identity"
|
||||||
@click=${self.toggle_id_dropdown}
|
@click=${self.toggle_id_dropdown}
|
||||||
@ -266,7 +266,6 @@ class TfNavigationElement extends LitElement {
|
|||||||
<button
|
<button
|
||||||
@click=${() => this.reset_permission(key)}
|
@click=${() => this.reset_permission(key)}
|
||||||
class="w3-button w3-red"
|
class="w3-button w3-red"
|
||||||
id=${'permission_reset:' + key}
|
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
@ -276,7 +275,6 @@ class TfNavigationElement extends LitElement {
|
|||||||
<button
|
<button
|
||||||
@click=${() => (this.show_permissions = false)}
|
@click=${() => (this.show_permissions = false)}
|
||||||
class="w3-button w3-blue"
|
class="w3-button w3-blue"
|
||||||
id="permissions_close"
|
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
@ -1327,7 +1325,7 @@ function _receive_websocket_message(message) {
|
|||||||
line.append(key, message.stats[key]);
|
line.append(key, message.stats[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (message && message.action === 'tfrpc' && message.method) {
|
} else if (message && message.message === 'tfrpc' && message.method) {
|
||||||
let api = k_api[message.method];
|
let api = k_api[message.method];
|
||||||
let id = message.id;
|
let id = message.id;
|
||||||
let params = message.params;
|
let params = message.params;
|
||||||
@ -1335,14 +1333,14 @@ function _receive_websocket_message(message) {
|
|||||||
Promise.resolve(api.func(...params))
|
Promise.resolve(api.func(...params))
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
send({
|
send({
|
||||||
action: 'tfrpc',
|
message: 'tfrpc',
|
||||||
id: id,
|
id: id,
|
||||||
result: result,
|
result: result,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
send({
|
send({
|
||||||
action: 'tfrpc',
|
message: 'tfrpc',
|
||||||
id: id,
|
id: id,
|
||||||
error: error,
|
error: error,
|
||||||
});
|
});
|
||||||
|
176
core/core.js
176
core/core.js
@ -1,24 +1,34 @@
|
|||||||
import * as app from './app.js';
|
import * as app from './app.js';
|
||||||
|
import * as form from './form.js';
|
||||||
import * as http from './http.js';
|
import * as http from './http.js';
|
||||||
|
|
||||||
let gProcesses = {};
|
let gProcesses = {};
|
||||||
let gStatsTimer = false;
|
let gStatsTimer = false;
|
||||||
let g_handler_index = 0;
|
let kPingInterval = 60 * 1000;
|
||||||
|
|
||||||
const k_ping_interval = 60 * 1000;
|
/**
|
||||||
|
* TODOC
|
||||||
function printError(error) {
|
* @param {*} out
|
||||||
|
* @param {*} error
|
||||||
|
*/
|
||||||
|
function printError(out, error) {
|
||||||
if (error.stackTrace) {
|
if (error.stackTrace) {
|
||||||
print(error.fileName + ':' + error.lineNumber + ': ' + error.message);
|
out.print(error.fileName + ':' + error.lineNumber + ': ' + error.message);
|
||||||
print(error.stackTrace);
|
out.print(error.stackTrace);
|
||||||
} else {
|
} else {
|
||||||
for (let [k, v] of Object.entries(error)) {
|
for (let [k, v] of Object.entries(error)) {
|
||||||
print(k, v);
|
out.print(k, v);
|
||||||
}
|
}
|
||||||
print(error.toString());
|
out.print(error.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} handlers
|
||||||
|
* @param {*} argv
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function invoke(handlers, argv) {
|
function invoke(handlers, argv) {
|
||||||
let promises = [];
|
let promises = [];
|
||||||
if (handlers) {
|
if (handlers) {
|
||||||
@ -39,6 +49,12 @@ function invoke(handlers, argv) {
|
|||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} eventName
|
||||||
|
* @param {*} argv
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function broadcastEvent(eventName, argv) {
|
function broadcastEvent(eventName, argv) {
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (let process of Object.values(gProcesses)) {
|
for (let process of Object.values(gProcesses)) {
|
||||||
@ -49,6 +65,11 @@ function broadcastEvent(eventName, argv) {
|
|||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} message
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function broadcast(message) {
|
function broadcast(message) {
|
||||||
let sender = this;
|
let sender = this;
|
||||||
let promises = [];
|
let promises = [];
|
||||||
@ -65,6 +86,12 @@ function broadcast(message) {
|
|||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {String} eventName
|
||||||
|
* @param {*} argv
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function broadcastAppEventToUser(
|
function broadcastAppEventToUser(
|
||||||
user,
|
user,
|
||||||
packageOwner,
|
packageOwner,
|
||||||
@ -87,6 +114,12 @@ function broadcastAppEventToUser(
|
|||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} caller
|
||||||
|
* @param {*} process
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function getUser(caller, process) {
|
function getUser(caller, process) {
|
||||||
return {
|
return {
|
||||||
key: process.key,
|
key: process.key,
|
||||||
@ -97,6 +130,12 @@ function getUser(caller, process) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} user
|
||||||
|
* @param {*} process
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async function getApps(user, process) {
|
async function getApps(user, process) {
|
||||||
if (
|
if (
|
||||||
process.credentials &&
|
process.credentials &&
|
||||||
@ -123,13 +162,28 @@ async function getApps(user, process) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} from
|
||||||
|
* @param {*} to
|
||||||
|
* @param {*} message
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function postMessageInternal(from, to, message) {
|
function postMessageInternal(from, to, message) {
|
||||||
if (to.eventHandlers['message']) {
|
if (to.eventHandlers['message']) {
|
||||||
return invoke(to.eventHandlers['message'], [getUser(from, from), message]);
|
return invoke(to.eventHandlers['message'], [getUser(from, from), message]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} blobId
|
||||||
|
* @param {*} key
|
||||||
|
* @param {*} options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async function getProcessBlob(blobId, key, options) {
|
async function getProcessBlob(blobId, key, options) {
|
||||||
|
// TODO(tasiaiso): break this down ?
|
||||||
let process = gProcesses[key];
|
let process = gProcesses[key];
|
||||||
if (!process && !(options && 'create' in options && !options.create)) {
|
if (!process && !(options && 'create' in options && !options.create)) {
|
||||||
let resolveReady;
|
let resolveReady;
|
||||||
@ -148,7 +202,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
}
|
}
|
||||||
process.lastActive = Date.now();
|
process.lastActive = Date.now();
|
||||||
process.lastPing = null;
|
process.lastPing = null;
|
||||||
process.timeout = k_ping_interval;
|
process.timeout = kPingInterval;
|
||||||
process.ready = new Promise(function (resolve, reject) {
|
process.ready = new Promise(function (resolve, reject) {
|
||||||
resolveReady = resolve;
|
resolveReady = resolve;
|
||||||
rejectReady = reject;
|
rejectReady = reject;
|
||||||
@ -408,15 +462,16 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
if (process.app) {
|
if (process.app) {
|
||||||
process.app.makeFunction(['error'])(error);
|
process.app.makeFunction(['error'])(error);
|
||||||
} else {
|
} else {
|
||||||
printError(error);
|
printError({print: print}, error);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printError(error);
|
printError({print: print}, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
imports.ssb = Object.fromEntries(
|
imports.ssb = Object.fromEntries(
|
||||||
Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)])
|
Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)])
|
||||||
);
|
);
|
||||||
|
imports.ssb.port = tildefriends.ssb_port;
|
||||||
imports.ssb.createIdentity = () => process.createIdentity();
|
imports.ssb.createIdentity = () => process.createIdentity();
|
||||||
imports.ssb.addIdentity = function (id) {
|
imports.ssb.addIdentity = function (id) {
|
||||||
if (
|
if (
|
||||||
@ -522,6 +577,19 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
imports.ssb.setServerFollowingMe = function (id, following) {
|
||||||
|
if (
|
||||||
|
process.credentials &&
|
||||||
|
process.credentials.session &&
|
||||||
|
process.credentials.session.name
|
||||||
|
) {
|
||||||
|
return ssb.setServerFollowingMe(
|
||||||
|
process.credentials.session.name,
|
||||||
|
id,
|
||||||
|
following
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
imports.ssb.swapWithServerIdentity = function (id) {
|
imports.ssb.swapWithServerIdentity = function (id) {
|
||||||
if (
|
if (
|
||||||
process.credentials &&
|
process.credentials &&
|
||||||
@ -596,26 +664,17 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
permissions: await imports.core.permissionsGranted(),
|
permissions: await imports.core.permissionsGranted(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
process.client_api = {
|
process.resetPermission = async function resetPermission(permission) {
|
||||||
createIdentity: function () {
|
|
||||||
return process.createIdentity();
|
|
||||||
},
|
|
||||||
resetPermission: async function resetPermission(message) {
|
|
||||||
let user = process?.credentials?.session?.name;
|
let user = process?.credentials?.session?.name;
|
||||||
await ssb.setUserPermission(
|
await ssb.setUserPermission(
|
||||||
user,
|
user,
|
||||||
options?.packageOwner,
|
options?.packageOwner,
|
||||||
options?.packageName,
|
options?.packageName,
|
||||||
message.permission,
|
permission,
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
return process.sendPermissions();
|
return process.sendPermissions();
|
||||||
},
|
|
||||||
setActiveIdentity: function setActiveIdentity(message) {
|
|
||||||
return process.setActiveIdentity(message.identity);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
ssb.registerImports(imports, process);
|
|
||||||
process.task.setImports(imports);
|
process.task.setImports(imports);
|
||||||
process.task.activate();
|
process.task.activate();
|
||||||
let source = await ssb.blobGet(blobId);
|
let source = await ssb.blobGet(blobId);
|
||||||
@ -642,7 +701,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printError(e);
|
printError({print: print}, e);
|
||||||
}
|
}
|
||||||
broadcastEvent('onSessionBegin', [getUser(process, process)]);
|
broadcastEvent('onSessionBegin', [getUser(process, process)]);
|
||||||
if (process.app) {
|
if (process.app) {
|
||||||
@ -656,10 +715,14 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
sendStats();
|
sendStats();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (process?.app && process?.task?.onError) {
|
if (process.app) {
|
||||||
|
if (process?.task?.onError) {
|
||||||
process.task.onError(error);
|
process.task.onError(error);
|
||||||
} else {
|
} else {
|
||||||
printError(error);
|
printError({print: print}, error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printError({print: print}, error);
|
||||||
}
|
}
|
||||||
rejectReady(error);
|
rejectReady(error);
|
||||||
}
|
}
|
||||||
@ -679,6 +742,9 @@ ssb.addEventListener('connections', function () {
|
|||||||
broadcastEvent('onConnectionsChanged', []);
|
broadcastEvent('onConnectionsChanged', []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
*/
|
||||||
async function loadSettings() {
|
async function loadSettings() {
|
||||||
let data = {};
|
let data = {};
|
||||||
try {
|
try {
|
||||||
@ -697,6 +763,9 @@ async function loadSettings() {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
*/
|
||||||
function sendStats() {
|
function sendStats() {
|
||||||
let apps = Object.values(gProcesses)
|
let apps = Object.values(gProcesses)
|
||||||
.filter((process) => process.app)
|
.filter((process) => process.app)
|
||||||
@ -712,6 +781,8 @@ function sendStats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let g_handler_index = 0;
|
||||||
|
|
||||||
exports.callAppHandler = async function callAppHandler(
|
exports.callAppHandler = async function callAppHandler(
|
||||||
response,
|
response,
|
||||||
app_blob_id,
|
app_blob_id,
|
||||||
@ -777,4 +848,59 @@ exports.callAppHandler = async function callAppHandler(
|
|||||||
response.end(answer?.data);
|
response.end(answer?.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
*/
|
||||||
|
loadSettings()
|
||||||
|
.then(function (settings) {
|
||||||
|
if (tildefriends.https_port && settings.http_redirect) {
|
||||||
|
httpd.set_http_redirect(settings.http_redirect);
|
||||||
|
}
|
||||||
|
httpd.all('/app/socket', app.socket);
|
||||||
|
let port = httpd.start(tildefriends.http_port);
|
||||||
|
if (tildefriends.args.out_http_port_file) {
|
||||||
|
print('Writing the port file.');
|
||||||
|
File.writeFile(
|
||||||
|
tildefriends.args.out_http_port_file,
|
||||||
|
port.toString() + '\n'
|
||||||
|
)
|
||||||
|
.then(function (r) {
|
||||||
|
print(
|
||||||
|
'Wrote the port file:',
|
||||||
|
tildefriends.args.out_http_port_file,
|
||||||
|
r
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
print('Failed to write the port file.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tildefriends.https_port) {
|
||||||
|
async function start_tls() {
|
||||||
|
const kCertificatePath = 'data/httpd/certificate.pem';
|
||||||
|
const kPrivateKeyPath = 'data/httpd/privatekey.pem';
|
||||||
|
let privateKey;
|
||||||
|
let certificate;
|
||||||
|
try {
|
||||||
|
privateKey = utf8Decode(await File.readFile(kPrivateKeyPath));
|
||||||
|
certificate = utf8Decode(await File.readFile(kCertificatePath));
|
||||||
|
} catch (e) {
|
||||||
|
print(`TLS disabled (${e.message}).`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let context = new TlsContext();
|
||||||
|
context.setPrivateKey(privateKey);
|
||||||
|
context.setCertificate(certificate);
|
||||||
|
httpd.start(tildefriends.https_port, context);
|
||||||
|
}
|
||||||
|
start_tls();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
print('Failed to load settings.');
|
||||||
|
printError({print: print}, error);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
export {invoke, getProcessBlob};
|
export {invoke, getProcessBlob};
|
||||||
|
44
core/form.js
Normal file
44
core/form.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} encoded
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function decode(encoded) {
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < encoded.length; i++) {
|
||||||
|
let c = encoded[i];
|
||||||
|
if (c == '+') {
|
||||||
|
result += ' ';
|
||||||
|
} else if (c == '%') {
|
||||||
|
result += String.fromCharCode(parseInt(encoded.slice(i + 1, i + 3), 16));
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
result += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODOC
|
||||||
|
* @param {*} encoded
|
||||||
|
* @param {*} initial
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function decodeForm(encoded, initial) {
|
||||||
|
let result = initial || {};
|
||||||
|
if (encoded) {
|
||||||
|
encoded = encoded.trim();
|
||||||
|
let items = encoded.split('&');
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
let item = items[i];
|
||||||
|
let equals = item.indexOf('=');
|
||||||
|
let key = decode(item.slice(0, equals));
|
||||||
|
let value = decode(item.slice(equals + 1));
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {decodeForm};
|
@ -38,8 +38,8 @@
|
|||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
width: 100%;
|
width: 100vw;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
@ -7,8 +7,8 @@ html {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
background-color: #444;
|
background-color: #002b36;
|
||||||
color: #fff;
|
color: #eee8d5;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
25
core/w3.css
25
core/w3.css
@ -1,4 +1,4 @@
|
|||||||
/* W3.CSS 5.01 March 14 2025 by Jan Egil and Borge Refsnes */
|
/* W3.CSS 4.15 December 2020 by Jan Egil and Borge Refsnes */
|
||||||
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
|
||||||
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */
|
||||||
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||||
@ -108,10 +108,6 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}
|
||||||
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}
|
||||||
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}
|
||||||
|
|
||||||
.w3-grid{display:grid}.w3-grid-padding{display:grid;gap:16px}.w3-flex{display:flex}
|
|
||||||
.w3-text-center{text-align:center}.w3-text-bold,.w3-bold{font-weight:bold}.w3-text-italic,.w3-italic{font-style:italic}
|
|
||||||
|
|
||||||
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}
|
||||||
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
|
||||||
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
|
||||||
@ -153,9 +149,9 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}
|
||||||
.w3-hover-none:hover{box-shadow:none!important}
|
.w3-hover-none:hover{box-shadow:none!important}
|
||||||
/* Colors */
|
/* Colors */
|
||||||
.w3-amber,.w3-hover-amber:hover,.w3-warning{color:#000!important;background-color:#ffc107!important}
|
.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}
|
||||||
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}
|
||||||
.w3-blue,.w3-hover-blue:hover,.w3-info,.w3-primary{color:#fff!important;background-color:#2196F3!important}
|
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
|
||||||
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}
|
||||||
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}
|
||||||
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}
|
||||||
@ -170,24 +166,15 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
|
|||||||
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
|
||||||
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}
|
||||||
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}
|
||||||
.w3-red,.w3-hover-red:hover,.w3-danger{color:#fff!important;background-color:#f44336!important}
|
.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}
|
||||||
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}
|
||||||
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}
|
||||||
.w3-yellow,.w3-hover-yellow:hover,.w3-note{color:#000!important;background-color:#ffeb3b!important}
|
.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}
|
||||||
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}
|
||||||
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}
|
||||||
|
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}
|
||||||
.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover,.w3-secondary{color:#000!important;background-color:#9e9e9e!important}
|
|
||||||
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
|
||||||
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}
|
||||||
|
|
||||||
.w3-asphalt,.w3-hover-asphalt:hover{color:#fff!important;background-color:#343a40!important}.w3-crimson,.w3-hover-crimson:hover{color:#fff!important;background-color:#a20025!important}
|
|
||||||
.w3-cobalt,w3-hover-cobalt:hover{color:#fff!important;background-color:#0050ef!important}
|
|
||||||
.w3-emerald,.w3-hover-emerald:hover,.w3-success{color:#fff!important;background-color:#008a00!important}
|
|
||||||
.w3-olive,.w3-hover-olive:hover{color:#fff!important;background-color:#6d8764!important}
|
|
||||||
.w3-paper,.w3-hover-paper:hover{color:#000!important;background-color:#f8f9fa!important}.w3-sienna,.w3-hover-sienna:hover{color:#fff!important;background-color:#a0522d!important}
|
|
||||||
.w3-taupe,.w3-hover-taupe:hover{color:#fff!important;background-color:#87794e!important}
|
|
||||||
|
|
||||||
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}
|
||||||
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}
|
||||||
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}
|
||||||
|
10
default.nix
10
default.nix
@ -1,8 +1,4 @@
|
|||||||
# How to upgrade to a newer version
|
# How to upgrade to a newer version
|
||||||
# - On the june and december release, you'll have to update nixpkgs to the current branch
|
|
||||||
# Change `nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";`
|
|
||||||
# to the latest release (see https://nixos.org/)
|
|
||||||
# - Run `$ nix flake update`
|
|
||||||
# - Comment `src.hash`
|
# - Comment `src.hash`
|
||||||
# - Change `version`
|
# - Change `version`
|
||||||
# - Run `$ nix build`
|
# - Run `$ nix build`
|
||||||
@ -25,14 +21,14 @@
|
|||||||
}:
|
}:
|
||||||
pkgs.stdenv.mkDerivation rec {
|
pkgs.stdenv.mkDerivation rec {
|
||||||
pname = "tildefriends";
|
pname = "tildefriends";
|
||||||
version = "0.0.29";
|
version = "0.0.26";
|
||||||
|
|
||||||
src = pkgs.fetchFromGitea {
|
src = pkgs.fetchFromGitea {
|
||||||
domain = "dev.tildefriends.net";
|
domain = "dev.tildefriends.net";
|
||||||
owner = "cory";
|
owner = "cory";
|
||||||
repo = "tildefriends";
|
repo = "tildefriends";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-bQXFpocOYOlFmVj9OZeQhNrgFuTJ8sx2RSw1tgmelOM=";
|
hash = "sha256-XJ7M++risfsRn9GkS1zjTQpqqV5S09uyimeVzU9hGGg=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +46,7 @@ pkgs.stdenv.mkDerivation rec {
|
|||||||
];
|
];
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
make -j $NIX_BUILD_CORES release USE_SYSTEM_SSL=1
|
make -j $NIX_BUILD_CORES release
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
2
deps/c-ares
vendored
2
deps/c-ares
vendored
@ -1 +1 @@
|
|||||||
Subproject commit d3a507e920e7af18a5efb7f9f1d8044ed4750013
|
Subproject commit b82840329a4081a1f1b125e6e6b760d4e1237b52
|
2
deps/codemirror/cm6.js
vendored
2
deps/codemirror/cm6.js
vendored
File diff suppressed because one or more lines are too long
355
deps/codemirror_src/package-lock.json
generated
vendored
355
deps/codemirror_src/package-lock.json
generated
vendored
@ -19,9 +19,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/autocomplete": {
|
"node_modules/@codemirror/autocomplete": {
|
||||||
"version": "6.18.6",
|
"version": "6.18.4",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz",
|
||||||
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
|
"integrity": "sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
@ -30,9 +31,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/commands": {
|
"node_modules/@codemirror/commands": {
|
||||||
"version": "6.8.1",
|
"version": "6.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.7.1.tgz",
|
||||||
"integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==",
|
"integrity": "sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/state": "^6.4.0",
|
"@codemirror/state": "^6.4.0",
|
||||||
@ -44,6 +46,7 @@
|
|||||||
"version": "6.3.1",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz",
|
||||||
"integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==",
|
"integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
@ -56,6 +59,7 @@
|
|||||||
"version": "6.4.9",
|
"version": "6.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz",
|
||||||
"integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==",
|
"integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/lang-css": "^6.0.0",
|
"@codemirror/lang-css": "^6.0.0",
|
||||||
@ -69,9 +73,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/lang-javascript": {
|
"node_modules/@codemirror/lang-javascript": {
|
||||||
"version": "6.2.3",
|
"version": "6.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
|
||||||
"integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==",
|
"integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/language": "^6.6.0",
|
"@codemirror/language": "^6.6.0",
|
||||||
@ -86,15 +91,17 @@
|
|||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
|
||||||
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
|
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@lezer/json": "^1.0.0"
|
"@lezer/json": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/language": {
|
"node_modules/@codemirror/language": {
|
||||||
"version": "6.11.0",
|
"version": "6.10.7",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.7.tgz",
|
||||||
"integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==",
|
"integrity": "sha512-aOswhVOLYhMNeqykt4P7+ukQSpGL0ynZYaEyFDVHE7fl2xgluU3yuE9MdgYNfw6EmaNidoFMIQ2iTh1ADrnT6A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
"@codemirror/view": "^6.23.0",
|
"@codemirror/view": "^6.23.0",
|
||||||
@ -105,9 +112,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/lint": {
|
"node_modules/@codemirror/lint": {
|
||||||
"version": "6.8.5",
|
"version": "6.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.4.tgz",
|
||||||
"integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==",
|
"integrity": "sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
"@codemirror/view": "^6.35.0",
|
"@codemirror/view": "^6.35.0",
|
||||||
@ -115,9 +123,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/search": {
|
"node_modules/@codemirror/search": {
|
||||||
"version": "6.5.10",
|
"version": "6.5.8",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.8.tgz",
|
||||||
"integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==",
|
"integrity": "sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
"@codemirror/view": "^6.0.0",
|
"@codemirror/view": "^6.0.0",
|
||||||
@ -125,9 +134,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/state": {
|
"node_modules/@codemirror/state": {
|
||||||
"version": "6.5.2",
|
"version": "6.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.0.tgz",
|
||||||
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
"integrity": "sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@marijn/find-cluster-break": "^1.0.0"
|
"@marijn/find-cluster-break": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -136,6 +146,7 @@
|
|||||||
"version": "6.1.2",
|
"version": "6.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
|
||||||
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
|
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
@ -144,9 +155,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/view": {
|
"node_modules/@codemirror/view": {
|
||||||
"version": "6.36.5",
|
"version": "6.36.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.1.tgz",
|
||||||
"integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==",
|
"integrity": "sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.5.0",
|
"@codemirror/state": "^6.5.0",
|
||||||
"style-mod": "^4.1.0",
|
"style-mod": "^4.1.0",
|
||||||
@ -158,6 +170,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
|
||||||
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
|
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/set-array": "^1.2.1",
|
"@jridgewell/set-array": "^1.2.1",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||||
@ -172,6 +185,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
@ -181,6 +195,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
@ -190,6 +205,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
||||||
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/gen-mapping": "^0.3.5",
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
"@jridgewell/trace-mapping": "^0.3.25"
|
"@jridgewell/trace-mapping": "^0.3.25"
|
||||||
@ -199,13 +215,15 @@
|
|||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.25",
|
"version": "0.3.25",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
@ -214,12 +232,14 @@
|
|||||||
"node_modules/@lezer/common": {
|
"node_modules/@lezer/common": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
|
||||||
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="
|
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@lezer/css": {
|
"node_modules/@lezer/css": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.9.tgz",
|
||||||
"integrity": "sha512-FuAnusbLBl1SEAtfN8NdShxYJiESKw9LAFysfea1T96jD3ydBn12oYjaSG1a04BQRIUd93/0D8e5CV1cUMkmQg==",
|
"integrity": "sha512-TYwgljcDv+YrV0MZFFvYFQHCfGgbPMR6nuqLabBdmZoFH3EP1gvw8t0vae326Ne3PszQkbXfVBjCnf3ZVCr0bA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.2.0",
|
"@lezer/common": "^1.2.0",
|
||||||
"@lezer/highlight": "^1.0.0",
|
"@lezer/highlight": "^1.0.0",
|
||||||
@ -230,6 +250,7 @@
|
|||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
|
||||||
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
|
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -238,6 +259,7 @@
|
|||||||
"version": "1.3.10",
|
"version": "1.3.10",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz",
|
||||||
"integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==",
|
"integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.2.0",
|
"@lezer/common": "^1.2.0",
|
||||||
"@lezer/highlight": "^1.0.0",
|
"@lezer/highlight": "^1.0.0",
|
||||||
@ -248,6 +270,7 @@
|
|||||||
"version": "1.4.21",
|
"version": "1.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz",
|
||||||
"integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==",
|
"integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.2.0",
|
"@lezer/common": "^1.2.0",
|
||||||
"@lezer/highlight": "^1.1.3",
|
"@lezer/highlight": "^1.1.3",
|
||||||
@ -255,9 +278,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lezer/json": {
|
"node_modules/@lezer/json": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz",
|
||||||
"integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==",
|
"integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.2.0",
|
"@lezer/common": "^1.2.0",
|
||||||
"@lezer/highlight": "^1.0.0",
|
"@lezer/highlight": "^1.0.0",
|
||||||
@ -268,6 +292,7 @@
|
|||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
||||||
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -275,12 +300,14 @@
|
|||||||
"node_modules/@marijn/find-cluster-break": {
|
"node_modules/@marijn/find-cluster-break": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||||
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="
|
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/plugin-node-resolve": {
|
"node_modules/@rollup/plugin-node-resolve": {
|
||||||
"version": "15.3.1",
|
"version": "15.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
|
||||||
"integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
|
"integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rollup/pluginutils": "^5.0.1",
|
"@rollup/pluginutils": "^5.0.1",
|
||||||
"@types/resolve": "1.20.2",
|
"@types/resolve": "1.20.2",
|
||||||
@ -305,6 +332,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
|
||||||
"integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
|
"integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"serialize-javascript": "^6.0.1",
|
"serialize-javascript": "^6.0.1",
|
||||||
"smob": "^1.0.0",
|
"smob": "^1.0.0",
|
||||||
@ -326,6 +354,7 @@
|
|||||||
"version": "5.1.4",
|
"version": "5.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
||||||
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
|
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.0",
|
"@types/estree": "^1.0.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
@ -344,260 +373,270 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
|
||||||
"integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==",
|
"integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz",
|
||||||
"integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==",
|
"integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz",
|
||||||
"integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==",
|
"integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz",
|
||||||
"integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==",
|
"integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz",
|
||||||
"integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==",
|
"integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz",
|
||||||
"integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==",
|
"integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz",
|
||||||
"integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==",
|
"integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz",
|
||||||
"integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==",
|
"integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==",
|
"integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz",
|
||||||
"integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==",
|
"integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==",
|
"integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==",
|
"integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==",
|
"integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==",
|
||||||
"cpu": [
|
|
||||||
"riscv64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
|
||||||
"version": "4.40.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.0.tgz",
|
|
||||||
"integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==",
|
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==",
|
"integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz",
|
||||||
"integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
|
"integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz",
|
||||||
"integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==",
|
"integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz",
|
||||||
"integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==",
|
"integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz",
|
||||||
"integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==",
|
"integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz",
|
||||||
"integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==",
|
"integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||||
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
|
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
|
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.1",
|
"version": "8.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@ -609,12 +648,14 @@
|
|||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/codemirror": {
|
"node_modules/codemirror": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/commands": "^6.0.0",
|
"@codemirror/commands": "^6.0.0",
|
||||||
@ -629,17 +670,20 @@
|
|||||||
"version": "2.20.3",
|
"version": "2.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/crelt": {
|
"node_modules/crelt": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
|
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/deepmerge": {
|
"node_modules/deepmerge": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -647,13 +691,15 @@
|
|||||||
"node_modules/estree-walker": {
|
"node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@ -666,6 +712,7 @@
|
|||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
@ -674,6 +721,7 @@
|
|||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"function-bind": "^1.1.2"
|
"function-bind": "^1.1.2"
|
||||||
},
|
},
|
||||||
@ -685,6 +733,7 @@
|
|||||||
"version": "2.16.1",
|
"version": "2.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hasown": "^2.0.2"
|
"hasown": "^2.0.2"
|
||||||
},
|
},
|
||||||
@ -698,17 +747,20 @@
|
|||||||
"node_modules/is-module": {
|
"node_modules/is-module": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
|
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@ -721,6 +773,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "^5.1.0"
|
"safe-buffer": "^5.1.0"
|
||||||
}
|
}
|
||||||
@ -729,6 +782,7 @@
|
|||||||
"version": "1.22.10",
|
"version": "1.22.10",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||||
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-core-module": "^2.16.0",
|
"is-core-module": "^2.16.0",
|
||||||
"path-parse": "^1.0.7",
|
"path-parse": "^1.0.7",
|
||||||
@ -745,11 +799,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.40.0",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz",
|
||||||
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
|
"integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.7"
|
"@types/estree": "1.0.6"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
@ -759,26 +814,25 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.40.0",
|
"@rollup/rollup-android-arm-eabi": "4.29.1",
|
||||||
"@rollup/rollup-android-arm64": "4.40.0",
|
"@rollup/rollup-android-arm64": "4.29.1",
|
||||||
"@rollup/rollup-darwin-arm64": "4.40.0",
|
"@rollup/rollup-darwin-arm64": "4.29.1",
|
||||||
"@rollup/rollup-darwin-x64": "4.40.0",
|
"@rollup/rollup-darwin-x64": "4.29.1",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.40.0",
|
"@rollup/rollup-freebsd-arm64": "4.29.1",
|
||||||
"@rollup/rollup-freebsd-x64": "4.40.0",
|
"@rollup/rollup-freebsd-x64": "4.29.1",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.40.0",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.40.0",
|
"@rollup/rollup-linux-arm-musleabihf": "4.29.1",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.40.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.40.0",
|
"@rollup/rollup-linux-arm64-musl": "4.29.1",
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": "4.40.0",
|
"@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.40.0",
|
"@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.40.0",
|
"@rollup/rollup-linux-riscv64-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.40.0",
|
"@rollup/rollup-linux-s390x-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.40.0",
|
"@rollup/rollup-linux-x64-gnu": "4.29.1",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.40.0",
|
"@rollup/rollup-linux-x64-musl": "4.29.1",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.40.0",
|
"@rollup/rollup-win32-arm64-msvc": "4.29.1",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.40.0",
|
"@rollup/rollup-win32-ia32-msvc": "4.29.1",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.40.0",
|
"@rollup/rollup-win32-x64-msvc": "4.29.1",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.40.0",
|
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -800,13 +854,15 @@
|
|||||||
"type": "consulting",
|
"type": "consulting",
|
||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/serialize-javascript": {
|
"node_modules/serialize-javascript": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
||||||
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
|
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"randombytes": "^2.1.0"
|
"randombytes": "^2.1.0"
|
||||||
}
|
}
|
||||||
@ -815,13 +871,15 @@
|
|||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
|
||||||
"integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
|
"integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -831,6 +889,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-from": "^1.0.0",
|
"buffer-from": "^1.0.0",
|
||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
@ -839,12 +898,14 @@
|
|||||||
"node_modules/style-mod": {
|
"node_modules/style-mod": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
||||||
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
|
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/supports-preserve-symlinks-flag": {
|
"node_modules/supports-preserve-symlinks-flag": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@ -853,10 +914,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.39.0",
|
"version": "5.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
|
||||||
"integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
|
"integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.8.2",
|
"acorn": "^8.8.2",
|
||||||
@ -873,7 +935,8 @@
|
|||||||
"node_modules/w3c-keyname": {
|
"node_modules/w3c-keyname": {
|
||||||
"version": "2.2.8",
|
"version": "2.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
|
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||||
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
deps/libbacktrace
vendored
2
deps/libbacktrace
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f1104f3270095831df536a2539f4cc408365105c
|
Subproject commit d48f84034ce3e53e501d10593710d025cb1121db
|
2
deps/libuv
vendored
2
deps/libuv
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 8fb9cb919489a48880680a56efecff6a7dfb4504
|
Subproject commit e1095c7a4373ce00cd8874d8e820de5afb25776e
|
42
deps/lit/lit-all.min.js
vendored
42
deps/lit/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
2
deps/lit/lit-all.min.js.map
vendored
2
deps/lit/lit-all.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
deps/openssl_src
vendored
2
deps/openssl_src
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 636dfadc70ce26f2473870570bfd9ec352806b1d
|
Subproject commit 98acb6b02839c609ef5b837794e08d906d965335
|
4
deps/speedscope/demangle-cpp.1768f4cc.js
vendored
Normal file
4
deps/speedscope/demangle-cpp.1768f4cc.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
deps/speedscope/favicon-16x16-V2DMIAZS.js
vendored
2
deps/speedscope/favicon-16x16-V2DMIAZS.js
vendored
@ -1,2 +0,0 @@
|
|||||||
(()=>{var D="./favicon-16x16-VSI62OPJ.png";})();
|
|
||||||
//# sourceMappingURL=favicon-16x16-V2DMIAZS.js.map
|
|
Before Width: | Height: | Size: 679 B After Width: | Height: | Size: 679 B |
2
deps/speedscope/favicon-32x32-THY3JDJL.js
vendored
2
deps/speedscope/favicon-32x32-THY3JDJL.js
vendored
@ -1,2 +0,0 @@
|
|||||||
(()=>{var T="./favicon-32x32-3EB2YCUY.png";})();
|
|
||||||
//# sourceMappingURL=favicon-32x32-THY3JDJL.js.map
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
deps/speedscope/favicon-FOKUP5Y5.ico
vendored
BIN
deps/speedscope/favicon-FOKUP5Y5.ico
vendored
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
2
deps/speedscope/favicon-M34RF7BI.js
vendored
2
deps/speedscope/favicon-M34RF7BI.js
vendored
@ -1,2 +0,0 @@
|
|||||||
(()=>{var m="./favicon-FOKUP5Y5.ico";})();
|
|
||||||
//# sourceMappingURL=favicon-M34RF7BI.js.map
|
|
123
deps/speedscope/import.bcbb2033.js
vendored
Normal file
123
deps/speedscope/import.bcbb2033.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
deps/speedscope/index.html
vendored
21
deps/speedscope/index.html
vendored
@ -1,19 +1,2 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>speedscope</title><link href="source-code-pro.52b1676f.css" rel="stylesheet"><script></script><link rel="stylesheet" href="reset.8c46b7a1.css"><link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.bc503437.png"><link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.f74b3187.png"></head><body> <script src="speedscope.6f107512.js"></script>
|
||||||
<html>
|
</body></html>
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>speedscope</title>
|
|
||||||
<link rel="stylesheet" href="speedscope-GHPHNKXC.css">
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32-3EB2YCUY.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16-VSI62OPJ.png">
|
|
||||||
<link rel="icon" type="image/x-icon" href="favicon-FOKUP5Y5.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="speedscope-VHEG2FVF.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
6
deps/speedscope/release.txt
vendored
6
deps/speedscope/release.txt
vendored
@ -1,3 +1,3 @@
|
|||||||
speedscope@1.22.2
|
speedscope@1.21.0
|
||||||
Sat Feb 15 13:02:38 PST 2025
|
Sat Nov 16 22:13:27 PST 2024
|
||||||
1c254dcb3e2b4f6d921340d20e972d9d27b788f4
|
d36c3a54424063a8df7bc67a7b824a223d73861b
|
||||||
|
2
deps/speedscope/reset.8c46b7a1.css
vendored
Normal file
2
deps/speedscope/reset.8c46b7a1.css
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:initial}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}html{overflow:hidden}body,html{height:100%}body{overflow:auto}
|
||||||
|
/*# sourceMappingURL=reset.8c46b7a1.css.map */
|
2
deps/speedscope/source-code-pro.52b1676f.css
vendored
Normal file
2
deps/speedscope/source-code-pro.52b1676f.css
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@font-face{font-family:Source Code Pro;font-weight:400;font-style:normal;font-stretch:normal;src:url(SourceCodePro-Regular.ttf.f546cbe0.woff2) format("woff2")}
|
||||||
|
/*# sourceMappingURL=source-code-pro.52b1676f.css.map */
|
24
deps/speedscope/source-map.438fa06b.js
vendored
Normal file
24
deps/speedscope/source-map.438fa06b.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
deps/speedscope/speedscope-GHPHNKXC.css
vendored
2
deps/speedscope/speedscope-GHPHNKXC.css
vendored
@ -1,2 +0,0 @@
|
|||||||
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:"";content:none}table{border-collapse:collapse;border-spacing:0}html{overflow:hidden;height:100%}body{height:100%;overflow:auto}@font-face{font-family:Source Code Pro;font-weight:400;font-style:normal;font-stretch:normal;src:url("./SourceCodePro-Regular.ttf-ILST5JV6.woff2") format("woff2")}
|
|
||||||
/*# sourceMappingURL=speedscope-GHPHNKXC.css.map */
|
|
189
deps/speedscope/speedscope-VHEG2FVF.js
vendored
189
deps/speedscope/speedscope-VHEG2FVF.js
vendored
File diff suppressed because one or more lines are too long
193
deps/speedscope/speedscope.6f107512.js
vendored
Normal file
193
deps/speedscope/speedscope.6f107512.js
vendored
Normal file
File diff suppressed because one or more lines are too long
620
deps/sqlite/shell.c
vendored
620
deps/sqlite/shell.c
vendored
File diff suppressed because it is too large
Load Diff
5481
deps/sqlite/sqlite3.c
vendored
5481
deps/sqlite/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
200
deps/sqlite/sqlite3.h
vendored
200
deps/sqlite/sqlite3.h
vendored
@ -146,9 +146,9 @@ extern "C" {
|
|||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.49.1"
|
#define SQLITE_VERSION "3.47.2"
|
||||||
#define SQLITE_VERSION_NUMBER 3049001
|
#define SQLITE_VERSION_NUMBER 3047002
|
||||||
#define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70"
|
#define SQLITE_SOURCE_ID "2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c14685b6c"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
@ -1100,11 +1100,6 @@ struct sqlite3_io_methods {
|
|||||||
** pointed to by the pArg argument. This capability is used during testing
|
** pointed to by the pArg argument. This capability is used during testing
|
||||||
** and only needs to be supported when SQLITE_TEST is defined.
|
** and only needs to be supported when SQLITE_TEST is defined.
|
||||||
**
|
**
|
||||||
** <li>[[SQLITE_FCNTL_NULL_IO]]
|
|
||||||
** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
|
|
||||||
** or file handle for the [sqlite3_file] object such that it will no longer
|
|
||||||
** read or write to the database file.
|
|
||||||
**
|
|
||||||
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
|
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
|
||||||
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
|
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
|
||||||
** be advantageous to block on the next WAL lock if the lock is not immediately
|
** be advantageous to block on the next WAL lock if the lock is not immediately
|
||||||
@ -1258,7 +1253,6 @@ struct sqlite3_io_methods {
|
|||||||
#define SQLITE_FCNTL_EXTERNAL_READER 40
|
#define SQLITE_FCNTL_EXTERNAL_READER 40
|
||||||
#define SQLITE_FCNTL_CKSM_FILE 41
|
#define SQLITE_FCNTL_CKSM_FILE 41
|
||||||
#define SQLITE_FCNTL_RESET_CACHE 42
|
#define SQLITE_FCNTL_RESET_CACHE 42
|
||||||
#define SQLITE_FCNTL_NULL_IO 43
|
|
||||||
|
|
||||||
/* deprecated names */
|
/* deprecated names */
|
||||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||||
@ -2211,15 +2205,7 @@ struct sqlite3_mem_methods {
|
|||||||
** CAPI3REF: Database Connection Configuration Options
|
** CAPI3REF: Database Connection Configuration Options
|
||||||
**
|
**
|
||||||
** These constants are the available integer configuration options that
|
** These constants are the available integer configuration options that
|
||||||
** can be passed as the second parameter to the [sqlite3_db_config()] interface.
|
** can be passed as the second argument to the [sqlite3_db_config()] interface.
|
||||||
**
|
|
||||||
** The [sqlite3_db_config()] interface is a var-args functions. It takes a
|
|
||||||
** variable number of parameters, though always at least two. The number of
|
|
||||||
** parameters passed into sqlite3_db_config() depends on which of these
|
|
||||||
** constants is given as the second parameter. This documentation page
|
|
||||||
** refers to parameters beyond the second as "arguments". Thus, when this
|
|
||||||
** page says "the N-th argument" it means "the N-th parameter past the
|
|
||||||
** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()".
|
|
||||||
**
|
**
|
||||||
** New configuration options may be added in future releases of SQLite.
|
** New configuration options may be added in future releases of SQLite.
|
||||||
** Existing configuration options might be discontinued. Applications
|
** Existing configuration options might be discontinued. Applications
|
||||||
@ -2231,14 +2217,8 @@ struct sqlite3_mem_methods {
|
|||||||
** <dl>
|
** <dl>
|
||||||
** [[SQLITE_DBCONFIG_LOOKASIDE]]
|
** [[SQLITE_DBCONFIG_LOOKASIDE]]
|
||||||
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
|
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
|
||||||
** <dd> The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the
|
** <dd> ^This option takes three additional arguments that determine the
|
||||||
** configuration of the lookaside memory allocator within a database
|
** [lookaside memory allocator] configuration for the [database connection].
|
||||||
** connection.
|
|
||||||
** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are <i>not</i>
|
|
||||||
** in the [DBCONFIG arguments|usual format].
|
|
||||||
** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two,
|
|
||||||
** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE
|
|
||||||
** should have a total of five parameters.
|
|
||||||
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
|
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
|
||||||
** pointer to a memory buffer to use for lookaside memory.
|
** pointer to a memory buffer to use for lookaside memory.
|
||||||
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
|
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
|
||||||
@ -2261,8 +2241,7 @@ struct sqlite3_mem_methods {
|
|||||||
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
|
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
|
||||||
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
|
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
|
||||||
** <dd> ^This option is used to enable or disable the enforcement of
|
** <dd> ^This option is used to enable or disable the enforcement of
|
||||||
** [foreign key constraints]. This is the same setting that is
|
** [foreign key constraints]. There should be two additional arguments.
|
||||||
** enabled or disabled by the [PRAGMA foreign_keys] statement.
|
|
||||||
** The first argument is an integer which is 0 to disable FK enforcement,
|
** The first argument is an integer which is 0 to disable FK enforcement,
|
||||||
** positive to enable FK enforcement or negative to leave FK enforcement
|
** positive to enable FK enforcement or negative to leave FK enforcement
|
||||||
** unchanged. The second parameter is a pointer to an integer into which
|
** unchanged. The second parameter is a pointer to an integer into which
|
||||||
@ -2284,13 +2263,13 @@ struct sqlite3_mem_methods {
|
|||||||
** <p>Originally this option disabled all triggers. ^(However, since
|
** <p>Originally this option disabled all triggers. ^(However, since
|
||||||
** SQLite version 3.35.0, TEMP triggers are still allowed even if
|
** SQLite version 3.35.0, TEMP triggers are still allowed even if
|
||||||
** this option is off. So, in other words, this option now only disables
|
** this option is off. So, in other words, this option now only disables
|
||||||
** triggers in the main database schema or in the schemas of [ATTACH]-ed
|
** triggers in the main database schema or in the schemas of ATTACH-ed
|
||||||
** databases.)^ </dd>
|
** databases.)^ </dd>
|
||||||
**
|
**
|
||||||
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
||||||
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
||||||
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
||||||
** There must be two additional arguments.
|
** There should be two additional arguments.
|
||||||
** The first argument is an integer which is 0 to disable views,
|
** The first argument is an integer which is 0 to disable views,
|
||||||
** positive to enable views or negative to leave the setting unchanged.
|
** positive to enable views or negative to leave the setting unchanged.
|
||||||
** The second parameter is a pointer to an integer into which
|
** The second parameter is a pointer to an integer into which
|
||||||
@ -2309,7 +2288,7 @@ struct sqlite3_mem_methods {
|
|||||||
** <dd> ^This option is used to enable or disable the
|
** <dd> ^This option is used to enable or disable the
|
||||||
** [fts3_tokenizer()] function which is part of the
|
** [fts3_tokenizer()] function which is part of the
|
||||||
** [FTS3] full-text search engine extension.
|
** [FTS3] full-text search engine extension.
|
||||||
** There must be two additional arguments.
|
** There should be two additional arguments.
|
||||||
** The first argument is an integer which is 0 to disable fts3_tokenizer() or
|
** The first argument is an integer which is 0 to disable fts3_tokenizer() or
|
||||||
** positive to enable fts3_tokenizer() or negative to leave the setting
|
** positive to enable fts3_tokenizer() or negative to leave the setting
|
||||||
** unchanged.
|
** unchanged.
|
||||||
@ -2324,7 +2303,7 @@ struct sqlite3_mem_methods {
|
|||||||
** interface independently of the [load_extension()] SQL function.
|
** interface independently of the [load_extension()] SQL function.
|
||||||
** The [sqlite3_enable_load_extension()] API enables or disables both the
|
** The [sqlite3_enable_load_extension()] API enables or disables both the
|
||||||
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
|
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||||
** There must be two additional arguments.
|
** There should be two additional arguments.
|
||||||
** When the first argument to this interface is 1, then only the C-API is
|
** When the first argument to this interface is 1, then only the C-API is
|
||||||
** enabled and the SQL function remains disabled. If the first argument to
|
** enabled and the SQL function remains disabled. If the first argument to
|
||||||
** this interface is 0, then both the C-API and the SQL function are disabled.
|
** this interface is 0, then both the C-API and the SQL function are disabled.
|
||||||
@ -2338,30 +2317,23 @@ struct sqlite3_mem_methods {
|
|||||||
**
|
**
|
||||||
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||||
** <dd> ^This option is used to change the name of the "main" database
|
** <dd> ^This option is used to change the name of the "main" database
|
||||||
** schema. This option does not follow the
|
** schema. ^The sole argument is a pointer to a constant UTF8 string
|
||||||
** [DBCONFIG arguments|usual SQLITE_DBCONFIG argument format].
|
** which will become the new schema name in place of "main". ^SQLite
|
||||||
** This option takes exactly one additional argument so that the
|
** does not make a copy of the new main schema name string, so the application
|
||||||
** [sqlite3_db_config()] call has a total of three parameters. The
|
** must ensure that the argument passed into this DBCONFIG option is unchanged
|
||||||
** extra argument must be a pointer to a constant UTF8 string which
|
** until after the database connection closes.
|
||||||
** will become the new schema name in place of "main". ^SQLite does
|
|
||||||
** not make a copy of the new main schema name string, so the application
|
|
||||||
** must ensure that the argument passed into SQLITE_DBCONFIG MAINDBNAME
|
|
||||||
** is unchanged until after the database connection closes.
|
|
||||||
** </dd>
|
** </dd>
|
||||||
**
|
**
|
||||||
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
|
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
|
||||||
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
|
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
|
||||||
** <dd> Usually, when a database in [WAL mode] is closed or detached from a
|
** <dd> Usually, when a database in wal mode is closed or detached from a
|
||||||
** database handle, SQLite checks if if there are other connections to the
|
** database handle, SQLite checks if this will mean that there are now no
|
||||||
** same database, and if there are no other database connection (if the
|
** connections at all to the database. If so, it performs a checkpoint
|
||||||
** connection being closed is the last open connection to the database),
|
** operation before closing the connection. This option may be used to
|
||||||
** then SQLite performs a [checkpoint] before closing the connection and
|
** override this behavior. The first parameter passed to this operation
|
||||||
** deletes the WAL file. The SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE option can
|
** is an integer - positive to disable checkpoints-on-close, or zero (the
|
||||||
** be used to override that behavior. The first argument passed to this
|
** default) to enable them, and negative to leave the setting unchanged.
|
||||||
** operation (the third parameter to [sqlite3_db_config()]) is an integer
|
** The second parameter is a pointer to an integer
|
||||||
** which is positive to disable checkpoints-on-close, or zero (the default)
|
|
||||||
** to enable them, and negative to leave the setting unchanged.
|
|
||||||
** The second argument (the fourth parameter) is a pointer to an integer
|
|
||||||
** into which is written 0 or 1 to indicate whether checkpoints-on-close
|
** into which is written 0 or 1 to indicate whether checkpoints-on-close
|
||||||
** have been disabled - 0 if they are not disabled, 1 if they are.
|
** have been disabled - 0 if they are not disabled, 1 if they are.
|
||||||
** </dd>
|
** </dd>
|
||||||
@ -2522,7 +2494,7 @@ struct sqlite3_mem_methods {
|
|||||||
** statistics. For statistics to be collected, the flag must be set on
|
** statistics. For statistics to be collected, the flag must be set on
|
||||||
** the database handle both when the SQL statement is prepared and when it
|
** the database handle both when the SQL statement is prepared and when it
|
||||||
** is stepped. The flag is set (collection of statistics is enabled)
|
** is stepped. The flag is set (collection of statistics is enabled)
|
||||||
** by default. <p>This option takes two arguments: an integer and a pointer to
|
** by default. This option takes two arguments: an integer and a pointer to
|
||||||
** an integer.. The first argument is 1, 0, or -1 to enable, disable, or
|
** an integer.. The first argument is 1, 0, or -1 to enable, disable, or
|
||||||
** leave unchanged the statement scanstatus option. If the second argument
|
** leave unchanged the statement scanstatus option. If the second argument
|
||||||
** is not NULL, then the value of the statement scanstatus setting after
|
** is not NULL, then the value of the statement scanstatus setting after
|
||||||
@ -2536,7 +2508,7 @@ struct sqlite3_mem_methods {
|
|||||||
** in which tables and indexes are scanned so that the scans start at the end
|
** in which tables and indexes are scanned so that the scans start at the end
|
||||||
** and work toward the beginning rather than starting at the beginning and
|
** and work toward the beginning rather than starting at the beginning and
|
||||||
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
|
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
|
||||||
** same as setting [PRAGMA reverse_unordered_selects]. <p>This option takes
|
** same as setting [PRAGMA reverse_unordered_selects]. This option takes
|
||||||
** two arguments which are an integer and a pointer to an integer. The first
|
** two arguments which are an integer and a pointer to an integer. The first
|
||||||
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
|
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
|
||||||
** reverse scan order flag, respectively. If the second argument is not NULL,
|
** reverse scan order flag, respectively. If the second argument is not NULL,
|
||||||
@ -2545,76 +2517,7 @@ struct sqlite3_mem_methods {
|
|||||||
** first argument.
|
** first argument.
|
||||||
** </dd>
|
** </dd>
|
||||||
**
|
**
|
||||||
** [[SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]]
|
|
||||||
** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE</dt>
|
|
||||||
** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE option enables or disables
|
|
||||||
** the ability of the [ATTACH DATABASE] SQL command to create a new database
|
|
||||||
** file if the database filed named in the ATTACH command does not already
|
|
||||||
** exist. This ability of ATTACH to create a new database is enabled by
|
|
||||||
** default. Applications can disable or reenable the ability for ATTACH to
|
|
||||||
** create new database files using this DBCONFIG option.<p>
|
|
||||||
** This option takes two arguments which are an integer and a pointer
|
|
||||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
|
||||||
** leave unchanged the attach-create flag, respectively. If the second
|
|
||||||
** argument is not NULL, then 0 or 1 is written into the integer that the
|
|
||||||
** second argument points to depending on if the attach-create flag is set
|
|
||||||
** after processing the first argument.
|
|
||||||
** </dd>
|
|
||||||
**
|
|
||||||
** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]]
|
|
||||||
** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt>
|
|
||||||
** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the
|
|
||||||
** ability of the [ATTACH DATABASE] SQL command to open a database for writing.
|
|
||||||
** This capability is enabled by default. Applications can disable or
|
|
||||||
** reenable this capability using the current DBCONFIG option. If the
|
|
||||||
** the this capability is disabled, the [ATTACH] command will still work,
|
|
||||||
** but the database will be opened read-only. If this option is disabled,
|
|
||||||
** then the ability to create a new database using [ATTACH] is also disabled,
|
|
||||||
** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]
|
|
||||||
** option.<p>
|
|
||||||
** This option takes two arguments which are an integer and a pointer
|
|
||||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
|
||||||
** leave unchanged the ability to ATTACH another database for writing,
|
|
||||||
** respectively. If the second argument is not NULL, then 0 or 1 is written
|
|
||||||
** into the integer to which the second argument points, depending on whether
|
|
||||||
** the ability to ATTACH a read/write database is enabled or disabled
|
|
||||||
** after processing the first argument.
|
|
||||||
** </dd>
|
|
||||||
**
|
|
||||||
** [[SQLITE_DBCONFIG_ENABLE_COMMENTS]]
|
|
||||||
** <dt>SQLITE_DBCONFIG_ENABLE_COMMENTS</dt>
|
|
||||||
** <dd>The SQLITE_DBCONFIG_ENABLE_COMMENTS option enables or disables the
|
|
||||||
** ability to include comments in SQL text. Comments are enabled by default.
|
|
||||||
** An application can disable or reenable comments in SQL text using this
|
|
||||||
** DBCONFIG option.<p>
|
|
||||||
** This option takes two arguments which are an integer and a pointer
|
|
||||||
** to an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
|
||||||
** leave unchanged the ability to use comments in SQL text,
|
|
||||||
** respectively. If the second argument is not NULL, then 0 or 1 is written
|
|
||||||
** into the integer that the second argument points to depending on if
|
|
||||||
** comments are allowed in SQL text after processing the first argument.
|
|
||||||
** </dd>
|
|
||||||
**
|
|
||||||
** </dl>
|
** </dl>
|
||||||
**
|
|
||||||
** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3>
|
|
||||||
**
|
|
||||||
** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the
|
|
||||||
** overall call to [sqlite3_db_config()] has a total of four parameters.
|
|
||||||
** The first argument (the third parameter to sqlite3_db_config()) is a integer.
|
|
||||||
** The second argument is a pointer to an integer. If the first argument is 1,
|
|
||||||
** then the option becomes enabled. If the first integer argument is 0, then the
|
|
||||||
** option is disabled. If the first argument is -1, then the option setting
|
|
||||||
** is unchanged. The second argument, the pointer to an integer, may be NULL.
|
|
||||||
** If the second argument is not NULL, then a value of 0 or 1 is written into
|
|
||||||
** the integer to which the second argument points, depending on whether the
|
|
||||||
** setting is disabled or enabled after applying any changes specified by
|
|
||||||
** the first argument.
|
|
||||||
**
|
|
||||||
** <p>While most SQLITE_DBCONFIG options use the argument format
|
|
||||||
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME]
|
|
||||||
** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the
|
|
||||||
** documentation of those exceptional options for details.
|
|
||||||
*/
|
*/
|
||||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||||
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
||||||
@ -2636,10 +2539,7 @@ struct sqlite3_mem_methods {
|
|||||||
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
|
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
|
||||||
#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */
|
#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */
|
||||||
#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */
|
#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */
|
||||||
#define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */
|
#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */
|
||||||
#define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */
|
|
||||||
#define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */
|
|
||||||
#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||||
@ -2731,14 +2631,10 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
|
|||||||
** deleted by the most recently completed INSERT, UPDATE or DELETE
|
** deleted by the most recently completed INSERT, UPDATE or DELETE
|
||||||
** statement on the database connection specified by the only parameter.
|
** statement on the database connection specified by the only parameter.
|
||||||
** The two functions are identical except for the type of the return value
|
** The two functions are identical except for the type of the return value
|
||||||
** and that if the number of rows modified by the most recent INSERT, UPDATE,
|
** and that if the number of rows modified by the most recent INSERT, UPDATE
|
||||||
** or DELETE is greater than the maximum value supported by type "int", then
|
** or DELETE is greater than the maximum value supported by type "int", then
|
||||||
** the return value of sqlite3_changes() is undefined. ^Executing any other
|
** the return value of sqlite3_changes() is undefined. ^Executing any other
|
||||||
** type of SQL statement does not modify the value returned by these functions.
|
** type of SQL statement does not modify the value returned by these functions.
|
||||||
** For the purposes of this interface, a CREATE TABLE AS SELECT statement
|
|
||||||
** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
|
|
||||||
** added to the new table by the CREATE TABLE AS SELECT statement are not
|
|
||||||
** counted.
|
|
||||||
**
|
**
|
||||||
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
|
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
|
||||||
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
|
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
|
||||||
@ -4298,22 +4194,11 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
|
|||||||
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
|
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
|
||||||
** to return an error (error code SQLITE_ERROR) if the statement uses
|
** to return an error (error code SQLITE_ERROR) if the statement uses
|
||||||
** any virtual tables.
|
** any virtual tables.
|
||||||
**
|
|
||||||
** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt>
|
|
||||||
** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler
|
|
||||||
** errors from being sent to the error log defined by
|
|
||||||
** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test
|
|
||||||
** compiles to see if some SQL syntax is well-formed, without generating
|
|
||||||
** messages on the global error log when it is not. If the test compile
|
|
||||||
** fails, the sqlite3_prepare_v3() call returns the same error indications
|
|
||||||
** with or without this flag; it just omits the call to [sqlite3_log()] that
|
|
||||||
** logs the error.
|
|
||||||
** </dl>
|
** </dl>
|
||||||
*/
|
*/
|
||||||
#define SQLITE_PREPARE_PERSISTENT 0x01
|
#define SQLITE_PREPARE_PERSISTENT 0x01
|
||||||
#define SQLITE_PREPARE_NORMALIZE 0x02
|
#define SQLITE_PREPARE_NORMALIZE 0x02
|
||||||
#define SQLITE_PREPARE_NO_VTAB 0x04
|
#define SQLITE_PREPARE_NO_VTAB 0x04
|
||||||
#define SQLITE_PREPARE_DONT_LOG 0x10
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Compiling An SQL Statement
|
** CAPI3REF: Compiling An SQL Statement
|
||||||
@ -10842,9 +10727,8 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c
|
|||||||
/*
|
/*
|
||||||
** CAPI3REF: Serialize a database
|
** CAPI3REF: Serialize a database
|
||||||
**
|
**
|
||||||
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to
|
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
|
||||||
** memory that is a serialization of the S database on
|
** that is a serialization of the S database on [database connection] D.
|
||||||
** [database connection] D. If S is a NULL pointer, the main database is used.
|
|
||||||
** If P is not a NULL pointer, then the size of the database in bytes
|
** If P is not a NULL pointer, then the size of the database in bytes
|
||||||
** is written into *P.
|
** is written into *P.
|
||||||
**
|
**
|
||||||
@ -11005,7 +10889,7 @@ SQLITE_API int sqlite3_deserialize(
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* End of the 'extern "C"' block */
|
} /* End of the 'extern "C"' block */
|
||||||
#endif
|
#endif
|
||||||
/* #endif for SQLITE3_H will be added by mksqlite3.tcl */
|
#endif /* SQLITE3_H */
|
||||||
|
|
||||||
/******** Begin file sqlite3rtree.h *********/
|
/******** Begin file sqlite3rtree.h *********/
|
||||||
/*
|
/*
|
||||||
@ -13256,29 +13140,14 @@ struct Fts5PhraseIter {
|
|||||||
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
|
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
|
||||||
** output variable (*ppToken) is set to point to a buffer containing the
|
** output variable (*ppToken) is set to point to a buffer containing the
|
||||||
** matching document token, and (*pnToken) to the size of that buffer in
|
** matching document token, and (*pnToken) to the size of that buffer in
|
||||||
** bytes.
|
** bytes. This API is not available if the specified token matches a
|
||||||
|
** prefix query term. In that case both output variables are always set
|
||||||
|
** to 0.
|
||||||
**
|
**
|
||||||
** The output text is not a copy of the document text that was tokenized.
|
** The output text is not a copy of the document text that was tokenized.
|
||||||
** It is the output of the tokenizer module. For tokendata=1 tables, this
|
** It is the output of the tokenizer module. For tokendata=1 tables, this
|
||||||
** includes any embedded 0x00 and trailing data.
|
** includes any embedded 0x00 and trailing data.
|
||||||
**
|
**
|
||||||
** This API may be slow in some cases if the token identified by parameters
|
|
||||||
** iIdx and iToken matched a prefix token in the query. In most cases, the
|
|
||||||
** first call to this API for each prefix token in the query is forced
|
|
||||||
** to scan the portion of the full-text index that matches the prefix
|
|
||||||
** token to collect the extra data required by this API. If the prefix
|
|
||||||
** token matches a large number of token instances in the document set,
|
|
||||||
** this may be a performance problem.
|
|
||||||
**
|
|
||||||
** If the user knows in advance that a query may use this API for a
|
|
||||||
** prefix token, FTS5 may be configured to collect all required data as part
|
|
||||||
** of the initial querying of the full-text index, avoiding the second scan
|
|
||||||
** entirely. This also causes prefix queries that do not use this API to
|
|
||||||
** run more slowly and use more memory. FTS5 may be configured in this way
|
|
||||||
** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
|
|
||||||
** option, or on a per-query basis using the
|
|
||||||
** [fts5_insttoken | fts5_insttoken()] user function.
|
|
||||||
**
|
|
||||||
** This API can be quite slow if used with an FTS5 table created with the
|
** This API can be quite slow if used with an FTS5 table created with the
|
||||||
** "detail=none" or "detail=column" option.
|
** "detail=none" or "detail=column" option.
|
||||||
**
|
**
|
||||||
@ -13712,4 +13581,3 @@ struct fts5_api {
|
|||||||
#endif /* _FTS5_H */
|
#endif /* _FTS5_H */
|
||||||
|
|
||||||
/******** End of fts5.h *********/
|
/******** End of fts5.h *********/
|
||||||
#endif /* SQLITE3_H */
|
|
||||||
|
1
deps/zsign
vendored
1
deps/zsign
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit d995d539ff16f28d985f5b2a1c62dd4eb9f029ea
|
|
1
docs
Submodule
1
docs
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a40758cc4bef5ded4d214c2acf1c95e554e20564
|
@ -1,63 +0,0 @@
|
|||||||
# App Development Cheat Sheet
|
|
||||||
|
|
||||||
Making apps for the impatient tilde friend.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- either run your own instance or use [tildefriends.net](https://www.tildefriends.net/)
|
|
||||||
- register and login
|
|
||||||
- [optional] use the `ssb` app to create yourself an SSB identity
|
|
||||||
|
|
||||||
## Development Process
|
|
||||||
|
|
||||||
1. hit the `edit` link from any app or new app URL
|
|
||||||
2. make sure the path in the text box is under your username: `/~username/app/`
|
|
||||||
3. write server-side code in `app.js`
|
|
||||||
4. click the `save` button or press the save hotkey (Alt+S or _[browser-specific modifiers]_+S)
|
|
||||||
5. see the app reload on the right side
|
|
||||||
|
|
||||||
## Output
|
|
||||||
|
|
||||||
- `app.setDocument(html)` - send HTML to the browser
|
|
||||||
- `print(...)` - send values to the browser's developer console
|
|
||||||
|
|
||||||
## Persistence
|
|
||||||
|
|
||||||
- `app.localStorageGet(key)` -> `value`
|
|
||||||
- `app.localStorageSet(key, value)`
|
|
||||||
- `database()`, `shared_database(key)`, `my_shared_database(package, key)`
|
|
||||||
- `db.get(key)` -> `value`
|
|
||||||
- `db.set(key, value)`
|
|
||||||
- `db.exchange(key, expected, value)` -> `exchanged`
|
|
||||||
- `db.remove(key)`
|
|
||||||
- `db.getAll()` -> `[key1, ...]`
|
|
||||||
- `db.getLike(pattern)` -> `{key1: value1, ...}`
|
|
||||||
|
|
||||||
## SSB
|
|
||||||
|
|
||||||
- `ssb.createIdentity()` -> `id`
|
|
||||||
- `ssb.getIdentities()` -> `[id1, ...]`
|
|
||||||
- `ssb.appendMessageWithIdentity(id, content)` -> `message_id`
|
|
||||||
- `ssb.blobStore(blob)` -> `blob_id`
|
|
||||||
- `ssb.blobGet(id)` -> `blob`
|
|
||||||
- `ssb.sqlAsync(query, args, row_callback)`
|
|
||||||
|
|
||||||
## TF-RPC
|
|
||||||
|
|
||||||
Stock helper code for calling functions across the web server and browser boundary.
|
|
||||||
|
|
||||||
- on the server: `import * as tfrpc from "/tfrpc.js";`
|
|
||||||
- in the browser: `import * as tfrpc from "/static/tfrpc.js";`
|
|
||||||
- either direction:
|
|
||||||
- register a function: `tfrpc.register(function my_function() {});`
|
|
||||||
- call a remote function: `let promise = tfrpc.rpc.my_function();`
|
|
||||||
|
|
||||||
## Share
|
|
||||||
|
|
||||||
- give out web links: [https://www.tildefriends.net/~cory/screwble/](https://www.tildefriends.net/~cory/screwble/)
|
|
||||||
- use the `Attach App` button when composing a post in [the SSB app](https://www.tildefriends.net/~core/ssb/)
|
|
||||||
|
|
||||||
## More Docs
|
|
||||||
|
|
||||||
- [api reference](https://www.tildefriends.net/~cory/api/)
|
|
||||||
- [source code](https://dev.tildefriends.net/cory/tildefriends/releases)
|
|
@ -1,166 +0,0 @@
|
|||||||
# App Development Guide
|
|
||||||
|
|
||||||
A Tilde Friends application starts with code that runs on a Tilde Friends server, possibly far away from where you wrote it, in a little JavaScript environment, in its own restricted process, with the only access to the outside world being the ability to send messages to the server. This document gives some recipes showing how that can be used to build a functional user-facing application in light of the unique constraints present.
|
|
||||||
|
|
||||||
## Example 1: Hello, world!
|
|
||||||
|
|
||||||
Of course we must start with a classic.
|
|
||||||
|
|
||||||
### app.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
app.setDocument('<h1 style="color: #fff">Hello, world!</h1>');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
<h1 style="color: #fff">Hello, world!</h1>
|
|
||||||
|
|
||||||
### Explanation
|
|
||||||
|
|
||||||
At a glance, this might seem mundane, but for it to work:
|
|
||||||
|
|
||||||
- the server starts a real process for your app and loads your code into it
|
|
||||||
- your code runs
|
|
||||||
- `app.setDocument()` sends a message back to the server
|
|
||||||
- the server interprets the message and redirects it to the browser
|
|
||||||
- `core/client.js` in the browser receives the message and puts your HTML into an iframe
|
|
||||||
- your HTML is presented by the browser in an iframe sandbox
|
|
||||||
|
|
||||||
But you don't have to think about all that. Call a function, and you see the result.
|
|
||||||
|
|
||||||
## Example 2: Hit Counter
|
|
||||||
|
|
||||||
Let's take advantage of code running on the server and create a little hit counter using a key value store shared between all visitors.
|
|
||||||
|
|
||||||
### app.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
async function main() {
|
|
||||||
let db = await shared_database('visitors');
|
|
||||||
let count = parseInt((await db.get('visitors')) ?? '0') + 1;
|
|
||||||
await db.set('visitors', count.toString());
|
|
||||||
await app.setDocument(`
|
|
||||||
<h1 style="color: #fff">Welcome, visitor #${count}!</h1>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
<h1 style="color: #fff">Welcome, visitor #1!</h1>
|
|
||||||
|
|
||||||
### Explanation
|
|
||||||
|
|
||||||
Just as pure browser apps have access to `localStorage`, Tilde Friends apps have access to key-value storage on the server.
|
|
||||||
|
|
||||||
The interface is a bit clunky and will likely change someday, but this example gets a database object, from which you can get and set string values by key. There are various on `shared_database` that let you store data that is private to the user or shared by different criteria.
|
|
||||||
|
|
||||||
Also, even though any browser-side code is sandboxed, it is allowed to access browser local storage by going through Tilde Friends API, because sometimes that is useful.
|
|
||||||
|
|
||||||
## Example 3: Files
|
|
||||||
|
|
||||||
Suppose you don't want to create your entire app in a single server-side file as we've done with the previous examples. There are some tools to allow you to begin to organize.
|
|
||||||
|
|
||||||
### app.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
async function main() {
|
|
||||||
let html = utf8Decode(await getFile('index.html'));
|
|
||||||
app.setDocument(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
```
|
|
||||||
|
|
||||||
### index.html
|
|
||||||
|
|
||||||
```html
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script type="module" src="script.js"></script>
|
|
||||||
</head>
|
|
||||||
<body style="color: #fff">
|
|
||||||
<h1>File Test</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
### script.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
window.addEventListener('load', function() {
|
|
||||||
document.body.appendChild(document.createTextNode('Hello, world');
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
<h1>File Test</h1><p>Hello, world!</p>
|
|
||||||
|
|
||||||
### Explanation
|
|
||||||
|
|
||||||
On the server, `utf8Decode(await getFile(fileName))` lets you load a file from your app. In the browser, your app files are made available by HTTP, so you can `<script src="my_script.js"></script>` and such to access them.
|
|
||||||
|
|
||||||
## Example 4: Remote Procedure Call
|
|
||||||
|
|
||||||
While making calls between the client and the server, it is possible to pass functions across that boundary. `tfrpc.js` is a tiny script which builds on that feature to try to hide some of the complexities.
|
|
||||||
|
|
||||||
### app.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
import * as tf from '/tfrpc.js';
|
|
||||||
|
|
||||||
function sum() {
|
|
||||||
let s = 0;
|
|
||||||
for (let x of arguments) {
|
|
||||||
s += x;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
tf.register(sum);
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
app.setDocument(utf8Decode(await getFile('index.html')));
|
|
||||||
}
|
|
||||||
main();
|
|
||||||
```
|
|
||||||
|
|
||||||
### index.html
|
|
||||||
|
|
||||||
```html
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<h1 id="result">Calculating...</h1>
|
|
||||||
</body>
|
|
||||||
<script type="module" src="script.js"></script>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
### script.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
import * as tf from '/static/tfrpc.js';
|
|
||||||
|
|
||||||
window.addEventListener('load', async function () {
|
|
||||||
document.getElementById('result').innerText = await tf.rpc.sum(1, 2, 3);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
<h1>6</h1>
|
|
||||||
|
|
||||||
### Explanation
|
|
||||||
|
|
||||||
Here the browser makes an asynchronous call to the server to do some basic math and update its DOM with the result.
|
|
||||||
|
|
||||||
With your favorite Vue/Lit/React/... library on the client-side and your favorite Tilde Friends API calls registered with tfrpc, it becomes pretty easy to start extracting interesting information from, say, SQL queries over Secure Scuttlebutt data, and generating complicated, dynamic user interface. These are the building blocks I used to make the current Tilde Friends SSB client interface.
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Tilde Friends is currently a pile of all the parts that I thought I needed to build interesting web applications, tied together by code that tries to walk the fine line between being secure enough to let us safely run code on the same device and being usable enough that you can open a tab in your browser and start building just by typing code.
|
|
||||||
|
|
||||||
I don't claim it thoroughly accomplishes either yet, but I believe it is at a stage where it is showing how promising this approach can be, and I am excited for you to take it for a spin and share.
|
|
@ -1,15 +0,0 @@
|
|||||||
# Inspiration
|
|
||||||
|
|
||||||
This is an ever-growing list of software that is similar to what Tilde Friends tries to be but as far as I can tell don't quite fit the same niche.
|
|
||||||
|
|
||||||
- Secure Scuttlebutt Clients
|
|
||||||
- [Manyverse](https://www.manyver.se/)
|
|
||||||
- [Patchwork](https://github.com/ssbc/patchwork)
|
|
||||||
- [Patchfox](https://patchfox.org/#/)
|
|
||||||
- [Habitat](https://gitlab.com/quickdudley/habitat)
|
|
||||||
- [Āhau](https://gitlab.com/ahau/ahau/)
|
|
||||||
- [erlbutt](https://github.com/cmoid/erlbutt/)
|
|
||||||
- Web Application Platforms
|
|
||||||
- [Glitch](https://glitch.com/)
|
|
||||||
- [Val Town](https://www.val.town/)
|
|
||||||
- [Clace](https://clace.io/)
|
|
@ -1,24 +0,0 @@
|
|||||||
# Release Checklist
|
|
||||||
|
|
||||||
- make sure ci is passing
|
|
||||||
- run the tests
|
|
||||||
- format + prettier
|
|
||||||
- update metadata/en-US/changelogs
|
|
||||||
- git tag v1.2.3
|
|
||||||
- git tag -f latest_release
|
|
||||||
- push
|
|
||||||
- make a release on gitea
|
|
||||||
- upload the artifacts
|
|
||||||
- upload the AppImage and zsyncmake
|
|
||||||
- upload to Google
|
|
||||||
- upload to Apple with dist-ios on macos
|
|
||||||
- nix
|
|
||||||
- june and december: update release version
|
|
||||||
- run `nix flake update`
|
|
||||||
- comment out the hash in default.nix
|
|
||||||
- update the version
|
|
||||||
- run `nix-build`
|
|
||||||
- update the hash
|
|
||||||
- bump the versions in GNUmakefile for the next release
|
|
||||||
- make
|
|
||||||
- commit
|
|
@ -1,18 +0,0 @@
|
|||||||
# Upgrading
|
|
||||||
|
|
||||||
Tilde Friends can be upgraded simply by running a new executable against an
|
|
||||||
existing database.
|
|
||||||
|
|
||||||
Tilde Friends writes all data to a `db.sqlite` file, either in
|
|
||||||
`~/.local/share/tildefriends/` or in the working directory where it is run,
|
|
||||||
depending on the platform and whether each one already exists. Run with
|
|
||||||
`tildefriends run -d DB_PATH` to specify the path to the database explicitly.
|
|
||||||
|
|
||||||
This file can be copied and moved across machines as needed like any [sqlite3
|
|
||||||
database](https://www.sqlite.org/onefile.html).
|
|
||||||
|
|
||||||
Schema changes and compatibility breaks have been rare, by design. In general,
|
|
||||||
upgrading is not expected to require any manual intervention and likely does
|
|
||||||
not involve any automatic migration, either. Downgrading is not well-supported
|
|
||||||
but will probably just work excepting rare changes that will be called out in
|
|
||||||
the changelog.
|
|
@ -1,64 +0,0 @@
|
|||||||
# Vision
|
|
||||||
|
|
||||||
Tilde Friends is a tool for making and sharing.
|
|
||||||
|
|
||||||
It is both a peer-to-peer social network client, participating in Secure
|
|
||||||
Scuttlebutt, and an environment for creating and running web applications.
|
|
||||||
|
|
||||||
## Why
|
|
||||||
|
|
||||||
This is a thing that I wanted to exist and wanted to work on. No other reason.
|
|
||||||
There is not a business model. I believe it is interesting and unique.
|
|
||||||
|
|
||||||
## Goals
|
|
||||||
|
|
||||||
1. Make it **easy and fun** to run all sorts of web applications.
|
|
||||||
|
|
||||||
2. Provide **security** that is easy to understand and protects your data.
|
|
||||||
|
|
||||||
3. Make **creating and sharing** web applications accessible to anyone with a
|
|
||||||
browser.
|
|
||||||
|
|
||||||
## Ways to Use Tilde Friends
|
|
||||||
|
|
||||||
1. **Social Network User**: This is a social network first. You are just here,
|
|
||||||
because your friends are. Or you like how we limit your message length or
|
|
||||||
short videos or whatever the trend is. If you are ambitious, you click links
|
|
||||||
and see interactive experiences (apps) that you wouldn't see elsewhere.
|
|
||||||
|
|
||||||
2. **Web Visitor**: You get links from a friend to meeting invites, polls, games,
|
|
||||||
lists, wiki pages, ..., and you interact with them as though they were
|
|
||||||
cloud-hosted by a megacorporation. They just work, and you don't think twice.
|
|
||||||
|
|
||||||
3. **Group leader**: You host or use a small public instance, installing apps for
|
|
||||||
a group of friends to use as web visitors.
|
|
||||||
|
|
||||||
4. **Developer**: You like to write code and make or improve apps for fun or to
|
|
||||||
solve problems. When you encounter a Tilde Friends app on a strange server,
|
|
||||||
you know you can trivially modify it or download it to your own instance.
|
|
||||||
|
|
||||||
## Future Goals / Endgame
|
|
||||||
|
|
||||||
1. Mobile apps. This can run on your old phone. Maybe you won't be hosting
|
|
||||||
the web interface publicly, but you can sync, install and edit apps, and
|
|
||||||
otherwise get the full experience from a tiny touch screen.
|
|
||||||
|
|
||||||
2. The universal application runtime. The web browser is the universal
|
|
||||||
platform, but even for the simplest application that you might want to host
|
|
||||||
for your friends, cloud hosting, containers, and complicated dependencies might
|
|
||||||
all enter the mix. Tilde Friends, though it is yet another thing to host,
|
|
||||||
includes everything you need out of the box to run a vast variety of interesting
|
|
||||||
apps.
|
|
||||||
|
|
||||||
Tilde Friends will be built out, gradually providing safe access to host
|
|
||||||
resources and client resources the same way web browsers extended access to
|
|
||||||
resources like GPU, persistent storage, cameras, ... over the years.
|
|
||||||
|
|
||||||
Not much effort has been put forward yet to having a robust, long-lasting API,
|
|
||||||
but since the client side longevity is already handled by web browsers, it
|
|
||||||
seems possible that the server-side API can be managed in a similar way.
|
|
||||||
|
|
||||||
3. An awesome development environment. Right now it runs JavaScript from the
|
|
||||||
first embeddable text editor I could poorly configure enough to edit code,
|
|
||||||
but it could incorporate a debugger, source control integration a la ssb-git,
|
|
||||||
merge tools, and transpiling from all sorts of different languages.
|
|
14
flake.lock
generated
14
flake.lock
generated
@ -5,11 +5,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1710146030,
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -20,16 +20,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1739758141,
|
"lastModified": 1717281328,
|
||||||
"narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=",
|
"narHash": "sha256-evZPzpf59oNcDUXxh2GHcxHkTEG4fjae2ytWP85jXRo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c618e28f70257593de75a7044438efc1c1fc0791",
|
"rev": "b3b2b28c1daa04fe2ae47c21bb76fd226eac4ca1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.11",
|
"ref": "nixos-24.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user