Compare commits
16 Commits
d891a412e1
...
7b17ebdcba
Author | SHA1 | Date |
---|---|---|
Alexander Zhirov | 7b17ebdcba | |
Alexander Zhirov | e8874acc69 | |
Infactum | c45b30924c | |
Infactum | 99805b7db6 | |
Infactum | 6e08102559 | |
Infactum | 4dca437ff6 | |
infactum | b5784d54f9 | |
infactum | f4495ede1b | |
infactum | 80bf430b08 | |
Infactum | a7c6d3e57d | |
infactum | d394f11915 | |
infactum | ce25cf6665 | |
infactum | e21fd4da62 | |
Infactum | b3d7b9859d | |
infactum | 713914b3ad | |
infactum | b90f91401f |
|
@ -0,0 +1,84 @@
|
|||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Native Build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
tag: [bionic, centos7]
|
||||
container: infactum/tg2sip-builder:${{ matrix.tag }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
[ -d "/opt/rh" ] && source /opt/rh/devtoolset-7/enable
|
||||
mkdir build && cd build
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . -j $(grep -c ^processor /proc/cpuinfo);
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: tg2sip_${{ matrix.tag }}
|
||||
path: |
|
||||
build/tg2sip
|
||||
build/gen_db
|
||||
build/settings.ini
|
||||
|
||||
# AppImage generation cannot be fully done inside container
|
||||
# because of FUSE requirements
|
||||
- name: Prepare AppImage
|
||||
if: matrix.tag == 'centos7'
|
||||
run: |
|
||||
linuxdeploy --appdir tg2sip -e build/tg2sip
|
||||
linuxdeploy --appdir gen_db -e build/gen_db
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: matrix.tag == 'centos7'
|
||||
with:
|
||||
name: tmp
|
||||
path: |
|
||||
tg2sip/
|
||||
gen_db/
|
||||
|
||||
appimage:
|
||||
name: Pack AppImage
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: tmp
|
||||
path: tmp
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool.AppImage
|
||||
chmod +x appimagetool.AppImage
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -O linuxdeploy.AppImage
|
||||
chmod +x linuxdeploy.AppImage
|
||||
|
||||
- name: Pack
|
||||
run: |
|
||||
./linuxdeploy.AppImage --appdir tmp/tg2sip -d buildenv/tg2sip.desktop -i buildenv/icon.svg
|
||||
./linuxdeploy.AppImage --appdir tmp/gen_db -d buildenv/gen_db.desktop -i buildenv/icon.svg
|
||||
chmod +x tmp/tg2sip/usr/bin/tg2sip
|
||||
chmod +x tmp/gen_db/usr/bin/gen_db
|
||||
./appimagetool.AppImage tmp/tg2sip
|
||||
./appimagetool.AppImage tmp/gen_db
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: tg2sip_universal
|
||||
path: |
|
||||
tg2sip-x86_64.AppImage
|
||||
gen_db-x86_64.AppImage
|
||||
settings.ini;
|
|
@ -0,0 +1,2 @@
|
|||
build
|
||||
.vscode
|
|
@ -7,8 +7,8 @@ add_subdirectory(libtgvoip)
|
|||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(Td 1.2.0 REQUIRED)
|
||||
find_package(spdlog 0.17 REQUIRED)
|
||||
find_package(Td 1.8.0 REQUIRED)
|
||||
find_package(spdlog 1.11.0 REQUIRED)
|
||||
pkg_check_modules(PJSIP libpjproject>=2.8 REQUIRED)
|
||||
pkg_check_modules(OPUS opus REQUIRED)
|
||||
|
||||
|
|
21
README.md
21
README.md
|
@ -1,4 +1,4 @@
|
|||
[![Build status](https://ci.appveyor.com/api/projects/status/4dnph34apvfy6vft?svg=true)](https://ci.appveyor.com/project/Infactum/tg2sip)
|
||||
[![Build status](https://github.com/Infactum/tg2sip/workflows/CI/badge.svg)](https://github.com/Infactum/tg2sip/actions)
|
||||
|
||||
# TG2SIP
|
||||
|
||||
|
@ -10,10 +10,14 @@ Your SIP PBX should be comaptible with `L16@48000` or `OPUS@48000` voice codec.
|
|||
|
||||
## Usage
|
||||
|
||||
1. Download prebuild versions for supported OS from CI or compile it yourself.
|
||||
[Ubuntu 18.04 Bionic](https://ci.appveyor.com/api/projects/Infactum/tg2sip/artifacts/tg2sip_bionic.zip?branch=master&job=Environment%3A%20target_name%3DUbuntu%20Bionic%2C%20docker_tag%3Dbionic)
|
||||
[CentOS 7](https://ci.appveyor.com/api/projects/Infactum/tg2sip/artifacts/tg2sip_centos7.zip?branch=master&job=Environment%3A%20target_name%3DCentOS%207%2C%20docker_tag%3Dcentos7)
|
||||
1. Obtain binaries in one of convenient ways for you.
|
||||
* Build them from source.
|
||||
Requires C++17 supported comiler, which may be a trouble for old linux distros.
|
||||
* Download prebuild native binaries for one of supported distros.
|
||||
Prebuild binaries requires OPUS libraries (`libopus0` for Ubuntu, `opus` for CentOS, etc).
|
||||
* Download universal AppImage package.
|
||||
More information of what is AppImage can be found here https://appimage.org/
|
||||
|
||||
2. Obtain `api_id` and `api_hash` tokens from [this](https://my.telegram.org) page and put them in `settings.ini` file.
|
||||
3. Login into telegram with `gen_db` app
|
||||
4. Set SIP server settings in `settings.ini`
|
||||
|
@ -25,14 +29,11 @@ SIP->Telegram calls can be done using 3 extension types:
|
|||
2. `\+[\d]+` for calls by phone number
|
||||
3. `[\d]+` for calls by telegram ID. Only known IDs allowed by telegram API.
|
||||
|
||||
All Telegram->SIP calls will be redirected to `callback_uri` SIP-URI that can be set in from `settings.ini` file.
|
||||
Extra information about caller Telegram account will be added into `X-TG-*` SIP tags.
|
||||
|
||||
## Donate
|
||||
|
||||
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=755FZWPRC9YGL&lc=US&item_name=TG2SIP¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)
|
||||
|
||||
[Yandex.Money](https://yasobe.ru/na/tg2sip)
|
||||
|
||||
**BTC** 39wNzvtcyRrTKmq5DjcUfGTixnGVSf8qLg
|
||||
**BCH** qqgwg0g96sayht4lzxc89ky7mkdxfyj7jcl5m8qfps
|
||||
**ETH** 0x72B8cb476b2c85b1170Ae2cdFB243B17680290b4
|
||||
**ETC** 0x9C7d6CD9F9E0584e65f8aD20e1d2Ced947a55207
|
||||
**LTC** MFyBRJTnHqXharzH7D3FYeEhAJuywMRfMd
|
||||
|
|
50
appveyor.yml
50
appveyor.yml
|
@ -1,50 +0,0 @@
|
|||
version: 1.0.0+{build}
|
||||
|
||||
image:
|
||||
- Ubuntu
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
configuration: Release
|
||||
|
||||
platform: x64
|
||||
|
||||
environment:
|
||||
global:
|
||||
docker_login: infactum
|
||||
docker_password:
|
||||
secure: wWPsUiEtw8rfnjX2/Y3/AA==
|
||||
docker_image: infactum/tg2sip-builder
|
||||
|
||||
matrix:
|
||||
- target_name: Ubuntu Bionic
|
||||
docker_tag: bionic
|
||||
|
||||
- target_name: CentOS 7
|
||||
docker_tag: centos7
|
||||
|
||||
init:
|
||||
- sh: |
|
||||
docker login -u "$docker_login" -p "$docker_password"
|
||||
docker pull "$docker_image":"$docker_tag"
|
||||
|
||||
install:
|
||||
- sh: docker build buildenv/ -f buildenv/Dockerfile."$docker_tag" --cache-from "$docker_image":"$docker_tag" -t "$docker_image":"$docker_tag"
|
||||
|
||||
build_script:
|
||||
- sh: >-
|
||||
mkdir build;
|
||||
docker run --rm -v "$(pwd)":/src "$docker_image":"$docker_tag" /bin/bash -c "
|
||||
mkdir build && cd build;
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig && cmake -DCMAKE_BUILD_TYPE=Release /src
|
||||
cmake --build .;
|
||||
chmod +x tg2sip;
|
||||
chmod +x gen_db;
|
||||
cp tg2sip /src/build;
|
||||
cp gen_db /src/build;"
|
||||
7z a tg2sip.zip ./build/tg2sip ./build/gen_db ./settings.ini;
|
||||
|
||||
after_build:
|
||||
- sh: docker push "$docker_image":"$docker_tag"
|
||||
- sh: appveyor PushArtifact tg2sip.zip -FileName tg2sip_"$docker_tag".zip -DeploymentName "TG2SIP $target_name"
|
|
@ -8,31 +8,33 @@ RUN apt-get update \
|
|||
zlib1g-dev gperf ccache \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN wget https://cmake.org/files/v3.9/cmake-3.9.6-Linux-x86_64.sh \
|
||||
&& sh cmake-3.9.6-Linux-x86_64.sh --prefix=/usr --exclude-subdir
|
||||
RUN wget https://cmake.org/files/v3.18/cmake-3.18.0-Linux-x86_64.sh \
|
||||
&& sh cmake-3.18.0-Linux-x86_64.sh --prefix=/usr --exclude-subdir
|
||||
|
||||
COPY tdlib_header.patch /
|
||||
COPY tdlib_threadname.patch /
|
||||
|
||||
# TDLib 1.7.10
|
||||
RUN git clone https://github.com/tdlib/td.git \
|
||||
&& cd td \
|
||||
&& git reset --hard v1.2.0 \
|
||||
&& git reset --hard a53cb30e99f937cfd64e0266fa558785a184a553 \
|
||||
&& git apply /tdlib_header.patch \
|
||||
&& git apply /tdlib_threadname.patch \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release .. \
|
||||
&& cmake --build . --target install \
|
||||
&& cmake --build . --target install -j $(grep -c ^processor /proc/cpuinfo) \
|
||||
&& cd / \
|
||||
&& rm -rf td
|
||||
|
||||
COPY config_site.h /
|
||||
|
||||
RUN git clone https://github.com/Infactum/pjproject.git \
|
||||
RUN git clone https://github.com/pjsip/pjproject.git \
|
||||
&& cd pjproject \
|
||||
&& git reset --hard 2.9 \
|
||||
&& cp /config_site.h pjlib/include/pj \
|
||||
&& ./configure --disable-sound CFLAGS="-O3 -DNDEBUG" \
|
||||
&& make dep && make && make install \
|
||||
&& make dep && make -j $(grep -c ^processor /proc/cpuinfo) && make install \
|
||||
&& cd / \
|
||||
&& rm -rf pjproject
|
||||
|
||||
|
@ -42,6 +44,6 @@ RUN git clone -n https://github.com/gabime/spdlog.git \
|
|||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLES=OFF -DSPDLOG_BUILD_TESTING=OFF .. \
|
||||
&& cmake --build . --target install \
|
||||
&& cmake --build . --target install -j $(grep -c ^processor /proc/cpuinfo) \
|
||||
&& cd / \
|
||||
&& rm -rf spdlog
|
|
@ -9,35 +9,40 @@ RUN yum install -y \
|
|||
make \
|
||||
git wget \
|
||||
zlib-devel opus-devel openssl-devel gperf \
|
||||
pkgconfig ccache gperf unzip
|
||||
pkgconfig ccache gperf unzip \
|
||||
libpng-devel libjpeg-devel \
|
||||
epel-release \
|
||||
&& yum install -y patchelf
|
||||
|
||||
RUN wget https://cmake.org/files/v3.9/cmake-3.9.6-Linux-x86_64.sh \
|
||||
&& sh cmake-3.9.6-Linux-x86_64.sh --prefix=/usr --exclude-subdir
|
||||
RUN wget https://cmake.org/files/v3.18/cmake-3.18.0-Linux-x86_64.sh \
|
||||
&& sh cmake-3.18.0-Linux-x86_64.sh --prefix=/usr --exclude-subdir
|
||||
|
||||
COPY tdlib_header.patch /
|
||||
COPY tdlib_threadname.patch /
|
||||
|
||||
# TDLib 1.7.10
|
||||
RUN source /opt/rh/devtoolset-7/enable \
|
||||
&& git clone https://github.com/tdlib/td.git \
|
||||
&& cd td \
|
||||
&& git reset --hard v1.2.0 \
|
||||
&& git reset --hard a53cb30e99f937cfd64e0266fa558785a184a553 \
|
||||
&& git apply /tdlib_header.patch \
|
||||
&& git apply /tdlib_threadname.patch \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release .. \
|
||||
&& cmake --build . --target install \
|
||||
&& cmake --build . --target install -j $(grep -c ^processor /proc/cpuinfo) \
|
||||
&& cd / \
|
||||
&& rm -rf td
|
||||
|
||||
COPY config_site.h /
|
||||
|
||||
RUN source /opt/rh/devtoolset-7/enable \
|
||||
&& git clone https://github.com/Infactum/pjproject.git \
|
||||
&& git clone https://github.com/pjsip/pjproject.git \
|
||||
&& cd pjproject \
|
||||
&& git reset --hard 2.9 \
|
||||
&& cp /config_site.h pjlib/include/pj \
|
||||
&& ./configure --disable-sound CFLAGS="-O3 -DNDEBUG" \
|
||||
&& make dep && make && make install \
|
||||
&& make dep && make -j $(grep -c ^processor /proc/cpuinfo) && make install \
|
||||
&& cd / \
|
||||
&& rm -rf pjproject
|
||||
|
||||
|
@ -48,10 +53,23 @@ RUN source /opt/rh/devtoolset-7/enable \
|
|||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLES=OFF -DSPDLOG_BUILD_TESTING=OFF .. \
|
||||
&& cmake --build . --target install \
|
||||
&& cmake --build . --target install -j $(grep -c ^processor /proc/cpuinfo) \
|
||||
&& cd / \
|
||||
&& rm -rf spdlog
|
||||
|
||||
RUN source /opt/rh/devtoolset-7/enable \
|
||||
&& git clone https://github.com/linuxdeploy/linuxdeploy.git \
|
||||
&& cd linuxdeploy \
|
||||
&& git checkout 557bad2241df2c33972c7e6bdbf0c528cee27cc8 \
|
||||
&& git submodule update --init --recursive \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig && cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_CIMG=0 .. \
|
||||
&& cmake --build . -j $(grep -c ^processor /proc/cpuinfo) \
|
||||
&& cp bin/linuxdeploy /usr/local/bin \
|
||||
&& cd / \
|
||||
&& rm -rf linuxdeploy
|
||||
|
||||
COPY centos_entrypoint.sh /
|
||||
|
||||
ENTRYPOINT ["/centos_entrypoint.sh"]
|
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Name=gen_db
|
||||
Exec=gen_db
|
||||
Comment=TG2SIP DB generator
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Icon=icon
|
||||
Categories=AudioVideo;
|
|
@ -0,0 +1,320 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48px"
|
||||
height="48px"
|
||||
id="svg3832"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="appimage-assistant_alt3.svg">
|
||||
<defs
|
||||
id="defs3834">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3308-4-6-931-761-0"
|
||||
id="linearGradient2975"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="24.3125"
|
||||
y1="22.96875"
|
||||
x2="24.3125"
|
||||
y2="41.03125" />
|
||||
<linearGradient
|
||||
id="linearGradient3308-4-6-931-761-0">
|
||||
<stop
|
||||
id="stop2919-2"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2921-76"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4222"
|
||||
id="linearGradient2979"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,0.3704967,-0.3617496,0,33.508315,6.1670925)"
|
||||
x1="7.6485429"
|
||||
y1="26.437023"
|
||||
x2="41.861729"
|
||||
y2="26.437023" />
|
||||
<linearGradient
|
||||
id="linearGradient4222">
|
||||
<stop
|
||||
id="stop4224"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4226"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3308-4-6-931-761"
|
||||
id="linearGradient2982"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,0.9999987)"
|
||||
x1="23.99999"
|
||||
y1="4.999989"
|
||||
x2="23.99999"
|
||||
y2="43" />
|
||||
<linearGradient
|
||||
id="linearGradient3308-4-6-931-761">
|
||||
<stop
|
||||
id="stop2919"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2921"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3575"
|
||||
id="radialGradient2985"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,1.0262008,-1.6561124,9.4072203e-4,-56.097482,-45.332325)"
|
||||
cx="48.42384"
|
||||
cy="-48.027504"
|
||||
fx="48.42384"
|
||||
fy="-48.027504"
|
||||
r="38.212933" />
|
||||
<linearGradient
|
||||
id="linearGradient3575">
|
||||
<stop
|
||||
id="stop3577"
|
||||
style="stop-color:#fafafa;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop3579"
|
||||
style="stop-color:#e6e6e6;stop-opacity:1"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3993"
|
||||
id="radialGradient2990"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,2.0478765,-2.7410544,-8.6412258e-8,47.161382,-8.837436)"
|
||||
cx="9.3330879"
|
||||
cy="8.4497671"
|
||||
fx="9.3330879"
|
||||
fy="8.4497671"
|
||||
r="19.99999" />
|
||||
<linearGradient
|
||||
id="linearGradient3993">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a3c0d0;stop-opacity:1"
|
||||
id="stop3995" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#427da1;stop-opacity:1"
|
||||
id="stop4001" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2508"
|
||||
id="linearGradient2992"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,0.9674382)"
|
||||
x1="14.048676"
|
||||
y1="44.137306"
|
||||
x2="14.048676"
|
||||
y2="4.0000005" />
|
||||
<linearGradient
|
||||
id="linearGradient2508">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#2e4a5a;stop-opacity:1"
|
||||
id="stop2510" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#6e8796;stop-opacity:1"
|
||||
id="stop2512" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="4.9929786"
|
||||
cy="43.5"
|
||||
r="2.5"
|
||||
fx="4.9929786"
|
||||
fy="43.5"
|
||||
id="radialGradient2873-966-168"
|
||||
xlink:href="#linearGradient3688-166-749"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.003784,0,0,1.4,27.98813,-17.4)" />
|
||||
<linearGradient
|
||||
id="linearGradient3688-166-749">
|
||||
<stop
|
||||
id="stop2883"
|
||||
style="stop-color:#181818;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2885"
|
||||
style="stop-color:#181818;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="4.9929786"
|
||||
cy="43.5"
|
||||
r="2.5"
|
||||
fx="4.9929786"
|
||||
fy="43.5"
|
||||
id="radialGradient2875-742-326"
|
||||
xlink:href="#linearGradient3688-464-309"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.003784,0,0,1.4,-20.01187,-104.4)" />
|
||||
<linearGradient
|
||||
id="linearGradient3688-464-309">
|
||||
<stop
|
||||
id="stop2889"
|
||||
style="stop-color:#181818;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2891"
|
||||
style="stop-color:#181818;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="25.058096"
|
||||
y1="47.027729"
|
||||
x2="25.058096"
|
||||
y2="39.999443"
|
||||
id="linearGradient2877-634-617"
|
||||
xlink:href="#linearGradient3702-501-757"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3702-501-757">
|
||||
<stop
|
||||
id="stop2895"
|
||||
style="stop-color:#181818;stop-opacity:0"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2897"
|
||||
style="stop-color:#181818;stop-opacity:1"
|
||||
offset="0.5" />
|
||||
<stop
|
||||
id="stop2899"
|
||||
style="stop-color:#181818;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7"
|
||||
inkscape:cx="24"
|
||||
inkscape:cy="24"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="603"
|
||||
inkscape:window-height="484"
|
||||
inkscape:window-x="417"
|
||||
inkscape:window-y="162"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3837">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g2036"
|
||||
transform="matrix(1.1,0,0,0.4444449,-2.4000022,25.11107)">
|
||||
<g
|
||||
style="opacity:0.4"
|
||||
id="g3712"
|
||||
transform="matrix(1.052632,0,0,1.285713,-1.263158,-13.42854)">
|
||||
<rect
|
||||
style="fill:url(#radialGradient2873-966-168);fill-opacity:1;stroke:none"
|
||||
id="rect2801"
|
||||
y="40"
|
||||
x="38"
|
||||
height="7"
|
||||
width="5" />
|
||||
<rect
|
||||
style="fill:url(#radialGradient2875-742-326);fill-opacity:1;stroke:none"
|
||||
id="rect3696"
|
||||
transform="scale(-1,-1)"
|
||||
y="-47"
|
||||
x="-10"
|
||||
height="7"
|
||||
width="5" />
|
||||
<rect
|
||||
style="fill:url(#linearGradient2877-634-617);fill-opacity:1;stroke:none"
|
||||
id="rect3700"
|
||||
y="40"
|
||||
x="10"
|
||||
height="7.0000005"
|
||||
width="28" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="fill:url(#radialGradient2990);fill-opacity:1;stroke:url(#linearGradient2992);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect5505"
|
||||
y="5.4674392"
|
||||
x="4.5"
|
||||
ry="2.2322156"
|
||||
rx="2.2322156"
|
||||
height="39"
|
||||
width="39" />
|
||||
<path
|
||||
style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path4294-1"
|
||||
d="m 21,6.9687498 a 2.0165107,2.0165107 0 0 0 -2.03125,2.03125 l 0,3.9687502 -1.15625,0 a 2.0165107,2.0165107 0 0 0 -1.5,3.375 l 5.0625,5.75 c -0.06312,0.110777 -0.178724,0.246032 -0.21875,0.34375 -0.195898,0.478256 -0.25,0.83653 -0.25,1.21875 l 0,0.125 L 20.8125,23.6875 C 20.534322,23.409323 20.213169,23.162739 19.71875,22.96875 19.47154,22.87176 19.185456,22.791748 18.75,22.8125 c -0.435456,0.02075 -1.054055,0.210302 -1.46875,0.625 L 15.75,24.96875 c -0.414689,0.414689 -0.604245,1.033294 -0.625,1.46875 -0.02075,0.435456 0.05925,0.721537 0.15625,0.96875 C 15.475241,27.900677 15.721817,28.221821 16,28.5 l 0.09375,0.09375 -0.125,0 c -0.382218,0 -0.740493,0.0541 -1.21875,0.25 -0.239128,0.09795 -0.538285,0.214988 -0.84375,0.53125 -0.305465,0.316262 -0.625,0.914788 -0.625,1.53125 l 0,2.1875 c 0,0.616465 0.319536,1.214989 0.625,1.53125 0.305464,0.316261 0.604622,0.433301 0.84375,0.53125 0.478256,0.195898 0.83653,0.25 1.21875,0.25 l 0.125,0 L 16,35.5 c -0.278175,0.278176 -0.52476,0.599329 -0.71875,1.09375 -0.09699,0.24721 -0.177003,0.533292 -0.15625,0.96875 0.02075,0.435458 0.210304,1.054058 0.625,1.46875 l 1.53125,1.53125 c 0.414691,0.414697 1.033292,0.604245 1.46875,0.625 0.435458,0.02076 0.721537,-0.05926 0.96875,-0.15625 0.494425,-0.19399 0.81557,-0.440568 1.09375,-0.71875 l 0.09375,-0.09375 0,0.125 c 0,0.38222 0.0541,0.740495 0.25,1.21875 0.09795,0.239127 0.214989,0.538285 0.53125,0.84375 0.316261,0.305465 0.914783,0.625 1.53125,0.625 l 2.1875,0 c 0.616466,0 1.214989,-0.319534 1.53125,-0.625 0.316261,-0.305466 0.433302,-0.604622 0.53125,-0.84375 0.195896,-0.478255 0.25,-0.836532 0.25,-1.21875 l 0,-0.125 0.09375,0.09375 c 0.278176,0.278175 0.599329,0.52476 1.09375,0.71875 0.24721,0.09699 0.533292,0.177003 0.96875,0.15625 0.435458,-0.02075 1.054058,-0.210304 1.46875,-0.625 L 32.875,39.03125 C 33.289697,38.616559 33.479245,37.997958 33.5,37.5625 33.52076,37.127042 33.44074,36.840963 33.34375,36.59375 33.14976,36.099325 32.903182,35.77818 32.625,35.5 l -0.09375,-0.09375 0.125,0 c 0.38222,0 0.740494,-0.0541 1.21875,-0.25 0.239128,-0.09795 0.538286,-0.214988 0.84375,-0.53125 0.305464,-0.316262 0.625,-0.914787 0.625,-1.53125 l 0,-2.1875 c 0,-0.61646 -0.319535,-1.214987 -0.625,-1.53125 -0.305465,-0.316263 -0.604621,-0.433301 -0.84375,-0.53125 -0.478257,-0.195898 -0.836532,-0.25 -1.21875,-0.25 l -0.125,0 L 32.625,28.5 c 0.278177,-0.278177 0.52476,-0.599329 0.71875,-1.09375 C 33.44074,27.15904 33.520753,26.872957 33.5,26.4375 33.47925,26.002043 33.289697,25.383443 32.875,24.96875 L 31.34375,23.4375 c -0.414688,-0.414694 -1.03329,-0.604245 -1.46875,-0.625 -0.43546,-0.02076 -0.721537,0.05925 -0.96875,0.15625 -0.494426,0.193991 -0.815572,0.44057 -1.09375,0.71875 l -0.09375,0.09375 0,-0.125 c 0,-0.382218 -0.0541,-0.740493 -0.25,-1.21875 -0.09112,-0.22245 -0.228127,-0.500183 -0.5,-0.78125 l 4.71875,-5.3125 a 2.0165107,2.0165107 0 0 0 -1.5,-3.375 l -1.15625,0 0,-3.9687502 A 2.0165107,2.0165107 0 0 0 27,6.9687498 l -6,0 z M 24.3125,31.25 c 0.427097,0 0.75,0.322904 0.75,0.75 0,0.427096 -0.322903,0.75 -0.75,0.75 -0.427094,0 -0.75,-0.322906 -0.75,-0.75 0,-0.427094 0.322906,-0.75 0.75,-0.75 z" />
|
||||
<path
|
||||
style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path4294"
|
||||
d="m 20.90625,8.0312498 a 0.96385067,0.96385067 0 0 0 -0.875,0.96875 l 0,5.0312502 -2.21875,0 A 0.96385067,0.96385067 0 0 0 17.09375,15.625 l 5.78125,6.53125 c -0.158814,0.0616 -0.341836,0.0951 -0.4375,0.1875 -0.169161,0.163386 -0.252971,0.323419 -0.3125,0.46875 -0.119058,0.290663 -0.15625,0.566746 -0.15625,0.84375 l 0,1.65625 C 21.718163,25.40233 21.485871,25.509772 21.25,25.625 l -1.1875,-1.1875 c -0.199651,-0.19965 -0.421433,-0.352095 -0.71875,-0.46875 -0.148659,-0.05833 -0.329673,-0.104846 -0.5625,-0.09375 -0.232827,0.0111 -0.53583,0.09833 -0.75,0.3125 L 16.5,25.71875 c -0.214168,0.214168 -0.301403,0.517173 -0.3125,0.75 -0.0111,0.232827 0.03542,0.41384 0.09375,0.5625 0.116655,0.297321 0.269096,0.519099 0.46875,0.71875 l 1.1875,1.1875 c -0.115228,0.235871 -0.222668,0.468163 -0.3125,0.71875 l -1.65625,0 c -0.277003,0 -0.553087,0.03719 -0.84375,0.15625 -0.145332,0.05953 -0.305363,0.143338 -0.46875,0.3125 -0.163387,0.169162 -0.3125,0.46403 -0.3125,0.78125 l 0,2.1875 c 0,0.317221 0.149114,0.612089 0.3125,0.78125 0.163386,0.169161 0.323419,0.252971 0.46875,0.3125 0.290663,0.119058 0.566746,0.15625 0.84375,0.15625 l 1.65625,0 c 0.08983,0.250587 0.197272,0.482879 0.3125,0.71875 L 16.75,36.25 c -0.199649,0.19965 -0.352095,0.421432 -0.46875,0.71875 -0.05833,0.148659 -0.104846,0.329672 -0.09375,0.5625 0.0111,0.232828 0.09833,0.535831 0.3125,0.75 l 1.53125,1.53125 c 0.214168,0.214172 0.517172,0.301403 0.75,0.3125 0.232828,0.0111 0.41384,-0.03542 0.5625,-0.09375 0.29732,-0.116655 0.519098,-0.269096 0.71875,-0.46875 L 21.25,38.375 c 0.235871,0.115228 0.468164,0.222668 0.71875,0.3125 l 0,1.65625 c 0,0.277003 0.03719,0.553087 0.15625,0.84375 0.05953,0.145331 0.143339,0.305364 0.3125,0.46875 0.169161,0.163386 0.464028,0.3125 0.78125,0.3125 l 2.1875,0 c 0.317221,0 0.612089,-0.149113 0.78125,-0.3125 0.169161,-0.163387 0.252971,-0.323419 0.3125,-0.46875 0.119057,-0.290663 0.15625,-0.566748 0.15625,-0.84375 l 0,-1.65625 c 0.250586,-0.08983 0.482879,-0.197272 0.71875,-0.3125 l 1.1875,1.1875 c 0.19965,0.199649 0.421432,0.352095 0.71875,0.46875 0.148659,0.05833 0.329672,0.104846 0.5625,0.09375 0.232828,-0.0111 0.535831,-0.09833 0.75,-0.3125 L 32.125,38.28125 c 0.214172,-0.214168 0.301403,-0.517172 0.3125,-0.75 0.0111,-0.232828 -0.03542,-0.41384 -0.09375,-0.5625 C 32.227095,36.67143 32.074654,36.449652 31.875,36.25 L 30.6875,35.0625 C 30.802728,34.82663 30.910168,34.594337 31,34.34375 l 1.65625,0 c 0.277004,0 0.553087,-0.03719 0.84375,-0.15625 0.145332,-0.05953 0.305364,-0.143339 0.46875,-0.3125 0.163386,-0.169161 0.3125,-0.46403 0.3125,-0.78125 l 0,-2.1875 c 0,-0.317219 -0.149114,-0.612088 -0.3125,-0.78125 C 33.805364,29.955838 33.645332,29.872029 33.5,29.8125 33.209336,29.693442 32.933253,29.65625 32.65625,29.65625 l -1.65625,0 C 30.91017,29.405663 30.802728,29.17337 30.6875,28.9375 L 31.875,27.75 c 0.19965,-0.19965 0.352095,-0.421432 0.46875,-0.71875 0.05833,-0.148659 0.104846,-0.329672 0.09375,-0.5625 -0.0111,-0.232828 -0.09833,-0.535831 -0.3125,-0.75 L 30.59375,24.1875 c -0.214167,-0.21417 -0.517171,-0.301403 -0.75,-0.3125 -0.232829,-0.0111 -0.41384,0.03542 -0.5625,0.09375 -0.29732,0.116656 -0.519099,0.269097 -0.71875,0.46875 L 27.375,25.625 c -0.235871,-0.115228 -0.468163,-0.222668 -0.71875,-0.3125 l 0,-1.65625 c 0,-0.277003 -0.03719,-0.553087 -0.15625,-0.84375 -0.05953,-0.145332 -0.143338,-0.305363 -0.3125,-0.46875 -0.169162,-0.163387 -0.46403,-0.3125 -0.78125,-0.3125 l -0.15625,0 5.65625,-6.40625 A 0.96385067,0.96385067 0 0 0 30.1875,14.03125 l -2.21875,0 0,-5.0312502 A 0.96385067,0.96385067 0 0 0 27,8.0312498 l -6,0 a 0.96385067,0.96385067 0 0 0 -0.09375,0 z M 24.3125,30.1875 c 1.002113,0 1.8125,0.810388 1.8125,1.8125 0,1.002112 -0.810387,1.8125 -1.8125,1.8125 C 23.31039,33.8125 22.5,33.002111 22.5,32 c 0,-1.002111 0.81039,-1.8125 1.8125,-1.8125 z" />
|
||||
<path
|
||||
style="fill:url(#radialGradient2985);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path2317"
|
||||
d="M 21,8.9999996 21,15 17.8125,15 24,22 30.1875,15 27,15 l 0,-6.0000004 -6,0 z M 23.21875,23 c -0.172892,0 -0.28125,0.294922 -0.28125,0.65625 l 0,2.28125 C 22.24145,26.095996 21.585954,26.379869 21,26.75 l -1.625,-1.625 c -0.255498,-0.255497 -0.533998,-0.372253 -0.65625,-0.25 l -1.53125,1.53125 c -0.122254,0.122254 -0.0055,0.400753 0.25,0.65625 l 1.625,1.625 c -0.37013,0.585953 -0.654003,1.24145 -0.8125,1.9375 l -2.28125,0 c -0.361328,0 -0.65625,0.108357 -0.65625,0.28125 l 0,2.1875 c 0,0.172892 0.294922,0.28125 0.65625,0.28125 l 2.28125,0 c 0.158497,0.69605 0.44237,1.351546 0.8125,1.9375 l -1.625,1.625 c -0.255497,0.255498 -0.372254,0.533997 -0.25,0.65625 l 1.53125,1.53125 c 0.122252,0.122254 0.400752,0.0055 0.65625,-0.25 L 21,37.25 c 0.585954,0.37013 1.24145,0.654002 1.9375,0.8125 l 0,2.28125 C 22.9375,40.705077 23.045858,41 23.21875,41 l 2.1875,0 c 0.172893,0 0.28125,-0.294924 0.28125,-0.65625 l 0,-2.28125 c 0.69605,-0.158498 1.351546,-0.44237 1.9375,-0.8125 l 1.625,1.625 c 0.255498,0.255497 0.533997,0.372254 0.65625,0.25 l 1.53125,-1.53125 c 0.122254,-0.122252 0.0055,-0.400752 -0.25,-0.65625 l -1.625,-1.625 c 0.370129,-0.585954 0.654003,-1.24145 0.8125,-1.9375 l 2.28125,0 c 0.361329,0 0.65625,-0.108358 0.65625,-0.28125 l 0,-2.1875 c 0,-0.172893 -0.294921,-0.28125 -0.65625,-0.28125 l -2.28125,0 c -0.158497,-0.69605 -0.442371,-1.351547 -0.8125,-1.9375 l 1.625,-1.625 c 0.255497,-0.255497 0.372254,-0.533997 0.25,-0.65625 L 29.90625,24.875 C 29.783997,24.752745 29.505498,24.8695 29.25,25.125 l -1.625,1.625 c -0.585954,-0.370131 -1.24145,-0.654004 -1.9375,-0.8125 l 0,-2.28125 C 25.6875,23.294922 25.579143,23 25.40625,23 l -2.1875,0 z m 1.09375,6.21875 c 1.528616,0 2.78125,1.252635 2.78125,2.78125 0,1.528615 -1.252634,2.78125 -2.78125,2.78125 -1.528614,0 -2.78125,-1.252635 -2.78125,-2.78125 0,-1.528615 1.252636,-2.78125 2.78125,-2.78125 z" />
|
||||
<rect
|
||||
style="opacity:0.4;fill:none;stroke:url(#linearGradient2982);stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect6741"
|
||||
y="6.4999886"
|
||||
x="5.4999981"
|
||||
ry="1.365193"
|
||||
rx="1.365193"
|
||||
height="37.000011"
|
||||
width="36.999985" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient2979);stroke-width:0.99829447;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||
id="path2777"
|
||||
d="M 28.926376,15.466668 24,21.177578 18.963089,15.5 21.5,15.5 l 0,-6.0000004 5,0 0,6.0000004 2.426376,-0.03333 z" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient2975);stroke-width:1;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path4243"
|
||||
d="m 23.4375,23.46875 c -0.01166,0.05381 -0.03125,0.100205 -0.03125,0.1875 l 0,2.28125 a 0.48185467,0.48185467 0 0 1 -0.375,0.46875 c -0.638467,0.145384 -1.238423,0.407111 -1.78125,0.75 a 0.48185467,0.48185467 0 0 1 -0.59375,-0.0625 l -1.625,-1.625 C 18.9779,25.4154 18.9477,25.40242 18.90625,25.375 l -1.21875,1.21875 c 0.02742,0.04145 0.0404,0.07165 0.09375,0.125 l 1.625,1.625 a 0.48185467,0.48185467 0 0 1 0.0625,0.59375 c -0.342888,0.542826 -0.604615,1.142782 -0.75,1.78125 a 0.48185467,0.48185467 0 0 1 -0.46875,0.375 l -2.28125,0 c -0.08729,0 -0.133695,0.01959 -0.1875,0.03125 l 0,1.75 c 0.05381,0.01166 0.100205,0.03125 0.1875,0.03125 l 2.28125,0 a 0.48185467,0.48185467 0 0 1 0.46875,0.375 c 0.145385,0.638468 0.407112,1.238423 0.75,1.78125 a 0.48185467,0.48185467 0 0 1 -0.0625,0.59375 l -1.625,1.625 c -0.05335,0.05335 -0.06633,0.08355 -0.09375,0.125 l 1.21875,1.21875 c 0.04145,-0.02742 0.07165,-0.0404 0.125,-0.09375 l 1.625,-1.625 A 0.48185467,0.48185467 0 0 1 21.25,36.84375 c 0.542827,0.342888 1.142781,0.604614 1.78125,0.75 a 0.48185467,0.48185467 0 0 1 0.375,0.46875 l 0,2.28125 c 0,0.08729 0.01959,0.133695 0.03125,0.1875 l 1.75,0 c 0.01166,-0.0538 0.03125,-0.100206 0.03125,-0.1875 l 0,-2.28125 a 0.48185467,0.48185467 0 0 1 0.375,-0.46875 c 0.638469,-0.145386 1.238423,-0.407112 1.78125,-0.75 a 0.48185467,0.48185467 0 0 1 0.59375,0.0625 l 1.625,1.625 c 0.05335,0.05335 0.08355,0.06633 0.125,0.09375 l 1.21875,-1.21875 c -0.02742,-0.04145 -0.0404,-0.07165 -0.09375,-0.125 l -1.625,-1.625 a 0.48185467,0.48185467 0 0 1 -0.0625,-0.59375 c 0.342888,-0.542828 0.604615,-1.142783 0.75,-1.78125 a 0.48185467,0.48185467 0 0 1 0.46875,-0.375 l 2.28125,0 c 0.08729,0 0.133695,-0.01959 0.1875,-0.03125 l 0,-1.75 c -0.0538,-0.01166 -0.100204,-0.03125 -0.1875,-0.03125 l -2.28125,0 a 0.48185467,0.48185467 0 0 1 -0.46875,-0.375 c -0.145385,-0.638467 -0.407113,-1.238424 -0.75,-1.78125 a 0.48185467,0.48185467 0 0 1 0.0625,-0.59375 l 1.625,-1.625 c 0.05335,-0.05335 0.06633,-0.08355 0.09375,-0.125 L 29.71875,25.375 c -0.04145,0.02742 -0.07165,0.0404 -0.125,0.09375 l -1.625,1.625 a 0.48185467,0.48185467 0 0 1 -0.59375,0.0625 c -0.542827,-0.342889 -1.142783,-0.604616 -1.78125,-0.75 a 0.48185467,0.48185467 0 0 1 -0.375,-0.46875 l 0,-2.28125 c 0,-0.0873 -0.01959,-0.133695 -0.03125,-0.1875 l -1.75,0 z m 0.875,5.28125 c 1.791829,0 3.25,1.458172 3.25,3.25 0,1.791828 -1.458171,3.25 -3.25,3.25 -1.791827,0 -3.25,-1.458172 -3.25,-3.25 0,-1.791828 1.458173,-3.25 3.25,-3.25 z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 21 KiB |
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
DOCKER_IMAGE=infactum/tg2sip-builder
|
||||
|
||||
for DOCKER_TAG in bionic centos7
|
||||
do
|
||||
docker build . -f Dockerfile."$DOCKER_TAG" -t "$DOCKER_IMAGE:$DOCKER_TAG"
|
||||
docker push "$DOCKER_IMAGE:$DOCKER_TAG"
|
||||
done
|
|
@ -1,19 +1,19 @@
|
|||
diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp
|
||||
index a150e6c..cd66d91 100644
|
||||
index 0cbcde9c..50e05ffa 100644
|
||||
--- a/td/telegram/Td.cpp
|
||||
+++ b/td/telegram/Td.cpp
|
||||
@@ -4827,10 +4827,10 @@ Status Td::set_parameters(td_api::object_ptr<td_api::tdlibParameters> parameters
|
||||
if (options.application_version.empty()) {
|
||||
@@ -4419,10 +4419,10 @@ Status Td::set_parameters(td_api::object_ptr<td_api::tdlibParameters> parameters
|
||||
if (options_.application_version.empty()) {
|
||||
return Status::Error(400, "Application version must be non-empty");
|
||||
}
|
||||
- if (options.api_id != 21724) {
|
||||
- options.application_version += ", TDLib ";
|
||||
- options.application_version += TDLIB_VERSION;
|
||||
- if (options_.api_id != 21724) {
|
||||
- options_.application_version += ", TDLib ";
|
||||
- options_.application_version += TDLIB_VERSION;
|
||||
- }
|
||||
+ // if (options.api_id != 21724) {
|
||||
+ // options.application_version += ", TDLib ";
|
||||
+ // options.application_version += TDLIB_VERSION;
|
||||
+ // if (options_.api_id != 21724) {
|
||||
+ // options_.application_version += ", TDLib ";
|
||||
+ // options_.application_version += TDLIB_VERSION;
|
||||
+ // }
|
||||
G()->set_mtproto_header(std::make_unique<MtprotoHeader>(options));
|
||||
|
||||
state_ = State::Decrypt;
|
||||
options_.language_pack = string();
|
||||
options_.language_code = string();
|
||||
options_.parameters = string();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/tdutils/td/utils/port/detail/ThreadStl.h b/tdutils/td/utils/port/detail/ThreadStl.h
|
||||
index 64bf321..68d3bf6 100644
|
||||
index ef6ff475..c0e18ee4 100644
|
||||
--- a/tdutils/td/utils/port/detail/ThreadStl.h
|
||||
+++ b/tdutils/td/utils/port/detail/ThreadStl.h
|
||||
@@ -37,6 +37,7 @@ class ThreadStl {
|
||||
@@ -41,6 +41,7 @@ class ThreadStl {
|
||||
invoke_tuple(std::move(args));
|
||||
clear_thread_locals();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Name=tg2sip
|
||||
Exec=tg2sip
|
||||
Comment=TG2SIP Voice Gateway
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Icon=icon
|
||||
Categories=AudioVideo;
|
|
@ -2525,7 +2525,7 @@ BOOST_SML_NAMESPACE_END
|
|||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#undef __has_builtin
|
||||
//#undef __has_builtin
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#undef __has_builtin
|
||||
|
|
|
@ -4,7 +4,7 @@ find_package(PkgConfig REQUIRED)
|
|||
pkg_check_modules(OPUS opus REQUIRED)
|
||||
pkg_check_modules(OPENSSL openssl REQUIRED)
|
||||
pkg_check_modules(PJSIP libpjproject>=2.8 REQUIRED)
|
||||
find_package(spdlog 0.17)
|
||||
find_package(spdlog 1.11.0)
|
||||
|
||||
add_library(libtgvoip STATIC
|
||||
BlockingQueue.cpp
|
||||
|
@ -657,6 +657,7 @@ target_include_directories(libtgvoip PRIVATE
|
|||
${PJSIP_INCLUDE_DIRS})
|
||||
|
||||
target_compile_definitions(libtgvoip PRIVATE
|
||||
__STDC_FORMAT_MACROS
|
||||
WEBRTC_APM_DEBUG_DUMP=0
|
||||
WEBRTC_POSIX
|
||||
WEBRTC_LINUX
|
||||
|
|
|
@ -85,6 +85,7 @@ AudioIO* AudioIO::Create(std::string inputDevice, std::string outputDevice){
|
|||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool AudioIO::Failed(){
|
||||
|
|
|
@ -25,6 +25,15 @@ namespace td_api = td::td_api;
|
|||
|
||||
volatile sig_atomic_t e_flag = 0;
|
||||
|
||||
namespace {
|
||||
vector<string> voip_library_versions() {
|
||||
// actually we want to provide real tgvoip version from
|
||||
// tgvoip::VoIPController::GetVersion()
|
||||
// but telegram servers accepts only this one
|
||||
return vector<string>{"2.4.4"};
|
||||
}
|
||||
}
|
||||
|
||||
namespace state_machine::guards {
|
||||
bool IsIncoming::operator()(const td::td_api::object_ptr<td::td_api::updateCall> &event) const {
|
||||
return !event->call_->is_outgoing_;
|
||||
|
@ -57,12 +66,9 @@ namespace state_machine::guards {
|
|||
// the event type 16 (flash) as stated in RFC 4730.
|
||||
// PJSUA maximum number of characters are 32.
|
||||
|
||||
auto content = td_api::move_object_as<td_api::messageText>(event->message_->content_);
|
||||
auto text = static_cast<const td_api::messageText &>(*event->message_->content_).text_->text_;
|
||||
const std::regex dtmf_regex("^[0-9A-D*#]{1,32}$");
|
||||
auto result = regex_match(content->text_->text_, dtmf_regex);
|
||||
|
||||
// Don't forget to put data back!
|
||||
event->message_->content_ = td_api::move_object_as<td_api::MessageContent>(content);
|
||||
auto result = regex_match(text, dtmf_regex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -111,6 +117,7 @@ namespace state_machine::actions {
|
|||
ctx.tg_call_id, /* call_id_ */
|
||||
false, /* is_disconnected_ */
|
||||
0, /* duration_ */
|
||||
false, /* is_video_ */
|
||||
ctx.tg_call_id /*connection_id */
|
||||
)).get();
|
||||
|
||||
|
@ -214,7 +221,8 @@ namespace state_machine::actions {
|
|||
td_api::make_object<td_api::callProtocol>(settings.udp_p2p(),
|
||||
settings.udp_reflector(),
|
||||
CALL_PROTO_MIN_LAYER,
|
||||
tgvoip::VoIPController::GetConnectionMaxLayer())
|
||||
tgvoip::VoIPController::GetConnectionMaxLayer(),
|
||||
voip_library_versions())
|
||||
)).get();
|
||||
|
||||
if (response->get_id() == td_api::error::ID) {
|
||||
|
@ -245,7 +253,7 @@ namespace state_machine::actions {
|
|||
ctx.ext_phone = ext.substr(1, std::string::npos);
|
||||
} else if (is_digits(ext)) {
|
||||
try {
|
||||
ctx.user_id = std::stoi(ext);
|
||||
ctx.user_id = std::stol(ext);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
ext_valid = false;
|
||||
} catch (const std::out_of_range &e) {
|
||||
|
@ -312,7 +320,7 @@ namespace state_machine::actions {
|
|||
|
||||
using namespace tgvoip;
|
||||
|
||||
auto state = td_api::move_object_as<td_api::callStateReady>(event->call_->state_);
|
||||
const auto &state = static_cast<const td_api::callStateReady &>(*event->call_->state_);
|
||||
auto voip_controller = std::make_shared<VoIPController>();
|
||||
|
||||
static auto config = VoIPController::Config(
|
||||
|
@ -336,17 +344,22 @@ namespace state_machine::actions {
|
|||
}
|
||||
|
||||
char encryption_key[256];
|
||||
memcpy(encryption_key, state->encryption_key_.c_str(), 256);
|
||||
memcpy(encryption_key, state.encryption_key_.c_str(), 256);
|
||||
voip_controller->SetEncryptionKey(encryption_key, event->call_->is_outgoing_);
|
||||
|
||||
vector<Endpoint> endpoints;
|
||||
for (auto &connection : state->connections_) {
|
||||
for (const auto &server : state.servers_) {
|
||||
if (server->type_->get_id() != td_api::callServerTypeTelegramReflector::ID)
|
||||
continue;
|
||||
|
||||
auto reflector = static_cast<const td_api::callServerTypeTelegramReflector *>(server->type_.get());
|
||||
|
||||
unsigned char peer_tag[16];
|
||||
memcpy(peer_tag, connection->peer_tag_.c_str(), 16);
|
||||
auto ipv4 = IPv4Address(connection->ip_);
|
||||
auto ipv6 = IPv6Address(connection->ipv6_);
|
||||
endpoints.emplace_back(Endpoint(connection->id_,
|
||||
static_cast<uint16_t>(connection->port_),
|
||||
memcpy(peer_tag, reflector->peer_tag_.c_str(), 16);
|
||||
auto ipv4 = IPv4Address(server->ip_address_);
|
||||
auto ipv6 = IPv6Address(server->ipv6_address_);
|
||||
endpoints.emplace_back(Endpoint(server->id_,
|
||||
static_cast<uint16_t>(server->port_),
|
||||
ipv4,
|
||||
ipv6,
|
||||
Endpoint::UDP_RELAY,
|
||||
|
@ -422,12 +435,14 @@ namespace state_machine::actions {
|
|||
}
|
||||
}
|
||||
|
||||
void DialTg::dial_by_id(int32_t id) {
|
||||
void DialTg::dial_by_id(int64_t id) {
|
||||
auto response = tg_client_->send_query_async(td_api::make_object<td_api::createCall>(
|
||||
id /* id */,
|
||||
td_api::make_object<td_api::callProtocol>(settings_->udp_p2p(), settings_->udp_reflector(),
|
||||
CALL_PROTO_MIN_LAYER,
|
||||
tgvoip::VoIPController::GetConnectionMaxLayer()))
|
||||
tgvoip::VoIPController::GetConnectionMaxLayer(),
|
||||
voip_library_versions()),
|
||||
false /* is_video_ */)
|
||||
).get();
|
||||
|
||||
if (response->get_id() == td_api::error::ID) {
|
||||
|
@ -538,7 +553,7 @@ namespace state_machine::actions {
|
|||
return;
|
||||
}
|
||||
|
||||
auto id = static_cast<int32_t>(chat->id_);
|
||||
auto id = chat->id_;
|
||||
DEBUG(logger_, "[{}] adding id {} for {} to username cache", ctx_->id(), id, ctx_->ext_username);
|
||||
cache_->username_cache.emplace(ctx_->ext_username, id);
|
||||
dial_by_id(id);
|
||||
|
@ -566,10 +581,10 @@ namespace state_machine::actions {
|
|||
const td_api::object_ptr<td::td_api::updateNewMessage> &event,
|
||||
std::shared_ptr<spdlog::logger> logger) const {
|
||||
|
||||
auto content = td_api::move_object_as<td_api::messageText>(event->message_->content_);
|
||||
DEBUG(logger, "[{}] sending DTMF {}", ctx.id(), content->text_->text_);
|
||||
auto text = static_cast<const td_api::messageText &>(*event->message_->content_).text_->text_;
|
||||
DEBUG(logger, "[{}] sending DTMF {}", ctx.id(), text);
|
||||
try {
|
||||
sip_client.DialDtmf(ctx.sip_call_id, content->text_->text_);
|
||||
sip_client.DialDtmf(ctx.sip_call_id, text);
|
||||
} catch (const pj::Error &error) {
|
||||
logger->error(error.reason);
|
||||
}
|
||||
|
@ -838,15 +853,20 @@ void Gateway::process_event(td::td_api::object_ptr<td::td_api::updateCall> updat
|
|||
|
||||
void Gateway::process_event(td::td_api::object_ptr<td::td_api::updateNewMessage> update_message) {
|
||||
|
||||
auto &sender = update_message->message_->sender_id_;
|
||||
if (sender->get_id() == td_api::messageSenderUser::ID)
|
||||
return;
|
||||
auto user = static_cast<const td_api::messageSenderUser *>(sender.get());
|
||||
|
||||
std::vector<Bridge *> matches;
|
||||
for (auto bridge : bridges) {
|
||||
if (bridge->ctx->user_id == update_message->message_->sender_user_id_) {
|
||||
if (bridge->ctx->user_id == user->user_id_) {
|
||||
matches.emplace_back(bridge);
|
||||
}
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
logger_->error("ambiguous message from {}", update_message->message_->sender_user_id_);
|
||||
logger_->error("ambiguous message from {}", user->user_id_);
|
||||
return;
|
||||
} else if (matches.size() == 1) {
|
||||
TRACE(logger_, "routing message to ctx {}", matches[0]->ctx->id());
|
||||
|
|
|
@ -170,7 +170,7 @@ namespace state_machine::actions {
|
|||
|
||||
void parse_error(td::td_api::object_ptr<td::td_api::error> error);
|
||||
|
||||
void dial_by_id(int32_t id);
|
||||
void dial_by_id(int64_t id);
|
||||
|
||||
void dial_by_phone();
|
||||
|
||||
|
@ -226,8 +226,8 @@ namespace state_machine {
|
|||
}
|
||||
|
||||
struct Cache {
|
||||
std::map<std::string, int32_t> username_cache;
|
||||
std::map<std::string, int32_t> phone_cache;
|
||||
std::map<std::string, int64_t> username_cache;
|
||||
std::map<std::string, int64_t> phone_cache;
|
||||
};
|
||||
|
||||
class Context {
|
||||
|
@ -242,7 +242,7 @@ public:
|
|||
|
||||
std::string ext_phone;
|
||||
std::string ext_username;
|
||||
int32_t user_id{0};
|
||||
int64_t user_id{0};
|
||||
|
||||
pj::CallOpParam hangup_prm;
|
||||
|
||||
|
|
|
@ -152,20 +152,21 @@ private:
|
|||
sequence_done = true;
|
||||
std::cerr << "Terminated" << std::endl;
|
||||
},
|
||||
[this](td_api::authorizationStateWaitCode &wait_code) {
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
if (!wait_code.is_registered_) {
|
||||
std::cerr << "Enter your first name: ";
|
||||
std::cin >> first_name;
|
||||
std::cerr << "Enter your last name: ";
|
||||
std::cin >> last_name;
|
||||
}
|
||||
std::cerr << "Enter authentication code: ";
|
||||
[this](td_api::authorizationStateWaitCode &) {
|
||||
std::cout << "Enter authentication code: " << std::flush;
|
||||
std::string code;
|
||||
std::cin >> code;
|
||||
send_query(
|
||||
td_api::make_object<td_api::checkAuthenticationCode>(code, first_name, last_name),
|
||||
send_query(td_api::make_object<td_api::checkAuthenticationCode>(code),
|
||||
create_authentication_query_handler());
|
||||
},
|
||||
[this](td_api::authorizationStateWaitRegistration &) {
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
std::cout << "Enter your first name: " << std::flush;
|
||||
std::cin >> first_name;
|
||||
std::cout << "Enter your last name: " << std::flush;
|
||||
std::cin >> last_name;
|
||||
send_query(td_api::make_object<td_api::registerUser>(first_name, last_name),
|
||||
create_authentication_query_handler());
|
||||
},
|
||||
[this](td_api::authorizationStateWaitPassword &) {
|
||||
|
@ -175,34 +176,35 @@ private:
|
|||
send_query(td_api::make_object<td_api::checkAuthenticationPassword>(password),
|
||||
create_authentication_query_handler());
|
||||
},
|
||||
[this](td_api::authorizationStateWaitOtherDeviceConfirmation &state) {
|
||||
std::cout << "Confirm this login link on another device: " << state.link_ << std::endl;
|
||||
},
|
||||
[this](td_api::authorizationStateWaitPhoneNumber &) {
|
||||
std::cerr << "Enter phone number: ";
|
||||
std::cout << "Enter phone number: " << std::flush;
|
||||
std::string phone_number;
|
||||
std::cin >> phone_number;
|
||||
send_query(td_api::make_object<td_api::setAuthenticationPhoneNumber>(
|
||||
phone_number, false /*allow_flash_calls*/, false /*is_current_phone_number*/),
|
||||
send_query(td_api::make_object<td_api::setAuthenticationPhoneNumber>(phone_number, nullptr),
|
||||
create_authentication_query_handler());
|
||||
},
|
||||
[this](td_api::authorizationStateWaitEncryptionKey &) {
|
||||
send_query(td_api::make_object<td_api::checkDatabaseEncryptionKey>(""),
|
||||
create_authentication_query_handler());
|
||||
|
||||
td_api::object_ptr<td_api::Proxy> proxy;
|
||||
if (settings.proxy_enabled()) {
|
||||
auto socks_proxy = td_api::make_object<td_api::proxySocks5>(
|
||||
settings.proxy_address(),
|
||||
settings.proxy_port(),
|
||||
auto socks_proxy_type = td_api::make_object<td_api::proxyTypeSocks5>(
|
||||
settings.proxy_username(),
|
||||
settings.proxy_password()
|
||||
);
|
||||
proxy = td_api::move_object_as<td_api::Proxy>(socks_proxy);
|
||||
} else {
|
||||
auto empty_proxy = td_api::make_object<td_api::proxyEmpty>();
|
||||
proxy = td_api::move_object_as<td_api::Proxy>(empty_proxy);
|
||||
}
|
||||
send_query(td_api::make_object<td_api::setProxy>(
|
||||
td_api::move_object_as<td_api::Proxy>(proxy)),
|
||||
send_query(td_api::make_object<td_api::addProxy>(
|
||||
settings.proxy_address(),
|
||||
settings.proxy_port(),
|
||||
true,
|
||||
td_api::move_object_as<td_api::ProxyType>(socks_proxy_type)),
|
||||
[](Object) {});
|
||||
} else {
|
||||
send_query(td_api::make_object<td_api::disableProxy>(), [](Object) {});
|
||||
}
|
||||
|
||||
},
|
||||
[this](td_api::authorizationStateWaitTdlibParameters &) {
|
||||
auto lib_parameters = td_api::make_object<td_api::tdlibParameters>();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <iostream>
|
||||
#include <td/telegram/Log.h>
|
||||
#include "logging.h"
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
|
||||
void init_logging(Settings &settings) {
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <optional>
|
||||
#include <condition_variable>
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -60,16 +60,17 @@ void Client::init_lib_parameters(Settings &settings) {
|
|||
|
||||
void Client::init_proxy(Settings &settings) {
|
||||
if (settings.proxy_enabled()) {
|
||||
auto socks_proxy = td_api::make_object<td_api::proxySocks5>(
|
||||
settings.proxy_address(),
|
||||
settings.proxy_port(),
|
||||
auto socks_proxy_type = td_api::make_object<td_api::proxyTypeSocks5>(
|
||||
settings.proxy_username(),
|
||||
settings.proxy_password()
|
||||
);
|
||||
proxy = td_api::move_object_as<td_api::Proxy>(socks_proxy);
|
||||
set_proxy = td_api::make_object<td_api::addProxy>(
|
||||
settings.proxy_address(),
|
||||
settings.proxy_port(),
|
||||
true,
|
||||
td_api::move_object_as<td_api::ProxyType>(socks_proxy_type));
|
||||
} else {
|
||||
auto empty_proxy = td_api::make_object<td_api::proxyEmpty>();
|
||||
proxy = td_api::move_object_as<td_api::Proxy>(empty_proxy);
|
||||
set_proxy = td_api::make_object<td_api::disableProxy>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,8 +187,7 @@ void Client::on_authorization_state_update(td_api::object_ptr<td_api::Authorizat
|
|||
case td_api::authorizationStateWaitEncryptionKey::ID:
|
||||
send_query(td_api::make_object<td_api::checkDatabaseEncryptionKey>(),
|
||||
create_authentication_query_handler());
|
||||
send_query(td_api::make_object<td_api::setProxy>(td_api::move_object_as<td_api::Proxy>(proxy)),
|
||||
create_authentication_query_handler());
|
||||
send_query(std::move(set_proxy), create_authentication_query_handler());
|
||||
break;
|
||||
case td_api::authorizationStateWaitTdlibParameters::ID: {
|
||||
send_query(td_api::make_object<td_api::setTdlibParameters>(
|
||||
|
|
|
@ -57,8 +57,8 @@ namespace tg {
|
|||
const double WAIT_TIMEOUT = 10;
|
||||
|
||||
std::unique_ptr<td::Client> client;
|
||||
std::unique_ptr<td_api::tdlibParameters> lib_parameters;
|
||||
td_api::object_ptr<td_api::Proxy> proxy;
|
||||
td::tl::unique_ptr<td_api::tdlibParameters> lib_parameters;
|
||||
td_api::object_ptr<td_api::Function> set_proxy;
|
||||
|
||||
std::thread thread_;
|
||||
|
||||
|
|
|
@ -17,5 +17,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include "utils.h"
|
||||
#include <string>
|
||||
|
||||
bool is_digits(const std::string &str) { return std::all_of(str.begin(), str.end(), ::isdigit); };
|
Loading…
Reference in New Issue