mirror of
https://github.com/maunium/stickerpicker.git
synced 2025-08-28 19:01:44 +02:00
Compare commits
11 Commits
master
...
398fc952b6
Author | SHA1 | Date | |
---|---|---|---|
|
398fc952b6 | ||
|
91eca68c7b | ||
|
182cafe13a | ||
|
c4588f19a7 | ||
|
2e1b333cbb | ||
|
64b7b1507f | ||
|
0897ce6c20 | ||
|
380a070e71 | ||
|
59bf7ef252 | ||
|
8c4291d266 | ||
|
cfd0b8e292 |
@@ -1,15 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 4
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.{yaml,yml,sql,py,sass}]
|
|
||||||
indent_style = space
|
|
||||||
|
|
||||||
[*.sass]
|
|
||||||
indent_size = 2
|
|
@@ -1,13 +0,0 @@
|
|||||||
variables:
|
|
||||||
GOTOOLCHAIN: local
|
|
||||||
|
|
||||||
build giphy proxy docker:
|
|
||||||
image: docker:stable
|
|
||||||
stage: build
|
|
||||||
before_script:
|
|
||||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
|
||||||
script:
|
|
||||||
- docker build -t $CI_REGISTRY_IMAGE/giphyproxy:latest giphyproxy
|
|
||||||
- docker push $CI_REGISTRY_IMAGE/giphyproxy:latest
|
|
||||||
only:
|
|
||||||
- master
|
|
@@ -1,16 +0,0 @@
|
|||||||
FROM golang:1-alpine AS builder
|
|
||||||
|
|
||||||
RUN apk add --no-cache ca-certificates
|
|
||||||
WORKDIR /build/giphyproxy
|
|
||||||
COPY . /build/giphyproxy
|
|
||||||
ENV CGO_ENABLED=0
|
|
||||||
RUN go build -o /usr/bin/giphyproxy
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
|
|
||||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
||||||
COPY --from=builder /usr/bin/giphyproxy /usr/bin/giphyproxy
|
|
||||||
|
|
||||||
VOLUME /data
|
|
||||||
WORKDIR /data
|
|
||||||
CMD ["/usr/bin/giphyproxy"]
|
|
@@ -1,21 +0,0 @@
|
|||||||
# The server name to use for the custom mxc:// URIs.
|
|
||||||
# This server name will effectively be a real Matrix server, it just won't implement anything other than media.
|
|
||||||
# You must either set up .well-known delegation from this domain to this program, or proxy the domain directly to this program.
|
|
||||||
server_name: giphy.example.com
|
|
||||||
# Optionally a custom .well-known response. This defaults to `server_name:443` if empty.
|
|
||||||
well_known_response:
|
|
||||||
# Matrix server signing key to make the federation tester pass, same format as synapse's .signing.key file.
|
|
||||||
# You can generate one using `giphyproxy -generate-key`.
|
|
||||||
server_key: CHANGE ME
|
|
||||||
# Should federation authentication be enforced?
|
|
||||||
# If true, requests to the /_matrix/federation/v1/media/download/... endpoint
|
|
||||||
# will check the Authorization: X-Matrix header before redirecting.
|
|
||||||
federation_auth: false
|
|
||||||
|
|
||||||
# Hostname where the proxy should listen on
|
|
||||||
hostname: 0.0.0.0
|
|
||||||
# Port where the proxy should listen on
|
|
||||||
port: 8008
|
|
||||||
|
|
||||||
# Redirect destination. This can be changed to serve a different format.
|
|
||||||
destination: https://i.giphy.com/%s.webp
|
|
@@ -1,28 +0,0 @@
|
|||||||
module go.mau.fi/stickerpicker/giphyproxy
|
|
||||||
|
|
||||||
go 1.23.0
|
|
||||||
|
|
||||||
toolchain go1.24.4
|
|
||||||
|
|
||||||
require (
|
|
||||||
go.mau.fi/util v0.8.8
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
|
||||||
maunium.net/go/mautrix v0.24.2-0.20250629161127-7a7d7f70ef92
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
||||||
github.com/rs/zerolog v1.34.0 // indirect
|
|
||||||
github.com/tidwall/gjson v1.18.0 // indirect
|
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
|
||||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect
|
|
||||||
golang.org/x/net v0.41.0 // indirect
|
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
|
||||||
golang.org/x/text v0.26.0 // indirect
|
|
||||||
)
|
|
@@ -1,54 +0,0 @@
|
|||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
|
||||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
|
||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
|
||||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
|
||||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
|
||||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
|
||||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
|
||||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
|
||||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
|
||||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
|
||||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
|
||||||
go.mau.fi/util v0.8.8 h1:OnuEEc/sIJFhnq4kFggiImUpcmnmL/xpvQMRu5Fiy5c=
|
|
||||||
go.mau.fi/util v0.8.8/go.mod h1:Y/kS3loxTEhy8Vill513EtPXr+CRDdae+Xj2BXXMy/c=
|
|
||||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
|
||||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=
|
|
||||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
|
||||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
|
||||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
|
||||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
maunium.net/go/mautrix v0.24.2-0.20250629161127-7a7d7f70ef92 h1:j/QuGIVm5/KPlxMgbViphre7shSwnI7LIjNeiLDSnL4=
|
|
||||||
maunium.net/go/mautrix v0.24.2-0.20250629161127-7a7d7f70ef92/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI=
|
|
@@ -1,76 +0,0 @@
|
|||||||
// maunium-stickerpicker - A fast and simple Matrix sticker picker widget.
|
|
||||||
// Copyright (C) 2024 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.mau.fi/util/exerrors"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"maunium.net/go/mautrix/federation"
|
|
||||||
"maunium.net/go/mautrix/mediaproxy"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
mediaproxy.BasicConfig `yaml:",inline"`
|
|
||||||
mediaproxy.ServerConfig `yaml:",inline"`
|
|
||||||
Destination string `yaml:"destination"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var configPath = flag.String("config", "config.yaml", "config file path")
|
|
||||||
var generateServerKey = flag.Bool("generate-key", false, "generate a new server key and exit")
|
|
||||||
|
|
||||||
var giphyIDRegex = regexp.MustCompile(`^[a-zA-Z0-9-_]+$`)
|
|
||||||
var destination = "https://i.giphy.com/%s.webp"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
if *generateServerKey {
|
|
||||||
fmt.Println(federation.GenerateSigningKey().SynapseString())
|
|
||||||
} else {
|
|
||||||
cfgFile := exerrors.Must(os.ReadFile(*configPath))
|
|
||||||
var cfg Config
|
|
||||||
exerrors.PanicIfNotNil(yaml.Unmarshal(cfgFile, &cfg))
|
|
||||||
mp := exerrors.Must(mediaproxy.NewFromConfig(cfg.BasicConfig, getMedia))
|
|
||||||
mp.KeyServer.Version.Name = "mautrix-go + maunium-stickerpicker giphy proxy"
|
|
||||||
if cfg.Destination != "" {
|
|
||||||
destination = cfg.Destination
|
|
||||||
}
|
|
||||||
exerrors.PanicIfNotNil(mp.Listen(cfg.ServerConfig))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMedia(_ context.Context, id string, _ map[string]string) (response mediaproxy.GetMediaResponse, err error) {
|
|
||||||
// This is not related to giphy, but random cats are always fun
|
|
||||||
if id == "cat" {
|
|
||||||
return &mediaproxy.GetMediaResponseURL{
|
|
||||||
URL: "https://cataas.com/cat",
|
|
||||||
ExpiresAt: time.Now(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if !giphyIDRegex.MatchString(id) {
|
|
||||||
return nil, mediaproxy.ErrInvalidMediaIDSyntax
|
|
||||||
}
|
|
||||||
return &mediaproxy.GetMediaResponseURL{
|
|
||||||
URL: fmt.Sprintf(destination, id),
|
|
||||||
}, nil
|
|
||||||
}
|
|
1
setup.py
1
setup.py
@@ -50,6 +50,5 @@ setuptools.setup(
|
|||||||
entry_points={"console_scripts": [
|
entry_points={"console_scripts": [
|
||||||
"sticker-import=sticker.stickerimport:cmd",
|
"sticker-import=sticker.stickerimport:cmd",
|
||||||
"sticker-pack=sticker.pack:cmd",
|
"sticker-pack=sticker.pack:cmd",
|
||||||
"sticker-download-thumbnails=sticker.download_thumbnails:cmd",
|
|
||||||
]},
|
]},
|
||||||
)
|
)
|
||||||
|
@@ -1,58 +0,0 @@
|
|||||||
# maunium-stickerpicker - A fast and simple Matrix sticker picker widget.
|
|
||||||
# Copyright (C) 2025 Tulir Asokan
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict
|
|
||||||
import argparse
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
|
|
||||||
from aiohttp import ClientSession
|
|
||||||
from yarl import URL
|
|
||||||
|
|
||||||
from .lib import matrix, util
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("--config",
|
|
||||||
help="Path to JSON file with Matrix homeserver and access_token",
|
|
||||||
type=str, default="config.json", metavar="file")
|
|
||||||
parser.add_argument("path", help="Path to the sticker pack JSON file", type=str)
|
|
||||||
|
|
||||||
|
|
||||||
async def main(args: argparse.Namespace) -> None:
|
|
||||||
await matrix.load_config(args.config)
|
|
||||||
with util.open_utf8(args.path) as pack_file:
|
|
||||||
pack = json.load(pack_file)
|
|
||||||
print(f"Loaded existing pack meta from {args.path}")
|
|
||||||
|
|
||||||
stickers_data: Dict[str, bytes] = {}
|
|
||||||
async with ClientSession() as sess:
|
|
||||||
for sticker in pack["stickers"]:
|
|
||||||
dl_url = URL(matrix.homeserver_url) / "_matrix/client/v1/media/download" / sticker["url"].removeprefix("mxc://")
|
|
||||||
print("Downloading", sticker["url"])
|
|
||||||
async with sess.get(dl_url, headers={"Authorization": f"Bearer {matrix.access_token}"}) as resp:
|
|
||||||
resp.raise_for_status()
|
|
||||||
stickers_data[sticker["url"]] = await resp.read()
|
|
||||||
|
|
||||||
print("All stickers downloaded, generating thumbnails...")
|
|
||||||
util.add_thumbnails(pack["stickers"], stickers_data, Path(args.path).parent)
|
|
||||||
print("Done!")
|
|
||||||
|
|
||||||
def cmd():
|
|
||||||
asyncio.run(main(parser.parse_args()))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
cmd()
|
|
@@ -55,11 +55,13 @@ async def load_config(path: str) -> None:
|
|||||||
config = json.load(config_file)
|
config = json.load(config_file)
|
||||||
homeserver_url = config["homeserver"]
|
homeserver_url = config["homeserver"]
|
||||||
access_token = config["access_token"]
|
access_token = config["access_token"]
|
||||||
|
giphy_api_key = config["giphy_api_key"]
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("Matrix config file not found. Please enter your homeserver and access token.")
|
print("Matrix config file not found. Please enter your homeserver and access token. Enter the Giphy API token if required, leave blank to disable the gif picker.")
|
||||||
homeserver_url = input("Homeserver URL: ")
|
homeserver_url = input("Homeserver URL: ")
|
||||||
access_token = input("Access token: ")
|
access_token = input("Access token: ")
|
||||||
whoami_url = URL(homeserver_url) / "_matrix" / "client" / "v3" / "account" / "whoami"
|
giphy_api_key = input("Giphy API key: ")
|
||||||
|
whoami_url = URL(homeserver_url) / "_matrix" / "client" / "r0" / "account" / "whoami"
|
||||||
if whoami_url.scheme not in ("https", "http"):
|
if whoami_url.scheme not in ("https", "http"):
|
||||||
whoami_url = whoami_url.with_scheme("https")
|
whoami_url = whoami_url.with_scheme("https")
|
||||||
user_id = await whoami(whoami_url, access_token)
|
user_id = await whoami(whoami_url, access_token)
|
||||||
@@ -68,10 +70,11 @@ async def load_config(path: str) -> None:
|
|||||||
"homeserver": homeserver_url,
|
"homeserver": homeserver_url,
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"access_token": access_token,
|
"access_token": access_token,
|
||||||
|
"giphy_api_key": giphy_api_key
|
||||||
}, config_file)
|
}, config_file)
|
||||||
print(f"Wrote config to {path}")
|
print(f"Wrote config to {path}")
|
||||||
|
|
||||||
upload_url = URL(homeserver_url) / "_matrix" / "media" / "v3" / "upload"
|
upload_url = URL(homeserver_url) / "_matrix" / "media" / "r0" / "upload"
|
||||||
|
|
||||||
|
|
||||||
async def whoami(url: URL, access_token: str) -> str:
|
async def whoami(url: URL, access_token: str) -> str:
|
||||||
|
@@ -17,8 +17,6 @@ from functools import partial
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import os.path
|
import os.path
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict, List
|
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
@@ -26,19 +24,19 @@ from . import matrix
|
|||||||
|
|
||||||
open_utf8 = partial(open, encoding='UTF-8')
|
open_utf8 = partial(open, encoding='UTF-8')
|
||||||
|
|
||||||
def convert_image(data: bytes, max_w=256, max_h=256) -> (bytes, int, int):
|
def convert_image(data: bytes) -> (bytes, int, int):
|
||||||
image: Image.Image = Image.open(BytesIO(data)).convert("RGBA")
|
image: Image.Image = Image.open(BytesIO(data)).convert("RGBA")
|
||||||
new_file = BytesIO()
|
new_file = BytesIO()
|
||||||
image.save(new_file, "png")
|
image.save(new_file, "png")
|
||||||
w, h = image.size
|
w, h = image.size
|
||||||
if w > max_w or h > max_h:
|
if w > 256 or h > 256:
|
||||||
# Set the width and height to lower values so clients wouldn't show them as huge images
|
# Set the width and height to lower values so clients wouldn't show them as huge images
|
||||||
if w > h:
|
if w > h:
|
||||||
h = int(h / (w / max_w))
|
h = int(h / (w / 256))
|
||||||
w = max_w
|
w = 256
|
||||||
else:
|
else:
|
||||||
w = int(w / (h / max_h))
|
w = int(w / (h / 256))
|
||||||
h = max_h
|
h = 256
|
||||||
return new_file.getvalue(), w, h
|
return new_file.getvalue(), w, h
|
||||||
|
|
||||||
|
|
||||||
@@ -80,15 +78,3 @@ def make_sticker(mxc: str, width: int, height: int, size: int,
|
|||||||
},
|
},
|
||||||
"msgtype": "m.sticker",
|
"msgtype": "m.sticker",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def add_thumbnails(stickers: List[matrix.StickerInfo], stickers_data: Dict[str, bytes], output_dir: str) -> None:
|
|
||||||
thumbnails = Path(output_dir, "thumbnails")
|
|
||||||
thumbnails.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
for sticker in stickers:
|
|
||||||
image_data, _, _ = convert_image(stickers_data[sticker["url"]], 128, 128)
|
|
||||||
|
|
||||||
name = sticker["url"].split("/")[-1]
|
|
||||||
thumbnail_path = thumbnails / name
|
|
||||||
thumbnail_path.write_bytes(image_data)
|
|
@@ -13,7 +13,6 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
import mimetypes
|
import mimetypes
|
||||||
@@ -108,11 +107,9 @@ async def main(args: argparse.Namespace) -> None:
|
|||||||
old_stickers = {sticker["id"]: sticker for sticker in pack["stickers"]}
|
old_stickers = {sticker["id"]: sticker for sticker in pack["stickers"]}
|
||||||
pack["stickers"] = []
|
pack["stickers"] = []
|
||||||
|
|
||||||
stickers_data: Dict[str, bytes] = {}
|
|
||||||
for file in sorted(os.listdir(args.path)):
|
for file in sorted(os.listdir(args.path)):
|
||||||
sticker = await upload_sticker(file, args.path, old_stickers=old_stickers)
|
sticker = await upload_sticker(file, args.path, old_stickers=old_stickers)
|
||||||
if sticker:
|
if sticker:
|
||||||
stickers_data[sticker["url"]] = Path(args.path, file).read_bytes()
|
|
||||||
pack["stickers"].append(sticker)
|
pack["stickers"].append(sticker)
|
||||||
|
|
||||||
with util.open_utf8(meta_path, "w") as pack_file:
|
with util.open_utf8(meta_path, "w") as pack_file:
|
||||||
@@ -125,8 +122,6 @@ async def main(args: argparse.Namespace) -> None:
|
|||||||
with util.open_utf8(picker_pack_path, "w") as pack_file:
|
with util.open_utf8(picker_pack_path, "w") as pack_file:
|
||||||
json.dump(pack, pack_file)
|
json.dump(pack, pack_file)
|
||||||
print(f"Copied pack to {picker_pack_path}")
|
print(f"Copied pack to {picker_pack_path}")
|
||||||
|
|
||||||
util.add_thumbnails(pack["stickers"], stickers_data, args.add_to_index)
|
|
||||||
util.add_to_index(picker_file_name, args.add_to_index)
|
util.add_to_index(picker_file_name, args.add_to_index)
|
||||||
|
|
||||||
|
|
||||||
@@ -143,7 +138,7 @@ parser.add_argument("path", help="Path to the sticker pack directory", type=str)
|
|||||||
|
|
||||||
|
|
||||||
def cmd():
|
def cmd():
|
||||||
asyncio.run(main(parser.parse_args()))
|
asyncio.get_event_loop().run_until_complete(main(parser.parse_args()))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
from typing import Dict, Tuple
|
from typing import Dict
|
||||||
import argparse
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
import os.path
|
import os.path
|
||||||
@@ -29,7 +29,7 @@ from telethon.tl.types.messages import StickerSet as StickerSetFull
|
|||||||
from .lib import matrix, util
|
from .lib import matrix, util
|
||||||
|
|
||||||
|
|
||||||
async def reupload_document(client: TelegramClient, document: Document) -> Tuple[matrix.StickerInfo, bytes]:
|
async def reupload_document(client: TelegramClient, document: Document) -> matrix.StickerInfo:
|
||||||
print(f"Reuploading {document.id}", end="", flush=True)
|
print(f"Reuploading {document.id}", end="", flush=True)
|
||||||
data = await client.download_media(document, file=bytes)
|
data = await client.download_media(document, file=bytes)
|
||||||
print(".", end="", flush=True)
|
print(".", end="", flush=True)
|
||||||
@@ -37,7 +37,7 @@ async def reupload_document(client: TelegramClient, document: Document) -> Tuple
|
|||||||
print(".", end="", flush=True)
|
print(".", end="", flush=True)
|
||||||
mxc = await matrix.upload(data, "image/png", f"{document.id}.png")
|
mxc = await matrix.upload(data, "image/png", f"{document.id}.png")
|
||||||
print(".", flush=True)
|
print(".", flush=True)
|
||||||
return util.make_sticker(mxc, width, height, len(data)), data
|
return util.make_sticker(mxc, width, height, len(data))
|
||||||
|
|
||||||
|
|
||||||
def add_meta(document: Document, info: matrix.StickerInfo, pack: StickerSetFull) -> None:
|
def add_meta(document: Document, info: matrix.StickerInfo, pack: StickerSetFull) -> None:
|
||||||
@@ -56,6 +56,10 @@ def add_meta(document: Document, info: matrix.StickerInfo, pack: StickerSetFull)
|
|||||||
|
|
||||||
|
|
||||||
async def reupload_pack(client: TelegramClient, pack: StickerSetFull, output_dir: str) -> None:
|
async def reupload_pack(client: TelegramClient, pack: StickerSetFull, output_dir: str) -> None:
|
||||||
|
if pack.set.animated:
|
||||||
|
print("Animated stickerpacks are currently not supported")
|
||||||
|
return
|
||||||
|
|
||||||
pack_path = os.path.join(output_dir, f"{pack.set.short_name}.json")
|
pack_path = os.path.join(output_dir, f"{pack.set.short_name}.json")
|
||||||
try:
|
try:
|
||||||
os.mkdir(os.path.dirname(pack_path))
|
os.mkdir(os.path.dirname(pack_path))
|
||||||
@@ -75,17 +79,15 @@ async def reupload_pack(client: TelegramClient, pack: StickerSetFull, output_dir
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
stickers_data: Dict[str, bytes] = {}
|
|
||||||
reuploaded_documents: Dict[int, matrix.StickerInfo] = {}
|
reuploaded_documents: Dict[int, matrix.StickerInfo] = {}
|
||||||
for document in pack.documents:
|
for document in pack.documents:
|
||||||
try:
|
try:
|
||||||
reuploaded_documents[document.id] = already_uploaded[document.id]
|
reuploaded_documents[document.id] = already_uploaded[document.id]
|
||||||
print(f"Skipped reuploading {document.id}")
|
print(f"Skipped reuploading {document.id}")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
reuploaded_documents[document.id], data = await reupload_document(client, document)
|
reuploaded_documents[document.id] = await reupload_document(client, document)
|
||||||
# Always ensure the body and telegram metadata is correct
|
# Always ensure the body and telegram metadata is correct
|
||||||
add_meta(document, reuploaded_documents[document.id], pack)
|
add_meta(document, reuploaded_documents[document.id], pack)
|
||||||
stickers_data[reuploaded_documents[document.id]["url"]] = data
|
|
||||||
|
|
||||||
for sticker in pack.packs:
|
for sticker in pack.packs:
|
||||||
if not sticker.emoticon:
|
if not sticker.emoticon:
|
||||||
@@ -109,7 +111,6 @@ async def reupload_pack(client: TelegramClient, pack: StickerSetFull, output_dir
|
|||||||
}, pack_file, ensure_ascii=False)
|
}, pack_file, ensure_ascii=False)
|
||||||
print(f"Saved {pack.set.title} as {pack.set.short_name}.json")
|
print(f"Saved {pack.set.title} as {pack.set.short_name}.json")
|
||||||
|
|
||||||
util.add_thumbnails(list(reuploaded_documents.values()), stickers_data, output_dir)
|
|
||||||
util.add_to_index(os.path.basename(pack_path), output_dir)
|
util.add_to_index(os.path.basename(pack_path), output_dir)
|
||||||
|
|
||||||
|
|
||||||
@@ -161,7 +162,7 @@ async def main(args: argparse.Namespace) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def cmd() -> None:
|
def cmd() -> None:
|
||||||
asyncio.run(main(parser.parse_args()))
|
asyncio.get_event_loop().run_until_complete(main(parser.parse_args()))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -1 +1,6 @@
|
|||||||
from .get_version import git_tag, git_revision, version, linkified_version
|
# Generated in setup.py
|
||||||
|
|
||||||
|
git_tag = None
|
||||||
|
git_revision = 'f59406a4'
|
||||||
|
version = '0.1.0+dev.f59406a4'
|
||||||
|
linkified_version = '0.1.0+dev.[f59406a4](https://github.com/maunium/stickerpicker/commit/f59406a47a6778cd402e656ffb64f667335f665a)'
|
||||||
|
@@ -4,11 +4,10 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
|
||||||
<title>Maunium sticker picker</title>
|
<title>Maunium sticker picker</title>
|
||||||
|
<script src="https://unpkg.com/matrix-widget-api@1.6.0/dist/api.js"></script>
|
||||||
<link rel="modulepreload" href="src/widget-api.js"/>
|
<script type="module" src="src/widget-api.js"></script>
|
||||||
<link rel="modulepreload" href="src/frequently-used.js"/>
|
<link rel="modulepreload" href="src/frequently-used.js"/>
|
||||||
<link rel="modulepreload" href="src/spinner.js"/>
|
<link rel="modulepreload" href="src/spinner.js"/>
|
||||||
<link rel="modulepreload" href="src/giphy.js"/>
|
|
||||||
<link rel="modulepreload" href="lib/htm/preact.js"/>
|
<link rel="modulepreload" href="lib/htm/preact.js"/>
|
||||||
<link rel="preload" href="packs/index.json" as="fetch" type="application/json" crossorigin/>
|
<link rel="preload" href="packs/index.json" as="fetch" type="application/json" crossorigin/>
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -11,9 +11,9 @@
|
|||||||
"sass": "sass --no-source-map --style=compressed style/"
|
"sass": "sass --no-source-map --style=compressed style/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esinstall": "^1.1.7",
|
|
||||||
"htm": "^3.1.0",
|
"htm": "^3.1.0",
|
||||||
"preact": "^10.5.14",
|
"preact": "^10.5.14",
|
||||||
|
"esinstall": "^1.1.7",
|
||||||
"sass": "^1.42.1"
|
"sass": "^1.42.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
web/packs/index.json
Normal file
16
web/packs/index.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"packs": [
|
||||||
|
"scalar-isabella.json",
|
||||||
|
"scalar-privacy_pam.json",
|
||||||
|
"scalar-sheltie.json",
|
||||||
|
"scalar-stakey.json",
|
||||||
|
"scalar-videoplasty.json",
|
||||||
|
"scalar-geeko.json",
|
||||||
|
"scalar-loading_artist.json",
|
||||||
|
"scalar-rabbit.json",
|
||||||
|
"scalar-smilies.json",
|
||||||
|
"scalar-stickman.json"
|
||||||
|
],
|
||||||
|
"homeserver_url": "https://matrix.intothematrix.in",
|
||||||
|
"giphy_api_key": "Gc7131jiJuvI7IdN0HZ1D7nh0ow5BU6g"
|
||||||
|
}
|
1
web/packs/scalar-geeko.json
Normal file
1
web/packs/scalar-geeko.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Geeko", "id": "scalar-191580", "stickers": [{"body": "Geeko with a suitcase, wearing a suit", "info": {"h": 256, "mimetype": "image/png", "size": 41241, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 41241, "w": 256}, "thumbnail_url": "mxc://matrix.org/GWyQoBKgXAoIXhBcCMCxmkxd", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/GWyQoBKgXAoIXhBcCMCxmkxd", "id": "GWyQoBKgXAoIXhBcCMCxmkxd"}, {"body": "Geeko driving away in a car waving", "info": {"h": 256, "mimetype": "image/png", "size": 51387, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 51387, "w": 256}, "thumbnail_url": "mxc://matrix.org/JkAPbbuIuOMMbWqhKTNnGETu", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/JkAPbbuIuOMMbWqhKTNnGETu", "id": "JkAPbbuIuOMMbWqhKTNnGETu"}, {"body": "Geeko enjoying his time in an armchair with a cup of tea", "info": {"h": 256, "mimetype": "image/png", "size": 44188, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 44188, "w": 256}, "thumbnail_url": "mxc://matrix.org/AdkCycKHKGfgpyOCrlcSihDK", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/AdkCycKHKGfgpyOCrlcSihDK", "id": "AdkCycKHKGfgpyOCrlcSihDK"}, {"body": "Sick Geeko wrapped in a blanket with a tray of refreshing bevarage", "info": {"h": 256, "mimetype": "image/png", "size": 36364, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 36364, "w": 256}, "thumbnail_url": "mxc://matrix.org/SNkQWaqBkKwIEHQyJmAuhnIL", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/SNkQWaqBkKwIEHQyJmAuhnIL", "id": "SNkQWaqBkKwIEHQyJmAuhnIL"}, {"body": "Geeko in a balerina skirt inviting to dance with them", "info": {"h": 256, "mimetype": "image/png", "size": 34716, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 34716, "w": 256}, "thumbnail_url": "mxc://matrix.org/WLjGVDOlqAPtMaggqcgmjZsB", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/WLjGVDOlqAPtMaggqcgmjZsB", "id": "WLjGVDOlqAPtMaggqcgmjZsB"}, {"body": "Geeko laying on a cloud", "info": {"h": 256, "mimetype": "image/png", "size": 39189, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 39189, "w": 256}, "thumbnail_url": "mxc://matrix.org/ouaitVRUeqIJCuMuKLNtzOPl", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/ouaitVRUeqIJCuMuKLNtzOPl", "id": "ouaitVRUeqIJCuMuKLNtzOPl"}, {"body": "Geeko stretching", "info": {"h": 256, "mimetype": "image/png", "size": 34670, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 34670, "w": 256}, "thumbnail_url": "mxc://matrix.org/DXEyavdgypGEPLeWdmaAkOAG", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/DXEyavdgypGEPLeWdmaAkOAG", "id": "DXEyavdgypGEPLeWdmaAkOAG"}, {"body": "Geeko aproaching Nirvana", "info": {"h": 256, "mimetype": "image/png", "size": 42035, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 42035, "w": 256}, "thumbnail_url": "mxc://matrix.org/DRCkchiNQgASUCFTxFDDfhvi", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/DRCkchiNQgASUCFTxFDDfhvi", "id": "DRCkchiNQgASUCFTxFDDfhvi"}, {"body": "Geeko dressed in a paper airplane, running", "info": {"h": 256, "mimetype": "image/png", "size": 49568, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 49568, "w": 256}, "thumbnail_url": "mxc://matrix.org/YrJQDfZpESKIYdUzvhMDXBLU", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/YrJQDfZpESKIYdUzvhMDXBLU", "id": "YrJQDfZpESKIYdUzvhMDXBLU"}, {"body": "Geeko drawing an animal", "info": {"h": 256, "mimetype": "image/png", "size": 54112, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 54112, "w": 256}, "thumbnail_url": "mxc://matrix.org/bHmdDCDjmolEjrxAFDGuHoJa", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/bHmdDCDjmolEjrxAFDGuHoJa", "id": "bHmdDCDjmolEjrxAFDGuHoJa"}]}
|
1
web/packs/scalar-isabella.json
Normal file
1
web/packs/scalar-isabella.json
Normal file
File diff suppressed because one or more lines are too long
1
web/packs/scalar-loading_artist.json
Normal file
1
web/packs/scalar-loading_artist.json
Normal file
File diff suppressed because one or more lines are too long
1
web/packs/scalar-privacy_pam.json
Normal file
1
web/packs/scalar-privacy_pam.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Privacy Pam", "id": "scalar-191583", "stickers": [{"body": "Privacy Pam is Angry", "info": {"h": 256, "mimetype": "image/png", "size": 184861, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 184861, "w": 256}, "thumbnail_url": "mxc://matrix.org/WYZLGkpAXwgOftafRtSQVNYF", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/WYZLGkpAXwgOftafRtSQVNYF", "id": "WYZLGkpAXwgOftafRtSQVNYF"}, {"body": "Privacy Pam Cries", "info": {"h": 256, "mimetype": "image/png", "size": 164740, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 164740, "w": 256}, "thumbnail_url": "mxc://matrix.org/aVOIYKvTRBiKqZbxomKeuwYD", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/aVOIYKvTRBiKqZbxomKeuwYD", "id": "aVOIYKvTRBiKqZbxomKeuwYD"}, {"body": "Privacy Pam is Happy", "info": {"h": 256, "mimetype": "image/png", "size": 172907, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 172907, "w": 256}, "thumbnail_url": "mxc://matrix.org/FZolsrwTDUJoLlGfWHffwuFP", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/FZolsrwTDUJoLlGfWHffwuFP", "id": "FZolsrwTDUJoLlGfWHffwuFP"}, {"body": "Privacy Pam Laughs", "info": {"h": 256, "mimetype": "image/png", "size": 170855, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 170855, "w": 256}, "thumbnail_url": "mxc://matrix.org/qTfporLEnxtdkdwmPUQwWNtg", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/qTfporLEnxtdkdwmPUQwWNtg", "id": "qTfporLEnxtdkdwmPUQwWNtg"}, {"body": "Privacy Pam is Sad", "info": {"h": 256, "mimetype": "image/png", "size": 179575, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 179575, "w": 256}, "thumbnail_url": "mxc://matrix.org/MvUDjTTYKanEzFAExAhJfyAL", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/MvUDjTTYKanEzFAExAhJfyAL", "id": "MvUDjTTYKanEzFAExAhJfyAL"}, {"body": "Privacy Pam Smiles", "info": {"h": 256, "mimetype": "image/png", "size": 185764, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 185764, "w": 256}, "thumbnail_url": "mxc://matrix.org/cUbyqEDvdvxMqnfBGKmIpgfp", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/cUbyqEDvdvxMqnfBGKmIpgfp", "id": "cUbyqEDvdvxMqnfBGKmIpgfp"}, {"body": "Privacy Pam is Thinking", "info": {"h": 256, "mimetype": "image/png", "size": 199567, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 199567, "w": 256}, "thumbnail_url": "mxc://matrix.org/JnxtjVDYQHKGMWDRqSDgCwPL", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/JnxtjVDYQHKGMWDRqSDgCwPL", "id": "JnxtjVDYQHKGMWDRqSDgCwPL"}, {"body": "Privacy Pam Likes", "info": {"h": 256, "mimetype": "image/png", "size": 196924, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 196924, "w": 256}, "thumbnail_url": "mxc://matrix.org/umFLoIIzwirpWpcbnlgbtNNW", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/umFLoIIzwirpWpcbnlgbtNNW", "id": "umFLoIIzwirpWpcbnlgbtNNW"}, {"body": "Privacy Pam Winks", "info": {"h": 256, "mimetype": "image/png", "size": 167280, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 167280, "w": 256}, "thumbnail_url": "mxc://matrix.org/mehuoFXMMUdUSezwTwkkxHCB", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/mehuoFXMMUdUSezwTwkkxHCB", "id": "mehuoFXMMUdUSezwTwkkxHCB"}]}
|
1
web/packs/scalar-rabbit.json
Normal file
1
web/packs/scalar-rabbit.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Rabbit", "id": "scalar-191566", "stickers": [{"body": "Carrot", "info": {"h": 200, "mimetype": "image/png", "size": 80625, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 80625, "w": 142}, "thumbnail_url": "mxc://matrix.org/kGJDCjMOgpLmZzbgknMTUHNm", "w": 142}, "msgtype": "m.sticker", "url": "mxc://matrix.org/kGJDCjMOgpLmZzbgknMTUHNm", "id": "kGJDCjMOgpLmZzbgknMTUHNm"}, {"body": "Chef", "info": {"h": 200, "mimetype": "image/png", "size": 88633, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 88633, "w": 151}, "thumbnail_url": "mxc://matrix.org/szaTExsJurtDBUUEeHHbhyqk", "w": 151}, "msgtype": "m.sticker", "url": "mxc://matrix.org/szaTExsJurtDBUUEeHHbhyqk", "id": "szaTExsJurtDBUUEeHHbhyqk"}, {"body": "Coding", "info": {"h": 185, "mimetype": "image/png", "size": 97412, "thumbnail_info": {"h": 185, "mimetype": "image/png", "size": 97412, "w": 200}, "thumbnail_url": "mxc://matrix.org/DykipVHRXsfamLGJscNLbFAB", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/DykipVHRXsfamLGJscNLbFAB", "id": "DykipVHRXsfamLGJscNLbFAB"}, {"body": "Doctor", "info": {"h": 200, "mimetype": "image/png", "size": 113391, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 113391, "w": 184}, "thumbnail_url": "mxc://matrix.org/GEhjrKIapqcbVWKEsoDMhXeZ", "w": 184}, "msgtype": "m.sticker", "url": "mxc://matrix.org/GEhjrKIapqcbVWKEsoDMhXeZ", "id": "GEhjrKIapqcbVWKEsoDMhXeZ"}, {"body": "Driving", "info": {"h": 200, "mimetype": "image/png", "size": 77577, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 77577, "w": 156}, "thumbnail_url": "mxc://matrix.org/jxPXTKpyydzdHJkdFNZjTZrD", "w": 156}, "msgtype": "m.sticker", "url": "mxc://matrix.org/jxPXTKpyydzdHJkdFNZjTZrD", "id": "jxPXTKpyydzdHJkdFNZjTZrD"}, {"body": "Landing", "info": {"h": 200, "mimetype": "image/png", "size": 73602, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 73602, "w": 140}, "thumbnail_url": "mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP", "w": 140}, "msgtype": "m.sticker", "url": "mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP", "id": "sHhqkFCvSkFwtmvtETOtKnLP"}, {"body": "Phone", "info": {"h": 200, "mimetype": "image/png", "size": 94007, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 94007, "w": 172}, "thumbnail_url": "mxc://matrix.org/mnNNbLjjLjQIcKaybAyVMKMQ", "w": 172}, "msgtype": "m.sticker", "url": "mxc://matrix.org/mnNNbLjjLjQIcKaybAyVMKMQ", "id": "mnNNbLjjLjQIcKaybAyVMKMQ"}, {"body": "Running", "info": {"h": 157, "mimetype": "image/png", "size": 83290, "thumbnail_info": {"h": 157, "mimetype": "image/png", "size": 83290, "w": 200}, "thumbnail_url": "mxc://matrix.org/gloPNMnAwUEtrtTsaeqPTlhK", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/gloPNMnAwUEtrtTsaeqPTlhK", "id": "gloPNMnAwUEtrtTsaeqPTlhK"}, {"body": "Science", "info": {"h": 200, "mimetype": "image/png", "size": 103111, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 103111, "w": 155}, "thumbnail_url": "mxc://matrix.org/uDmIFKTXYQpzipNELqRhWSsj", "w": 155}, "msgtype": "m.sticker", "url": "mxc://matrix.org/uDmIFKTXYQpzipNELqRhWSsj", "id": "uDmIFKTXYQpzipNELqRhWSsj"}, {"body": "Work", "info": {"h": 150, "mimetype": "image/png", "size": 81850, "thumbnail_info": {"h": 150, "mimetype": "image/png", "size": 81850, "w": 200}, "thumbnail_url": "mxc://matrix.org/kYOcGZCqtNzBSUqBBOaLDBgE", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/kYOcGZCqtNzBSUqBBOaLDBgE", "id": "kYOcGZCqtNzBSUqBBOaLDBgE"}]}
|
1
web/packs/scalar-sheltie.json
Normal file
1
web/packs/scalar-sheltie.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Sheltie", "id": "scalar-192093", "stickers": [{"body": "Busy", "info": {"h": 173, "mimetype": "image/png", "size": 132161, "thumbnail_info": {"h": 173, "mimetype": "image/png", "size": 132161, "w": 200}, "thumbnail_url": "mxc://matrix.org/KbQyHYcnRFPSfRCbGqbTBiWt", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/KbQyHYcnRFPSfRCbGqbTBiWt", "id": "KbQyHYcnRFPSfRCbGqbTBiWt"}, {"body": "Confused", "info": {"h": 200, "mimetype": "image/png", "size": 111042, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 111042, "w": 173}, "thumbnail_url": "mxc://matrix.org/KkCmAbAPsgeUFdOyOceqAFBr", "w": 173}, "msgtype": "m.sticker", "url": "mxc://matrix.org/KkCmAbAPsgeUFdOyOceqAFBr", "id": "KkCmAbAPsgeUFdOyOceqAFBr"}, {"body": "Happy", "info": {"h": 158, "mimetype": "image/png", "size": 110679, "thumbnail_info": {"h": 158, "mimetype": "image/png", "size": 110679, "w": 200}, "thumbnail_url": "mxc://matrix.org/gFrdGIZbVATfwziAHnIYwEuh", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/gFrdGIZbVATfwziAHnIYwEuh", "id": "gFrdGIZbVATfwziAHnIYwEuh"}, {"body": "Hungry", "info": {"h": 183, "mimetype": "image/png", "size": 97642, "thumbnail_info": {"h": 183, "mimetype": "image/png", "size": 97642, "w": 200}, "thumbnail_url": "mxc://matrix.org/LWtWooRvIbhgLjQPPtyhWNgP", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/LWtWooRvIbhgLjQPPtyhWNgP", "id": "LWtWooRvIbhgLjQPPtyhWNgP"}, {"body": "Innocent", "info": {"h": 200, "mimetype": "image/png", "size": 107331, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 107331, "w": 186}, "thumbnail_url": "mxc://matrix.org/IItfiFhKoPieFyPLceBLcFhd", "w": 186}, "msgtype": "m.sticker", "url": "mxc://matrix.org/IItfiFhKoPieFyPLceBLcFhd", "id": "IItfiFhKoPieFyPLceBLcFhd"}, {"body": "Laughing", "info": {"h": 200, "mimetype": "image/png", "size": 118620, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 118620, "w": 194}, "thumbnail_url": "mxc://matrix.org/LxEPZAsPAfjyRfAwpYSoIxwV", "w": 194}, "msgtype": "m.sticker", "url": "mxc://matrix.org/LxEPZAsPAfjyRfAwpYSoIxwV", "id": "LxEPZAsPAfjyRfAwpYSoIxwV"}, {"body": "Sad", "info": {"h": 200, "mimetype": "image/png", "size": 104622, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 104622, "w": 177}, "thumbnail_url": "mxc://matrix.org/MjdsQxPFskrLFQfXHFuJrwbr", "w": 177}, "msgtype": "m.sticker", "url": "mxc://matrix.org/MjdsQxPFskrLFQfXHFuJrwbr", "id": "MjdsQxPFskrLFQfXHFuJrwbr"}, {"body": "Sleepy", "info": {"h": 200, "mimetype": "image/png", "size": 116609, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 116609, "w": 196}, "thumbnail_url": "mxc://matrix.org/iqEhhOuswzPITADcrmQZPxbh", "w": 196}, "msgtype": "m.sticker", "url": "mxc://matrix.org/iqEhhOuswzPITADcrmQZPxbh", "id": "iqEhhOuswzPITADcrmQZPxbh"}, {"body": "Thank-you", "info": {"h": 200, "mimetype": "image/png", "size": 109865, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 109865, "w": 160}, "thumbnail_url": "mxc://matrix.org/qnyciftjKPqVDyEIjcakwCUO", "w": 160}, "msgtype": "m.sticker", "url": "mxc://matrix.org/qnyciftjKPqVDyEIjcakwCUO", "id": "qnyciftjKPqVDyEIjcakwCUO"}, {"body": "Thumb-up", "info": {"h": 200, "mimetype": "image/png", "size": 120744, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 120744, "w": 184}, "thumbnail_url": "mxc://matrix.org/xHCAaOqwMjyJYQMHIFIgeryn", "w": 184}, "msgtype": "m.sticker", "url": "mxc://matrix.org/xHCAaOqwMjyJYQMHIFIgeryn", "id": "xHCAaOqwMjyJYQMHIFIgeryn"}]}
|
1
web/packs/scalar-smilies.json
Normal file
1
web/packs/scalar-smilies.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Smilies", "id": "scalar-192094", "stickers": [{"body": "I'm really angry!", "info": {"h": 256, "mimetype": "image/png", "size": 20840, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 20840, "w": 256}, "thumbnail_url": "mxc://matrix.org/vjgWJdgaAdPLYJMsAjbJrOIa", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/vjgWJdgaAdPLYJMsAjbJrOIa", "id": "vjgWJdgaAdPLYJMsAjbJrOIa"}, {"body": "I'm dead tired", "info": {"h": 256, "mimetype": "image/png", "size": 20143, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 20143, "w": 256}, "thumbnail_url": "mxc://matrix.org/GAZUrYmcYRtcNofjGGqAWhqI", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/GAZUrYmcYRtcNofjGGqAWhqI", "id": "GAZUrYmcYRtcNofjGGqAWhqI"}, {"body": "I'm really happy", "info": {"h": 256, "mimetype": "image/png", "size": 20509, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 20509, "w": 256}, "thumbnail_url": "mxc://matrix.org/SthCvLTenNJopFCEzEeZEwJy", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/SthCvLTenNJopFCEzEeZEwJy", "id": "SthCvLTenNJopFCEzEeZEwJy"}, {"body": "Friday I'm in love!", "info": {"h": 256, "mimetype": "image/png", "size": 20726, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 20726, "w": 256}, "thumbnail_url": "mxc://matrix.org/sCpzSdxGKNVTyyaaTtDvKIVw", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/sCpzSdxGKNVTyyaaTtDvKIVw", "id": "sCpzSdxGKNVTyyaaTtDvKIVw"}, {"body": "Show me the money!", "info": {"h": 256, "mimetype": "image/png", "size": 20852, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 20852, "w": 256}, "thumbnail_url": "mxc://matrix.org/RPsEdZjVSCdxklObGMzyeUBm", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/RPsEdZjVSCdxklObGMzyeUBm", "id": "RPsEdZjVSCdxklObGMzyeUBm"}, {"body": "I'm just sad", "info": {"h": 256, "mimetype": "image/png", "size": 22825, "thumbnail_info": {"h": 256, "mimetype": "image/png", "size": 22825, "w": 256}, "thumbnail_url": "mxc://matrix.org/RseXEsYHhkmmiGCzKYDuFyZt", "w": 256}, "msgtype": "m.sticker", "url": "mxc://matrix.org/RseXEsYHhkmmiGCzKYDuFyZt", "id": "RseXEsYHhkmmiGCzKYDuFyZt"}]}
|
1
web/packs/scalar-stakey.json
Normal file
1
web/packs/scalar-stakey.json
Normal file
File diff suppressed because one or more lines are too long
1
web/packs/scalar-stickman.json
Normal file
1
web/packs/scalar-stickman.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"title": "Stickman", "id": "scalar-192096", "stickers": [{"body": "A hastily-rendered stick figure stares at you blankly. Its arms are folded: perhaps defensively, perhaps in a half-hearted Gangnam Style.", "info": {"h": 200, "mimetype": "image/png", "size": 28154, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 28154, "w": 106}, "thumbnail_url": "mxc://matrix.org/bQGEpjrZQcWLgygXmuaJCNNA", "w": 106}, "msgtype": "m.sticker", "url": "mxc://matrix.org/bQGEpjrZQcWLgygXmuaJCNNA", "id": "bQGEpjrZQcWLgygXmuaJCNNA"}, {"body": "Question marks of varying sizes orbit a stick figure's head.", "info": {"h": 194, "mimetype": "image/png", "size": 95200, "thumbnail_info": {"h": 194, "mimetype": "image/png", "size": 95200, "w": 200}, "thumbnail_url": "mxc://matrix.org/aVdcZtGRijWluoSjCAytBHnP", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/aVdcZtGRijWluoSjCAytBHnP", "id": "aVdcZtGRijWluoSjCAytBHnP"}, {"body": "A hastily-rendered stick figure stands with arms outstretched, smiling, beneath the word 'HOORAY' in an arc above its head. The figure is smiling in celebration.", "info": {"h": 200, "mimetype": "image/png", "size": 27199, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 27199, "w": 142}, "thumbnail_url": "mxc://matrix.org/BMcDXCuQjoAaWvlPBlUjXBNa", "w": 142}, "msgtype": "m.sticker", "url": "mxc://matrix.org/BMcDXCuQjoAaWvlPBlUjXBNa", "id": "BMcDXCuQjoAaWvlPBlUjXBNa"}, {"body": "A hastily-rendered stick figure stands with arms in the air beneath three blue-and-white juggling balls apparently in motion. We cannot tell whether the figure is juggling competently or has simply thrown all three balls into the air and is awaiting the inevitable. The figure's mouth is formed into an enigmatic 'o'.", "info": {"h": 200, "mimetype": "image/png", "size": 30170, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 30170, "w": 88}, "thumbnail_url": "mxc://matrix.org/mQEotjwsEKeZivqIfZjxNfgC", "w": 88}, "msgtype": "m.sticker", "url": "mxc://matrix.org/mQEotjwsEKeZivqIfZjxNfgC", "id": "mQEotjwsEKeZivqIfZjxNfgC"}, {"body": "A hastily-rendered stick figure is thinking about lunch. Shouldn't you be thinking about lunch?", "info": {"h": 187, "mimetype": "image/png", "size": 55105, "thumbnail_info": {"h": 187, "mimetype": "image/png", "size": 55105, "w": 200}, "thumbnail_url": "mxc://matrix.org/ZHGncPEBowOpxqbVYCGbBTff", "w": 200}, "msgtype": "m.sticker", "url": "mxc://matrix.org/ZHGncPEBowOpxqbVYCGbBTff", "id": "ZHGncPEBowOpxqbVYCGbBTff"}, {"body": "A hastily-rendered stick figure stands with arms outstretched, smiling.", "info": {"h": 200, "mimetype": "image/png", "size": 26585, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 26585, "w": 138}, "thumbnail_url": "mxc://matrix.org/FGCzIxIKpswOIJCWZUWlCoKi", "w": 138}, "msgtype": "m.sticker", "url": "mxc://matrix.org/FGCzIxIKpswOIJCWZUWlCoKi", "id": "FGCzIxIKpswOIJCWZUWlCoKi"}, {"body": "A hastily-rendered stick figure stands holding a placard which reads 'I HAVE OPINIONS'. The figure's mouth is wide and angry, suggesting said opinions might not be the same as yours.", "info": {"h": 200, "mimetype": "image/png", "size": 45505, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 45505, "w": 139}, "thumbnail_url": "mxc://matrix.org/eSdUNjchqskXmCOiLgjqsakm", "w": 139}, "msgtype": "m.sticker", "url": "mxc://matrix.org/eSdUNjchqskXmCOiLgjqsakm", "id": "eSdUNjchqskXmCOiLgjqsakm"}, {"body": "A hastily-rendered stick figure stands with arms in the air. The figure's mouth is formed into an enigmatic 'o'.", "info": {"h": 200, "mimetype": "image/png", "size": 25059, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 25059, "w": 132}, "thumbnail_url": "mxc://matrix.org/puRSMGiaBfdAwYzfdHQFiJMJ", "w": 132}, "msgtype": "m.sticker", "url": "mxc://matrix.org/puRSMGiaBfdAwYzfdHQFiJMJ", "id": "puRSMGiaBfdAwYzfdHQFiJMJ"}, {"body": "A hastily-rendered stick figure has put on its robe and wizard hat.", "info": {"h": 200, "mimetype": "image/png", "size": 43579, "thumbnail_info": {"h": 200, "mimetype": "image/png", "size": 43579, "w": 108}, "thumbnail_url": "mxc://matrix.org/aplWcQPboleenDWMurAdHpHb", "w": 108}, "msgtype": "m.sticker", "url": "mxc://matrix.org/aplWcQPboleenDWMurAdHpHb", "id": "aplWcQPboleenDWMurAdHpHb"}]}
|
1
web/packs/scalar-videoplasty.json
Normal file
1
web/packs/scalar-videoplasty.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="534"
|
|
||||||
width="427.20001"
|
|
||||||
viewBox="0 0 27.990145 35"
|
|
||||||
version="1.1"
|
|
||||||
id="svg24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs28" />
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
id="g22"
|
|
||||||
transform="translate(-0.02883895)">
|
|
||||||
<path
|
|
||||||
d="M 4,4 H 24 V 31 H 4 Z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path2"
|
|
||||||
style="fill:#ffffff;fill-opacity:1" />
|
|
||||||
<g
|
|
||||||
fill-rule="nonzero"
|
|
||||||
id="g16">
|
|
||||||
<path
|
|
||||||
d="M 0,3 H 4 V 32 H 0 Z"
|
|
||||||
fill="#04ff8e"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
d="m 24,11 h 4 v 21 h -4 z"
|
|
||||||
fill="#8e2eff"
|
|
||||||
id="path6" />
|
|
||||||
<path
|
|
||||||
d="m 0,31 h 28 v 4 H 0 Z"
|
|
||||||
fill="#00c5ff"
|
|
||||||
id="path8" />
|
|
||||||
<path
|
|
||||||
d="M 0,0 H 16 V 4 H 0 Z"
|
|
||||||
fill="#fff152"
|
|
||||||
id="path10" />
|
|
||||||
<path
|
|
||||||
d="M 24,8 V 4 H 20 V 0 H 16 V 12 H 28 V 8"
|
|
||||||
fill="#ff5b5b"
|
|
||||||
id="path12" />
|
|
||||||
<path
|
|
||||||
d="m 24,16 v -4 h 4"
|
|
||||||
fill="#551c99"
|
|
||||||
id="path14" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="M 16,0 V 4 H 12"
|
|
||||||
fill="#999131"
|
|
||||||
id="path18" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="534"
|
|
||||||
width="427.20001"
|
|
||||||
viewBox="0 0 27.990145 35"
|
|
||||||
version="1.1"
|
|
||||||
id="svg24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs28" />
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
id="g22"
|
|
||||||
transform="translate(-0.02883895)">
|
|
||||||
<path
|
|
||||||
d="M 4,4 H 24 V 31 H 4 Z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path2" />
|
|
||||||
<g
|
|
||||||
fill-rule="nonzero"
|
|
||||||
id="g16">
|
|
||||||
<path
|
|
||||||
d="M 0,3 H 4 V 32 H 0 Z"
|
|
||||||
fill="#04ff8e"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
d="m 24,11 h 4 v 21 h -4 z"
|
|
||||||
fill="#8e2eff"
|
|
||||||
id="path6" />
|
|
||||||
<path
|
|
||||||
d="m 0,31 h 28 v 4 H 0 Z"
|
|
||||||
fill="#00c5ff"
|
|
||||||
id="path8" />
|
|
||||||
<path
|
|
||||||
d="M 0,0 H 16 V 4 H 0 Z"
|
|
||||||
fill="#fff152"
|
|
||||||
id="path10" />
|
|
||||||
<path
|
|
||||||
d="M 24,8 V 4 H 20 V 0 H 16 V 12 H 28 V 8"
|
|
||||||
fill="#ff5b5b"
|
|
||||||
id="path12" />
|
|
||||||
<path
|
|
||||||
d="m 24,16 v -4 h 4"
|
|
||||||
fill="#551c99"
|
|
||||||
id="path14" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="M 16,0 V 4 H 12"
|
|
||||||
fill="#999131"
|
|
||||||
id="path18" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB |
107
web/src/giphy.js
107
web/src/giphy.js
@@ -1,107 +0,0 @@
|
|||||||
import {Component, html} from "../lib/htm/preact.js";
|
|
||||||
import * as widgetAPI from "./widget-api.js";
|
|
||||||
import {SearchBox} from "./search-box.js";
|
|
||||||
|
|
||||||
const GIPHY_SEARCH_DEBOUNCE = 1000
|
|
||||||
let GIPHY_API_KEY = "HQku8974Uq5MZn3MZns46kXn2R4GDm75"
|
|
||||||
let GIPHY_MXC_PREFIX = "mxc://giphy.mau.dev/"
|
|
||||||
|
|
||||||
export function giphyIsEnabled() {
|
|
||||||
return GIPHY_API_KEY !== ""
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setGiphyAPIKey(apiKey, mxcPrefix) {
|
|
||||||
GIPHY_API_KEY = apiKey
|
|
||||||
if (mxcPrefix) {
|
|
||||||
GIPHY_MXC_PREFIX = mxcPrefix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GiphySearchTab extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
this.state = {
|
|
||||||
searchTerm: "",
|
|
||||||
gifs: [],
|
|
||||||
loading: false,
|
|
||||||
error: null,
|
|
||||||
}
|
|
||||||
this.handleGifClick = this.handleGifClick.bind(this)
|
|
||||||
this.searchKeyUp = this.searchKeyUp.bind(this)
|
|
||||||
this.updateGifSearchQuery = this.updateGifSearchQuery.bind(this)
|
|
||||||
this.searchTimeout = null
|
|
||||||
}
|
|
||||||
|
|
||||||
async makeGifSearchRequest() {
|
|
||||||
try {
|
|
||||||
const resp = await fetch(`https://api.giphy.com/v1/gifs/search?q=${this.state.searchTerm}&api_key=${GIPHY_API_KEY}`)
|
|
||||||
// TODO handle error responses properly?
|
|
||||||
const data = await resp.json()
|
|
||||||
if (data.data.length === 0) {
|
|
||||||
this.setState({gifs: [], error: "No results"})
|
|
||||||
} else {
|
|
||||||
this.setState({gifs: data.data, error: null})
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.setState({error})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
clearTimeout(this.searchTimeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchKeyUp(event) {
|
|
||||||
if (event.key === "Enter") {
|
|
||||||
clearTimeout(this.searchTimeout)
|
|
||||||
this.makeGifSearchRequest()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateGifSearchQuery(event) {
|
|
||||||
this.setState({searchTerm: event.target.value})
|
|
||||||
clearTimeout(this.searchTimeout)
|
|
||||||
this.searchTimeout = setTimeout(() => this.makeGifSearchRequest(), GIPHY_SEARCH_DEBOUNCE)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleGifClick(gif) {
|
|
||||||
widgetAPI.sendSticker({
|
|
||||||
"body": gif.title,
|
|
||||||
"info": {
|
|
||||||
"h": +gif.images.original.height,
|
|
||||||
"w": +gif.images.original.width,
|
|
||||||
"size": +gif.images.original.size,
|
|
||||||
"mimetype": "image/webp",
|
|
||||||
},
|
|
||||||
"msgtype": "m.image",
|
|
||||||
"url": GIPHY_MXC_PREFIX + gif.id,
|
|
||||||
|
|
||||||
"id": gif.id,
|
|
||||||
"filename": gif.id + ".webp",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// TODO display loading state?
|
|
||||||
return html`
|
|
||||||
<${SearchBox} onInput=${this.updateGifSearchQuery} onKeyUp=${this.searchKeyUp} value=${this.state.searchTerm} placeholder="Find GIFs"/>
|
|
||||||
<div class="pack-list">
|
|
||||||
<section class="stickerpack" id="pack-giphy">
|
|
||||||
<div class="error">
|
|
||||||
${this.state.error}
|
|
||||||
</div>
|
|
||||||
<div class="sticker-list">
|
|
||||||
${this.state.gifs.map((gif) => html`
|
|
||||||
<div class="sticker" onClick=${() => this.handleGifClick(gif)} data-gif-id=${gif.id}>
|
|
||||||
<img src=${gif.images.fixed_height.url} alt=${gif.title} class="visible" data=/>
|
|
||||||
</div>
|
|
||||||
`)}
|
|
||||||
</div>
|
|
||||||
<div class="footer powered-by-giphy">
|
|
||||||
<img src="./res/powered-by-giphy.png" alt="Powered by GIPHY"/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
227
web/src/index.js
227
web/src/index.js
@@ -13,12 +13,12 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import {html, render, Component} from "../lib/htm/preact.js"
|
import { html, render, Component } from "../lib/htm/preact.js"
|
||||||
import {Spinner} from "./spinner.js"
|
import { Spinner } from "./spinner.js"
|
||||||
import {SearchBox} from "./search-box.js"
|
import { SearchBox } from "./search-box.js"
|
||||||
import {giphyIsEnabled, GiphySearchTab, setGiphyAPIKey} from "./giphy.js"
|
|
||||||
import * as widgetAPI from "./widget-api.js"
|
import * as widgetAPI from "./widget-api.js"
|
||||||
import * as frequent from "./frequently-used.js"
|
import * as frequent from "./frequently-used.js"
|
||||||
|
// import GiphyAPI from "./GiphySearch.js"
|
||||||
|
|
||||||
// The base URL for fetching packs. The app will first fetch ${PACK_BASE_URL}/index.json,
|
// The base URL for fetching packs. The app will first fetch ${PACK_BASE_URL}/index.json,
|
||||||
// then ${PACK_BASE_URL}/${packFile} for each packFile in the packs object of the index.json file.
|
// then ${PACK_BASE_URL}/${packFile} for each packFile in the packs object of the index.json file.
|
||||||
@@ -29,8 +29,11 @@ const params = new URLSearchParams(document.location.search)
|
|||||||
if (params.has('config')) {
|
if (params.has('config')) {
|
||||||
INDEX = params.get("config")
|
INDEX = params.get("config")
|
||||||
}
|
}
|
||||||
|
// This is updated from packs/index.json
|
||||||
|
let HOMESERVER_URL = "https://matrix-client.matrix.org"
|
||||||
|
let GIPHY_API_KEY = ""
|
||||||
|
|
||||||
const makeThumbnailURL = mxc => `${PACKS_BASE_URL}/thumbnails/${mxc.split("/").slice(-1)[0]}`
|
const makeThumbnailURL = mxc => `${HOMESERVER_URL}/_matrix/media/r0/thumbnail/${mxc.substr(6)}?height=128&width=128&method=scale`
|
||||||
|
|
||||||
// We need to detect iOS webkit because it has a bug related to scrolling non-fixed divs
|
// We need to detect iOS webkit because it has a bug related to scrolling non-fixed divs
|
||||||
// This is also used to fix scrolling to sections on Element iOS
|
// This is also used to fix scrolling to sections on Element iOS
|
||||||
@@ -38,6 +41,7 @@ const isMobileSafari = navigator.userAgent.match(/(iPod|iPhone|iPad)/) && naviga
|
|||||||
|
|
||||||
const supportedThemes = ["light", "dark", "black"]
|
const supportedThemes = ["light", "dark", "black"]
|
||||||
|
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
packs: [],
|
packs: [],
|
||||||
filtering: {
|
filtering: {
|
||||||
@@ -46,12 +50,108 @@ const defaultState = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GiphySearchTab extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
searchTerm: "",
|
||||||
|
gifs: [],
|
||||||
|
loading: false,
|
||||||
|
GIFById: {},
|
||||||
|
};
|
||||||
|
this.handleSearchChange = this.handleSearchChange.bind(this);
|
||||||
|
this.searchGifs = this.searchGifs.bind(this);
|
||||||
|
this.handleGifClick = this.handleGifClick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async searchGifs() {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
try {
|
||||||
|
// const apiKey = "Gc7131jiJuvI7IdN0HZ1D7nh0ow5BU6g";
|
||||||
|
const apiKey = GIPHY_API_KEY;
|
||||||
|
const url = `https://api.giphy.com/v1/gifs/search?q=${this.state.searchTerm}&api_key=${apiKey}`;
|
||||||
|
this.setState({ loading: true });
|
||||||
|
const response = await fetch(url);
|
||||||
|
const data = await response.json();
|
||||||
|
this.setState({ gifs: data.data, loading: false });
|
||||||
|
data.data.forEach((jsonElement) => {
|
||||||
|
const id = jsonElement.id;
|
||||||
|
const updatedItem = {
|
||||||
|
"body": jsonElement.title,
|
||||||
|
"info": {
|
||||||
|
"h": jsonElement.images.original.height,
|
||||||
|
"w": jsonElement.images.original.width,
|
||||||
|
"size": jsonElement.images.original.size,
|
||||||
|
"mimetype": "image/gif",
|
||||||
|
"thumbnail_info": {
|
||||||
|
"h": jsonElement.images.fixed_width_still.height,
|
||||||
|
"mimetype": "image/jpg",
|
||||||
|
"size": jsonElement.images.fixed_width_still.size,
|
||||||
|
"w": jsonElement.images.fixed_width_still.width
|
||||||
|
},
|
||||||
|
"thumbnail_url": jsonElement.images.fixed_width_still.url
|
||||||
|
},
|
||||||
|
"msgtype": "m.image",
|
||||||
|
"url": jsonElement.images.original.url
|
||||||
|
};
|
||||||
|
this.setState((prevState) => ({
|
||||||
|
GIFById: {...prevState.GIFById, [id]: updatedItem}}));
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ error: "Error fetching GIFs", loading: false });
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchChange(event) {
|
||||||
|
this.setState({ searchTerm: event.target.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGifClick(gif) {
|
||||||
|
console.log(this.state.GIFById[gif.id]);
|
||||||
|
widgetAPI.sendGIF(this.state.GIFById[gif.id]);
|
||||||
|
}
|
||||||
|
async searchGiphy(searchTerm) {
|
||||||
|
if (!searchTerm) return;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { searchTerm, gifs, loading } = this.state;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="search-box">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value=${searchTerm}
|
||||||
|
onInput=${this.handleSearchChange}
|
||||||
|
placeholder="Search GIFs..."
|
||||||
|
/>
|
||||||
|
<button onClick=${this.searchGifs} disabled=${loading}>Search</button>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="gifs-list" style="display: grid"> -->
|
||||||
|
<div class="pack-list">
|
||||||
|
<section class="stickerpack">
|
||||||
|
<div class="sticker-list">
|
||||||
|
${GIPHY_API_KEY !== "" && gifs.map((gif) => html`
|
||||||
|
<div class="sticker" onClick=${() => this.handleGifClick(gif)} data-gif-id=${gif.id}>
|
||||||
|
<img src=${gif.images.fixed_height.url} alt=${gif.title} class="visible" data=/>
|
||||||
|
</div>
|
||||||
|
`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.defaultTheme = params.get("theme")
|
this.defaultTheme = params.get("theme")
|
||||||
this.state = {
|
this.state = {
|
||||||
viewingGifs: false,
|
activeTab: "stickers",
|
||||||
packs: defaultState.packs,
|
packs: defaultState.packs,
|
||||||
loading: true,
|
loading: true,
|
||||||
error: null,
|
error: null,
|
||||||
@@ -118,7 +218,7 @@ class App extends Component {
|
|||||||
filtering: {
|
filtering: {
|
||||||
...this.state.filtering,
|
...this.state.filtering,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
packs: packsWithFilteredStickers.filter(({stickers}) => !!stickers.length),
|
packs: packsWithFilteredStickers.filter(({ stickers }) => !!stickers.length),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -135,10 +235,10 @@ class App extends Component {
|
|||||||
setTheme(theme) {
|
setTheme(theme) {
|
||||||
if (theme === "default") {
|
if (theme === "default") {
|
||||||
delete localStorage.mauStickerThemeOverride
|
delete localStorage.mauStickerThemeOverride
|
||||||
this.setState({theme: this.defaultTheme})
|
this.setState({ theme: this.defaultTheme })
|
||||||
} else {
|
} else {
|
||||||
localStorage.mauStickerThemeOverride = theme
|
localStorage.mauStickerThemeOverride = theme
|
||||||
this.setState({theme: theme})
|
this.setState({ theme: theme })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +254,7 @@ class App extends Component {
|
|||||||
|
|
||||||
_loadPacks(disableCache = false) {
|
_loadPacks(disableCache = false) {
|
||||||
const cache = disableCache ? "no-cache" : undefined
|
const cache = disableCache ? "no-cache" : undefined
|
||||||
fetch(INDEX, {cache}).then(async indexRes => {
|
fetch(INDEX, { cache }).then(async indexRes => {
|
||||||
if (indexRes.status >= 400) {
|
if (indexRes.status >= 400) {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -163,16 +263,15 @@ class App extends Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const indexData = await indexRes.json()
|
const indexData = await indexRes.json()
|
||||||
if (indexData.giphy_api_key !== undefined) {
|
HOMESERVER_URL = indexData.homeserver_url || HOMESERVER_URL
|
||||||
setGiphyAPIKey(indexData.giphy_api_key, indexData.giphy_mxc_prefix)
|
GIPHY_API_KEY = indexData.giphy_api_key || ""
|
||||||
}
|
|
||||||
// TODO only load pack metadata when scrolled into view?
|
// TODO only load pack metadata when scrolled into view?
|
||||||
for (const packFile of indexData.packs) {
|
for (const packFile of indexData.packs) {
|
||||||
let packRes
|
let packRes
|
||||||
if (packFile.startsWith("https://") || packFile.startsWith("http://")) {
|
if (packFile.startsWith("https://") || packFile.startsWith("http://")) {
|
||||||
packRes = await fetch(packFile, {cache})
|
packRes = await fetch(packFile, { cache })
|
||||||
} else {
|
} else {
|
||||||
packRes = await fetch(`${PACKS_BASE_URL}/${packFile}`, {cache})
|
packRes = await fetch(`${PACKS_BASE_URL}/${packFile}`, { cache })
|
||||||
}
|
}
|
||||||
const packData = await packRes.json()
|
const packData = await packRes.json()
|
||||||
for (const sticker of packData.stickers) {
|
for (const sticker of packData.stickers) {
|
||||||
@@ -184,7 +283,7 @@ class App extends Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.updateFrequentlyUsed()
|
this.updateFrequentlyUsed()
|
||||||
}, error => this.setState({loading: false, error}))
|
}, error => this.setState({ loading: false, error }))
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -216,9 +315,6 @@ class App extends Component {
|
|||||||
let maxXElem = null
|
let maxXElem = null
|
||||||
for (const entry of intersections) {
|
for (const entry of intersections) {
|
||||||
const packID = entry.target.getAttribute("data-pack-id")
|
const packID = entry.target.getAttribute("data-pack-id")
|
||||||
if (!packID) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
const navElement = document.getElementById(`nav-${packID}`)
|
const navElement = document.getElementById(`nav-${packID}`)
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
navElement.classList.add("visible")
|
navElement.classList.add("visible")
|
||||||
@@ -235,9 +331,9 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (minXElem !== null) {
|
if (minXElem !== null) {
|
||||||
minXElem.scrollIntoView({inline: "start"})
|
minXElem.scrollIntoView({ inline: "start" })
|
||||||
} else if (maxXElem !== null) {
|
} else if (maxXElem !== null) {
|
||||||
maxXElem.scrollIntoView({inline: "end"})
|
maxXElem.scrollIntoView({ inline: "end" })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,68 +367,57 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const theme = `theme-${this.state.theme}`
|
const theme = `theme-${this.state.theme}`;
|
||||||
const filterActive = !!this.state.filtering.searchTerm
|
const filterActive = !!this.state.filtering.searchTerm;
|
||||||
const packs = filterActive
|
const packs = filterActive
|
||||||
? this.state.filtering.packs
|
? this.state.filtering.packs
|
||||||
: [this.state.frequentlyUsed, ...this.state.packs]
|
: [this.state.frequentlyUsed, ...this.state.packs];
|
||||||
|
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
return html`
|
return html`<main class="spinner ${theme}"><${Spinner} size=${80} green /></main>`;
|
||||||
<main class="spinner ${theme}">
|
|
||||||
<${Spinner} size=${80} green/>
|
|
||||||
</main>
|
|
||||||
`
|
|
||||||
} else if (this.state.error) {
|
} else if (this.state.error) {
|
||||||
return html`
|
return html`<main class="error ${theme}">
|
||||||
<main class="error ${theme}">
|
|
||||||
<h1>Failed to load packs</h1>
|
<h1>Failed to load packs</h1>
|
||||||
<p>${this.state.error}</p>
|
<p>${this.state.error}</p>
|
||||||
</main>
|
</main>`;
|
||||||
`
|
|
||||||
} else if (this.state.packs.length === 0) {
|
} else if (this.state.packs.length === 0) {
|
||||||
return html`
|
return html`<main class="empty ${theme}"><h1>No packs found 😿</h1></main>`;
|
||||||
<main class="empty ${theme}"><h1>No packs found 😿</h1></main>
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClickOverride = this.state.viewingGifs
|
return html`<main class="has-content ${theme}">
|
||||||
? (evt, packID) => {
|
<div class="tab-container" style="display: flex;">
|
||||||
evt.preventDefault()
|
<a href="#stickers" class="tab" onClick=${() => this.setState({ activeTab: "stickers" })}>Stickers</a>
|
||||||
this.setState({viewingGifs: false}, () => {
|
<a href="#gifs" class="tab" onClick=${() => this.setState({ activeTab: "gifs" })}>GIFs</a>
|
||||||
scrollToSection(null, packID)
|
</div>
|
||||||
})
|
|
||||||
} : null
|
|
||||||
const switchToGiphy = () => this.setState({viewingGifs: true, filtering: defaultState.filtering})
|
|
||||||
|
|
||||||
return html`
|
${this.state.activeTab === "stickers" && html`
|
||||||
<main class="has-content ${theme}">
|
|
||||||
<nav onWheel=${this.navScroll} ref=${elem => this.navRef = elem}>
|
<nav onWheel=${this.navScroll} ref=${elem => this.navRef = elem}>
|
||||||
${giphyIsEnabled() && html`
|
<${NavBarItem} pack=${this.state.frequentlyUsed} iconOverride="recent" />
|
||||||
<${NavBarItem} pack=${{id: "giphy", title: "GIPHY"}} iconOverride="giphy" onClickOverride=${switchToGiphy} extraClass=${this.state.viewingGifs ? "visible" : ""}/>
|
${this.state.packs.map(pack => html`<${NavBarItem} id=${pack.id} pack=${pack}/>`)}
|
||||||
`}
|
<${NavBarItem} pack=${{ id: "settings", title: "Settings" }} iconOverride="settings" />
|
||||||
<${NavBarItem} pack=${this.state.frequentlyUsed} iconOverride="recent" onClickOverride=${onClickOverride}/>
|
|
||||||
${this.state.packs.map(pack => html`<${NavBarItem} id=${pack.id} pack=${pack} onClickOverride=${onClickOverride}/>`)}
|
|
||||||
<${NavBarItem} pack=${{id: "settings", title: "Settings"}} iconOverride="settings" onClickOverride=${onClickOverride}/>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
${this.state.viewingGifs ? html`
|
<${SearchBox} onKeyUp=${this.searchStickers} />
|
||||||
<${GiphySearchTab}/>
|
|
||||||
` : html`
|
|
||||||
<${SearchBox} onInput=${this.searchStickers} value=${this.state.filtering.searchTerm ?? ""}/>
|
|
||||||
<div class="pack-list ${isMobileSafari ? "ios-safari-hack" : ""}" ref=${(elem) => (this.packListRef = elem)}>
|
<div class="pack-list ${isMobileSafari ? "ios-safari-hack" : ""}" ref=${(elem) => (this.packListRef = elem)}>
|
||||||
${filterActive && packs.length === 0
|
${filterActive && packs.length === 0
|
||||||
? html`<div class="search-empty"><h1>No stickers match your search</h1></div>`
|
? html`<div class="search-empty"><h1>No stickers match your search</h1></div>`
|
||||||
: null}
|
: null}
|
||||||
${packs.map((pack) => html`<${Pack} id=${pack.id} pack=${pack} send=${this.sendSticker}/>`)}
|
${packs.map((pack) => html`<${Pack} id=${pack.id} pack=${pack} send=${this.sendSticker} />`)}
|
||||||
<${Settings} app=${this}/>
|
<${Settings} app=${this} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
`}
|
`}
|
||||||
</main>`
|
${this.state.activeTab === "gifs" && GIPHY_API_KEY !== "" && html`
|
||||||
|
<${GiphySearchTab} send=${this.sendGIF} />
|
||||||
|
`}
|
||||||
|
${this.state.activeTab === "gifs" && GIPHY_API_KEY === "" && html`
|
||||||
|
<h1><center>GIF Search is not enabled. Please enable it in the config.</center></h1>
|
||||||
|
`}
|
||||||
|
</main>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Settings = ({app}) => html`
|
const Settings = ({ app }) => html`
|
||||||
<section class="stickerpack settings" id="pack-settings" data-pack-id="settings">
|
<section class="stickerpack settings" id="pack-settings" data-pack-id="settings">
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
<div class="settings-list">
|
<div class="settings-list">
|
||||||
@@ -341,7 +426,7 @@ const Settings = ({app}) => html`
|
|||||||
<label for="stickers-per-row">Stickers per row: ${app.state.stickersPerRow}</label>
|
<label for="stickers-per-row">Stickers per row: ${app.state.stickersPerRow}</label>
|
||||||
<input type="range" min=2 max=10 id="stickers-per-row" id="stickers-per-row"
|
<input type="range" min=2 max=10 id="stickers-per-row" id="stickers-per-row"
|
||||||
value=${app.state.stickersPerRow}
|
value=${app.state.stickersPerRow}
|
||||||
onInput=${evt => app.setStickersPerRow(evt.target.value)}/>
|
onInput=${evt => app.setStickersPerRow(evt.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="theme">Theme: </label>
|
<label for="theme">Theme: </label>
|
||||||
@@ -360,15 +445,13 @@ const Settings = ({app}) => html`
|
|||||||
// open the link in the browser instead of just scrolling there, so we need to scroll manually:
|
// open the link in the browser instead of just scrolling there, so we need to scroll manually:
|
||||||
const scrollToSection = (evt, id) => {
|
const scrollToSection = (evt, id) => {
|
||||||
const pack = document.getElementById(`pack-${id}`)
|
const pack = document.getElementById(`pack-${id}`)
|
||||||
if (pack) {
|
pack.scrollIntoView({ block: "start", behavior: "instant" })
|
||||||
pack.scrollIntoView({block: "start", behavior: "instant"})
|
evt.preventDefault()
|
||||||
}
|
|
||||||
evt?.preventDefault()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavBarItem = ({pack, iconOverride = null, onClickOverride = null, extraClass = null}) => html`
|
const NavBarItem = ({ pack, iconOverride = null }) => html`
|
||||||
<a href="#pack-${pack.id}" id="nav-${pack.id}" data-pack-id=${pack.id} title=${pack.title} class="${extraClass}"
|
<a href="#pack-${pack.id}" id="nav-${pack.id}" data-pack-id=${pack.id} title=${pack.title}
|
||||||
onClick=${onClickOverride ? (evt => onClickOverride(evt, pack.id)) : (isMobileSafari ? (evt => scrollToSection(evt, pack.id)) : undefined)}>
|
onClick=${isMobileSafari ? (evt => scrollToSection(evt, pack.id)) : undefined}>
|
||||||
<div class="sticker">
|
<div class="sticker">
|
||||||
${iconOverride ? html`
|
${iconOverride ? html`
|
||||||
<span class="icon icon-${iconOverride}"/>
|
<span class="icon icon-${iconOverride}"/>
|
||||||
@@ -380,7 +463,7 @@ const NavBarItem = ({pack, iconOverride = null, onClickOverride = null, extraCla
|
|||||||
</a>
|
</a>
|
||||||
`
|
`
|
||||||
|
|
||||||
const Pack = ({pack, send}) => html`
|
const Pack = ({ pack, send }) => html`
|
||||||
<section class="stickerpack" id="pack-${pack.id}" data-pack-id=${pack.id}>
|
<section class="stickerpack" id="pack-${pack.id}" data-pack-id=${pack.id}>
|
||||||
<h1>${pack.title}</h1>
|
<h1>${pack.title}</h1>
|
||||||
<div class="sticker-list">
|
<div class="sticker-list">
|
||||||
@@ -391,10 +474,10 @@ const Pack = ({pack, send}) => html`
|
|||||||
</section>
|
</section>
|
||||||
`
|
`
|
||||||
|
|
||||||
const Sticker = ({content, send}) => html`
|
const Sticker = ({ content, send }) => html`
|
||||||
<div class="sticker" onClick=${send} data-sticker-id=${content.id}>
|
<div class="sticker" onClick=${send} data-sticker-id=${content.id}>
|
||||||
<img data-src=${makeThumbnailURL(content.url)} alt=${content.body} title=${content.body}/>
|
<img data-src=${makeThumbnailURL(content.url)} alt=${content.body} title=${content.body} />
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
render(html`<${App}/>`, document.body)
|
render(html`<${App} />`, document.body)
|
||||||
|
@@ -13,13 +13,13 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import {html} from "../lib/htm/preact.js"
|
import { html } from "../lib/htm/preact.js"
|
||||||
|
|
||||||
export const SearchBox = ({onInput, onKeyUp, value, placeholder = 'Find stickers'}) => {
|
export const SearchBox = ({ onKeyUp, placeholder = 'Find stickers' }) => {
|
||||||
const component = html`
|
const component = html`
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<input type="text" placeholder=${placeholder} value=${value} onInput=${onInput} onKeyUp=${onKeyUp}/>
|
<input type="text" placeholder=${placeholder} onKeyUp=${onKeyUp} />
|
||||||
<span class="icon icon-search"/>
|
<span class="icon icon-search" />
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
return component
|
return component
|
||||||
|
@@ -13,65 +13,178 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
let widgetId = null
|
|
||||||
|
|
||||||
window.onmessage = event => {
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
if (!window.parent || !event.data) {
|
const widgetId = urlParams.get('widgetId'); // if you know the widget ID, supply it.
|
||||||
return
|
console.log("Widget ID:"+widgetId);
|
||||||
}
|
const api = new mxwidgets.WidgetApi(widgetId, '*');
|
||||||
|
|
||||||
const request = event.data
|
|
||||||
if (!request.requestId || !request.widgetId || !request.action || request.api !== "toWidget") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widgetId) {
|
// Before doing anything else, request capabilities:
|
||||||
if (widgetId !== request.widgetId) {
|
api.requestCapabilities(mxwidgets.StickerpickerCapabilities);
|
||||||
return
|
api.requestCapability(mxwidgets.MatrixCapabilities.MSC4039UploadFile);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
widgetId = request.widgetId
|
|
||||||
}
|
|
||||||
|
|
||||||
let response
|
api.on("ready", () => {console.log("ready event received")});
|
||||||
|
|
||||||
if (request.action === "visibility") {
|
// Start the messaging
|
||||||
response = {}
|
api.start();
|
||||||
} else if (request.action === "capabilities") {
|
|
||||||
response = { capabilities: ["m.sticker"] }
|
|
||||||
} else {
|
|
||||||
response = { error: { message: "Action not supported" } }
|
|
||||||
}
|
|
||||||
|
|
||||||
window.parent.postMessage({ ...request, response }, event.origin)
|
// If waitForIframeLoad is false, tell the client that we're good to go
|
||||||
}
|
//api.sendContentLoaded();
|
||||||
|
|
||||||
export function sendSticker(content) {
|
export function sendSticker(content){
|
||||||
const data = {
|
const data = {
|
||||||
content: { ...content },
|
content: {...content},
|
||||||
// `name` is for Element Web (and also the spec)
|
|
||||||
// Element Android uses content -> body as the name
|
|
||||||
name: content.body,
|
name: content.body,
|
||||||
}
|
};
|
||||||
// Custom field that stores the ID even for non-telegram stickers
|
// do the same thing that tulir does
|
||||||
delete data.content.id
|
delete data.content.id;
|
||||||
|
// send data
|
||||||
// This is for Element iOS
|
api.sendSticker(data);
|
||||||
const widgetData = {
|
|
||||||
...data,
|
|
||||||
description: content.body,
|
|
||||||
file: content.filename ?? `${content.id}.png`,
|
|
||||||
}
|
|
||||||
delete widgetData.content.filename
|
|
||||||
// Element iOS explodes if there are extra fields present
|
|
||||||
delete widgetData.content["net.maunium.telegram.sticker"]
|
|
||||||
|
|
||||||
window.parent.postMessage({
|
|
||||||
api: "fromWidget",
|
|
||||||
action: "m.sticker",
|
|
||||||
requestId: `sticker-${Date.now()}`,
|
|
||||||
widgetId,
|
|
||||||
data,
|
|
||||||
widgetData,
|
|
||||||
}, "*")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*export function sendGIF(content){
|
||||||
|
* // just print out content, should be URL
|
||||||
|
* console.log("Content:"+content.url);
|
||||||
|
* return new Promise((resolve, reject) => {
|
||||||
|
* const xhr = new XMLHttpRequest();
|
||||||
|
* xhr.open('GET', content.url, true);
|
||||||
|
* xhr.onreadystatechange = function() {
|
||||||
|
* if (xhr.readyState === 4) {
|
||||||
|
* if (xhr.status === 200) {
|
||||||
|
* const responseData = xhr.responseText;
|
||||||
|
* // Call uploadFile with response data
|
||||||
|
* api.uploadFile(responseData)
|
||||||
|
* .then(result => {
|
||||||
|
* console.log("Here's the result:"+result.content_uri);
|
||||||
|
* // mess around with the content object, then send it as sticker
|
||||||
|
* content.url = result.content_uri;
|
||||||
|
* sendSticker(content);
|
||||||
|
* resolve(result);
|
||||||
|
* })
|
||||||
|
* .catch(error => {
|
||||||
|
* reject(error);
|
||||||
|
* });
|
||||||
|
* } else {
|
||||||
|
* reject(new Error('Failed to fetch data')); // Reject the outer promise if fetching data fails
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* xhr.send();
|
||||||
|
* });
|
||||||
|
*}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export async function sendGIF(content){
|
||||||
|
// just print content, since it's a custom type with URL
|
||||||
|
console.log("Content:"+content.url);
|
||||||
|
// use fetch because I'm on IE
|
||||||
|
const lol = await fetch(content.url);
|
||||||
|
const uri_file = await lol.blob();
|
||||||
|
// call uploadFile with this
|
||||||
|
var result = await api.uploadFile(uri_file)
|
||||||
|
console.log("Got URI:"+result.content_uri);
|
||||||
|
content.url = result.content_uri;
|
||||||
|
// get thumbnail
|
||||||
|
//const thumb_uri = await fetch(content.info.thumbnail_url)
|
||||||
|
//const thumb_file = await thumb_uri.blob();
|
||||||
|
//result = await api.uploadFile(thumb_file)
|
||||||
|
//console.log("Thumb URI:"+result.content_uri);
|
||||||
|
//content.info.thumbnail_url = result.content_uri;
|
||||||
|
// actually, just delete the thumbnail
|
||||||
|
delete content.info.thumbnail_url;
|
||||||
|
// finally, send it as sticker
|
||||||
|
sendSticker(content);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*let widgetId = null
|
||||||
|
*
|
||||||
|
*window.onmessage = event => {
|
||||||
|
* if (!window.parent || !event.data) {
|
||||||
|
* return
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* const request = event.data
|
||||||
|
* if (!request.requestId || !request.widgetId || !request.action || request.api !== "toWidget") {
|
||||||
|
* return
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (widgetId) {
|
||||||
|
* if (widgetId !== request.widgetId) {
|
||||||
|
* return
|
||||||
|
* }
|
||||||
|
* } else {
|
||||||
|
* widgetId = request.widgetId
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* let response
|
||||||
|
*
|
||||||
|
* if (request.action === "visibility") {
|
||||||
|
* response = {}
|
||||||
|
* } else if (request.action === "capabilities") {
|
||||||
|
* response = { capabilities: ["m.sticker", "org.matrix.msc4039.upload_file"] }
|
||||||
|
* } else {
|
||||||
|
* response = { error: { message: "Action not supported" } }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* window.parent.postMessage({ ...request, response }, event.origin)
|
||||||
|
*}
|
||||||
|
*
|
||||||
|
*export function sendSticker(content) {
|
||||||
|
* const data = {
|
||||||
|
* content: { ...content },
|
||||||
|
* // `name` is for Element Web (and also the spec)
|
||||||
|
* // Element Android uses content -> body as the name
|
||||||
|
* name: content.body,
|
||||||
|
* }
|
||||||
|
* // Custom field that stores the ID even for non-telegram stickers
|
||||||
|
* delete data.content.id
|
||||||
|
*
|
||||||
|
* // This is for Element iOS
|
||||||
|
* const widgetData = {
|
||||||
|
* ...data,
|
||||||
|
* description: content.body,
|
||||||
|
* file: `${content.id}.png`,
|
||||||
|
* }
|
||||||
|
* // Element iOS explodes if there are extra fields present
|
||||||
|
* delete widgetData.content["net.maunium.telegram.sticker"]
|
||||||
|
*
|
||||||
|
* window.parent.postMessage({
|
||||||
|
* api: "fromWidget",
|
||||||
|
* action: "m.sticker",
|
||||||
|
* requestId: `sticker-${Date.now()}`,
|
||||||
|
* widgetId,
|
||||||
|
* data,
|
||||||
|
* widgetData,
|
||||||
|
* }, "*")
|
||||||
|
*}
|
||||||
|
*
|
||||||
|
*export function sendGIF(content) {
|
||||||
|
* const data = {
|
||||||
|
* content: { ...content },
|
||||||
|
* name: content.body,
|
||||||
|
* msgtype: "m.image"
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* delete data.content.id
|
||||||
|
* // This is for Element iOS
|
||||||
|
* const widgetData = {
|
||||||
|
* ...data,
|
||||||
|
* description: content.body,
|
||||||
|
* file: `${content.id}.png`,
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* window.parent.postMessage({
|
||||||
|
* api: "fromWidget",
|
||||||
|
* action: "m.room.message",
|
||||||
|
* requestId: `gif-${Date.now()}`,
|
||||||
|
* widgetId,
|
||||||
|
* data,
|
||||||
|
* widgetData,
|
||||||
|
* }, "*")
|
||||||
|
*}
|
||||||
|
*/
|
||||||
|
@@ -1 +1,16 @@
|
|||||||
*{font-family:sans-serif}body{margin:0}h1{font-size:1rem}:root{--stickers-per-row: 4;--sticker-size: calc(100vw / var(--stickers-per-row))}main{color:var(--text-color)}main.spinner{margin-top:5rem}main.error,main.empty{margin:2rem}main.empty{text-align:center}main.has-content{position:fixed;top:0;left:0;right:0;bottom:0;display:grid;grid-template-rows:calc(12vw + 2px) min-content auto}main.theme-light{--highlight-color: #eee;--search-box-color: var(--highlight-color);--text-color: black;background-color:#fff}main.theme-dark{--highlight-color: #444;--search-box-color: #383e4b;--text-color: white;background-color:#22262e}main.theme-dark .icon.icon-giphy{background-image:url(../res/giphy-dark.svg)}main.theme-black{--highlight-color: #222;--search-box-color: var(--highlight-color);--text-color: white;background-color:#000}main.theme-black .icon.icon-giphy{background-image:url(../res/giphy-dark.svg)}div.powered-by-giphy{padding:1rem}div.powered-by-giphy>img{width:100%}.icon{width:100%;height:100%;background-color:var(--text-color);mask-size:contain;-webkit-mask-size:contain;mask-image:var(--icon-image);-webkit-mask-image:var(--icon-image)}.icon.icon-settings{--icon-image: url(../res/settings.svg)}.icon.icon-recent{--icon-image: url(../res/recent.svg)}.icon.icon.icon-search{--icon-image: url(../res/search.svg)}.icon.icon.icon-giphy{background:center/contain no-repeat url(../res/giphy-light.svg);mask:unset}nav{display:flex;overflow-x:auto}nav>a{border-bottom:2px solid rgba(0,0,0,0)}nav>a.visible{border-bottom-color:green}nav>a>div.sticker{width:12vw;height:12vw}div.pack-list,nav{scrollbar-width:none}div.pack-list::-webkit-scrollbar,nav::-webkit-scrollbar{display:none}div.pack-list{overflow-y:auto}div.pack-list.ios-safari-hack{position:fixed;top:calc(calc(12vw + 2px) + calc(2 * 0.7rem + 2 * 0.5rem + 1rem));bottom:0;left:0;right:0;-webkit-overflow-scrolling:touch}div.search-empty{margin:1.2rem;text-align:center}section.stickerpack{margin-top:.75rem}section.stickerpack>div.sticker-list{display:flex;flex-wrap:wrap}section.stickerpack>h1{margin:0 0 0 .75rem}section.stickerpack#pack-giphy{display:flex;justify-content:space-between;flex-direction:column;min-height:100%}div.sticker{display:flex;padding:4px;cursor:pointer;position:relative;width:var(--sticker-size);height:var(--sticker-size);box-sizing:border-box}div.sticker:hover{background-color:var(--highlight-color)}div.sticker>img{display:none;width:100%;object-fit:contain}div.sticker>img.visible{display:initial}div.sticker>.icon{width:70%;height:70%;margin:15%}div.search-box{position:relative;display:flex}div.search-box>input[type=text]{flex-grow:1;background-color:var(--search-box-color);outline:none;border:none;border-radius:.25rem;height:1rem;padding:.7rem;padding-right:calc(1rem + 0.7rem);margin:.5rem;font-size:1rem;color:var(--text-color)}div.search-box>span.icon{display:flex;position:absolute;top:calc(50% - 1rem/2);right:1rem;width:1rem;height:1rem;box-sizing:border-box}div.settings-list{display:flex;flex-direction:column}div.settings-list>*{margin:.5rem}div.settings-list button{padding:.5rem;border-radius:.25rem}div.settings-list input{width:100%}
|
*{font-family:sans-serif}body{margin:0}h1{font-size:1rem}:root{--stickers-per-row: 4;--sticker-size: calc(100vw / var(--stickers-per-row))}main{color:var(--text-color)}main.spinner{margin-top:5rem}main.error,main.empty{margin:2rem}main.empty{text-align:center}main.has-content{position:fixed;top:0;left:0;right:0;bottom:0;display:grid;grid-template-rows:calc(12vw + 2px) min-content auto}main.theme-light{--highlight-color: #eee;--search-box-color: var(--highlight-color);--text-color: black;background-color:#fff}main.theme-dark{--highlight-color: #444;--search-box-color: #383e4b;--text-color: white;background-color:#22262e}main.theme-black{--highlight-color: #222;--search-box-color: var(--highlight-color);--text-color: white;background-color:#000}.icon{width:100%;height:100%;background-color:var(--text-color);mask-size:contain;-webkit-mask-size:contain;mask-image:var(--icon-image);-webkit-mask-image:var(--icon-image)}.icon.icon-settings{--icon-image: url(../res/settings.svg)}.icon.icon-recent{--icon-image: url(../res/recent.svg)}.icon.icon.icon-search{--icon-image: url(../res/search.svg)}nav{display:flex;overflow-x:auto}nav>a{border-bottom:2px solid transparent}nav>a.visible{border-bottom-color:green}nav>a>div.sticker{width:12vw;height:12vw}div.pack-list,nav{scrollbar-width:none}div.pack-list::-webkit-scrollbar,nav::-webkit-scrollbar{display:none}div.pack-list{overflow-y:auto}div.pack-list.ios-safari-hack{position:fixed;top:calc(calc(12vw + 2px) + calc(2 * 0.7rem + 2 * 0.5rem + 1rem));bottom:0;left:0;right:0;-webkit-overflow-scrolling:touch}div.search-empty{margin:1.2rem;text-align:center}section.stickerpack{margin-top:.75rem}section.stickerpack>div.sticker-list{display:flex;flex-wrap:wrap}section.stickerpack>h1{margin:0 0 0 .75rem}div.sticker{display:flex;padding:4px;cursor:pointer;position:relative;width:var(--sticker-size);height:var(--sticker-size);box-sizing:border-box}div.sticker:hover{background-color:var(--highlight-color)}div.sticker>img{display:none;width:100%;object-fit:contain}div.sticker>img.visible{display:initial}div.sticker>.icon{width:70%;height:70%;margin:15%}div.search-box{position:relative;display:flex}div.search-box>input[type=text]{flex-grow:1;background-color:var(--search-box-color);outline:none;border:none;border-radius:.25rem;height:1rem;padding:.7rem;padding-right:calc(1rem + 0.7rem);margin:.5rem;font-size:1rem;color:var(--text-color)}div.search-box>span.icon{display:flex;position:absolute;top:calc(50% - 1rem / 2);right:1rem;width:1rem;height:1rem;box-sizing:border-box}div.settings-list{display:flex;flex-direction:column}div.settings-list>*{margin:.5rem}div.settings-list button{padding:.5rem;border-radius:.25rem}div.settings-list input{width:100%}
|
||||||
|
|
||||||
|
a.tab {
|
||||||
|
padding: 5% 5%;
|
||||||
|
width: 40%;
|
||||||
|
text-align: center;
|
||||||
|
border: none;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
-moz-appearance: button;
|
||||||
|
appearance: button;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
color: initial;
|
||||||
|
}
|
||||||
|
@@ -71,23 +71,12 @@ main.theme-dark
|
|||||||
--text-color: white
|
--text-color: white
|
||||||
background-color: #22262e
|
background-color: #22262e
|
||||||
|
|
||||||
.icon.icon-giphy
|
|
||||||
background-image: url(../res/giphy-dark.svg)
|
|
||||||
|
|
||||||
main.theme-black
|
main.theme-black
|
||||||
--highlight-color: #222
|
--highlight-color: #222
|
||||||
--search-box-color: var(--highlight-color)
|
--search-box-color: var(--highlight-color)
|
||||||
--text-color: white
|
--text-color: white
|
||||||
background-color: black
|
background-color: black
|
||||||
|
|
||||||
.icon.icon-giphy
|
|
||||||
background-image: url(../res/giphy-dark.svg)
|
|
||||||
|
|
||||||
div.powered-by-giphy
|
|
||||||
padding: 1rem
|
|
||||||
> img
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
.icon
|
.icon
|
||||||
width: 100%
|
width: 100%
|
||||||
height: 100%
|
height: 100%
|
||||||
@@ -106,10 +95,6 @@ div.powered-by-giphy
|
|||||||
&.icon.icon-search
|
&.icon.icon-search
|
||||||
--icon-image: url(../res/search.svg)
|
--icon-image: url(../res/search.svg)
|
||||||
|
|
||||||
&.icon.icon-giphy
|
|
||||||
background: center / contain no-repeat url(../res/giphy-light.svg)
|
|
||||||
mask: unset
|
|
||||||
|
|
||||||
nav
|
nav
|
||||||
display: flex
|
display: flex
|
||||||
overflow-x: auto
|
overflow-x: auto
|
||||||
@@ -155,12 +140,6 @@ section.stickerpack
|
|||||||
> h1
|
> h1
|
||||||
margin: 0 0 0 .75rem
|
margin: 0 0 0 .75rem
|
||||||
|
|
||||||
section.stickerpack#pack-giphy
|
|
||||||
display: flex
|
|
||||||
justify-content: space-between
|
|
||||||
flex-direction: column
|
|
||||||
min-height: 100%
|
|
||||||
|
|
||||||
div.sticker
|
div.sticker
|
||||||
display: flex
|
display: flex
|
||||||
padding: 4px
|
padding: 4px
|
||||||
@@ -225,3 +204,4 @@ div.settings-list
|
|||||||
|
|
||||||
input
|
input
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
|
372
web/yarn.lock
372
web/yarn.lock
@@ -16,13 +16,13 @@
|
|||||||
resolve "^1.17.0"
|
resolve "^1.17.0"
|
||||||
|
|
||||||
"@rollup/plugin-inject@^4.0.0", "@rollup/plugin-inject@^4.0.2":
|
"@rollup/plugin-inject@^4.0.0", "@rollup/plugin-inject@^4.0.2":
|
||||||
version "4.0.4"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz#fbeee66e9a700782c4f65c8b0edbafe58678fbc2"
|
resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-4.0.2.tgz#55b21bb244a07675f7fdde577db929c82fc17395"
|
||||||
integrity sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==
|
integrity sha512-TSLMA8waJ7Dmgmoc8JfPnwUwVZgLjjIAM6MqeIFqPO2ODK36JqE0Cf2F54UTgCUuW8da93Mvoj75a6KAVWgylw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@rollup/pluginutils" "^3.1.0"
|
"@rollup/pluginutils" "^3.0.4"
|
||||||
estree-walker "^2.0.1"
|
estree-walker "^1.0.1"
|
||||||
magic-string "^0.25.7"
|
magic-string "^0.25.5"
|
||||||
|
|
||||||
"@rollup/plugin-json@^4.0.0":
|
"@rollup/plugin-json@^4.0.0":
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"@rollup/pluginutils" "^3.1.0"
|
"@rollup/pluginutils" "^3.1.0"
|
||||||
magic-string "^0.25.7"
|
magic-string "^0.25.7"
|
||||||
|
|
||||||
"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0":
|
"@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
||||||
integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
|
integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
|
||||||
@@ -61,9 +61,9 @@
|
|||||||
picomatch "^2.2.2"
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
"@types/estree@*":
|
"@types/estree@*":
|
||||||
version "1.0.5"
|
version "0.0.50"
|
||||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
||||||
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
|
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
||||||
|
|
||||||
"@types/estree@0.0.39":
|
"@types/estree@0.0.39":
|
||||||
version "0.0.39"
|
version "0.0.39"
|
||||||
@@ -71,11 +71,9 @@
|
|||||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "20.12.12"
|
version "16.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.2.tgz#5764ca9aa94470adb4e1185fe2e9f19458992b2e"
|
||||||
integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==
|
integrity sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==
|
||||||
dependencies:
|
|
||||||
undici-types "~5.26.4"
|
|
||||||
|
|
||||||
"@types/resolve@1.17.1":
|
"@types/resolve@1.17.1":
|
||||||
version "1.17.1"
|
version "1.17.1"
|
||||||
@@ -84,31 +82,21 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
acorn-walk@^8.2.0:
|
|
||||||
version "8.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa"
|
|
||||||
integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==
|
|
||||||
|
|
||||||
acorn@^8.7.0:
|
|
||||||
version "8.11.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
|
|
||||||
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
|
|
||||||
|
|
||||||
anymatch@~3.1.2:
|
anymatch@~3.1.2:
|
||||||
version "3.1.3"
|
version "3.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||||
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||||
dependencies:
|
dependencies:
|
||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
assert@^1.4.1:
|
assert@^1.4.1:
|
||||||
version "1.5.1"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76"
|
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
|
||||||
integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==
|
integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
|
||||||
dependencies:
|
dependencies:
|
||||||
object.assign "^4.1.4"
|
object-assign "^4.1.1"
|
||||||
util "^0.10.4"
|
util "0.10.3"
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@@ -116,9 +104,9 @@ balanced-match@^1.0.0:
|
|||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
binary-extensions@^2.0.0:
|
binary-extensions@^2.0.0:
|
||||||
version "2.3.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
@@ -136,30 +124,19 @@ braces@~3.0.2:
|
|||||||
fill-range "^7.0.1"
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
builtin-modules@^3.1.0, builtin-modules@^3.2.0:
|
builtin-modules@^3.1.0, builtin-modules@^3.2.0:
|
||||||
version "3.3.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
|
||||||
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
|
||||||
|
|
||||||
builtins@^1.0.3:
|
builtins@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
|
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
|
||||||
integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==
|
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
|
||||||
|
|
||||||
call-bind@^1.0.5:
|
|
||||||
version "1.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
|
|
||||||
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
set-function-length "^1.2.1"
|
|
||||||
|
|
||||||
"chokidar@>=3.0.0 <4.0.0":
|
"chokidar@>=3.0.0 <4.0.0":
|
||||||
version "3.6.0"
|
version "3.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
|
||||||
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
anymatch "~3.1.2"
|
anymatch "~3.1.2"
|
||||||
braces "~3.0.2"
|
braces "~3.0.2"
|
||||||
@@ -172,19 +149,19 @@ call-bind@^1.0.5:
|
|||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
cjs-module-lexer@^1.2.1:
|
cjs-module-lexer@^1.2.1:
|
||||||
version "1.3.1"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c"
|
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
|
||||||
integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==
|
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
||||||
|
|
||||||
commondir@^1.0.1:
|
commondir@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||||
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
|
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
cross-spawn@^7.0.3:
|
cross-spawn@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
@@ -196,39 +173,9 @@ cross-spawn@^7.0.3:
|
|||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
deepmerge@^4.2.2:
|
deepmerge@^4.2.2:
|
||||||
version "4.3.1"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
|
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||||
|
|
||||||
define-data-property@^1.0.1, define-data-property@^1.1.4:
|
|
||||||
version "1.1.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
|
|
||||||
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
gopd "^1.0.1"
|
|
||||||
|
|
||||||
define-properties@^1.2.1:
|
|
||||||
version "1.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
|
|
||||||
integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
|
|
||||||
dependencies:
|
|
||||||
define-data-property "^1.0.1"
|
|
||||||
has-property-descriptors "^1.0.0"
|
|
||||||
object-keys "^1.1.1"
|
|
||||||
|
|
||||||
es-define-property@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
|
|
||||||
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
|
|
||||||
dependencies:
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
|
|
||||||
es-errors@^1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
|
||||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
|
||||||
|
|
||||||
es-module-lexer@^0.6.0:
|
es-module-lexer@^0.6.0:
|
||||||
version "0.6.0"
|
version "0.6.0"
|
||||||
@@ -296,7 +243,7 @@ fill-range@^7.0.1:
|
|||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
|
|
||||||
fsevents@~2.1.2:
|
fsevents@~2.1.2:
|
||||||
version "2.1.3"
|
version "2.1.3"
|
||||||
@@ -304,25 +251,14 @@ fsevents@~2.1.2:
|
|||||||
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
|
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
|
||||||
|
|
||||||
fsevents@~2.3.2:
|
fsevents@~2.3.2:
|
||||||
version "2.3.3"
|
version "2.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
|
|
||||||
function-bind@^1.1.2:
|
function-bind@^1.1.1:
|
||||||
version "1.1.2"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
|
|
||||||
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
|
|
||||||
dependencies:
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
has-proto "^1.0.1"
|
|
||||||
has-symbols "^1.0.3"
|
|
||||||
hasown "^2.0.0"
|
|
||||||
|
|
||||||
get-stream@^6.0.0:
|
get-stream@^6.0.0:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
@@ -337,67 +273,38 @@ glob-parent@~5.1.2:
|
|||||||
is-glob "^4.0.1"
|
is-glob "^4.0.1"
|
||||||
|
|
||||||
glob@^7.1.3, glob@^7.1.6:
|
glob@^7.1.3, glob@^7.1.6:
|
||||||
version "7.2.3"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||||
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
|
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
fs.realpath "^1.0.0"
|
fs.realpath "^1.0.0"
|
||||||
inflight "^1.0.4"
|
inflight "^1.0.4"
|
||||||
inherits "2"
|
inherits "2"
|
||||||
minimatch "^3.1.1"
|
minimatch "^3.0.4"
|
||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
path-is-absolute "^1.0.0"
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
gopd@^1.0.1:
|
has@^1.0.3:
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
|
|
||||||
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
|
|
||||||
dependencies:
|
|
||||||
get-intrinsic "^1.1.3"
|
|
||||||
|
|
||||||
has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
|
|
||||||
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
|
|
||||||
has-proto@^1.0.1:
|
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
|
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||||
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
|
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||||
|
|
||||||
has-symbols@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
|
||||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
|
||||||
|
|
||||||
hasown@^2.0.0:
|
|
||||||
version "2.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
|
||||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.2"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
htm@^3.1.0:
|
htm@^3.1.0:
|
||||||
version "3.1.1"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/htm/-/htm-3.1.1.tgz#49266582be0dc66ed2235d5ea892307cc0c24b78"
|
resolved "https://registry.yarnpkg.com/htm/-/htm-3.1.0.tgz#0c305493b60da9f6ed097a2aaf4c994bd85ea022"
|
||||||
integrity sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==
|
integrity sha512-L0s3Sid5r6YwrEvkig14SK3Emmc+kIjlfLhEGn2Vy3bk21JyDEes4MoDsbJk6luaPp8bugErnxPz86ZuAw6e5Q==
|
||||||
|
|
||||||
human-signals@^2.1.0:
|
human-signals@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||||
|
|
||||||
immutable@^4.0.0:
|
|
||||||
version "4.3.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.6.tgz#6a05f7858213238e587fb83586ffa3b4b27f0447"
|
|
||||||
integrity sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==
|
|
||||||
|
|
||||||
inflight@^1.0.4:
|
inflight@^1.0.4:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
|
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||||
dependencies:
|
dependencies:
|
||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
@@ -407,10 +314,10 @@ inherits@2:
|
|||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
inherits@2.0.3:
|
inherits@2.0.1:
|
||||||
version "2.0.3"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||||
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
|
integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
|
||||||
|
|
||||||
is-binary-path@~2.1.0:
|
is-binary-path@~2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
@@ -419,17 +326,17 @@ is-binary-path@~2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions "^2.0.0"
|
binary-extensions "^2.0.0"
|
||||||
|
|
||||||
is-core-module@^2.13.0:
|
is-core-module@^2.2.0:
|
||||||
version "2.13.1"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3"
|
||||||
integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
|
integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
hasown "^2.0.0"
|
has "^1.0.3"
|
||||||
|
|
||||||
is-extglob@^2.1.1:
|
is-extglob@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||||
|
|
||||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
@@ -441,7 +348,7 @@ is-glob@^4.0.1, is-glob@~4.0.1:
|
|||||||
is-module@^1.0.0:
|
is-module@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||||
integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
|
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
|
||||||
|
|
||||||
is-number@^7.0.0:
|
is-number@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
@@ -470,19 +377,19 @@ is-valid-identifier@^2.0.2:
|
|||||||
isexe@^2.0.0:
|
isexe@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||||
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
|
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||||
|
|
||||||
kleur@^4.1.1:
|
kleur@^4.1.1:
|
||||||
version "4.1.5"
|
version "4.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d"
|
||||||
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
|
integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==
|
||||||
|
|
||||||
magic-string@^0.25.7:
|
magic-string@^0.25.5, magic-string@^0.25.7:
|
||||||
version "0.25.9"
|
version "0.25.7"
|
||||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||||
integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
|
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
sourcemap-codec "^1.4.8"
|
sourcemap-codec "^1.4.4"
|
||||||
|
|
||||||
merge-stream@^2.0.0:
|
merge-stream@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@@ -494,10 +401,10 @@ mimic-fn@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||||
|
|
||||||
minimatch@^3.1.1:
|
minimatch@^3.0.4:
|
||||||
version "3.1.2"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
@@ -518,25 +425,15 @@ npm-run-path@^4.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
path-key "^3.0.0"
|
path-key "^3.0.0"
|
||||||
|
|
||||||
object-keys@^1.1.1:
|
object-assign@^4.1.1:
|
||||||
version "1.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
|
||||||
object.assign@^4.1.4:
|
|
||||||
version "4.1.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0"
|
|
||||||
integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==
|
|
||||||
dependencies:
|
|
||||||
call-bind "^1.0.5"
|
|
||||||
define-properties "^1.2.1"
|
|
||||||
has-symbols "^1.0.3"
|
|
||||||
object-keys "^1.1.1"
|
|
||||||
|
|
||||||
once@^1.3.0:
|
once@^1.3.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
|
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||||
dependencies:
|
dependencies:
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
@@ -550,27 +447,27 @@ onetime@^5.1.2:
|
|||||||
path-is-absolute@^1.0.0:
|
path-is-absolute@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
path-key@^3.0.0, path-key@^3.1.0:
|
path-key@^3.0.0, path-key@^3.1.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
|
|
||||||
path-parse@^1.0.7:
|
path-parse@^1.0.6:
|
||||||
version "1.0.7"
|
version "1.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.0:
|
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.0:
|
||||||
version "2.3.1"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||||
|
|
||||||
preact@^10.5.14:
|
preact@^10.5.14:
|
||||||
version "10.22.0"
|
version "10.5.14"
|
||||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.22.0.tgz#a50f38006ae438d255e2631cbdaf7488e6dd4e16"
|
resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.14.tgz#0b14a2eefba3c10a57116b90d1a65f5f00cd2701"
|
||||||
integrity sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==
|
integrity sha512-KojoltCrshZ099ksUZ2OQKfbH66uquFoxHSbnwKbTJHeQNvx42EmC7wQVWNuDt6vC5s3nudRHFtKbpY4ijKlaQ==
|
||||||
|
|
||||||
readdirp@~3.6.0:
|
readdirp@~3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
@@ -580,13 +477,12 @@ readdirp@~3.6.0:
|
|||||||
picomatch "^2.2.1"
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
resolve@^1.17.0, resolve@^1.20.0:
|
resolve@^1.17.0, resolve@^1.20.0:
|
||||||
version "1.22.8"
|
version "1.20.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||||
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
|
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||||
dependencies:
|
dependencies:
|
||||||
is-core-module "^2.13.0"
|
is-core-module "^2.2.0"
|
||||||
path-parse "^1.0.7"
|
path-parse "^1.0.6"
|
||||||
supports-preserve-symlinks-flag "^1.0.0"
|
|
||||||
|
|
||||||
rimraf@^3.0.0:
|
rimraf@^3.0.0:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
@@ -610,25 +506,11 @@ rollup@~2.37.1:
|
|||||||
fsevents "~2.1.2"
|
fsevents "~2.1.2"
|
||||||
|
|
||||||
sass@^1.42.1:
|
sass@^1.42.1:
|
||||||
version "1.77.2"
|
version "1.42.1"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.2.tgz#18d4ed2eefc260cdc8099c5439ec1303fd5863aa"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.42.1.tgz#5ab17bebc1cb1881ad2e0c9a932c66ad64e441e2"
|
||||||
integrity sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==
|
integrity sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
immutable "^4.0.0"
|
|
||||||
source-map-js ">=0.6.2 <2.0.0"
|
|
||||||
|
|
||||||
set-function-length@^1.2.1:
|
|
||||||
version "1.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
|
|
||||||
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
|
|
||||||
dependencies:
|
|
||||||
define-data-property "^1.1.4"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
gopd "^1.0.1"
|
|
||||||
has-property-descriptors "^1.0.2"
|
|
||||||
|
|
||||||
shebang-command@^2.0.0:
|
shebang-command@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@@ -643,21 +525,16 @@ shebang-regex@^3.0.0:
|
|||||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||||
|
|
||||||
signal-exit@^3.0.3:
|
signal-exit@^3.0.3:
|
||||||
version "3.0.7"
|
version "3.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f"
|
||||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==
|
||||||
|
|
||||||
slash@~3.0.0:
|
slash@~3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
"source-map-js@>=0.6.2 <2.0.0":
|
sourcemap-codec@^1.4.4:
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
|
|
||||||
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
|
|
||||||
|
|
||||||
sourcemap-codec@^1.4.8:
|
|
||||||
version "1.4.8"
|
version "1.4.8"
|
||||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||||
@@ -667,11 +544,6 @@ strip-final-newline@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
supports-preserve-symlinks-flag@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
|
||||||
|
|
||||||
to-regex-range@^5.0.1:
|
to-regex-range@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||||
@@ -679,32 +551,24 @@ to-regex-range@^5.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-number "^7.0.0"
|
is-number "^7.0.0"
|
||||||
|
|
||||||
undici-types@~5.26.4:
|
util@0.10.3:
|
||||||
version "5.26.5"
|
version "0.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
|
||||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
|
||||||
|
|
||||||
util@^0.10.4:
|
|
||||||
version "0.10.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901"
|
|
||||||
integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits "2.0.3"
|
inherits "2.0.1"
|
||||||
|
|
||||||
validate-npm-package-name@^3.0.0:
|
validate-npm-package-name@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"
|
resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"
|
||||||
integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==
|
integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34=
|
||||||
dependencies:
|
dependencies:
|
||||||
builtins "^1.0.3"
|
builtins "^1.0.3"
|
||||||
|
|
||||||
vm2@^3.9.2:
|
vm2@^3.9.2:
|
||||||
version "3.9.19"
|
version "3.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.19.tgz#be1e1d7a106122c6c492b4d51c2e8b93d3ed6a4a"
|
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.3.tgz#29917f6cc081cc43a3f580c26c5b553fd3c91f40"
|
||||||
integrity sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==
|
integrity sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q==
|
||||||
dependencies:
|
|
||||||
acorn "^8.7.0"
|
|
||||||
acorn-walk "^8.2.0"
|
|
||||||
|
|
||||||
which@^2.0.1:
|
which@^2.0.1:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
@@ -716,4 +580,4 @@ which@^2.0.1:
|
|||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
Reference in New Issue
Block a user