1. added multipath protocol and schema suport

2. added SCTP protocol and schema support
3. added set of NAS models support (Asustor, ReadyNAS, Drobo, QNAP, WD, Synology, Terramaster)
4. moved to fc00::/7 private segment
5. added Windows, MacOS and Linux UI for peers edit and current status
This commit is contained in:
vadym 2022-10-27 22:03:37 +03:00
parent cfa293d189
commit d8a4000141
198 changed files with 8589 additions and 697 deletions

View file

@ -1,6 +1,6 @@
/*
This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/)
This file generates crypto keys for [ansible-mesh](https://github.com/jcgruenhage/ansible-mesh/)
*/
package main
@ -14,7 +14,7 @@ import (
"os"
"github.com/cheggaaa/pb/v3"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/RiV-chain/RiV-mesh/src/address"
)
var numHosts = flag.Int("hosts", 1, "number of host vars to generate")
@ -57,8 +57,8 @@ func main() {
return
}
defer file.Close()
file.WriteString(fmt.Sprintf("yggdrasil_public_key: %v\n", hex.EncodeToString(keys[i].pub)))
file.WriteString("yggdrasil_private_key: \"{{ vault_yggdrasil_private_key }}\"\n")
file.WriteString(fmt.Sprintf("mesh_public_key: %v\n", hex.EncodeToString(keys[i].pub)))
file.WriteString("mesh_private_key: \"{{ vault_mesh_private_key }}\"\n")
file.WriteString(fmt.Sprintf("ansible_host: %v\n", keys[i].ip))
file, err = os.Create(fmt.Sprintf("host_vars/%x/vault", i))
@ -66,7 +66,7 @@ func main() {
return
}
defer file.Close()
file.WriteString(fmt.Sprintf("vault_yggdrasil_private_key: %v\n", hex.EncodeToString(keys[i].priv)))
file.WriteString(fmt.Sprintf("vault_mesh_private_key: %v\n", hex.EncodeToString(keys[i].priv)))
bar.Increment()
}
bar.Finish()

View file

@ -1,7 +1,7 @@
# Last Modified: Fri Oct 30 11:33:31 2020
#include <tunables/global>
/usr/bin/yggdrasil {
/usr/bin/mesh {
#include <abstractions/base>
#include <abstractions/nameservice>
@ -12,6 +12,6 @@
/proc/sys/net/core/somaxconn r,
/sys/kernel/mm/transparent_hugepage/hpage_pmd_size r,
/etc/yggdrasil.conf rw,
/run/yggdrasil.sock rw,
/etc/mesh.conf rw,
/run/mesh.sock rw,
}

View file

@ -1,9 +1,9 @@
#!/bin/sh
CONFFILE="/etc/yggdrasil.conf"
CONFFILE="/etc/mesh.conf"
genconf() {
/usr/bin/yggdrasil -genconf > "$1"
/usr/bin/mesh -genconf > "$1"
return $?
}
@ -33,8 +33,8 @@ start() {
fi
fi
printf 'Starting yggdrasil: '
if start-stop-daemon -S -q -b -x /usr/bin/yggdrasil \
printf 'Starting mesh: '
if start-stop-daemon -S -q -b -x /usr/bin/mesh \
-- -useconffile "$CONFFILE"; then
echo "OK"
else
@ -43,8 +43,8 @@ start() {
}
stop() {
printf "Stopping yggdrasil: "
if start-stop-daemon -K -q -x /usr/bin/yggdrasil; then
printf "Stopping mesh: "
if start-stop-daemon -K -q -x /usr/bin/mesh; then
echo "OK"
else
echo "FAIL"
@ -52,8 +52,8 @@ stop() {
}
reload() {
printf "Reloading yggdrasil: "
if start-stop-daemon -K -q -s HUP -x /usr/bin/yggdrasil; then
printf "Reloading mesh: "
if start-stop-daemon -K -q -s HUP -x /usr/bin/mesh; then
echo "OK"
else
echo "FAIL"

165
contrib/deb/generate-gui.sh Executable file
View file

@ -0,0 +1,165 @@
#!/bin/sh
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
# mesh and enables it in systemd. You can give it the PKGARCH= argument
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
PKGFILE=$PKGNAME.deb
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build
else
echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64,armel"
exit 1
fi
echo "Building $PKGFILE"
mkdir -p /tmp/$PKGNAME/
mkdir -p /tmp/$PKGNAME/debian/
mkdir -p /tmp/$PKGNAME/DEBIAN/
mkdir -p /tmp/$PKGNAME/usr/bin/
mkdir -p /tmp/$PKGNAME/usr/local/bin/
mkdir -p /tmp/$PKGNAME/etc/systemd/system/
mkdir -p /tmp/$PKGNAME/usr/share/applications/
mkdir -p /tmp/$PKGNAME/etc/
mkdir -p /tmp/$PKGNAME/etc/xdg/autostart
chmod 0775 /tmp/$PKGNAME/ -R
for resolution in 16x16 24x24 32x32 48x48 64x64 192x192 256x256 512x512; do
echo "Converting icon for: $resolution"
mkdir -p /tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps && \
convert -colorspace sRGB ./riv.png -resize $resolution PNG8:/tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps/riv.png && \
chmod 644 /tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps/riv.png
done
cp contrib/ui/mesh-ui/index.html /tmp/$PKGNAME/etc/
cat > /tmp/$PKGNAME/usr/share/applications/riv.desktop << EOF
[Desktop Entry]
Name=RiV mesh
GenericName=Mesh network
Comment=RiV-mesh is an early-stage implementation of a fully end-to-end encrypted IPv6 network
Exec=sh -c "/usr/bin/mesh-ui /etc/index.html"
Terminal=false
Type=Application
Icon=riv
Categories=Network;FileTransfer;
StartupNotify=false
EOF
cat > /tmp/$PKGNAME/debian/changelog << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
echo 9 > /tmp/$PKGNAME/debian/compat
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
Package: mesh
Version: $PKGVERSION
Section: contrib/net
Priority: extra
Architecture: $PKGARCH
Replaces: $PKGREPLACES
Conflicts: $PKGREPLACES
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other RiV-mesh nodes.
EOF
cat > /tmp/$PKGNAME/debian/copyright << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cat > /tmp/$PKGNAME/debian/docs << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cat > /tmp/$PKGNAME/debian/install << EOF
usr/bin/mesh usr/bin
usr/bin/meshctl usr/bin
usr/bin/mesh-ui usr/bin
usr/local/bin/meshctl usr/local/bin
etc/index.html etc
etc/xdg/autostart/riv.desktop etc/xdg/autostart
etc/systemd/system/*.service etc/systemd/system
usr/share/applications/riv.desktop usr/share/applications
usr/share/icons/hicolor/16x16/apps/riv.png usr/share/icons/hicolor/16x16/apps
usr/share/icons/hicolor/24x24/apps/riv.png usr/share/icons/hicolor/24x24/apps
usr/share/icons/hicolor/32x32/apps/riv.png usr/share/icons/hicolor/32x32/apps
usr/share/icons/hicolor/48x48/apps/riv.png usr/share/icons/hicolor/48x48/apps
usr/share/icons/hicolor/64x64/apps/riv.png usr/share/icons/hicolor/64x64/apps
usr/share/icons/hicolor/192x192/apps/riv.png usr/share/icons/hicolor/192x192/apps
usr/share/icons/hicolor/256x256/apps/riv.png usr/share/icons/hicolor/256x256/apps
usr/share/icons/hicolor/512x512/apps/riv.png usr/share/icons/hicolor/512x512/apps
EOF
cat > /tmp/$PKGNAME/DEBIAN/postinst << EOF
#!/bin/sh
if ! getent group mesh 2>&1 > /dev/null; then
groupadd --system --force mesh || echo "Failed to create group 'mesh' - please create it manually and reinstall"
fi
if [ -f /etc/mesh.conf ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/mesh.conf"
/usr/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
else
echo "Generating initial configuration file /etc/mesh.conf"
echo "Please familiarise yourself with this file before starting Mesh"
sh -c 'umask 0027 && /usr/bin/mesh -genconf > /etc/mesh.conf'
fi
chgrp mesh /etc/mesh.conf
chmod 755 /etc/mesh.conf
if command -v systemctl >/dev/null; then
systemctl daemon-reload || echo -n "daemon not reloaded!"
systemctl enable mesh || echo -n "systemctl enable failed!"
systemctl restart mesh || echo -n "systemctl restart failed!"
fi
update-icon-caches /usr/share/icons/*
update-desktop-database /usr/share/applications
EOF
cat > /tmp/$PKGNAME/DEBIAN/prerm << EOF
#!/bin/sh
if command -v systemctl >/dev/null; then
if systemctl is-active --quiet mesh; then
systemctl stop mesh || true
fi
systemctl disable mesh || true
fi
EOF
cp mesh /tmp/$PKGNAME/usr/bin/
cp meshctl /tmp/$PKGNAME/usr/bin/
cp mesh-ui /tmp/$PKGNAME/usr/bin/
ln -s /usr/bin/meshctl /tmp/$PKGNAME/usr/local/bin/meshctl
cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/
cp /tmp/$PKGNAME/usr/share/applications/riv.desktop /tmp/$PKGNAME/etc/xdg/autostart
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
chmod 644 /tmp/$PKGNAME/etc/systemd/system/*
chmod 644 /tmp/$PKGNAME/usr/share/applications/riv.desktop
chmod 644 /tmp/$PKGNAME/etc/xdg/autostart/*
chmod 755 /tmp/$PKGNAME/usr/bin/*
chmod 755 /tmp/$PKGNAME/etc/index.html
dpkg-deb --build --root-owner-group /tmp/$PKGNAME
cp /tmp/$PKGFILE .
rm -rf /tmp/$PKGNAME

View file

@ -1,7 +1,7 @@
#!/bin/sh
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
# yggdrasil and enables it in systemd. You can give it the PKGARCH= argument
# mesh and enables it in systemd. You can give it the PKGARCH= argument
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
@ -11,14 +11,15 @@ then
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKGNAME=$(sh contrib/semver/name.sh)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb
PKGREPLACES=yggdrasil
PKGNAME=$PKG-$PKGVERSION-$PKGARCH-nogui
PKGFILE=$PKGNAME.deb
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=yggdrasil-develop
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
@ -37,91 +38,92 @@ echo "Building $PKGFILE"
mkdir -p /tmp/$PKGNAME/
mkdir -p /tmp/$PKGNAME/debian/
mkdir -p /tmp/$PKGNAME/DEBIAN/
mkdir -p /tmp/$PKGNAME/usr/bin/
mkdir -p /tmp/$PKGNAME/usr/local/bin/
mkdir -p /tmp/$PKGNAME/etc/systemd/system/
chmod 0775 /tmp/$PKGNAME/ -R
cat > /tmp/$PKGNAME/debian/changelog << EOF
Please see https://github.com/yggdrasil-network/yggdrasil-go/
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
echo 9 > /tmp/$PKGNAME/debian/compat
cat > /tmp/$PKGNAME/debian/control << EOF
Package: $PKGNAME
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
Package: mesh
Version: $PKGVERSION
Section: contrib/net
Priority: extra
Architecture: $PKGARCH
Replaces: $PKGREPLACES
Conflicts: $PKGREPLACES
Maintainer: Neil Alexander <neilalexander@users.noreply.github.com>
Description: Yggdrasil Network
Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6
network. It is lightweight, self-arranging, supported on multiple platforms and
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other Yggdrasil nodes.
other RiV-mesh nodes.
EOF
cat > /tmp/$PKGNAME/debian/copyright << EOF
Please see https://github.com/yggdrasil-network/yggdrasil-go/
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cat > /tmp/$PKGNAME/debian/docs << EOF
Please see https://github.com/yggdrasil-network/yggdrasil-go/
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cat > /tmp/$PKGNAME/debian/install << EOF
usr/bin/yggdrasil usr/bin
usr/bin/yggdrasilctl usr/bin
usr/bin/mesh usr/bin
usr/bin/meshctl usr/bin
usr/local/bin/meshctl usr/local/bin
etc/systemd/system/*.service etc/systemd/system
EOF
cat > /tmp/$PKGNAME/debian/postinst << EOF
cat > /tmp/$PKGNAME/DEBIAN/postinst << EOF
#!/bin/sh
if ! getent group yggdrasil 2>&1 > /dev/null; then
groupadd --system --force yggdrasil || echo "Failed to create group 'yggdrasil' - please create it manually and reinstall"
if ! getent group mesh 2>&1 > /dev/null; then
groupadd --system --force mesh || echo "Failed to create group 'mesh' - please create it manually and reinstall"
fi
if [ -f /etc/yggdrasil.conf ];
then
if [ -f /etc/mesh.conf ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/yggdrasil.conf.`date +%Y%m%d`"
cp /etc/yggdrasil.conf /var/backups/yggdrasil.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/yggdrasil.conf"
/usr/bin/yggdrasil -useconf -normaliseconf < /var/backups/yggdrasil.conf.`date +%Y%m%d` > /etc/yggdrasil.conf
chgrp yggdrasil /etc/yggdrasil.conf
if command -v systemctl >/dev/null; then
systemctl daemon-reload >/dev/null || true
systemctl enable yggdrasil || true
systemctl start yggdrasil || true
fi
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/mesh.conf"
/usr/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
else
echo "Generating initial configuration file /etc/yggdrasil.conf"
echo "Please familiarise yourself with this file before starting Yggdrasil"
sh -c 'umask 0027 && /usr/bin/yggdrasil -genconf > /etc/yggdrasil.conf'
chgrp yggdrasil /etc/yggdrasil.conf
echo "Generating initial configuration file /etc/mesh.conf"
echo "Please familiarise yourself with this file before starting RiV-mesh"
sh -c 'umask 0027 && /usr/bin/mesh -genconf > /etc/mesh.conf'
fi
chgrp mesh /etc/mesh.conf
chmod 755 /etc/mesh.conf
if command -v systemctl >/dev/null; then
systemctl daemon-reload || echo -n "daemon not reloaded!"
systemctl enable mesh || echo -n "systemctl enable failed!"
systemctl restart mesh || echo -n "systemctl restart failed!"
fi
EOF
cat > /tmp/$PKGNAME/debian/prerm << EOF
cat > /tmp/$PKGNAME/DEBIAN/prerm << EOF
#!/bin/sh
if command -v systemctl >/dev/null; then
if systemctl is-active --quiet yggdrasil; then
systemctl stop yggdrasil || true
if systemctl is-active --quiet mesh; then
systemctl stop mesh || true
fi
systemctl disable yggdrasil || true
systemctl disable mesh || true
fi
EOF
cp yggdrasil /tmp/$PKGNAME/usr/bin/
cp yggdrasilctl /tmp/$PKGNAME/usr/bin/
cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/
cp mesh /tmp/$PKGNAME/usr/bin/
cp meshctl /tmp/$PKGNAME/usr/bin/
ln -s /usr/bin/meshctl /tmp/$PKGNAME/usr/local/bin/meshctl
if [ $LOGLEVEL = "DEBUG" ]; then cp contrib/systemd/mesh-debug.service /tmp/$PKGNAME/etc/systemd/system/mesh.service
else
cp contrib/systemd/mesh.service /tmp/$PKGNAME/etc/systemd/system/
fi
tar -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \
usr/bin/yggdrasil usr/bin/yggdrasilctl \
etc/systemd/system/yggdrasil.service \
etc/systemd/system/yggdrasil-default-config.service
tar -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian .
echo 2.0 > /tmp/$PKGNAME/debian-binary
cp contrib/systemd/mesh-default-config.service /tmp/$PKGNAME/etc/systemd/system/
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
chmod 644 /tmp/$PKGNAME/etc/systemd/system/*
chmod 755 /tmp/$PKGNAME/usr/bin/*
ar -r $PKGFILE \
/tmp/$PKGNAME/debian-binary \
/tmp/$PKGNAME/control.tar.gz \
/tmp/$PKGNAME/data.tar.gz
dpkg-deb --build --root-owner-group /tmp/$PKGNAME
cp /tmp/$PKGFILE .
rm -rf /tmp/$PKGNAME

View file

@ -9,17 +9,17 @@ RUN apk add git && ./build && go build -o /src/genkeys cmd/genkeys/main.go
FROM docker.io/alpine
COPY --from=builder /src/yggdrasil /usr/bin/yggdrasil
COPY --from=builder /src/yggdrasilctl /usr/bin/yggdrasilctl
COPY --from=builder /src/mesh /usr/bin/mesh
COPY --from=builder /src/meshctl /usr/bin/meshctl
COPY --from=builder /src/genkeys /usr/bin/genkeys
COPY contrib/docker/entrypoint.sh /usr/bin/entrypoint.sh
# RUN addgroup -g 1000 -S yggdrasil-network \
# && adduser -u 1000 -S -g 1000 --home /etc/yggdrasil-network yggdrasil-network
# RUN addgroup -g 1000 -S RiV-chain \
# && adduser -u 1000 -S -g 1000 --home /etc/RiV-chain RiV-chain
#
# USER yggdrasil-network
# USER RiV-chain
# TODO: Make running unprivileged work
VOLUME [ "/etc/yggdrasil-network" ]
VOLUME [ "/etc/RiV-chain" ]
ENTRYPOINT [ "/usr/bin/entrypoint.sh" ]

View file

@ -2,12 +2,12 @@
set -e
CONF_DIR="/etc/yggdrasil-network"
CONF_DIR="/etc/RiV-chain"
if [ ! -f "$CONF_DIR/config.conf" ]; then
echo "generate $CONF_DIR/config.conf"
yggdrasil --genconf > "$CONF_DIR/config.conf"
mesh --genconf > "$CONF_DIR/config.conf"
fi
yggdrasil --useconf < "$CONF_DIR/config.conf"
mesh --useconf < "$CONF_DIR/config.conf"
exit $?

72
contrib/freebsd/mesh Normal file
View file

@ -0,0 +1,72 @@
#!/bin/sh
#
# Put the mesh and meshctl binaries into /usr/local/bin
# Then copy this script into /etc/rc.d/mesh
# Finally, run:
# 1. chmod +x /etc/rc.d/mesh /usr/local/bin/{mesh,meshctl}
# 2. echo "mesh_enable=yes" >> /etc/rc.d
# 3. service mesh start
#
# PROVIDE: mesh
# REQUIRE: networking
# KEYWORD:
. /etc/rc.subr
name="mesh"
rcvar="mesh_enable"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
pidfile="/var/run/mesh/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f ${mesh_command}"
mesh_start()
{
test ! -x /usr/local/bin/mesh && (
logger -s -t mesh "Warning: /usr/local/bin/mesh is missing or not executable"
logger -s -t mesh "Copy the mesh binary into /usr/local/bin and then chmod +x /usr/local/bin/mesh"
return 1
)
test ! -f /etc/mesh.conf && (
logger -s -t mesh "Generating new configuration file into /etc/mesh.conf"
/usr/local/bin/mesh -genconf > /etc/mesh.conf
)
tap_path="$(cat /etc/mesh.conf | egrep -o '/dev/tap[0-9]{1,2}$')"
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 || (
logger -s -t mesh "Creating ${tap_name} adapter"
/sbin/ifconfig ${tap_name} create || logger -s -t mesh "Failed to create ${tap_name} adapter"
)
test ! -d /var/run/mesh && mkdir -p /var/run/mesh
logger -s -t mesh "Starting mesh"
${command} ${command_args} /usr/local/bin/mesh -useconffile /etc/mesh.conf \
1>/var/log/mesh.stdout.log \
2>/var/log/mesh.stderr.log &
}
mesh_stop()
{
logger -s -t mesh "Stopping mesh"
test -f /var/run/mesh/${name}.pid && kill -TERM $(cat /var/run/mesh/${name}.pid)
tap_path="$(cat /etc/mesh.conf | grep /dev/tap | egrep -o '/dev/.*$')"
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 && (
logger -s -t mesh "Destroying ${tap_name} adapter"
/sbin/ifconfig ${tap_name} destroy || logger -s -t mesh "Failed to destroy ${tap_name} adapter"
)
}
load_rc_config $name
: ${mesh_enable:=no}
run_rc_command "$1"

View file

@ -1,72 +0,0 @@
#!/bin/sh
#
# Put the yggdrasil and yggdrasilctl binaries into /usr/local/bin
# Then copy this script into /etc/rc.d/yggdrasil
# Finally, run:
# 1. chmod +x /etc/rc.d/yggdrasil /usr/local/bin/{yggdrasil,yggdrasilctl}
# 2. echo "yggdrasil_enable=yes" >> /etc/rc.d
# 3. service yggdrasil start
#
# PROVIDE: yggdrasil
# REQUIRE: networking
# KEYWORD:
. /etc/rc.subr
name="yggdrasil"
rcvar="yggdrasil_enable"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
pidfile="/var/run/yggdrasil/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f ${yggdrasil_command}"
yggdrasil_start()
{
test ! -x /usr/local/bin/yggdrasil && (
logger -s -t yggdrasil "Warning: /usr/local/bin/yggdrasil is missing or not executable"
logger -s -t yggdrasil "Copy the yggdrasil binary into /usr/local/bin and then chmod +x /usr/local/bin/yggdrasil"
return 1
)
test ! -f /etc/yggdrasil.conf && (
logger -s -t yggdrasil "Generating new configuration file into /etc/yggdrasil.conf"
/usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf
)
tap_path="$(cat /etc/yggdrasil.conf | egrep -o '/dev/tap[0-9]{1,2}$')"
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 || (
logger -s -t yggdrasil "Creating ${tap_name} adapter"
/sbin/ifconfig ${tap_name} create || logger -s -t yggdrasil "Failed to create ${tap_name} adapter"
)
test ! -d /var/run/yggdrasil && mkdir -p /var/run/yggdrasil
logger -s -t yggdrasil "Starting yggdrasil"
${command} ${command_args} /usr/local/bin/yggdrasil -useconffile /etc/yggdrasil.conf \
1>/var/log/yggdrasil.stdout.log \
2>/var/log/yggdrasil.stderr.log &
}
yggdrasil_stop()
{
logger -s -t yggdrasil "Stopping yggdrasil"
test -f /var/run/yggdrasil/${name}.pid && kill -TERM $(cat /var/run/yggdrasil/${name}.pid)
tap_path="$(cat /etc/yggdrasil.conf | grep /dev/tap | egrep -o '/dev/.*$')"
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 && (
logger -s -t yggdrasil "Destroying ${tap_name} adapter"
/sbin/ifconfig ${tap_name} destroy || logger -s -t yggdrasil "Failed to destroy ${tap_name} adapter"
)
}
load_rc_config $name
: ${yggdrasil_enable:=no}
run_rc_command "$1"

View file

@ -0,0 +1,176 @@
#!/bin/sh
# Check if xar and mkbom are available
command -v xar >/dev/null 2>&1 || (
echo "Building xar"
sudo apt-get install libxml2-dev libssl1.0-dev zlib1g-dev autoconf -y
rm -rf /tmp/xar && mkdir -p /tmp/xar && cd /tmp/xar
#git clone https://github.com/mackyle/xar && cd xar/xar
git clone https://github.com/RiV-chain/xar.git && cd xar/xar
(sh autogen.sh && make && sudo make install) || (echo "Failed to build xar"; exit 1)
)
command -v mkbom >/dev/null 2>&1 || (
echo "Building mkbom"
mkdir -p /tmp/mkbom && cd /tmp/mkbom
git clone https://github.com/hogliux/bomutils && cd bomutils
sudo make install || (echo "Failed to build mkbom"; exit 1)
)
# Build RiV-mesh
echo "running GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build"
GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build
# Check if we can find the files we need - they should
# exist if you are running this script from the root of
# the RiV-mesh repo and you have ran ./build
test -f mesh || (echo "mesh binary not found"; exit 1)
test -f meshctl || (echo "meshctl binary not found"; exit 1)
test -f mesh-ui || (echo "mesh-ui binary not found"; exit 1)
test -f contrib/macos/mesh.plist || (echo "contrib/macos/mesh.plist not found"; exit 1)
test -f contrib/semver/version.sh || (echo "contrib/semver/version.sh not found"; exit 1)
# Delete the pkgbuild folder if it already exists
test -d pkgbuild && rm -rf pkgbuild
# Create our folder structure
mkdir -p pkgbuild/scripts
mkdir -p pkgbuild/flat/base.pkg
mkdir -p pkgbuild/flat/Resources/en.lproj
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/Resources
mkdir -p pkgbuild/root/usr/local/bin
mkdir -p pkgbuild/root/Library/LaunchDaemons
# Copy package contents into the pkgbuild root
cp meshctl pkgbuild/root/usr/local/bin
cp mesh pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
cp mesh-ui pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
cp riv.icns pkgbuild/root/Applications/RiV-mesh.app/Contents/Resources
cp contrib/ui/mesh-ui/index.html pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
cp contrib/macos/mesh.plist pkgbuild/root/Library/LaunchDaemons
# Create the postinstall script
cat > pkgbuild/scripts/postinstall << EOF
#!/bin/sh
# Normalise the config if it exists, generate it if it doesn't
if [ -f /etc/mesh.conf ];
then
mkdir -p /Library/Preferences/RiV-mesh
echo "Backing up configuration file to /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`"
cp /etc/mesh.conf /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`
echo "Normalising /etc/mesh.conf"
/Applications/RiV-mesh.app/Contents/MacOS/mesh -useconffile /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf
else
/Applications/RiV-mesh.app/Contents/MacOS/mesh -genconf > /etc/mesh.conf
fi
chmod 755 /etc/mesh.conf
# Unload existing RiV-mesh launchd service, if possible
test -f /Library/LaunchDaemons/mesh.plist && (launchctl unload /Library/LaunchDaemons/mesh.plist || true)
# Load RiV-mesh launchd service and start RiV-mesh
launchctl load /Library/LaunchDaemons/mesh.plist
EOF
# Set execution permissions
chmod 755 pkgbuild/scripts/postinstall
chmod 755 pkgbuild/root/usr/local/bin/meshctl
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh-ui
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/index.html
# Work out metadata for the package info
PKGNAME=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
# Create the Info.plist file
cat > pkgbuild/root/Applications/RiV-mesh.app/Contents/Info.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.riv-mesh.ui</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleName</key>
<string>RiV-mesh</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>CFBundleIconFile</key>
<string>riv.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleGetInfoString</key>
<string>${PKGVERSION}</string>
<key>CFBundleVersion</key>
<string>${PKGVERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${PKGVERSION}</string>
<key>CFBundleExecutable</key>
<string>mesh-ui</string>
<key>CFBundleIdentifier</key>
<string>io.github.RiV-mesh.pkg</string>
<key>StandardOutPath</key>
<string>/tmp/mesh-ui.stdout.log</string>
<key>StandardErrorPath</key>
<string>/tmp/mesh-ui.stderr.log</string>
</dict>
</plist>
EOF
# Pack payload and scripts
( cd pkgbuild/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Scripts
( cd pkgbuild/root && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Payload
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
# Create the PackageInfo file
cat > pkgbuild/flat/base.pkg/PackageInfo << EOF
<pkg-info format-version="2" identifier="io.github.RiV-mesh.pkg" version="${PKGVERSION}" install-location="/" auth="root">
<payload installKBytes="${PAYLOADSIZE}" numberOfFiles="6"/>
<scripts>
<postinstall file="./postinstall"/>
</scripts>
</pkg-info>
EOF
# Create the BOM
( cd pkgbuild && mkbom root flat/base.pkg/Bom )
# Create the Distribution file
cat > pkgbuild/flat/Distribution << EOF
<?xml version="1.0" encoding="utf-8"?>
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.3" authoringToolBuild="174">
<title>RiV-mesh (${PKGNAME}-${PKGVERSION})</title>
<options customize="never" allow-external-scripts="no"/>
<domains enable_anywhere="true"/>
<installation-check script="pm_install_check();"/>
<script>
function pm_install_check() {
if(!(system.compareVersions(system.version.ProductVersion,'10.10') >= 0)) {
my.result.title = 'Failure';
my.result.message = 'You need at least Mac OS X 10.10 to install RiV-mesh.';
my.result.type = 'Fatal';
return false;
}
return true;
}
</script>
<choices-outline>
<line choice="choice1"/>
</choices-outline>
<choice id="choice1" title="base">
<pkg-ref id="io.github.RiV-mesh.pkg"/>
</choice>
<pkg-ref id="io.github.RiV-mesh.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
</installer-script>
EOF
# Finally pack the .pkg
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}.pkg" * )

View file

@ -15,16 +15,12 @@ command -v mkbom >/dev/null 2>&1 || (
sudo make install || (echo "Failed to build mkbom"; exit 1)
)
# Build Yggdrasil
echo "running GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build"
GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build
# Check if we can find the files we need - they should
# exist if you are running this script from the root of
# the yggdrasil-go repo and you have ran ./build
test -f yggdrasil || (echo "yggdrasil binary not found"; exit 1)
test -f yggdrasilctl || (echo "yggdrasilctl binary not found"; exit 1)
test -f contrib/macos/yggdrasil.plist || (echo "contrib/macos/yggdrasil.plist not found"; exit 1)
# the RiV-mesh repo and you have ran ./build
test -f mesh || (echo "mesh binary not found"; exit 1)
test -f meshctl || (echo "meshctl binary not found"; exit 1)
test -f contrib/macos/mesh.plist || (echo "contrib/macos/mesh.plist not found"; exit 1)
test -f contrib/semver/version.sh || (echo "contrib/semver/version.sh not found"; exit 1)
# Delete the pkgbuild folder if it already exists
@ -35,40 +31,43 @@ mkdir -p pkgbuild/scripts
mkdir -p pkgbuild/flat/base.pkg
mkdir -p pkgbuild/flat/Resources/en.lproj
mkdir -p pkgbuild/root/usr/local/bin
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
mkdir -p pkgbuild/root/Library/LaunchDaemons
# Copy package contents into the pkgbuild root
cp yggdrasil pkgbuild/root/usr/local/bin
cp yggdrasilctl pkgbuild/root/usr/local/bin
cp contrib/macos/yggdrasil.plist pkgbuild/root/Library/LaunchDaemons
cp mesh pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
cp meshctl pkgbuild/root/usr/local/bin
cp contrib/macos/mesh.plist pkgbuild/root/Library/LaunchDaemons
# Create the postinstall script
cat > pkgbuild/scripts/postinstall << EOF
#!/bin/sh
# Normalise the config if it exists, generate it if it doesn't
if [ -f /etc/yggdrasil.conf ];
if [ -f /etc/mesh.conf ];
then
mkdir -p /Library/Preferences/Yggdrasil
echo "Backing up configuration file to /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d`"
cp /etc/yggdrasil.conf /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d`
echo "Normalising /etc/yggdrasil.conf"
/usr/local/bin/yggdrasil -useconffile /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d` -normaliseconf > /etc/yggdrasil.conf
mkdir -p /Library/Preferences/RiV-mesh
echo "Backing up configuration file to /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`"
cp /etc/mesh.conf /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`
echo "Normalising /etc/mesh.conf"
/Applications/RiV-mesh.app/Contents/MacOS/mesh -useconffile /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf
else
/usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf
/Applications/RiV-mesh.app/Contents/MacOS/mesh -genconf > /etc/mesh.conf
fi
# Unload existing Yggdrasil launchd service, if possible
test -f /Library/LaunchDaemons/yggdrasil.plist && (launchctl unload /Library/LaunchDaemons/yggdrasil.plist || true)
chmod 755 /etc/mesh.conf
# Load Yggdrasil launchd service and start Yggdrasil
launchctl load /Library/LaunchDaemons/yggdrasil.plist
# Unload existing RiV-mesh launchd service, if possible
test -f /Library/LaunchDaemons/mesh.plist && (launchctl unload /Library/LaunchDaemons/mesh.plist || true)
# Load RiV-mesh launchd service and start RiV-mesh
launchctl load /Library/LaunchDaemons/mesh.plist
EOF
# Set execution permissions
chmod +x pkgbuild/scripts/postinstall
chmod +x pkgbuild/root/usr/local/bin/yggdrasil
chmod +x pkgbuild/root/usr/local/bin/yggdrasilctl
chmod 755 pkgbuild/scripts/postinstall
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh
chmod 755 pkgbuild/root/usr/local/bin/meshctl
# Pack payload and scripts
( cd pkgbuild/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Scripts
@ -79,11 +78,10 @@ PKGNAME=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
[ "$PKGARCH" = "amd64" ] && PKGHOSTARCH="x86_64" || PKGHOSTARCH=${PKGARCH}
# Create the PackageInfo file
cat > pkgbuild/flat/base.pkg/PackageInfo << EOF
<pkg-info format-version="2" identifier="io.github.yggdrasil-network.pkg" version="${PKGVERSION}" install-location="/" auth="root">
<pkg-info format-version="2" identifier="io.github.RiV-chain.pkg" version="${PKGVERSION}" install-location="/" auth="root">
<payload installKBytes="${PAYLOADSIZE}" numberOfFiles="3"/>
<scripts>
<postinstall file="./postinstall"/>
@ -98,15 +96,15 @@ EOF
cat > pkgbuild/flat/Distribution << EOF
<?xml version="1.0" encoding="utf-8"?>
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.3" authoringToolBuild="174">
<title>Yggdrasil (${PKGNAME}-${PKGVERSION})</title>
<options customize="never" allow-external-scripts="no" hostArchitectures="${PKGHOSTARCH}" />
<title>RiV-mesh (${PKGNAME}-${PKGVERSION})</title>
<options customize="never" allow-external-scripts="no"/>
<domains enable_anywhere="true"/>
<installation-check script="pm_install_check();"/>
<script>
function pm_install_check() {
if(!(system.compareVersions(system.version.ProductVersion,'10.10') >= 0)) {
my.result.title = 'Failure';
my.result.message = 'You need at least Mac OS X 10.10 to install Yggdrasil.';
my.result.message = 'You need at least Mac OS X 10.10 to install RiV-mesh.';
my.result.type = 'Fatal';
return false;
}
@ -117,11 +115,11 @@ cat > pkgbuild/flat/Distribution << EOF
<line choice="choice1"/>
</choices-outline>
<choice id="choice1" title="base">
<pkg-ref id="io.github.yggdrasil-network.pkg"/>
<pkg-ref id="io.github.RiV-mesh.pkg"/>
</choice>
<pkg-ref id="io.github.yggdrasil-network.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
<pkg-ref id="io.github.RiV-mesh.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
</installer-script>
EOF
# Finally pack the .pkg
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}.pkg" * )
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}-nogui.pkg" * )

26
contrib/macos/mesh.plist Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.riv-mesh.service</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/RiV-mesh.app/Contents/MacOS/mesh</string>
<string>-useconffile</string>
<string>/etc/mesh.conf</string>
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>ProcessType</key>
<string>Interactive</string>
<key>WorkingDirectory</key>
<string>/Applications/RiV-mesh.app/Contents/MacOS</string>
<key>StandardOutPath</key>
<string>/tmp/mesh.stdout.log</string>
<key>StandardErrorPath</key>
<string>/tmp/mesh.stderr.log</string>
</dict>
</plist>

View file

@ -0,0 +1,12 @@
.PHONY: all
all: util mesh-brute-multi-curve25519 mesh-brute-multi-ed25519
util: util.c
gcc -Wall -std=c89 -O3 -c -o util.o util.c
mesh-brute-multi-ed25519: mesh-brute-multi-ed25519.c util.o
gcc -Wall -std=c89 -O3 -o mesh-brute-multi-ed25519 -lsodium mesh-brute-multi-ed25519.c util.o
mesh-brute-multi-curve25519: mesh-brute-multi-curve25519.c util.o
gcc -Wall -std=c89 -O3 -o mesh-brute-multi-curve25519 -lsodium mesh-brute-multi-curve25519.c util.o

View file

@ -1,4 +1,4 @@
# yggdrasil-brute-simple
# mesh-brute-simple
Simple program for finding curve25519 and ed25519 public keys whose sha512 hash has many leading ones.
Because ed25519 private keys consist of a seed that is hashed to find the secret part of the keypair,

View file

@ -13,7 +13,7 @@ if besthash:
besthash = hash
*/
#include "yggdrasil-brute.h"
#include "mesh-brute.h"
void seed(unsigned char sk[32]) {
@ -43,7 +43,7 @@ int main(int argc, char **argv) {
int where;
if (argc != 2) {
fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 <seconds>\n");
fprintf(stderr, "usage: ./mesh-brute-multi-curve25519 <seconds>\n");
return 1;
}
@ -57,7 +57,7 @@ int main(int argc, char **argv) {
requestedtime = atoi(argv[1]);
if (requestedtime < 0) requestedtime = 0;
fprintf(stderr, "Searching for yggdrasil curve25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
fprintf(stderr, "Searching for mesh curve25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
sodium_memzero(bestsklist, NUMKEYS * 32);
sodium_memzero(bestpklist, NUMKEYS * 32);

View file

@ -20,7 +20,7 @@ if besthash:
besthash = hash
*/
#include "yggdrasil-brute.h"
#include "mesh-brute.h"
int main(int argc, char **argv) {
@ -41,7 +41,7 @@ int main(int argc, char **argv) {
int where;
if (argc != 2) {
fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 <seconds>\n");
fprintf(stderr, "usage: ./mesh-brute-multi-curve25519 <seconds>\n");
return 1;
}
@ -55,7 +55,7 @@ int main(int argc, char **argv) {
requestedtime = atoi(argv[1]);
if (requestedtime < 0) requestedtime = 0;
fprintf(stderr, "Searching for yggdrasil ed25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
fprintf(stderr, "Searching for mesh ed25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
sodium_memzero(bestsklist, NUMKEYS * 64);
sodium_memzero(besthashlist, NUMKEYS * 64);

View file

@ -1,4 +1,4 @@
#include "yggdrasil-brute.h"
#include "mesh-brute.h"
int find_where(unsigned char hash[64], unsigned char besthashlist[NUMKEYS][64]) {
/* Where to insert hash into sorted hashlist */
@ -28,7 +28,7 @@ void insert_32(unsigned char itemlist[NUMKEYS][32], unsigned char item[32], int
}
void make_addr(unsigned char addr[32], unsigned char hash[64]) {
/* Public key hash to yggdrasil ipv6 address */
/* Public key hash to mesh ipv6 address */
int i;
int offset;
unsigned char mask;

View file

@ -4,7 +4,7 @@ set -ef
[ ! -d contrib/mobile ] && (echo "Must run ./contrib/mobile/build [-i] [-a] from the repository top level folder"; exit 1)
PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version}
PKGSRC=${PKGSRC:-github.com/RiV-chain/RiV-mesh/src/version}
PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)}
PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)}
@ -37,7 +37,7 @@ if [ $IOS ]; then
echo "Building framework for iOS"
go get golang.org/x/mobile/bind
gomobile bind \
-target ios -tags mobile -o Yggdrasil.xcframework \
-target ios -tags mobile -o Mesh.xcframework \
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
./contrib/mobile ./src/config;
fi
@ -46,7 +46,7 @@ if [ $ANDROID ]; then
echo "Building aar for Android"
go get golang.org/x/mobile/bind
gomobile bind \
-target android -tags mobile -o yggdrasil.aar \
-target android -tags mobile -o mesh.aar \
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
./contrib/mobile ./src/config;
fi

View file

@ -9,23 +9,23 @@ import (
"github.com/gologme/log"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/config"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
"github.com/yggdrasil-network/yggdrasil-go/src/version"
"github.com/RiV-chain/RiV-mesh/src/address"
"github.com/RiV-chain/RiV-mesh/src/config"
"github.com/RiV-chain/RiV-mesh/src/core"
"github.com/RiV-chain/RiV-mesh/src/defaults"
"github.com/RiV-chain/RiV-mesh/src/ipv6rwc"
"github.com/RiV-chain/RiV-mesh/src/multicast"
"github.com/RiV-chain/RiV-mesh/src/version"
_ "golang.org/x/mobile/bind"
)
// Yggdrasil mobile package is meant to "plug the gap" for mobile support, as
// RiV-mesh mobile package is meant to "plug the gap" for mobile support, as
// Gomobile will not create headers for Swift/Obj-C etc if they have complex
// (non-native) types. Therefore for iOS we will expose some nice simple
// functions. Note that in the case of iOS we handle reading/writing to/from TUN
// in Swift therefore we use the "dummy" TUN interface instead.
type Yggdrasil struct {
type Mesh struct {
core *core.Core
iprwc *ipv6rwc.ReadWriteCloser
config *config.NodeConfig
@ -34,13 +34,13 @@ type Yggdrasil struct {
}
// StartAutoconfigure starts a node with a randomly generated config
func (m *Yggdrasil) StartAutoconfigure() error {
func (m *Mesh) StartAutoconfigure() error {
return m.StartJSON([]byte("{}"))
}
// StartJSON starts a node with the given JSON config. You can get JSON config
// (rather than HJSON) by using the GenerateConfigJSON() function
func (m *Yggdrasil) StartJSON(configjson []byte) error {
func (m *Mesh) StartJSON(configjson []byte) error {
logger := log.New(m.log, "", 0)
logger.EnableLevel("error")
logger.EnableLevel("warn")
@ -83,10 +83,10 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error {
options := []multicast.SetupOption{}
for _, intf := range m.config.MulticastInterfaces {
options = append(options, multicast.MulticastInterface{
Regex: regexp.MustCompile(intf.Regex),
Beacon: intf.Beacon,
Listen: intf.Listen,
Port: intf.Port,
Regex: regexp.MustCompile(intf.Regex),
Beacon: intf.Beacon,
Listen: intf.Listen,
Port: intf.Port,
Priority: intf.Priority,
})
}
@ -105,9 +105,9 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error {
return nil
}
// Send sends a packet to Yggdrasil. It should be a fully formed
// Send sends a packet to Mesh. It should be a fully formed
// IPv6 packet
func (m *Yggdrasil) Send(p []byte) error {
func (m *Mesh) Send(p []byte) error {
if m.iprwc == nil {
return nil
}
@ -115,9 +115,9 @@ func (m *Yggdrasil) Send(p []byte) error {
return nil
}
// Recv waits for and reads a packet coming from Yggdrasil. It
// Recv waits for and reads a packet coming from Mesh. It
// will be a fully formed IPv6 packet
func (m *Yggdrasil) Recv() ([]byte, error) {
func (m *Mesh) Recv() ([]byte, error) {
if m.iprwc == nil {
return nil, nil
}
@ -126,11 +126,11 @@ func (m *Yggdrasil) Recv() ([]byte, error) {
return buf[:n], nil
}
// Stop the mobile Yggdrasil instance
func (m *Yggdrasil) Stop() error {
// Stop the mobile Mesh instance
func (m *Mesh) Stop() error {
logger := log.New(m.log, "", 0)
logger.EnableLevel("info")
logger.Infof("Stop the mobile Yggdrasil instance %s", "")
logger.Infof("Stop the mobile Mesh instance %s", "")
if err := m.multicast.Stop(); err != nil {
return err
}
@ -149,28 +149,28 @@ func GenerateConfigJSON() []byte {
}
// GetAddressString gets the node's IPv6 address
func (m *Yggdrasil) GetAddressString() string {
func (m *Mesh) GetAddressString() string {
ip := m.core.Address()
return ip.String()
}
// GetSubnetString gets the node's IPv6 subnet in CIDR notation
func (m *Yggdrasil) GetSubnetString() string {
func (m *Mesh) GetSubnetString() string {
subnet := m.core.Subnet()
return subnet.String()
}
// GetPublicKeyString gets the node's public key in hex form
func (m *Yggdrasil) GetPublicKeyString() string {
func (m *Mesh) GetPublicKeyString() string {
return hex.EncodeToString(m.core.GetSelf().Key)
}
// GetCoordsString gets the node's coordinates
func (m *Yggdrasil) GetCoordsString() string {
func (m *Mesh) GetCoordsString() string {
return fmt.Sprintf("%v", m.core.GetSelf().Coords)
}
func (m *Yggdrasil) GetPeersJSON() (result string) {
func (m *Mesh) GetPeersJSON() (result string) {
peers := []struct {
core.PeerInfo
IP string
@ -193,7 +193,7 @@ func (m *Yggdrasil) GetPeersJSON() (result string) {
}
}
func (m *Yggdrasil) GetDHTJSON() (result string) {
func (m *Mesh) GetDHTJSON() (result string) {
if res, err := json.Marshal(m.core.GetDHT()); err == nil {
return string(res)
} else {
@ -202,7 +202,7 @@ func (m *Yggdrasil) GetDHTJSON() (result string) {
}
// GetMTU returns the configured node MTU. This must be called AFTER Start.
func (m *Yggdrasil) GetMTU() int {
func (m *Mesh) GetMTU() int {
return int(m.core.MTU())
}

View file

@ -3,14 +3,14 @@ package mobile
import "testing"
func TestStartYggdrasil(t *testing.T) {
ygg := &Yggdrasil{}
if err := ygg.StartAutoconfigure(); err != nil {
t.Fatalf("Failed to start Yggdrasil: %s", err)
ygg := &Mesh{}
if err := mesh.StartAutoconfigure(); err != nil {
t.Fatalf("Failed to start Mesh: %s", err)
}
t.Log("Address:", ygg.GetAddressString())
t.Log("Subnet:", ygg.GetSubnetString())
t.Log("Coords:", ygg.GetCoordsString())
if err := ygg.Stop(); err != nil {
t.Log("Address:", mesh.GetAddressString())
t.Log("Subnet:", mesh.GetSubnetString())
t.Log("Coords:", mesh.GetCoordsString())
if err := mesh.Stop(); err != nil {
t.Fatalf("Failed to stop Yggdrasil: %s", err)
}
}

View file

@ -0,0 +1,313 @@
#!/bin/sh
# This script generates an MSI file for Mesh for a given architecture. It
# needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on
# the system and within the PATH. This is ran currently by Appveyor or GitHub Actions (see
# appveyor.yml in the repository root) for both x86 and x64.
#
# Author: Neil Alexander <neilalexander@users.noreply.github.com>, Vadym Vikulin <vadym.vikulin@rivchain.org>
# Get arch from command line if given
PKGARCH=$1
if [ "${PKGARCH}" == "" ];
then
echo "tell me the architecture: x86, x64 or arm"
exit 1
fi
# Get the rest of the repository history. This is needed within Appveyor because
# otherwise we don't get all of the branch histories and therefore the semver
# scripts don't work properly.
if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ];
then
git fetch --all
git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
elif [ "${APPVEYOR_REPO_BRANCH}" != "" ];
then
git fetch --all
git checkout ${APPVEYOR_REPO_BRANCH}
fi
# Install prerequisites within MSYS2
pacman -S --needed --noconfirm unzip git curl
# Download the wix tools!
if [ ! -d wixbin ];
then
curl -LO https://wixtoolset.org/downloads/v3.14.0.3910/wix314-binaries.zip
if [ `md5sum wix314-binaries.zip | cut -f 1 -d " "` != "34f655cf108086838dd5a76d4318063b" ];
then
echo "wix package didn't match expected checksum"
exit 1
fi
mkdir -p wixbin
unzip -o wix311-binaries.zip -d wixbin || (
echo "failed to unzip WiX"
exit 1
)
fi
# Work out metadata for the package info
PKGNAME=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
PKGVERSIONMS=$(echo $PKGVERSION | tr - .)
PKGINDEXFILE=contrib/ui/mesh-ui/index.html
PKGLICENSEFILE=LICENSE.rtf
#Build winres
go-winres simply --icon riv.ico --file-version $PKGVERSION --file-description "RiV-mesh (c) service, 2021 RIV CHAIN" \
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN"
cp *.syso cmd/mesh
go-winres simply --icon riv.ico --file-version $PKGVERSION --file-description "RiV-mesh (c) GUI, 2021 RIV CHAIN" \
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN" --manifest gui
cp *.syso contrib/ui/mesh-ui
go-winres simply --file-version $PKGVERSION --file-description "RiV-mesh (c) CLI, 2021 RIV CHAIN" \
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN" --manifest cli
cp *.syso cmd/meshctl
# Build Mesh!
[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ LDFLAGS="-H windowsgui" ./build
[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ LDFLAGS="-H windowsgui" ./build
[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
#[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ ./build
#[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ ./build
#[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
#[ "${PKGARCH}" == "arm64" ] && GOOS=windows GOARCH=arm64 CGO_ENABLED=0 ./build
# Create the postinstall script
cat > updateconfig.bat << EOF
if not exist %ALLUSERSPROFILE%\\RiV-mesh (
mkdir %ALLUSERSPROFILE%\\RiV-mesh
)
if not exist %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf (
if exist mesh.exe (
mesh.exe -genconf > %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf
)
)
EOF
[ "${PKGARCH}" == "x64" ] && \
PKGGUID="5bcfdddd-66a7-4eb7-b5f7-4a7500dcc65d" PKGINSTFOLDER="ProgramFiles64Folder" || \
PKGGUID="cbf6ffa1-219e-4bb2-a0e5-74dbf1b58a45" PKGINSTFOLDER="ProgramFilesFolder"
# Download the Wintun driver
if [ ! -d wintun ];
then
curl -o wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip
unzip wintun.zip
fi
if [ $PKGARCH = "x64" ]; then
PKGWINTUNDLL=wintun/bin/amd64/wintun.dll
PKGWEBVIEWFILE=contrib/ui/mesh-ui/dll/x64/webview.dll
PKGWEBVIEWFILELOADER=contrib/ui/mesh-ui/dll/x64/WebView2Loader.dll
elif [ $PKGARCH = "x86" ]; then
PKGWINTUNDLL=wintun/bin/x86/wintun.dll
PKGWEBVIEWFILE=contrib/ui/mesh-ui/dll/x86/webview.dll
PKGWEBVIEWFILELOADER=contrib/ui/mesh-ui/dll/x86/WebView2Loader.dll
elif [ $PKGARCH = "arm" ]; then
PKGWINTUNDLL=wintun/bin/arm/wintun.dll
#elif [ $PKGARCH = "arm64" ]; then
# PKGWINTUNDLL=wintun/bin/arm64/wintun.dll
else
echo "wasn't sure which architecture to get wintun for"
exit 1
fi
if [ $PKGNAME != "master" ]; then
PKGDISPLAYNAME="RiV-mesh Network (${PKGNAME} branch)"
else
PKGDISPLAYNAME="RiV-mesh Network"
fi
# Generate the wix.xml file
cat > wix.xml << EOF
<?xml version="1.0" encoding="windows-1252"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product
Name="${PKGDISPLAYNAME}"
Id="*"
UpgradeCode="${PKGGUID}"
Language="1033"
Codepage="1252"
Version="${PKGVERSIONMS}"
Manufacturer="RiV-chain">
<Package
Id="*"
Keywords="Installer"
Description="RiV-mesh Network Installer"
Comments="RiV-mesh Network standalone router for Windows."
Manufacturer="RiV-chain"
InstallerVersion="200"
InstallScope="perMachine"
Languages="1033"
Compressed="yes"
SummaryCodepage="1252" />
<MajorUpgrade
AllowDowngrades="yes" />
<Media
Id="1"
Cabinet="Media.cab"
EmbedCab="yes"
CompressionLevel="high" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop"/>
<Directory Id="${PKGINSTFOLDER}" Name="PFiles">
<Directory Id="MeshInstallFolder" Name="RiV-mesh">
<Component Id="MainExecutable" Guid="c2119231-2aa3-4962-867a-9759c87beb24">
<File
Id="Mesh"
Name="mesh.exe"
DiskId="1"
Source="mesh.exe"
KeyPath="yes" />
<File
Id="Wintun"
Name="wintun.dll"
DiskId="1"
Source="${PKGWINTUNDLL}" />
<ServiceInstall
Id="MeshServiceInstaller"
Account="LocalSystem"
Description="RiV-mesh Network router process"
DisplayName="RiV-mesh Service"
ErrorControl="normal"
LoadOrderGroup="NetworkProvider"
Name="Mesh"
Start="auto"
Type="ownProcess"
Arguments='-useconffile "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf" -logto "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.log"'
Vital="yes" />
<ServiceControl
Id="MeshServiceControl"
Name="Mesh"
Start="install"
Stop="both"
Remove="uninstall" />
</Component>
<Component Id="CtrlExecutable" Guid="a916b730-974d-42a1-b687-d9d504cbb86a">
<File
Id="Meshctl"
Name="meshctl.exe"
DiskId="1"
Source="meshctl.exe"
KeyPath="yes"/>
</Component>
<Component Id="UIExecutable" Guid="ef9f30e0-8274-4526-835b-51bc09b5b1b7">
<File
Id="MeshUI"
Name="mesh-ui.exe"
DiskId="1"
Source="mesh-ui.exe"
KeyPath="yes" />
<File
Id="WebViewHtmlFile"
Name="index.html"
DiskId="1"
Source="${PKGINDEXFILE}" />
<File
Id="WebViewDllFile"
Name="webview.dll"
DiskId="1"
Source="${PKGWEBVIEWFILE}" />
<File
Id="WebViewLoaderFile"
Name="WebView2Loader.dll"
DiskId="1"
Source="${PKGWEBVIEWFILELOADER}" />
</Component>
<Component Id="ConfigScript" Guid="64a3733b-c98a-4732-85f3-20cd7da1a785">
<File
Id="Configbat"
Name="updateconfig.bat"
DiskId="1"
Source="updateconfig.bat"
KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="MeshFeature" Title="Mesh" Level="1">
<ComponentRef Id="MainExecutable" />
<ComponentRef Id="UIExecutable" />
<ComponentRef Id="CtrlExecutable" />
<ComponentRef Id="cmpDesktopShortcut" />
<ComponentRef Id="ConfigScript" />
</Feature>
<CustomAction
Id="UpdateGenerateConfig"
Directory="MeshInstallFolder"
ExeCommand="cmd.exe /c updateconfig.bat"
Execute="deferred"
Return="check"
Impersonate="yes" />
<!-- Step 2: Add UI to your installer / Step 4: Trigger the custom action -->
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<WixVariable Id="WixUILicenseRtf" Value="${PKGLICENSEFILE}" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch RiV-mesh" />
<!-- Step 3: Include the custom action -->
<Property Id="WixShellExecTarget" Value="[#MeshUI]" />
<Property Id="ASSISTANCE_START_VIA_REGISTRY">1</Property>
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
<InstallExecuteSequence>
<Custom
Action="UpdateGenerateConfig"
Before="StartServices">
NOT Installed AND NOT REMOVE
</Custom>
</InstallExecuteSequence>
<Component Id="cmpDesktopShortcut" Guid="e32e4d07-abf8-4c37-a2c3-1ca4b4f98adc" Directory="DesktopFolder" >
<Shortcut Id="RiVMeshDesktopShortcut"
Name="RiV-mesh"
Description="RiV-mesh is IoT E2E encrypted network"
Directory="DesktopFolder"
Target="[MeshInstallFolder]mesh-ui.exe"
WorkingDirectory="MeshInstallFolder"/>
<RegistryValue Root="HKCU" Key="Software\RiV-chain\RiV-mesh" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RegistryValue Id="MerAs.rst" Root="HKMU" Action="write"
Key="Software\Microsoft\Windows\CurrentVersion\Run"
Name="RiV-mesh client"
Value="[MeshInstallFolder]mesh-ui.exe"
Type="string" />
<Condition>ASSISTANCE_START_VIA_REGISTRY</Condition>
</Component>
</Product>
</Wix>
EOF
# Generate the MSI
CANDLEFLAGS="-nologo"
LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61"
wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \
wixbin/light $LIGHTFLAGS -ext WixUIExtension -ext WixUtilExtension -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj

View file

@ -1,9 +1,9 @@
#!/bin/sh
# This script generates an MSI file for Yggdrasil for a given architecture. It
# needs to run on Windows within MSYS2 and Go 1.17 or later must be installed on
# the system and within the PATH. This is ran currently by GitHub Actions (see
# the workflows in the repository).
# This script generates an MSI file for Mesh for a given architecture. It
# needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on
# the system and within the PATH. This is ran currently by Appveyor or GitHub Actions (see
# appveyor.yml in the repository root) for both x86 and x64.
#
# Author: Neil Alexander <neilalexander@users.noreply.github.com>
@ -15,6 +15,22 @@ then
exit 1
fi
# Get the rest of the repository history. This is needed within Appveyor because
# otherwise we don't get all of the branch histories and therefore the semver
# scripts don't work properly.
if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ];
then
git fetch --all
git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
elif [ "${APPVEYOR_REPO_BRANCH}" != "" ];
then
git fetch --all
git checkout ${APPVEYOR_REPO_BRANCH}
fi
# Install prerequisites within MSYS2
pacman -S --needed --noconfirm unzip git curl
# Download the wix tools!
if [ ! -d wixbin ];
then
@ -31,7 +47,7 @@ then
)
fi
# Build Yggdrasil!
# Build Mesh!
[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./build
[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=0 ./build
[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
@ -39,12 +55,12 @@ fi
# Create the postinstall script
cat > updateconfig.bat << EOF
if not exist %ALLUSERSPROFILE%\\Yggdrasil (
mkdir %ALLUSERSPROFILE%\\Yggdrasil
if not exist %ALLUSERSPROFILE%\\RiV-mesh (
mkdir %ALLUSERSPROFILE%\\RiV-mesh
)
if not exist %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf (
if exist yggdrasil.exe (
yggdrasil.exe -genconf > %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf
if not exist %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf (
if exist mesh.exe (
mesh.exe -genconf > %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf
)
)
EOF
@ -53,9 +69,9 @@ EOF
PKGNAME=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
PKGVERSIONMS=$(echo $PKGVERSION | tr - .)
([ "${PKGARCH}" == "x64" ] || [ "${PKGARCH}" == "arm64" ]) && \
PKGGUID="77757838-1a23-40a5-a720-c3b43e0260cc" PKGINSTFOLDER="ProgramFiles64Folder" || \
PKGGUID="54a3294e-a441-4322-aefb-3bb40dd022bb" PKGINSTFOLDER="ProgramFilesFolder"
[ "${PKGARCH}" == "x64" ] && \
PKGGUID="5bcfdddd-66a7-4eb7-b5f7-4a7500dcc65d" PKGINSTFOLDER="ProgramFiles64Folder" || \
PKGGUID="cbf6ffa1-219e-4bb2-a0e5-74dbf1b58a45" PKGINSTFOLDER="ProgramFilesFolder"
# Download the Wintun driver
if [ ! -d wintun ];
@ -77,9 +93,9 @@ else
fi
if [ $PKGNAME != "master" ]; then
PKGDISPLAYNAME="Yggdrasil Network (${PKGNAME} branch)"
PKGDISPLAYNAME="RiV-mesh Network (${PKGNAME} branch)"
else
PKGDISPLAYNAME="Yggdrasil Network"
PKGDISPLAYNAME="RiV-mesh Network"
fi
# Generate the wix.xml file
@ -93,14 +109,14 @@ cat > wix.xml << EOF
Language="1033"
Codepage="1252"
Version="${PKGVERSIONMS}"
Manufacturer="github.com/yggdrasil-network">
Manufacturer="RiV-chain">
<Package
Id="*"
Keywords="Installer"
Description="Yggdrasil Network Installer"
Comments="Yggdrasil Network standalone router for Windows."
Manufacturer="github.com/yggdrasil-network"
Description="RiV-mesh Network Installer"
Comments="RiV-mesh Network standalone router for Windows."
Manufacturer="RiV-chain"
InstallerVersion="200"
InstallScope="perMachine"
Languages="1033"
@ -118,14 +134,14 @@ cat > wix.xml << EOF
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="${PKGINSTFOLDER}" Name="PFiles">
<Directory Id="YggdrasilInstallFolder" Name="Yggdrasil">
<Directory Id="MeshInstallFolder" Name="Mesh">
<Component Id="MainExecutable" Guid="c2119231-2aa3-4962-867a-9759c87beb24">
<File
Id="Yggdrasil"
Name="yggdrasil.exe"
Id="Mesh"
Name="mesh.exe"
DiskId="1"
Source="yggdrasil.exe"
Source="mesh.exe"
KeyPath="yes" />
<File
@ -137,19 +153,19 @@ cat > wix.xml << EOF
<ServiceInstall
Id="ServiceInstaller"
Account="LocalSystem"
Description="Yggdrasil Network router process"
DisplayName="Yggdrasil Service"
Description="RiV-mesh Network router process"
DisplayName="RiV-mesh Service"
ErrorControl="normal"
LoadOrderGroup="NetworkProvider"
Name="Yggdrasil"
Name="Mesh"
Start="auto"
Type="ownProcess"
Arguments='-useconffile "%ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf" -logto "%ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.log"'
Arguments='-useconffile "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf" -logto "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.log"'
Vital="yes" />
<ServiceControl
Id="ServiceControl"
Name="yggdrasil"
Id="MeshServiceControl"
Name="Mesh"
Start="install"
Stop="both"
Remove="uninstall" />
@ -157,10 +173,10 @@ cat > wix.xml << EOF
<Component Id="CtrlExecutable" Guid="a916b730-974d-42a1-b687-d9d504cbb86a">
<File
Id="Yggdrasilctl"
Name="yggdrasilctl.exe"
Id="Meshctl"
Name="meshctl.exe"
DiskId="1"
Source="yggdrasilctl.exe"
Source="meshctl.exe"
KeyPath="yes"/>
</Component>
@ -176,7 +192,7 @@ cat > wix.xml << EOF
</Directory>
</Directory>
<Feature Id="YggdrasilFeature" Title="Yggdrasil" Level="1">
<Feature Id="MeshFeature" Title="Mesh" Level="1">
<ComponentRef Id="MainExecutable" />
<ComponentRef Id="CtrlExecutable" />
<ComponentRef Id="ConfigScript" />
@ -184,7 +200,7 @@ cat > wix.xml << EOF
<CustomAction
Id="UpdateGenerateConfig"
Directory="YggdrasilInstallFolder"
Directory="MeshInstallFolder"
ExeCommand="cmd.exe /c updateconfig.bat"
Execute="deferred"
Return="check"
@ -206,4 +222,4 @@ EOF
CANDLEFLAGS="-nologo"
LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61"
wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \
wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj
wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}-nogui.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj

View file

@ -17,30 +17,6 @@ if [ $? != 0 ] || [ -z "$BRANCH" ]; then
BRANCH="master"
fi
# Split out into major, minor and patch numbers
MAJOR=$(echo $TAG | cut -c 2- | cut -d "." -f 1)
MINOR=$(echo $TAG | cut -c 2- | cut -d "." -f 2)
PATCH=$(echo $TAG | cut -c 2- | cut -d "." -f 3 | awk -F"rc" '{print $1}')
STAG=$(echo $TAG | sed 's/v//' | sed 's/[^0123456789.].//')
# Output in the desired format
if [ $((PATCH)) -eq 0 ]; then
printf '%s%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))"
else
printf '%s%d.%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))" "$((PATCH))"
fi
# Add the build tag on non-master branches
if [ "$BRANCH" != "master" ]; then
BUILD=$(git rev-list --count $TAG..HEAD 2>/dev/null)
# Did getting the count of commits since the tag succeed?
if [ $? != 0 ] || [ -z "$BUILD" ]; then
printf -- "-unknown"
exit 0
fi
# Is the build greater than zero?
if [ $((BUILD)) -gt 0 ]; then
printf -- "-%04d" "$((BUILD))"
fi
fi
printf '%s' "$STAG"

108
contrib/nas/nas-asustor.sh Normal file
View file

@ -0,0 +1,108 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFILE=mesh-$PKGFOLDER.apk
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=x86-64 or armv7"
exit 1
fi
echo "Building $PKGFOLDER"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/bin
mkdir -p /tmp/$PKGFOLDER/var/log
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-asustor/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
echo "Converting icon for: 90x90"
convert -colorspace sRGB ./riv.png -resize 90x90 PNG32:/tmp/$PKGFOLDER/CONTROL/icon.png
chmod 644 /tmp/$PKGFOLDER/CONTROL/icon.png
cat > /tmp/$PKGFOLDER/CONTROL/config.json << EOF
{
"general": {
"package": "mesh-$ENV_TAG",
"name": "RiV Mesh",
"version": "$PKGVERSION",
"depends": [],
"conflicts": [],
"developer": "Riv Chain ltd",
"maintainer": "Riv Chain ltd",
"email": "vadym.vikulin@rivchain.org",
"website": "https://github.com/RiV-chain/RiV-mesh",
"architecture": "$PKGARCH",
"firmware": "2.4.0"
},
"adm-desktop": {
"app": {
"type":"custom",
"protocol":"http",
"port": 19019,
"url": "/"
},
"privilege": {
"accessible": "administrators",
"customizable": true
}
},
"register": {
"share-folder": [
],
"prerequisites": {
"enable-service": [],
"restart-service": []
},
"boot-priority": {
"start-order": 95,
"stop-order": 5
},
"port": []
}
}
EOF
cat > /tmp/$PKGFOLDER/CHANGELOG.md << EOF
See https://github.com/RiV-chain/RiV-mesh
EOF
cat > /tmp/$PKGFOLDER/CONTROL/changelog.txt << EOF
See https://github.com/RiV-chain/RiV-mesh
EOF
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
cp LICENSE /tmp/$PKGFOLDER/CONTROL/license.txt
chmod +x /tmp/$PKGFOLDER/bin/*
chmod 0775 /tmp/$PKGFOLDER/www -R
fakeroot python2 ./contrib/nas/tool/asustor_apkg_tools.py create /tmp/$PKGFOLDER
rm -rf /tmp/$PKGFOLDER/
#mv *.apk $PKGFILE

90
contrib/nas/nas-drobo.sh Normal file
View file

@ -0,0 +1,90 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFOLDER=$PKGNAME/mesh
PKGFILE=mesh-$PKGNAME.tar.gz
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=armv7"
exit 1
fi
echo "Building $PKGFOLDER"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/bin
mkdir -p /tmp/$PKGFOLDER/config
mkdir -p /tmp/$PKGFOLDER/var/log
mkdir -p /tmp/$PKGFOLDER/lib/modules
if [ $ENV_TAG = "nas-drobo-5n" ]; then
for kernel in 3.2.96-3 3.2.58-2 3.2.58-1 3.2.58 3.2.27; do
echo "Loading tun module for Linux kernel $kernel"
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/5N/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
done
elif [ $ENV_TAG = "nas-drobo-5n2" ]; then
for kernel in 3.2.96-3 3.2.58-2; do
echo "Loading tun module for Linux kernel $kernel"
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/5N2/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
done
elif [ $ENV_TAG = "nas-drobo-b810n" ]; then
for kernel in 3.2.96-3 3.2.58-2 3.2.58-1 3.2.58; do
echo "Loading tun module for Linux kernel $kernel"
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/B810n/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
done
else
echo "Specify ENV_TAG=nas-drobo-5n or nas-drobo-5n2 or nas-drobo-b810n"
exit 1
fi
mkdir -p /tmp/$PKGFOLDER/tmp
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-drobo/Content/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
cat > /tmp/$PKGFOLDER/version.txt << EOF
$PKGVERSION
EOF
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
cp LICENSE /tmp/$PKGFOLDER/
chmod +x /tmp/$PKGFOLDER/*.sh
chmod +x /tmp/$PKGFOLDER/bin/*
chmod 0775 /tmp/$PKGFOLDER/www -R
current_dir=$(pwd)
cd /tmp/$PKGFOLDER && tar czf ../mesh.tgz $(ls .)
cd ../ && md5sum mesh.tgz > mesh.tgz.md5
tar czf $PKGFILE mesh.tgz mesh.tgz.md5
mv $PKGFILE "$current_dir"
cd "$current_dir"
rm -rf /tmp/$PKGNAME/

View file

@ -0,0 +1,108 @@
#!/bin/sh
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
# mesh and enables it in systemd. You can give it the PKGARCH= argument
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
if [ $(pwd) != $(git rev-parse --show-toplevel) ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$ENV_TAG-$PKGVERSION
PKGFILE=$PKGNAME.deb
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
elif [ $PKGARCH = "armel" ]; then GOARCH=arm GOARM=5 GOOS=linux ./build
else
echo "Specify PKGARCH=amd64,armel"
exit 1
fi
echo "Building $PKGFILE"
mkdir -p /tmp/$PKGNAME/usr/bin
mkdir -p /tmp/$PKGNAME/debian/
mkdir -p /tmp/$PKGNAME/DEBIAN/
mkdir -p /tmp/$PKGNAME/apps/mesh/bin
mkdir -p /tmp/$PKGNAME/apps/mesh/www
mkdir -p /tmp/$PKGNAME/apps/mesh/var/log
mkdir -p /tmp/$PKGNAME/apps/mesh/var/lib/mesh/hooks
mkdir -p /tmp/$PKGNAME/usr/share/doc/mesh
chmod 0775 /tmp/$PKGNAME/ -R
for resolution in 150x150; do
echo "Converting icon for: $resolution"
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGNAME/apps/mesh/logo.png && \
chmod 644 /tmp/$PKGNAME/apps/mesh/logo.png
done
cat > /tmp/$PKGNAME/apps/mesh/config.xml << EOF
<Application resource-id="mesh"><!-- 'resource-id' must be AppName -->
<Name>RiV Mesh</Name><!-- Any desciptive name, upto 48 chars -->
<Author>Riv Chain Ltd</Author><!-- Authors name. upto 48 chars -->
<Version>$PKGVERSION</Version><!-- Version -->
<RequireReboot>0</RequireReboot><!-- If non-zero, it indicates reboot is required. -->
<ConfigURL></ConfigURL><!-- 'localhost' will be replaced by framework JS. -->
<LaunchURL>https://localhost/apps/mesh/</LaunchURL><!-- 'localhost' will be replaced by framework JS. -->
<ReservePort>19019</ReservePort>
<DebianPackage>mesh</DebianPackage>
<ServiceName>fvapp-mesh.service</ServiceName><!-- If start/stop need to start/stop service, specify service name -->
<Description lang="en-us">RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.</Description>
</Application>
EOF
echo "coping ui package..."
cp contrib/ui/nas-netgear-os6/package/apps /tmp/$PKGNAME/ -r
cp contrib/ui/www/* /tmp/$PKGNAME/apps/mesh/www/ -r
cat > /tmp/$PKGNAME/debian/changelog << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
echo 9 > /tmp/$PKGNAME/debian/compat
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
Package: mesh
Version: $PKGVERSION
Section: contrib/net
Priority: extra
Architecture: $PKGARCH
Replaces: $PKGREPLACES
Conflicts: $PKGREPLACES
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other RiV-mesh nodes.
EOF
cat > /tmp/$PKGNAME/debian/copyright << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cat > /tmp/$PKGNAME/debian/docs << EOF
Please see https://github.com/RiV-chain/RiV-mesh/
EOF
cp mesh /tmp/$PKGNAME/apps/mesh/bin
cp meshctl /tmp/$PKGNAME/apps/mesh/bin
ln -s /apps/mesh/bin/meshctl /tmp/$PKGNAME/usr/bin/meshctl
ln -s /apps/mesh/var/log/mesh.log /tmp/$PKGNAME/apps/mesh/www/log
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
chmod 755 /tmp/$PKGNAME/apps/mesh/bin/*
dpkg-deb -Zxz --build --root-owner-group /tmp/$PKGNAME
cp /tmp/$PKGFILE .
rm -rf /tmp/$PKGNAME

84
contrib/nas/nas-qnap.sh Normal file
View file

@ -0,0 +1,84 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semmsiver/name.sh)
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFILE=mesh-$PKGFOLDER.qpkg
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
elif [ $PKGARCH = "arm-x31" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=x86-64 or arm-x31"
exit 1
fi
echo "Building $PKGFOLDER"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/mesh
mkdir -p /tmp/$PKGFOLDER/mesh/icons
mkdir -p /tmp/$PKGFOLDER/mesh/shared/bin
mkdir -p /tmp/$PKGFOLDER/mesh/shared/tmp
mkdir -p /tmp/$PKGFOLDER/mesh/shared/lib
mkdir -p /tmp/$PKGFOLDER/mesh/shared/www
mkdir -p /tmp/$PKGFOLDER/mesh/shared/var/log
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-qnap/package/* /tmp/$PKGFOLDER/mesh -r
cp contrib/ui/nas-qnap/au/* /tmp/$PKGFOLDER/mesh/shared -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/mesh/shared/www/ -r
echo "Converting icon for: 64x64"
convert -colorspace sRGB ./riv.png -resize 64x64 /tmp/$PKGFOLDER/mesh/icons/mesh.gif
echo "Converting icon for: 80x80"
convert -colorspace sRGB ./riv.png -resize 80x80 /tmp/$PKGFOLDER/mesh/icons/mesh_80.gif
convert -colorspace sRGB ./riv.png -resize 64x64 /tmp/$PKGFOLDER/mesh/icons/mesh_gray.gif
cat > /tmp/$PKGFOLDER/mesh/qpkg.cfg << EOF
QPKG_DISPLAY_NAME="RiV Mesh"
QPKG_NAME="mesh"
QPKG_VER="$PKGVERSION"
QPKG_AUTHOR="Riv Chain ltd"
QPKG_SUMMARY="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
QPKG_RC_NUM="198"
QPKG_SERVICE_PROGRAM="mesh.sh"
QPKG_WEBUI="/mesh"
QPKG_WEB_PORT=
QPKG_LICENSE="LGPLv3"
QDK_BUILD_ARCH="$PKGARCH"
EOF
touch /tmp/$PKGFOLDER/mesh/qdk.conf
cp mesh /tmp/$PKGFOLDER/mesh/shared/bin
cp meshctl /tmp/$PKGFOLDER/mesh/shared/bin
chmod +x /tmp/$PKGFOLDER/mesh/shared/bin/*
chmod 0775 /tmp/$PKGFOLDER/mesh/shared/www -R
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
curent_dir=$(pwd)
cd /tmp/$PKGFOLDER/mesh && /opt/tomcat/tool/Qnap/bin/qbuild --force-config -v
mv build/*.qpkg "$curent_dir"/$PKGFILE
rm -rf /tmp/$PKGFOLDER/

View file

@ -0,0 +1,92 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/nas/tool/synology_version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFOLDER=${PKGNAME}/package
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "x86_64" ]; then GOOS=linux GOARCH=amd64 ./build
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=x86_64"
exit 1
fi
echo "Building $PKGNAME"
rm -rf /tmp/${PKGNAME}
mkdir -p /tmp/$PKGFOLDER/bin/
mkdir -p /tmp/$PKGFOLDER/lib/
mkdir -p /tmp/$PKGFOLDER/tmp/
mkdir -p /tmp/$PKGFOLDER/ui/
mkdir -p /tmp/$PKGFOLDER/var/log/
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-synology-dsm6.0/package/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/nas-synology-dsm6.0/spk/* /tmp/$PKGNAME/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
for res in 16 24 32 48 64 72 256; do
resolution="${res}x${res}"
echo "Converting icon for: $resolution"
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/ui/mesh-$res.png && \
chmod 644 /tmp/$PKGFOLDER/ui/mesh-$res.png
done
echo "Converting icon for: 72x72"
convert -colorspace sRGB ./riv.png -resize 72x72 PNG32:/tmp/$PKGNAME/PACKAGE_ICON.PNG
echo "Converting icon for: 256x256"
convert -colorspace sRGB ./riv.png -resize 256x256 PNG32:/tmp/$PKGNAME/PACKAGE_ICON_256.PNG
cat > /tmp/$PKGNAME/INFO << EOF
package="mesh"
displayname="RiV Mesh"
version="$PKGVERSION"
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network. \
It is lightweight, self-arranging, supported on multiple platforms and \
allows pretty much any IPv6-capable application to communicate securely with \
other RiV-mesh nodes."
maintainer="Riv Chain ltd"
maintainer_url="https://github.com/RiV-chain/RiV-mesh"
support_url="https://github.com/RiV-chain/RiV-mesh"
dsmappname="org.mesh"
arch="$PKGARCH"
dsmuidir="ui"
silent_upgrade="yes"
os_min_ver="6.0-7320"
EOF
echo $PKGVERSION > /tmp/$PKGNAME/VERSION
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
cp LICENSE /tmp/$PKGNAME/
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
chmod -R +x /tmp/$PKGNAME/scripts
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_package /tmp/$PKGFOLDER /tmp/$PKGNAME
rm -rf /tmp/$PKGFOLDER/
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_spk /tmp/$PKGNAME . $PKGNAME.spk

View file

@ -0,0 +1,95 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/nas/tool/synology_version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFOLDER=${PKGNAME}/package
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "x86_64" ]; then GOOS=linux GOARCH=amd64 ./build
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=x86_64 or armv7"
exit 1
fi
echo "Building $PKGNAME"
rm -rf /tmp/${PKGNAME}
mkdir -p /tmp/$PKGFOLDER/bin/
mkdir -p /tmp/$PKGFOLDER/lib/
mkdir -p /tmp/$PKGFOLDER/tmp/
mkdir -p /tmp/$PKGFOLDER/ui/
mkdir -p /tmp/$PKGFOLDER/var/log/
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-synology-dsm6.0/package/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/nas-synology-dsm6.0/spk/* /tmp/$PKGNAME/ -r
cp contrib/ui/nas-synology-dsm7.0/package/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/nas-synology-dsm7.0/spk/* /tmp/$PKGNAME/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
for res in 16 24 32 48 64 72 256; do
resolution="${res}x${res}"
echo "Converting icon for: $resolution"
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/ui/mesh-$res.png && \
chmod 644 /tmp/$PKGFOLDER/ui/mesh-$res.png
done
echo "Converting icon for: 64x64"
convert -colorspace sRGB ./riv.png -resize 64x64 PNG32:/tmp/$PKGNAME/PACKAGE_ICON.PNG
echo "Converting icon for: 256x256"
convert -colorspace sRGB ./riv.png -resize 256x256 PNG32:/tmp/$PKGNAME/PACKAGE_ICON_256.PNG
cat > /tmp/$PKGNAME/INFO << EOF
package="mesh"
displayname="RiV Mesh"
version="$PKGVERSION"
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network. \
It is lightweight, self-arranging, supported on multiple platforms and \
allows pretty much any IPv6-capable application to communicate securely with \
other RiV-mesh nodes."
maintainer="Riv Chain ltd"
maintainer_url="https://github.com/RiV-chain/RiV-mesh"
support_url="https://github.com/RiV-chain/RiV-mesh"
dsmappname="org.mesh"
arch="$PKGARCH"
dsmuidir="ui"
silent_upgrade="yes"
os_min_ver="7.0-40000"
EOF
echo $PKGVERSION > /tmp/$PKGNAME/VERSION
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
cp LICENSE /tmp/$PKGNAME/
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
chmod -R 0755 /tmp/$PKGNAME/scripts
chmod -R 0755 /tmp/$PKGNAME/conf
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_package /tmp/$PKGFOLDER /tmp/$PKGNAME
rm -rf /tmp/$PKGFOLDER/
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_spk /tmp/$PKGNAME . $PKGNAME.spk

View file

@ -0,0 +1,91 @@
#!/bin/sh
# This is a lazy script to create a .bin for Terramaster NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=x86_64 contrib/nas/nas-terramaster.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semmsiver/name.sh)
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
PKGFILE=mesh-$PKGFOLDER.tpk
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ -z $TERRAMASTER_TOOLS ]; then
echo "Specify TERRAMASTER_TOOLS path"
exit 1
fi
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
elif [ $PKGARCH = "arm-x31" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=x86-64 or arm-x31"
exit 1
fi
echo "Building $PKGFOLDER"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/mesh/usr/bin
mkdir -p /tmp/$PKGFOLDER/mesh/var/log
mkdir -p /tmp/$PKGFOLDER/mesh/usr/www/images/icons
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-terramaster/mesh /tmp/$PKGFOLDER/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/mesh/usr/local/mesh/www -r
echo "Converting icon for: 120x120"
convert -colorspace sRGB ./riv.png -resize 120x120 PNG32:/tmp/$PKGFOLDER/mesh/usr/www/images/icons/mesh.png
echo "$PKGVERSION" > /tmp/$PKGFOLDER/mesh/version
cat > /tmp/$PKGFOLDER/mesh/mesh.lang << EOF
[zh-cn]
name = "RiV Mesh"
auth = "mesh"
version = "$PKGVERSION"
descript = "RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
[en-us]
name = "RiV Mesh"
auth = "mesh"
version = "$PKGVERSION"
descript = "RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
EOF
cp mesh /tmp/$PKGFOLDER/mesh/usr/bin
cp meshctl /tmp/$PKGFOLDER/mesh/usr/bin
cp riv.svg /tmp/$PKGFOLDER/mesh/usr/www/images/icons/mesh.svg
ln -s /usr/mesh/var/log/mesh.log /tmp/$PKGFOLDER/mesh/usr/local/mesh/www/log
chmod +x /tmp/$PKGFOLDER/mesh/usr/bin/*
chmod 0775 /tmp/$PKGFOLDER/mesh/usr/www -R
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
curent_dir=$(pwd)
cd /tmp/$PKGFOLDER/
cp $TERRAMASTER_TOOLS/makeapp .
cp $TERRAMASTER_TOOLS/install-* .
cp -r $TERRAMASTER_TOOLS/phpencode .
./makeapp mesh
cd dist/$PKGFOLDER && mv *.tpk "$curent_dir"/$PKGFILE
cd "$curent_dir"
rm -rf /tmp/$PKGFOLDER/

View file

@ -0,0 +1,92 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
PKGFOLDER=mesh
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "arm" ]; then GOOS=linux GOARCH=arm GOARM=5 ./build
else
echo "Specify PKGARCH=arm"
exit 1
fi
echo "Building $PKGNAME"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/bin/
mkdir -p /tmp/$PKGFOLDER/tmp/
mkdir -p /tmp/$PKGFOLDER/lib/
mkdir -p /tmp/$PKGFOLDER/var/log/
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-westerndigital/package/mesh/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
for resolution in 256x256; do
echo "Converting icon for: $resolution"
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/www/mesh.png && \
chmod 644 /tmp/$PKGFOLDER/www/mesh.png
done
cat > /tmp/$PKGFOLDER/apkg.rc << EOF
Package: mesh
Section: Apps
Version: $PKGVERSION
Packager: RiV Chain
Email: vadym.vikulin@rivchain.org
Homepage: https://github.com/RiV-chain/RiV-mesh
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other RiV-mesh nodes.
Icon: mesh.png
AddonShowName: RiV Mesh
AddonIndexPage: index.html?v=$PKGVERSION
AddonUsedPort:
InstDepend:
InstConflict:
StartDepend:
StartConflict:
CenterType: 0
UserControl: 1
MinFWVer:
MaxFWVer:
IndividualFlag:
EOF
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
chmod +x /tmp/$PKGFOLDER/*.sh
curent_dir=$(pwd)
echo "current folder=$curent_dir"
cd /tmp/$PKGFOLDER/ && mksapkg -E -s -m WDMyCloudEX4
cp /tmp/WDMyCloudEX4_mesh_$PKGVERSION.bin* "$curent_dir"
rm -rf /tmp/$PKGFOLDER
cd "$curent_dir"

View file

@ -0,0 +1,92 @@
#!/bin/sh
# This is a lazy script to create a .bin for WD NAS build.
# You can give it the PKGARCH= argument
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
if [ `pwd` != `git rev-parse --show-toplevel` ]
then
echo "You should run this script from the top-level directory of the git repo"
exit 1
fi
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
PKG=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
PKGFOLDER=mesh
PKGREPLACES=mesh
if [ $PKGBRANCH = "master" ]; then
PKGREPLACES=mesh-develop
fi
if [ $PKGARCH = "armv7hf" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
else
echo "Specify PKGARCH=armv7hf"
exit 1
fi
echo "Building $PKGNAME"
rm -rf /tmp/$PKGFOLDER
mkdir -p /tmp/$PKGFOLDER/bin/
mkdir -p /tmp/$PKGFOLDER/tmp/
mkdir -p /tmp/$PKGFOLDER/lib/
mkdir -p /tmp/$PKGFOLDER/var/log/
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
chmod 0775 /tmp/$PKGFOLDER/ -R
echo "coping ui package..."
cp contrib/ui/nas-westerndigital/package/mesh/* /tmp/$PKGFOLDER/ -r
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
for resolution in 256x256; do
echo "Converting icon for: $resolution"
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/www/mesh.png && \
chmod 644 /tmp/$PKGFOLDER/www/mesh.png
done
cat > /tmp/$PKGFOLDER/apkg.rc << EOF
Package: mesh
Section: Apps
Version: $PKGVERSION
Packager: RiV Chain
Email: vadym.vikulin@rivchain.org
Homepage: https://github.com/RiV-chain/RiV-mesh
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other RiV-mesh nodes.
Icon: mesh.png
AddonShowName: RiV Mesh
AddonIndexPage: index.html?v=$PKGVERSION
AddonUsedPort:
InstDepend:
InstConflict:
StartDepend:
StartConflict:
CenterType: 0
UserControl: 1
MinFWVer:
MaxFWVer:
IndividualFlag:
EOF
cp mesh /tmp/$PKGFOLDER/bin
cp meshctl /tmp/$PKGFOLDER/bin
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
chmod +x /tmp/$PKGFOLDER/*.sh
curent_dir=$(pwd)
echo "current folder=$curent_dir"
cd /tmp/$PKGFOLDER/ && MyCloudOS5_mksapkg -E -s -m WDMyCloudEX4100
cp /tmp/WDMyCloudEX4100_mesh_$PKGVERSION.bin* "$curent_dir"
rm -rf /tmp/$PKGFOLDER
cd "$curent_dir"

View file

@ -0,0 +1,574 @@
#!/usr/bin/env python2
# Copyright (c) 2011-2013 Asustor Systems, Inc. All Rights Reserved.
# -*- coding: utf-8 -*-
import os
import sys
import argparse
import zipfile
import tarfile
import tempfile
import shutil
import json
import glob
import re
import csv
__author__ = 'Walker Lee <walkerlee@asustor.com>'
__copyright__ = 'Copyright (C) 2011-2013 ASUSTOR Systems, Inc. All Rights Reserved.'
__version__ = '0.1'
__abs_path__ = os.path.abspath(sys.argv[0])
__program__ = os.path.basename(__abs_path__)
def find_developer(app):
developer = None
if os.path.exists('apkg-developer-mapping.csv'):
with open('apkg-developer-mapping.csv', 'r') as f:
for row in csv.reader(f):
if row[0] == app:
developer = row[1]
break;
return developer
class Chdir:
def __init__(self, newPath):
self.newPath = newPath
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)
class Apkg:
umask = 0022
tmp_dir = '/tmp'
tmp_prefix = 'APKG-'
apk_format = {
'version' : '2.0',
'format' : 'zip',
'suffix' : 'apk'
}
apk_file_contents = {
'version' : 'apkg-version',
'data' : 'data.tar.gz',
'control' : 'control.tar.gz'
}
apk_special_folders = {
'control' : 'CONTROL',
'webman' : 'webman',
'web' : 'www'
}
apk_control_files = {
'pkg-config' : 'config.json',
'changlog' : 'changelog.txt',
'description' : 'description.txt',
'icon' : 'icon.png',
'script-pre-install' : 'pre-install.sh',
'script-pre-uninstall' : 'pre-uninstall.sh',
'script-post-install' : 'post-install.sh',
'script-post-uninstall' : 'post-uninstall.sh',
'script-start-stop' : 'start-stop.sh',
}
apk_web_settings = {
'user' : 'admin',
'group' : 'administrators',
'uid' : 999,
'gid' : 999,
'perms' : 0770
}
def __init__(self):
self.pid = os.getpid()
self.cwd = os.getcwd()
self.pkg_tmp_dir = self.tmp_dir + '/APKG.' + str(self.pid)
def __del__(self):
pass
def pkg_misc_check(self):
pass
def compress_pkg(self):
pass
def __check_apk_format(self, apk_file):
file_list = []
# check apk file format
try:
with zipfile.ZipFile(apk_file, 'r') as apk_zip:
file_list = apk_zip.namelist()
except zipfile.BadZipfile:
print 'File is not a apk file: %s' % (apk_file)
return False
# check apk file contents
if not file_list:
print 'File is empty: %s' % (apk_file)
return False
result = True
for (key, value) in self.apk_file_contents.items():
if value not in file_list:
print 'Can\'t found file in apk file: %s' % (value)
result = False
return result
# return True for files we want to exclude
def __excluded_files(self, file):
_return = False
# here we're checking to see if the file is 'CONTROL' -
# a file don't want included in our tar archive.
if file.find('CONTROL') > -1:
_return = True
return _return
def __zip_archive(self, apk_file, file_list):
with zipfile.ZipFile(apk_file, 'w') as apk_zip:
for one_file in file_list:
apk_zip.write(one_file)
def __zip_extract(self, apk_file, member, path):
with zipfile.ZipFile(apk_file, 'r') as apk_zip:
apk_zip.extract(member, path)
def __tar_archive(self, tar_file, path):
# create a tar archive of directory
with tarfile.open(tar_file, 'w:gz') as tar:
if os.path.basename(tar_file) == self.apk_file_contents['data']:
tar.add(path, exclude=self.__excluded_files)
else:
tar.add(path)
def __tar_extract(self, tar_file, path):
with tarfile.open(tar_file, 'r:gz') as tar:
tar.extractall(path)
def __get_apkg_version(self, version_file):
with file(version_file) as f:
version = f.read().rstrip()
return version
def __get_app_info_v1(self, control_dir):
with open(control_dir + '/' + self.apk_control_files['pkg-config']) as data_file:
data = json.load(data_file)
return data
def __get_app_info_v2(self, control_dir):
with open(control_dir + '/' + self.apk_control_files['pkg-config']) as data_file:
data = json.load(data_file)
return data
def __get_app_info(self, control_dir, apkg_version):
if apkg_version == '1.0':
return self.__get_app_info_v1(control_dir)
elif apkg_version == '2.0':
return self.__get_app_info_v2(control_dir)
else:
return None
def __check_app_layout(self, app_dir):
control_dir = app_dir + '/' + self.apk_special_folders['control']
if not os.path.isdir(control_dir):
print '[Not found] CONTROL folder: %s' % (control_dir)
return False
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
if not os.path.isfile(config_file):
print '[Not found] config file: %s' % (config_file)
return False
# TODO: check icon exist?
icon_file = control_dir + '/' + self.apk_control_files['icon']
pass
return True
def __check_app_info_fields(self, app_info):
require_fields = ['package', 'version', 'architecture', 'firmware']
for field in require_fields:
try:
if app_info['general'][field].strip() == '':
print 'Empty field: %s' % (field)
return False
except KeyError:
print 'Missing field: %s' % (field)
return False
return True
def __filter_special_chars(self, string, pattern):
filter_string = re.sub(pattern, '', string)
return filter_string
def __check_app_package_name(self, package):
return True if self.__filter_special_chars(package, '[a-zA-Z0-9.+-]') == '' else False
def create(self, folder, dest_dir=None):
# check folder is exist
app_dir = os.path.abspath(folder)
if not os.path.isdir(app_dir):
print 'Not a directory: %s' % (app_dir)
return -1
control_dir = app_dir + '/' + self.apk_special_folders['control']
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
# check package layout is correct
if not self.__check_app_layout(app_dir):
print 'Invalid App layout: %s' % (app_dir)
return -1
# change file mode and owner
os.chmod(control_dir, 0755)
os.chown(control_dir, 0, 0)
all_files = glob.glob(control_dir + '/*')
sh_files = glob.glob(control_dir + '/*.sh')
py_files = glob.glob(control_dir + '/*.py')
for one_file in all_files:
os.chmod(one_file, 0644)
os.chown(one_file, 0, 0)
for one_file in sh_files:
os.chmod(one_file, 0755)
os.system('dos2unix %s > /dev/null 2>&1' % (one_file))
for one_file in py_files:
os.chmod(one_file, 0755)
app_info = self.__get_app_info(control_dir, self.apk_format['version'])
# check config.json fields
if not self.__check_app_info_fields(app_info):
print 'Invalid App config: %s' % (config_file)
return -1
# check package field value
if not self.__check_app_package_name(app_info['general']['package']):
print 'Invalid App package field: %s (valid characters [a-zA-Z0-9.+-])' % ('package')
return -1
# prepare tmp dir
tmp_dir = tempfile.mkdtemp(prefix=self.tmp_prefix)
version_file = tmp_dir + '/' + self.apk_file_contents['version']
control_tar_gz = tmp_dir + '/' + self.apk_file_contents['control']
data_tar_gz = tmp_dir + '/' + self.apk_file_contents['data']
if dest_dir == None:
dest_dir = os.getcwd()
else:
dest_dir = os.path.abspath(dest_dir)
apk_file = dest_dir + '/' + app_info['general']['package'] + '_' + app_info['general']['version'] + '_' + app_info['general']['architecture'] + '.' + self.apk_format['suffix']
# write apkg version
with open(version_file, 'w') as apkg_version:
apkg_version.write(self.apk_format['version'] + '\n')
# archive data files
with Chdir(app_dir):
self.__tar_archive(data_tar_gz, '.')
# archive control files
with Chdir(control_dir):
self.__tar_archive(control_tar_gz, '.')
# archive apk file
with Chdir(tmp_dir):
self.__zip_archive(apk_file, [self.apk_file_contents['version'], self.apk_file_contents['control'], self.apk_file_contents['data']])
# cleanup temp folder
shutil.rmtree(tmp_dir, ignore_errors=True)
return apk_file
def extract(self, package, dest_dir=None):
# check file is exist
apk_file = os.path.abspath(package)
if not os.path.isfile(apk_file):
print 'Not a file: %s' % (apk_file)
return -1
# check package format (apk: zip format; contain files: apkg-version, control.tar.gz, data.tar.gz)
if not self.__check_apk_format(apk_file):
return -1
# unpack package phase 1
tmp_dir = tempfile.mkdtemp(prefix=self.tmp_prefix)
tmp_contents_dir = tmp_dir + '/@contents@'
os.mkdir(tmp_contents_dir)
self.__zip_extract(apk_file, self.apk_file_contents['version'], tmp_contents_dir)
self.__zip_extract(apk_file, self.apk_file_contents['control'], tmp_contents_dir)
self.__zip_extract(apk_file, self.apk_file_contents['data'], tmp_contents_dir)
# unpack package phase 2
tmp_control_dir = tmp_dir + '/' + self.apk_special_folders['control']
os.mkdir(tmp_control_dir)
self.__tar_extract(tmp_contents_dir + '/' + self.apk_file_contents['control'], tmp_control_dir)
self.__tar_extract(tmp_contents_dir + '/' + self.apk_file_contents['data'], tmp_dir)
# get apkg version
apkg_version = self.__get_apkg_version(tmp_contents_dir + '/' + self.apk_file_contents['version'])
# clean tmp contents dir
shutil.rmtree(tmp_contents_dir, ignore_errors=True)
# get apk information
apk_info = self.__get_app_info(tmp_control_dir, apkg_version)
# error handle
if apk_info is None:
print 'Extract error: %s' % (apk_file)
shutil.rmtree(tmp_dir, ignore_errors=True)
return -1
if dest_dir == None:
dest_dir = os.getcwd()
else:
dest_dir = os.path.abspath(dest_dir)
# move dir
if apkg_version == '1.0':
app_dir = dest_dir + '/' + apk_info['app']['name'] + '_' + apk_info['app']['version'] + '_' + apk_info['app']['architecture']
elif apkg_version == '2.0':
app_dir = dest_dir + '/' + apk_info['general']['name'] + '_' + apk_info['general']['version'] + '_' + apk_info['general']['architecture']
if os.path.isdir(app_dir):
print 'The folder is exist, please remove it: %s' % (app_dir)
shutil.rmtree(tmp_dir, ignore_errors=True)
return -1
else:
shutil.move(tmp_dir, app_dir)
return app_dir
def convert(self, package):
app_dir = self.extract(package, dest_dir='/tmp')
if app_dir == -1:
print 'Convert error'
return -1
control_dir = app_dir + '/' + self.apk_special_folders['control']
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
changelog_file = control_dir + '/' + self.apk_control_files['changlog']
description_file = control_dir + '/' + self.apk_control_files['description']
# get old format app information
app_old_info = self.__get_app_info(control_dir, self.apk_format['version'])
app_new_info = {}
developer = find_developer(app_old_info['app']['package'])
app_new_info['general'] = {}
app_new_info['general']['package'] = app_old_info['app']['package']
app_new_info['general']['name'] = app_old_info['app']['name']
app_new_info['general']['version'] = app_old_info['app']['version']
app_new_info['general']['depends'] = app_old_info['app']['depends']
app_new_info['general']['conflicts'] = app_old_info['app']['conflicts']
app_new_info['general']['developer'] = app_old_info['app']['website'] if (developer is None) else developer
app_new_info['general']['maintainer'] = app_old_info['app']['maintainer']
app_new_info['general']['email'] = app_old_info['app']['email']
app_new_info['general']['website'] = app_old_info['app']['website']
app_new_info['general']['architecture'] = app_old_info['app']['architecture']
app_new_info['general']['firmware'] = '2.0'
try:
app_old_info['desktop']
except KeyError:
app_old_info['desktop'] = {}
try:
app_old_info['desktop']['icon']
except KeyError:
app_old_info['desktop']['icon'] = {}
# remove unused field
app_old_info['desktop']['icon'].pop('title', None)
try:
app_old_info['desktop']['privilege']
except KeyError:
app_old_info['desktop']['privilege'] = {}
app_new_info['adm-desktop'] = {}
app_new_info['adm-desktop']['app'] = app_old_info['desktop']['icon']
app_new_info['adm-desktop']['privilege'] = app_old_info['desktop']['privilege']
try:
app_old_info['install']['link']
except KeyError:
app_old_info['install']['link'] = {}
try:
app_old_info['install']['share']
except KeyError:
app_old_info['install']['share'] = []
try:
app_old_info['install']['service-reg']
except KeyError:
app_old_info['install']['service-reg'] = {}
try:
app_old_info['install']['service-reg']['priority']
except KeyError:
app_old_info['install']['service-reg']['priority'] = {}
try:
app_old_info['install']['service-reg']['port']
except KeyError:
app_old_info['install']['service-reg']['port'] = []
try:
app_old_info['install']['dep-service']
except KeyError:
app_old_info['install']['dep-service'] = {}
try:
app_old_info['install']['dep-service']['start']
except KeyError:
app_old_info['install']['dep-service']['start'] = []
try:
app_old_info['install']['dep-service']['restart']
except KeyError:
app_old_info['install']['dep-service']['restart'] = []
app_new_info['register'] = {}
app_new_info['register']['symbolic-link'] = app_old_info['install']['link']
app_new_info['register']['share-folder'] = app_old_info['install']['share']
app_new_info['register']['port'] = app_old_info['install']['service-reg']['port']
app_new_info['register']['boot-priority'] = {}
try:
app_new_info['register']['boot-priority']['start-order'] = app_old_info['install']['service-reg']['priority']['start']
except KeyError:
pass
try:
app_new_info['register']['boot-priority']['stop-order'] = app_old_info['install']['service-reg']['priority']['stop']
except KeyError:
pass
app_new_info['register']['prerequisites'] = {}
app_new_info['register']['prerequisites']['enable-service'] = app_old_info['install']['dep-service']['start']
app_new_info['register']['prerequisites']['restart-service'] = app_old_info['install']['dep-service']['restart']
# get changelog and description
changelog = app_old_info['app'].pop('changes', None).strip()
description = app_old_info['app'].pop('description', None).strip()
# convert json object to string
json_string = json.dumps(app_new_info, indent=3)
# set new format app information
with open(config_file, 'w') as new_file:
new_file.write(json_string + '\n')
# write changelog.txt
if changelog is not None and changelog != '':
with open(changelog_file, 'w') as new_file:
new_file.write(changelog + '\n')
# write description.txt
if description is not None and description != '':
with open(description_file, 'w') as new_file:
new_file.write(description + '\n')
# convert icon
icon_enable_file = control_dir + '/icon-enable.png'
icon_disable_file = control_dir + '/icon-disable.png'
icon_file = control_dir + '/' + self.apk_control_files['icon']
os.unlink(icon_disable_file)
os.rename(icon_enable_file, icon_file)
convert_dir = os.getcwd() + '/apk-2.0'
if not os.path.exists(convert_dir):
os.mkdir(convert_dir)
# re-pack apk
apk_file = self.create(app_dir, dest_dir=convert_dir)
# cleanup app folder
shutil.rmtree(app_dir, ignore_errors=True)
print 'Convert success: %s' % (apk_file)
def upload(self, package):
# check file is exist
abs_path = os.path.abspath(package)
if not os.path.isfile(abs_path):
print 'Not a file: %s' % (abs_path)
return -1
print 'function not support: %s' % ('upload')
# main
if __name__ == "__main__":
# create the top-level parser
parser = argparse.ArgumentParser(description='asustor package helper.')
subparsers = parser.add_subparsers(help='sub-commands')
# create the parser for the "create" commad
parser_create = subparsers.add_parser('create', help='create package from folder')
parser_create.add_argument('folder', help='select a package layout folder to pack')
parser_create.add_argument('--destination', help='move apk to destination folder')
parser_create.set_defaults(command='create')
# create the parser for the "extract" commad
parser_extract = subparsers.add_parser('extract', help='extract package to folder')
parser_extract.add_argument('package', help='select a package to extract')
parser_extract.add_argument('--destination', help='extract apk to destination folder')
parser_extract.set_defaults(command='extract')
# create the parser for the "convert" commad
# parser_convert = subparsers.add_parser('convert', help='convert package format to 2.0')
# parser_convert.add_argument('package', help='select a package to convert')
# parser_convert.set_defaults(command='convert')
# create the parser for the "upload" commad
# parser_upload = subparsers.add_parser('upload', help='upload package to file server')
# parser_upload.add_argument('package', help='select a package to upload')
# parser_upload.set_defaults(command='upload')
# parsing arguments
args = parser.parse_args()
# process commands
apkg = Apkg()
if args.command == 'create':
apkg.create(args.folder, args.destination)
elif args.command == 'extract':
apkg.extract(args.package, args.destination)
# elif args.command == 'convert':
# apkg.convert(args.package)
# elif args.command == 'upload':
# apkg.upload(args.package)

View file

@ -0,0 +1,436 @@
#!/bin/bash
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.
pkg_warn ()
{
local ret=$?;
echo "Error: $@" 1>&2;
return $?
}
pkg_log ()
{
local ret=$?;
echo "$@" 1>&2;
return $ret
}
pkg_get_string ()
{
local file="$1";
local sec="$2";
local key="$3";
local text="$(sed -n '/^\['$sec'\]/,/^'$key'/s/'$key'.*=[^"]*"\(.*\)"/\1/p' "$file")";
local product_name_original="_DISKSTATION_";
local product_name=$(pkg_get_product_name);
local os_name_original="_OSNAME_";
local os_name=$(pkg_get_os_name);
local idx=0;
shift 3;
for val in "$@";
do
text="${text/\{$idx\}/$val}";
let idx=1+$idx;
done;
echo "$text" | sed -e "s/${product_name_original}/${product_name}/g" | sed -e "s/${os_name_original}/${os_name}/g"
}
pkg_dump_info ()
{
local fields="package version maintainer maintainer_url distributor distributor_url arch exclude_arch model
adminprotocol adminurl adminport firmware dsmuidir dsmappname checkport allow_altport
startable helpurl report_url support_center install_reboot install_dep_packages install_conflict_packages install_dep_services
instuninst_restart_services startstop_restart_services start_dep_services silent_install silent_upgrade silent_uninstall install_type
checksum package_icon package_icon_120 package_icon_128 package_icon_144 package_icon_256 thirdparty support_conf_folder log_collector
support_aaprofile auto_upgrade_from offline_install precheckstartstop";
local f= lan= file= sec= key=;
for f in $fields;
do
if [ -n "${!f}" ]; then
echo $f=\"${!f}\";
fi;
done;
if [ -e "$UISTRING_PATH" -a "$description_sec" -a "$description_key" ]; then
sec=$description_sec;
key=$description_key;
for lan in $UISTRING_PATH/*;
do
lan=$(basename "$lan");
file="$UISTRING_PATH/$lan/strings";
if [ -r "$file" ]; then
echo description_$lan=\"$(pkg_get_string "$file" "$sec" "$key")\";
if [ "x$lan" = "xenu" ]; then
echo description=\"$(pkg_get_string "$file" "$sec" "$key")\";
fi;
fi;
done;
else
if [ "x" != "x$description" ]; then
echo "description=\"${description}\"";
fi;
fi;
if [ -e "$UISTRING_PATH" -a "$displayname_sec" -a "$displayname_key" ]; then
sec=$displayname_sec;
key=$displayname_key;
for lan in $UISTRING_PATH/*;
do
lan=$(basename "$lan");
file="$UISTRING_PATH/$lan/strings";
if [ -r "$file" ]; then
echo displayname_$lan=\"$(pkg_get_string "$file" "$sec" "$key")\";
if [ "x$lan" = "xenu" ]; then
echo displayname=\"$(pkg_get_string "$file" "$sec" "$key")\";
fi;
fi;
done;
else
if [ "x" != "x$displayname" ]; then
echo "displayname=\"${displayname}\"";
fi;
fi
}
plat_to_unified_plat() {
local plat="$1"
local unified_plat=
case "$plat" in
x86 | bromolow | cedarview | avoton )
unified_plat="x86 bromolow cedarview avoton"
;;
# alpine and alpine4k use same define.
alpine )
unified_plat="alpine"
;;
*)
unified_plat="$plat"
;;
esac
echo "$unified_plat"
}
get_var_from_envmak() {
return 1
local var="$1"
shift
local envmaks="$@"
local ret=
local defaultSearchPath="/env.mak /env32.mak"
for f in "${envmaks[@]}" $defaultSearchPath; do
if [ ! -r "$f" ]; then
continue
fi
ret=$(grep "^$var=" "$f" | cut -d= -f2)
if [ -n "$ret" ]; then
break
fi
done
if [ -z "$ret" ]; then
pkg_warn "get_var_from_envmak: can not extract $var from '[$envmaks $defaultSearchPath]'"
return 1
else
echo "$ret"
fi
}
pkg_get_platform ()
{
local arch=;
local PLATFORM_ABBR=$(get_var_from_envmak PLATFORM_ABBR "$1" 2> /dev/null) || return 1;
if [ -n "$PLATFORM_ABBR" ]; then
case "$PLATFORM_ABBR" in
6180)
arch="88f6180"
;;
6281)
arch="88f6281"
;;
816x)
arch="ti816x"
;;
ppc)
arch="powerpc"
;;
824x)
arch="ppc824x"
;;
853x)
arch="ppc853x"
;;
854x)
arch="ppc854x"
;;
x64)
arch="x86"
;;
*)
arch="$PLATFORM_ABBR"
;;
esac;
fi;
if [ -z "$arch" ]; then
local SYNO_PLATFORM=$(get_var_from_envmak SYNO_PLATFORM "$1") || return 1;
case "$SYNO_PLATFORM" in
MARVELL_88F6180)
arch="88f6180"
;;
MARVELL_88F6281)
arch="88f6281"
;;
TI_816X)
arch="ti816x"
;;
POWERPC)
arch="powerpc"
;;
PPC_824X)
arch="ppc824x"
;;
PPC_853X)
arch="ppc853x"
;;
PPC_854X)
arch="ppc854x"
;;
PPC_QORIQ)
arch="qoriq"
;;
X64)
arch="x86"
;;
BROMOLOW)
arch="bromolow"
;;
CEDARVIEW)
arch="cedarview"
;;
AVOTON)
arch="avoton"
;;
MARVELL_ARMADAXP)
arch="armadaxp"
;;
MARVELL_ARMADA370)
arch="armada370"
;;
MARVELL_ARMADA375)
arch="armada375"
;;
EVANSPORT)
arch="evansport"
;;
PPC_CATALINA)
arch="catalina"
;;
MINDSPEED_COMCERTO2K)
arch="comcerto2k"
;;
ALPINE)
arch="alpine"
;;
BROADCOM_NORTHSTARPLUS)
arch="northstarplus"
;;
STM_MONACO)
arch="monaco"
;;
HISILICON_HI3535)
arch="hi3535"
;;
MARVELL_ARMADA38X)
arch="armada38x"
;;
*)
arch=""
;;
esac;
fi;
echo "$arch"
}
pkg_get_spk_platform ()
{
local plat=$(pkg_get_platform "$1") || return 1;
local spk_plat=;
case "$plat" in
88f6281)
spk_plat="88f628x"
;;
*)
spk_plat="$plat"
;;
esac;
echo "$spk_plat"
}
pkg_make_package ()
{
local source_path=$1;
local dest_path=$2;
local package_name="package.tgz";
local temp_extractsize="extractsize_tmp";
local pkg_size=;
local tar_option="$(pkg_get_tar_option)";
if [ -z "$source_path" -o ! -d "$source_path" ]; then
pkg_warn "pkg_make_package: bad parameters, please set source dir";
return 1;
fi;
if [ -z "$dest_path" -o ! -d "$dest_path" ]; then
pkg_warn "pkg_make_package: bad parameters, please set destination dir";
return 1;
fi;
pkg_size=`du -sk "$source_path" | awk '{print $1}'`;
echo "${pkg_size}" >> "$dest_path/$temp_extractsize";
echo ls $source_path \| tar $tar_option "$dest_path/$package_name" -C "$source_path" -T /dev/stdin;
ls $source_path | tar $tar_option "$dest_path/$package_name" -C "$source_path" -T /dev/stdin
}
pkg_get_spk_name ()
{
__get_spk_name pkg_get_spk_platform $@
}
pkg_make_spk ()
{
local pack="tar cf";
local source_path=$1;
local dest_path=$2;
local info_path="$source_path/INFO";
local spk_name=$3;
local spk_arch=;
local temp_extractsize="extractsize_tmp";
if [ -z "$source_path" -o ! -d "$source_path" ]; then
pkg_warn "pkg_make_spk: bad parameters, please set source dir";
return 1;
fi;
if [ -z "$dest_path" -o ! -d "$dest_path" ]; then
pkg_warn "pkg_make_spk: bad parameters, please set destination dir";
return 1;
fi;
if [ ! -r "$info_path" ]; then
pkg_warn "pkg_make_spk: INFO '$info_path' is not existed";
return 1;
fi;
spk_name=${3:-`pkg_get_spk_name $info_path`};
pkg_size=`cat $source_path/$temp_extractsize`;
echo "extractsize=\"${pkg_size}\"" >> $info_path;
rm "$source_path/$temp_extractsize";
echo "toolkit_version=\"$DSM_BUILD_NUM\"" >> $info_path;
echo "create_time=\"$(date +%Y%m%d-%T)\"" >> $info_path;
pkg_log "creating package: $spk_name";
pkg_log "source: $source_path";
pkg_log "destination: $dest_path/$spk_name";
$pack "$dest_path/$spk_name" -C "$source_path" $(ls $source_path)
}
pkg_get_unified_platform ()
{
local plat=$(pkg_get_platform "$1") || return 1;
plat_to_unified_plat "$plat"
}
pkg_get_spk_unified_platform ()
{
local plat=$(pkg_get_platform "$1") || return 1;
local spk_unified_platform=;
case "$plat" in
88f6281)
spk_unified_platform="88f628x"
;;
x86 | bromolow | cedarview | avoton)
spk_unified_platform="x64"
;;
alpine)
spk_unified_platform="alpine"
;;
*)
spk_unified_platform="$plat"
;;
esac;
echo "$spk_unified_platform"
}
pkg_get_spk_unified_name ()
{
__get_spk_name pkg_get_spk_unified_platform $@
}
__get_spk_name() { #<info path>
local spk_name=
local platform_func="$1"
local info_path="${2:-$PKG_DIR/INFO}"
local package_name="$3"
. $info_path
# construct package name
if [ -z "$package" -o -z "$arch" -o -z "$version" ]; then
pkg_warn "pkg_make_spk: package, arch, version can not be empty"
return 1
fi
if [ "x$arch" = "xnoarch" ]; then
spk_arch="noarch"
elif ! spk_arch=$($platform_func); then
spk_arch="none"
fi
if [ "x$arch" = "xnoarch" ]; then
spk_arch=""
else
spk_arch="-"$spk_arch
fi
if [ -z "$package_name" ]; then
package_name="$package";
fi
if [ "${NOSTRIP}" == NOSTRIP ]; then
spk_name="$package_name$spk_arch-${version}_debug.spk"
else
spk_name="$package_name$spk_arch-$version.spk"
fi
echo $spk_name;
}
pkg_get_dsm_buildnum() { # [path of VERSION (default: )]
local version_file=${1:-/source/lnxsdk/init/etc/VERSION}
local dsm_build=
if [ ! -r "$version_file" ]; then
pkg_warn "pkg_get_dsm_buildnum: can not find version file '$version_file'"
pkg_warn "use default buildnum: 0"
echo 0
return 1
fi
if ! dsm_build=$(grep -s ^buildnumber "$version_file" | awk -F \" '{print $2}'); then
echo 0
return 1
fi
echo $(($dsm_build))
}
pkg_get_tar_option() {
local version_file="/PkgVersion"
if [ -r $version_file ] && [ "$(pkg_get_dsm_buildnum $version_file)" -ge 5943 ]; then
echo "cJf"
else
echo "czf"
fi
}
[ "$(caller)" != "0 NULL" ] && return 0
Usage() {
cat >&2 << EOF
Usage
$(basename $0) <action> [action options...]
Action
make_spk <source path> <dest path>
make_package <source path> <dest path>
EOF
exit 0
}
[ $# -eq 0 ] && Usage
PkgBuildAction=$1 ; shift
case "$PkgBuildAction" in
make_spk) pkg_make_spk "$@" ;;
make_package) pkg_make_package "$@" ;;
*) Usage ;;
esac

View file

@ -0,0 +1,33 @@
#!/bin/sh
# Get the last tag
TAG=$(git describe --abbrev=0 --tags --match="v[0-9]*\.[0-9]*\.[0-9]*" 2>/dev/null)
# Did getting the tag succeed?
if [ $? != 0 ] || [ -z "$TAG" ]; then
printf -- "unknown"
exit 0
fi
# Get the current branch
BRANCH=$(git symbolic-ref -q HEAD --short 2>/dev/null)
# Did getting the branch succeed?
if [ $? != 0 ] || [ -z "$BRANCH" ]; then
BRANCH="master"
fi
#replace last dot with -
STAG=$(echo $TAG | sed 's/v//' | sed 's/[^0123456789.].//' | sed 's/\.\([^.]*\)$/-\1/')
#get tail after - and do padding with 4 zeros
TAG_TAIL=$(echo $STAG | sed -n -e 's/^.*-//p' | sed -e :a -e 's/^.\{1,3\}$/&0/;ta')
#replace tail after -
SYNO_VERSION=$(echo $STAG | sed "s/-.*/-$TAG_TAIL/")
case "$*" in
*--bare*)
printf '%s\n' "$SYNO_VERSION"
;;
*)
printf '%s' "$SYNO_VERSION"
;;
esac

View file

@ -2,10 +2,10 @@
description="An experiment in scalable routing as an encrypted IPv6 overlay network."
CONFFILE="/etc/yggdrasil.conf"
CONFFILE="/etc/mesh.conf"
pidfile="/run/${RC_SVCNAME}.pid"
command="/usr/bin/yggdrasil"
command="/usr/bin/mesh"
extra_started_commands="reload"
depend() {
@ -36,8 +36,8 @@ start() {
--pidfile "${pidfile}" \
--make-pidfile \
--background \
--stdout /var/log/yggdrasil.stdout.log \
--stderr /var/log/yggdrasil.stderr.log \
--stdout /var/log/mesh.stdout.log \
--stderr /var/log/mesh.stderr.log \
--exec "${command}" -- -useconffile "${CONFFILE}"
eend $?
}

View file

@ -6,8 +6,9 @@ if [ -z "$BRANCH" ]; then
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
fi
# Complain if the git history is not available
if [ $? != 0 ] || [ -z "$BRANCH" ]; then
printf "yggdrasil"
printf "mesh"
exit 0
fi
@ -16,9 +17,9 @@ BRANCH=$(echo $BRANCH | tr -d "/")
# Check if the branch name is not master
if [ "$BRANCH" = "master" ]; then
printf "yggdrasil"
printf "mesh"
exit 0
fi
# If it is something other than master, append it
printf "yggdrasil-%s" "$BRANCH"
printf "mesh-%s" "$BRANCH"

View file

@ -0,0 +1,21 @@
[Unit]
Description=mesh
Wants=network-online.target
Wants=mesh-default-config.service
After=network-online.target
After=mesh-default-config.service
[Service]
Group=mesh
ProtectHome=true
ProtectSystem=true
SyslogIdentifier=mesh
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
ExecStartPre=+-/sbin/modprobe tun
ExecStart=/usr/bin/mesh -useconffile /etc/mesh.conf -loglevel debug -logto /var/log/mesh.log
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,13 @@
[Unit]
Description=mesh default config generator
ConditionPathExists=|!/etc/mesh.conf
ConditionFileNotEmpty=|!/etc/mesh.conf
Wants=local-fs.target
After=local-fs.target
[Service]
Type=oneshot
Group=mesh
StandardOutput=file:/etc/mesh.conf
ExecStart=/usr/bin/mesh -genconf
ExecStartPost=/usr/bin/chmod 0640 /etc/mesh.conf

View file

@ -0,0 +1,21 @@
[Unit]
Description=mesh
Wants=network-online.target
Wants=mesh-default-config.service
After=network-online.target
After=mesh-default-config.service
[Service]
Group=mesh
ProtectHome=true
ProtectSystem=true
SyslogIdentifier=mesh
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
ExecStartPre=+-/sbin/modprobe tun
ExecStart=/usr/bin/mesh -useconffile /etc/mesh.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target

View file

@ -1,13 +0,0 @@
[Unit]
Description=yggdrasil default config generator
ConditionPathExists=|!/etc/yggdrasil.conf
ConditionFileNotEmpty=|!/etc/yggdrasil.conf
Wants=local-fs.target
After=local-fs.target
[Service]
Type=oneshot
Group=yggdrasil
StandardOutput=file:/etc/yggdrasil.conf
ExecStart=/usr/bin/yggdrasil -genconf
ExecStartPost=/usr/bin/chmod 0640 /etc/yggdrasil.conf

View file

@ -1,21 +0,0 @@
[Unit]
Description=yggdrasil
Wants=network-online.target
Wants=yggdrasil-default-config.service
After=network-online.target
After=yggdrasil-default-config.service
[Service]
Group=yggdrasil
ProtectHome=true
ProtectSystem=true
SyslogIdentifier=yggdrasil
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
ExecStartPre=+-/sbin/modprobe tun
ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

669
contrib/ui/mesh-ui/index.html Executable file
View file

@ -0,0 +1,669 @@
<!DOCTYPE html>
<html class="is-clipped">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RiV-mesh</title>
<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/font-awesome-line-awesome/css/all.min.css" type="text/css">
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/slate/bulmaswatch.min.css" type="text/css">
<script>
function setFieldValue(id, value){
var field = document.getElementById(id);
field.innerHTML = value;
}
function setPingValue(peer, value){
var cellText;
var peerCell = document.getElementById(peer);
var peerTable = document.getElementById("peer_list");
if(value === "-1"){
var peerAddress = document.getElementById("label_"+peer);
peerAddress.style.color = "rgba(250,250,250,.5)";
moveRowToEnd(peerTable, peerCell.parentNode);
return;
}
cellText = document.createTextNode(value);
peerCell.appendChild(cellText);
var peerCellTime = document.getElementById("time_"+peer);
var cellTextTime = document.createTextNode("ms");
peerCellTime.appendChild(cellTextTime);
//sort table
sortTable(peerTable, 2, false);
}
function sortTable(table, col, reverse) {
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
i;
reverse = -((+reverse) || -1);
tr = tr.sort(function (a, b) { // sort rows
// `-1 *` if want opposite order
return reverse * (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
.localeCompare(b.cells[col].textContent.trim(), 'en', {numeric: true})
);
});
for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}
function moveRowToEnd(table, row) {
var tb = table.tBodies[0]; // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
var rowIndex = row.rowIndex;
table.deleteRow(rowIndex);
tb.appendChild(row); // append each row in order
}
function openTab(element, tabName) {
// Declare all variables
var i, tabContent, tabLinks;
// Get all elements with class="content" and hide them
tabContent = document.getElementsByClassName("tab here");
for (i = 0; i < tabContent.length; i++) {
tabContent[i].className = "tab here is-hidden";
}
// Get all elements with class="tab" and remove the class "is-active"
tabLinks = document.getElementsByClassName("tab is-active");
for (i = 0; i < tabLinks.length; i++) {
tabLinks[i].className = "tab";
}
// Show the current tab, and add an "is-active" class to the button that opened the tab
document.getElementById(tabName).className = "tab here";
element.parentElement.className = "tab is-active";
refreshRecordsList();
}
function copy2clipboard(text){
var textArea = document.createElement("textarea");
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of the white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
document.body.removeChild(textArea);
showInfo('value copied successfully!');
}
function showInfo(text) {
var info = document.getElementById("notification_info");
var message = document.getElementById("info_text");
message.innerHTML = text;
info.className = "notification is-primary";
var button = document.getElementById("info_close");
button.onclick = function() {
message.value = "";
info.className = "notification is-primary is-hidden";
};
setTimeout(button.onclick, 2000);
}
function showWindow(text) {
var info = document.getElementById("notification_window");
var message = document.getElementById("info_window");
message.innerHTML = text;
info.className = "notification is-primary";
var button_info_close = document.getElementById("info_close");
button_info_close.onclick = function() {
message.value = "";
info.className = "notification is-primary is-hidden";
};
var button_window_close = document.getElementById("window_close");
button_window_close.onclick = function() {
message.value = "";
info.className = "notification is-primary is-hidden";
};
var button_window_save = document.getElementById("window_save");
button_window_save.onclick = function() {
message.value = "";
info.className = "notification is-primary is-hidden";
//todo save peers
var peers = document.querySelectorAll('*[id^="peer-"]');
var peer_list = [];
for (i = 0; i < peers.length; ++i) {
var p = peers[i];
if (p.checked) {
var peerURL = p.parentElement.parentElement.children[1].innerText;
peer_list.push(peerURL);
}
}
savePeers(JSON.stringify(peer_list));
};
}
function getPeerList(){
var xhr = new XMLHttpRequest();
xhr.open("GET", 'https://map.rivchain.org/rest/peers.json', false);
xhr.send(null);
if (xhr.status === 200) {
const peerList = JSON.parse(xhr.responseText);
var peers = add_table(peerList);
//start peers test
ping(JSON.stringify(peers));
}
}
function add_table(peerList) {
var peers = [];
//const countries = Object.keys(peerList);
// get the reference for the body
var body = document.createElement("div");
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
tbl.setAttribute('id', "peer_list");
//tbl.setAttribute('cellpadding', '10');
var tblBody = document.createElement("tbody");
// creating all cells
for (var c in peerList) {
let counter = 1;
flag = document.getElementById("flag_"+c.slice(0, -3).replace(/ /g, "_"));
for (peer in peerList[c]){
peers.push(peer);
// creates a table row
var row = document.createElement("tr");
var imgElement = document.createElement("td");
clone = flag.cloneNode(false);
imgElement.appendChild(clone);
var peerAddress = document.createElement("td");
var cellText = document.createTextNode(peer);
peerAddress.appendChild(cellText);
peerAddress.setAttribute('id', "label_"+peer);
var peerPing = document.createElement("td");
peerPing.setAttribute('id', peer);
var peerPingTime = document.createElement("td");
peerPingTime.setAttribute('id', "time_"+peer);
var peerSelect = document.createElement("td");
var chk = document.createElement('input');
chk.setAttribute('type', 'checkbox');
chk.setAttribute('id', "peer-"+counter);
peerSelect.appendChild(chk);
row.appendChild(imgElement);
row.appendChild(peerAddress);
row.appendChild(peerPing);
row.appendChild(peerPingTime);
row.appendChild(peerSelect);
tblBody.appendChild(row);
}
}
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
//tbl.setAttribute("border", "0");
showWindow(body.innerHTML);
return peers;
}
</script>
<style>
.container-ip {
display: flex;
border: 1px solid #5d656d;
border-radius: 4px;
margin:10px;
}
.push-right {
margin-left: auto;
}
.item {
padding: 10px;
/*border: 1px solid #5d656d;*/
}
.column {
max-height: 350px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.over {
max-height: 150px;
overflow: auto;
}
.container{
position: relative;
}
.box{
width: 100%;
height: 100px;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.0);
}
.stack-top{
z-index: 9;
margin: 10px; /* for demo purpose */
background: rgba(255, 0, 0, 1);
}
table {
table-layout: fixed;
}
thead tr th:first-child,
tbody tr td:first-child {
width: 50px;
}
th, td {
padding: 5px;
}
img {
display: block;
}
</style>
</head>
<body onload="onLoad();">
<div style="padding:3px; max-height: 250px;">
<div class="box">
<div style="z-index: 9;" class="box stack-top notification is-primary is-hidden" id="notification_window">
<button class="delete" id="info_close"></button>
<p style="padding:3px; max-height: 250px; overflow-y: auto;" id="info_window"></p>
<div style="padding-left:100px; padding-top:15px;" class="field is-grouped" >
<p class="control">
<a id="window_save" class="button is-success">
<span class="icon is-small">
<i class="fa fa-check"> </i>
</span>
<span> Save </span>
</a>
</p>
<p class="control">
<a id="window_close" class="button is-danger is-outlined">
<span> Cancel </span>
<span class="icon is-small">
<i class="fa fa-times"> </i>
</span>
</a>
</p>
</div>
</div>
</div>
<!-- Tabs -->
<div class="tabs is-centered is-boxed">
<ul>
<li class="tab is-active">
<a onclick="openTab(this, 'my_node');">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 42 42"><path d="M18.5 35.5l-8 2c-.48.04-1 .52-1 1v1c0 .5.47 1 1 1h20c.43 0 1-.41 1-1v-1c-.02-.52-.55-.98-1-1l-8-2h-4zm19-1c2.59 0 3-.529 3-3v-26c0-2.391-.55-3-3-3h-34c-2.43 0-3 .54-3 3v26c0 2.51.529 3 3 3h34zm-2-27v22h-30v-22h30z" fill="white"/></svg>
</span>
<span>My Node</span>
</a>
</li>
<li class="tab">
<a onclick="openTab(this, 'keys');">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M5 15v15h22V15zm4 0C9 9 9 5 16 5s7 4 7 10m-7 5v3"/><circle cx="16" cy="24" r="1"/></g></svg>
</span>
<span>Keys</span>
</a>
</li>
<li class="tab">
<a onclick="openTab(this, 'about');">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 48 48"><path fill="#2196F3" d="M37 40H11l-6 6V12c0-3.3 2.7-6 6-6h26c3.3 0 6 2.7 6 6v22c0 3.3-2.7 6-6 6z"/><g fill="#fff"><path d="M22 20h4v11h-4z"/><circle cx="24" cy="15" r="2"/></g></svg>
</span>
<span>About</span>
</a>
</li>
</ul>
</div>
<div class="tab here " id="my_node">
<div class="column">
<div class="container-ip">
<div class="item">IPv6</div>
<div id="ipv6" class="item push-right">N/A</div>
<div class="item">
<a class="fas fa-copy" onclick="copy2clipboard(document.getElementById('ipv6').innerHTML);"/></a>
</div>
</div>
<div class="container-ip">
<div class="item">Subnet</div>
<div id="subnet" class="item push-right">N/A</div>
<div class="item">
<a class="fas fa-copy" onclick="copy2clipboard(document.getElementById('subnet').innerHTML);"></a>
</div>
</div>
<div class="container-ip">
<div class="item">Peers</div>
<div id="peers" class="item over">
</div>
<div class="item push-right">
<a class="fas fa-edit" onclick="getPeerList();"></a>
</div>
</div>
</div>
</div>
<div class="tab here is-hidden" id="keys">
</div>
</div>
</div>
<div style="margin-left: 100px; margin-right: 100px;">
<div class="notification is-primary is-hidden" id="notification_info">
<button class="delete" id="info_close"></button>
<p id="info_text"></p>
</div>
</div>
<div class="is-hidden">
<img id="flag_colombia" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAACwBgCdASpQADQAPtFSqE0oJCQiLNv6AQAaCWIAeIXYBLAMFA9f8BgrDzKuhE9x9GWK6QYvcXPYqTApg90hAAD+7+5j//yDDlmNa6/4GbPTedtphBBZRcDd4PnOa5vgRv/KS2OO3+UlsmZSrWYO0DYAxwSCrkPjdU0Dqj2F3sx1eV9fUs/xUAAAAAA=" />
<img id="flag_taiwan" src="data:image/webp;base64, UklGRkYBAABXRUJQVlA4IDoBAAAwCACdASpQADUAPtFkq1CoJaOipnQJAQAaCUASoH8z0FckV4QB+lfv/i1tDlf4lqwtIAv32y/QR3NN1D8mTTeDQC9hBxIFWph04AD+ytpqrvawThdf+9LtBSjbGyfX7diHcyC1vS2QlD6nfx/X6ejp0Rwei3A4oK9C2nY4gm/vWUOXeBq5tAFNj3Xd6b047DG0zu54W5YXqKr7aY/tEZArTPVDQW5k2k/Twhjc/Sv8NilVYRXwSMJ6k16PvnIf6Kx/4YX+0hf/UhrCmd4v7CdYzV1qVlBsIehAOf1bg22cNCCe3fYuVnQYCGEf0eaIYd5ZMq8XVPTBeAJoOSSeLYTYHmYIyJ5yOgM2CIzkmM307kJC6wH1tIzFl228EXkjLmIXtqAzvuWBU4T9FAbfDopGo6Oj0A/EXyAAAA==" />
<img id="flag_faroe_islands" src="data:image/webp;base64, UklGRlwBAABXRUJQVlA4IFABAAAQDACdASpQADkAPrlOn0unJKMhtmlY4BcJaACVA0Qlxbr3352hEkfVVig59XoAeYDzTf8B+2+s0+gB+u/VpBMtsx6TqUsDOTV0EYbsOYCjE/q3HxV+8tp7XFti7Rhl05mXMRm3ZovcPAAA/voEPr+kZUdWBpFVPYoAXint1DPXu0YxECTRRw+AnfoVakvhcXggdQjKwkzoegtL9cusBc5iPf/hmAtkFFoL6Njq3W776a+rcLVS5RgqDRGtzPlieLeOok8XLsrgz/Ga9fcCidK4/et/53MQIRGV39HXD7JgWNWvUz43OkAMsF8Yn2pZM7IgfD4X9MKXBhe0BAkl2Zj+fUF0UWv+tiKZoT4CwD8qWedMD+VvIiuIKD4DYz6mqAPr4ShiyVxT/rTtmKP/8jlkOV2NZEuMX5AuIOyCFuHOQuGtkBHABey1t8eOJEdUAAA=" />
<img id="flag_niue" src="data:image/webp;base64, UklGRgwCAABXRUJQVlA4IAACAACQCwCdASpPACcAPtFeq08oJKQiKrZo0QAaCWoAeBFIB+Od5B5gOgB/o98A9ADy1PZHrmKrfbv7wZQPAC4AM+/z8DCVp2m9eNsxM5pHMbRxLzQzYzyICLyiZ39HEXZjy8fKasp2AAD8+xR5Y8uR2t3TLXmDekQwCkJcxmKYuiK+/fH9T4i3rK4A2X/JDGvV+JdeeWOkI26hRA179WrccJooURHZAmhuazthG0gY+H0K+Aeqg2YbWYLeJkEKud+ka5I/oDZ2lKMzFxYD4iUNgsvJhERQ+0P4rCGa/4mEHXUp4oiUC0M+cwby4fKm0R//47g45rws6mWKVMaOcnVTKVUpjVrvsbVwnwRkUx/uQ1dHIL7iRttF8T+3zD+hPl/NXKRQnDPhACuL1oaeYw7Y7AhAUCsyPFnh74354nLrbrqkFyZqQLET7eMASxLnZN+btaSiGEAbVWffbIzu2rHUqbSyH4mWMRghIB2+g+/OtuvkP6s/lLI6NN8q33+QPebFwz/LhXzyCm8yxhuK+QFIE/OWDm2esmyf8EatsBCdkqmU5aBxkzECa/Bb5GXBHjz/bUtM//zK/3xvFR0y7EKPNbwQyLxJMIupVR3/kZ5ToyTut4zARKM3/OpPLpWqvFpFN18VIc7TnY19UjMODyb+wVqZcPd7ZGGlcbhfW5wY1gAAAA==" />
<img id="flag_egypt" src="data:image/webp;base64, UklGRswAAABXRUJQVlA4IMAAAADwBgCdASpQADUAPtFaqE+oJKOiKzJKcQAaCUASoCkwAHnX1Wq6JSJMj6mswUpLE6TrAWUnUlek023x/SxREJQAAP7i4L/3H9kfzlVb/9CT//gk//4JP3QgbhkyDy7bP621QJewSNOXJGYsHOj/4RQNI323/CKAF6Bhikl5DIzpxxGonjQilU/gN1SMT6JTH4c1E9Lm1J8MxFrMNxzWYufIIOQzrtjfW9+I+QYNO570zJPBIO4ov2L98tM1+fNrAAA=" />
<img id="flag_saint_kitts_and_nevis" src="data:image/webp;base64, UklGRroDAABXRUJQVlA4IK4DAADwEgCdASpQADUAPtFUo0uoJKMhsBmaaQAaCWwAxRGTvD/xvFwbkRoEpk4DxAOmh5iPPJ8+j1AP+zklP6y+gBmj2mnM6YgVq7/E7wPAjSOsw/tH7A/6v9aP0T22D/zR3laplB/qGXM/+rLr5cSF5WR+x2wlLpdRMrXz5T8JLkEZ4O+C++gyZSCLzZeyoETJLtJ/slT6cUIAzuBln52/HOJAAP7ff+oJ0qW/6aR/jSP8aRQ/hdp4bUVXsZecf1ChjhIC/YojxrKF1Uwunm0CLYAN3P1slTxbhnJqNywAPh/+s34hGCahBiMTW4gzMADtvB3huNHVX0+5mb0HUdXqB+m7bLDcNmtjNlv9kCBoMVfbZr1Wp1zvDEXKq+cEJUSig3nVA9NQ03f5b3eJrayt00TB7M9bHbn6ixU1i0mCQDZWTvPxSmtPGxQu2zulsmWyvs8dEJTqafKlBizqZb+YLypDQCYaERdSiek9dkBSlE/FaUqb/x5OA2DddCvlkSynfD9mXN6BGdQcJalS6kOHeds0FBBYrMwkyNeeWlluxvpdzBVfrCkccXPpVLS0BqKYZmTTNv9I54XMWNGeY9KrEe10QEo6rX7sbyQ0t7d9P3p1lojprJKC2AJX9urOtZDfpwJN7SEHTz/n+4xo24Llb3C+6hhumo41R8STmZv+CgdmjWSc4nJ79LbRRSIc0Bb+fOy38xG3mI7go0YcDclip0op6L5o7ZImH5VGxnIuChbanPpmDVMK2Te/L01j8RdMVb1MxPWV3T4HV7SRP2LNbX3lQZbwU5myIYZ96K8BLdpNq5lYTlAD/lCMem0P2jbWUyO1rfP9L3Ga67/PD20lJXVTs1lMgAuiEUVVzpwO7BCKfQ34oAfwGHVPyOVrSjgpg3lI/xgpxM4zJ32h49UX638cWscDyaz1COM8Eo/NIeN1bo0/a15MKt70nGSXNpXFiXAsBtuuseHLjLWPfgb9nH3dbtg+nrmInyw6cR+i6Gd5vvdrLursqSNtolxrZwVIJfxTEhFimsRGxRMds6oiu+/JDhXAJlwpOckbbRxdJUm8A3urJoC8vFTRt+vesjh/u8M5Q4yBqUHWDfI66sTdj6imsfIQKGufc5Spqe6Xf0nqgpUJGfMr+BbYlBUMz1uNvU8rycJUkYAN9zOB1/OeyGg2O6GleY+wxa8NJ56+wPNWXFNorZuZE59HdydPC5gUgsKG/IoWFcdekISobRkYrrBuawj1MeaPtuAAAAAAAAA=" />
<img id="flag_of_montenegro" src="data:image/webp;base64, UklGRrwBAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCB2AQAAMAsAnQEqUAAoAD7RaKtSKCWjoqIokQAaCWwAzQmHvV/wFzfcBjN7ZPcS70b6AHS6ZElcAaVhyWcmmVECvU/grG/96IaUiNE+EgHBrn4tmymgJR1gTBPNTgTx7jbzASp/yoAA/mg3U7iWdOsRv8MaNDZOdMywj7/5cW66hRa/hfW07WPyCWbt+HTGPYpMCAW0dhgx6z2PA/ok9DvY2T4sgTJEAv2RQQkSVCUG0M7Ehg6Ds9IG52VfmE7KvIapvdtkrmKTnPPC2L2rmiPu4lJLf2xAi+suzXL29sUrv+Hh9iyYbngEGZeNsVeADwPUEj6b5yeWY2oO953+FC73TiXKr2PH1ZwRUmTpd2HEg4eD4oUaghEYtVuSu/mXKXnFNWeIsBkB2G/0h/oZPJPnAPi7tmH89g6UQjRyj1FYhy7fHJSjg4E6n6t8hIZeQkx1umIZXw+R9g9ivLnH/sW6W5LNK/zdd5Bb6I2idJY8BoDeMCa7tciQAAA=" />
<img id="flag_mexico" src="data:image/webp;base64, UklGRn4BAABXRUJQVlA4IHIBAADQCACdASpQACwAPtFeqE8oJKOiJFgM6QAaCWgA0p6qy1Hm4yRBCAawRXwo8mK1OTf7dx928jCLCndNrMGxCTDSTXjKU3bK5VdDHRAfqxQQAP2MYcGKC0A0LN//4tDzD9vOtjYh68KwIW34qZ/kwX0OB1Ddjt7x7uBsIQ8mvcCXXVAIk8yQDAlrBpsz0fdfY0lDPG/GNJNQiyalA1auDW9ubWvBuSs7IhsxSjVNC/s3x/of8TVv/MPj/Q9MlOSzIx0jmXNhHuH+2uEJ6gpqD1MerZByeZRa2MlX82wjOkiiFuUNUi3rqX4K5sMX6cdEyzFAzS+2SqdUsYtvVN8yN/jverhfD0WMhGJYfGl5a/AM5sNKZTNSpW/mHz4uRiVHxZIf8M23a3NBhPZge2H3cUjv/wAl96wUqWJuaMwQxTvwPey1EM99P8+r/V8oEJ2SQ0Z4bzxx3s/YiVjastlrEGQw4K4U7puctddG2ypUkEHBWAAA" />
<img id="flag_christmas_island" src="data:image/webp;base64, UklGRlYCAABXRUJQVlA4IEoCAADQDgCdASpQACgAPtFWpEyoJKOiKrM/MQAaCWwAzfmB3L36emHK/WpeA8RP9FOsB5gP2Q6e700eog3jjyQIqDWnBgmfThw7ez9ok9plEbajp2CGmytK9qhENoDKFd5r5aZnXKUyaZGOFfs5ILE0pmSvJDlegoLBGJHYhBCv2x/gAP7s4F5i2elLAroUSJwzu/M+s0xz40jr/gzp4hig8sTxChM/LfNFkO+9wh7hsJ8fqJZIAt4d7q1Vc6ziGKTNqR/61JDES8sd5HtgPoHStHJp4WUSRJT0o26hQvvvcfBwblewWA7VOSaias/aZ0XahnzdsPZQ/TFZDsy74eO22IJXINXFk4cEsoslU3o/BF26bQ1G5+TZ+4gzSWTsAqR5uz+6cLja3afnxAY25HPpNVX3cHPrgvIMoIV6sfofz8QWp18iOnSbuc/1egs7zcxmY5bJ03//G7guekPeolL2Oe7yHvhR0qSNvQWe1dLgfG5+lceYwdWFqCyKygCWvsW2uOwN81pLAA5jJ8llpRyOKs/HDMU2X2uPQw4XHt747fOgOywWS78MOx4dXx6e61/4whFPjKT9cHrDn9t2c1hUZu3Z9KrvKHgmB0VmrwWQWiF55WU63/4DYcmKj8DuzalGRQpzmmtUQnFA1Eg3SbdSudMRsjtH+CgnqlvROppkmYcnAcC5hUlRzzzyQBA5X3saeUjBDBR5PMmMWq7rwS2N0iE4VG9GuK+FI1SkdUqIIEXyr7cAhmdEhfGEkWuQFYWdq8xvi93b0osxZwAA" />
<img id="flag_eritrea" src="data:image/webp;base64, UklGRpACAABXRUJQVlA4IIQCAAAQEACdASpQADQAPtFaqU6oJKQiKBmaqQAaCWwAzyAv+ye5/yj9cPZtrH+M+7PK1Ld9QHiT/1rqAeYD+Mf1D9gPeX9C3/09QD/3dRnz6Pso+Yj/nmiCAAlaPdourcI+6tScA/AU9ZjTAU2l8u9hWLlunM6jqGSVDuG6H7JnxPX+g+6dhI0KZLk0AAD+cWXQFK9m3i+CnFFd8//dhUa9VH002QlP//nvL2ElbZpo96PwPDyC91pK0irSp2PpKrMbj+S9guAagvyrQ/BOmVaQqkC6hsXCqx1WWxvlod3kLnnP+EbQ3xONxmrrneu99X8g74KZ2vCal9PT9D2lwtwrzY4m+JYL2KWxXT/es/FGmOZEI3/joisobMzILj7EHJW0m1WYDZ2oxkEtq/RMVZgXvQPkgC5aezf0iLbXms+0LGZwuwfw5O5XcKS4r6MMjKhtfPzEn91/UNSucSbbFnIndEJ7qn9Hj/C6k1rPqtGAlSwqA0qdsJ0UIsBhy2FTKZRYDx+gBxMC+L83WB5WKQqneP50SJkOeReVO9/EDYL2yfmi38YMqXROtLG68Low1uE7vNZWa3fwcXA+/rlqukxAsIOk8UeDAF+7e/iqu0e+LNZ4PHCwKmI/gBKKvR8N3gHRcx01Qd0lCHtTMXl/1t7RthR3BICvbSA1RzgDnB2/KlZTNCrmZtNJQTp/6y4HZlsbCSg/RAxNjR4BxYd/sk/J4cdstUchi+qyUerINBTXp/pEtXtAMuzDUFUZ03/WZtOFpzzGgodadlQ/5YT5f35N+aYL7w/H4uWpqECI+C74FSNH7FwkrdsJV8Z//45dXr/iJm9iFZ1J2BoZHP+3OPAwbXAGzAAAAA==" />
<img id="flag_georgia" src="data:image/webp;base64, UklGRuIDAABXRUJQVlA4INYDAADwFwCdASpQADsAPtFapU0oJSOiKzSc6QAaCWwAwzGu/mf4gdolc/wvm219+9fyX9I7xMaTrO5AO195gH+D8oz9ZvdP5gPNw/0PTgekB6t3ou+XF7M/+J/22CjaeL6CPv8M7JMcppid4tqQKghoHkQlOr2/tLSrF+f8e+EwBaaqRkwDbLonSAe7j+8w+GUgi8WcAP8Jl3K1lxBWYod2cCTMAvw3arYOrKVLvSRpo5ePfT62HXRmRAnxM8atzpEpZEZBRds5oQEoAAD+1ieL2S0PBTar1y95okff5VSOv1F/blO9KhrHizgZr5ffk1GOb1IPhmieipLJfFwaRc/8vrA/huiff3VJLWTe0BH507o97oOR5w9Bi7gsrxI+qFMxEatp8ImNybtmNgDsUeZVqALh/NXjTp/JvIQeb6a+Jnek32Ivb5XYMJ97fEkzOuOwjhXLiW/qM5AZXPSlxLFakBkNu7S4VDfqqNKTYOrpas8QzYQ4cwy6HXIFuW+8Ix5OWbefctHsa99GWNF35X3k6Tuzk+/fQ7NiW3mpQD8fMGMJH2YcT8rZYK8wBxYQCd4+WiDIZtJvMf2UD0HtzSWbSsRMpt6Lg+ruNAiqR7eL28OnkbD6uw1HMP5d97zFeGB1XDotJU2Ng3gCLuhgf7CSeBAW7eRAnmyyKZOAkr4BAZ6pmH41R4QBL+H16Fb0f2hSKyrFWNKs/lsVCUnZ3kL2Y8F7XvKOPJRS/UIPSEQPWk0PaSYg++ossNdCyRwT849bnEmrCV/w5AkrMxPMOyyQq4mOczkMqB/fKf8Si35nWT3ayU8gjCR14ETzn72XT+5FWYmJzARIWuIXduy6d8O/B1Jkvb34OmmDYy4Z3jxwBfdHYfAQtgsUf0VT0RXRG6bP34cm3Om5uBRIu942yVC+CZ33VNA+oWlXR+Vz5oRGJkfMNsRSRxDSIe2UlR7uVAApYWCYYEzvmWkP/V2P6VlCoUVQuoiYAObZkFMHhgHGXWAaAUqbMjn2q3kspVORzz0WQhqWb9VvkOIe0p1QHGlMyTzkoRRuon8sY51ZMiUitWI7/Nfhgtwk/lGQLFXN16g/vH/Sxhc00Jrb/s+P2TwJcxscNTv3h/OVzeJs0Mfci14/BvUouBXl+0NEGrAnl9nC2IcIDB6aDIZztMPNwJ/B7gbBkEzhufCrfjj9mLO1EdJnxkLa3D/ifLV5L5HdFpwRQrOr/oO6ffn9WlPiawN/QppO8jjbbO9itrsM8f8I159zVqS17NRbebTylJicqDq+izivp7uSfQ4yqZlhlEOCWLvieJgO4AAA" />
<img id="flag_rwanda" src="data:image/webp;base64, UklGRhIBAABXRUJQVlA4IAYBAAAQCQCdASpQADMAPtFYo0yoJSMiszK5AQAaCWYAlc9Rk6B+IHMdwdtAGDAfsB72Ixcw6EuvH0AXGYI0oBoz8BHCPrL3OEyg4HUFASJPfXbMiAAA/qTX/8DpAQQ3/81/+XLv2qjBSoovrAhH2AhY2iTwesm55velo/4RzlwLYm+Hg9wTuyilJxCzP1RsPdoXZ57h5yDDwqx6UwiegTVG69KFn6PdWKKdnEw6mq7sYxexBhhDPuDYt2MxkGeyNiCQ5nnJWgFG7KIwx9yCJ3jKlrFWUYwHw3QrTWNsPHKmBGkSvDw/SVLUpY/RI58rH0NBn6D6VOYx/GQrcgKD/+f5rAx2IWiXQAAA" />
<img id="flag_honduras" src="data:image/webp;base64, UklGRsAAAABXRUJQVlA4ILQAAACwBgCdASpQAC8APtFip0+oJaMiIi2xABoJQBqJuB/ANYq5n9gARX5lH5WhFN68JZTdZcbjzLmvMpb7FLLqAAD+7RJG0cDuyTGxeyQkjdZlfJK9v+m4HekUf+rPJnN9E77XF9FPQbxNblCreOkhOIjUXvwEZstGRQssFo5F0rHirzfAkPV+JquWk7yzZ05qbSF5p8sFtHW1/I1V4xbpeiL7kQXoZs/dBWIbnfRzuv449kMAAAA=" />
<img id="flag_netherlands" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAADwBQCdASpPADMAPs1SoUunpKMhsYgA8BmJQBKgaljyABHxQ1VvMpkVHeDAMEYER0qtCPZsG0fYAAD+34A/NXzlS//M0eW/Lfs8mt8Lar1qLbrb77GhDa0q3DHwXBWIVLJ/v/jgLS4FJ90kACfPrvCuTYQvYbmnf+qFE0dycjAAAA==" />
<img id="flag_sint_maarten" src="data:image/webp;base64, UklGRhgCAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCDSAQAAkAsAnQEqUAA1AD7RYqlPKCWjoigTOqkAGgloANSJwLwP8Rxt/HO4dtxPFy9Yrz/75QIkAO7J486TkBuZaYUFlUMNj1nZXZYGFKXq9ntScnsDe2B9OSKmqElNTGGhOq/L9y/kdIAA/thoHk2QAobZJ1FkVqHqTnELFHzlVA21NI0Kqezez02fgzAv6npOqa9xdFmwj+Iz1+wwZrAhI35pilDHN1jCyGtwytLI4ZgNyLyD1Z9FSq4oy4nFwxPvOvCGFrZhxr0AnzqVVcXsxrcxz8B2KcwzqFJqMfnpcNCaCUUWmAoY/wcJIiOxHs8wnnp9HrcJOSaCUs7VLUGIf4I2MOXoA2QCQtlTPWE5DiCM2KRDMdpinYH/NR/x/zBumFbrJxjOqrVtGp15htSrHrKupnsxaUXmglmDpF4e+aijrrh7T6VF38zvH5+VH8/SOj2eO5F50NnZybInvIDSG/OERohwIZvl1nnFveWw6fTvman36S/9HAGNGLHHi0NXTkgIoSeSLVloZiKg7SJF0+fGi9GQY6f/RLP0trBNIELIVx8Pn8SySNRHYr0hMC6h574CQuWVL8WJ/aDjR6rvVNrhQ46FsZTtJAH7FWlWZhT+TPKgAA==" />
<img id="flag_zambia" src="data:image/webp;base64, UklGRjYBAABXRUJQVlA4ICoBAABQCQCdASpQADQAPtFgq1AoJSSipNVa0QAaCWQA1fGBvV3sKCe8BtgPFm6gHn/9UBvLS/AFLneP6PO6Y3KXVzSG0/rzuPLl9+5g+VP+dQC7m77NAAD+6GeOHw2VHb0ofMzbP/i0PrQ+s/2fYx/UPMO99nza6B1R/9uWrSyPqnqe2dYoea5ide0JQRk2UPLe/8LCUkcY96szdJqwviTCbkDHESLAoP++FzR6bitdBbUAcaincFTM7lrQ8K+HKMa+jTESLPAgalm8eDKudC+IpnkrAd4rXlt2UoHupquwZmXaNZ/a//Lj/7p/ukBLAI4VEdXv++18/dr/vFx/Y39E7kv5+LnNV3GeSnNIW3dMWJCRrfOB8xaQp2x7uo6GT1o6xUdRfUyAEFd2UAAA" />
<img id="flag_cuba" src="data:image/webp;base64, UklGRrwBAABXRUJQVlA4ILABAACQCgCdASpQACcAPtFkrFEoJSQioipJABoJbAB4B/ZuPvuO8B4gG4A3P/qAN5G/ar0ALmbIgOVoYalg7CtxbrkvNb60p1U7//tJKQ7YH/0/FZWmAW1svfJC3FjrAsAA/tvXqERegdDuAD5uCOQQBGcXbXuVBBBGUpgLEf/PRIhouPeat5Tncc4MX//+TaRe07Sey3TGAW4Tq/yDPhZz79VFF1XPOhm6WD/IAUxgQkGxGeCq496KLoxiAQMre/S6Y1GxVKuMIf9/uIQgi8v7AZPHoPtfCVMSc4efyue2FDLyrM8hZJzhtUD4rg3dlhcizXWzr8j+1EGe3uswQFTDUFYdtcXysqJvF73hxHww5arc+2k1Q5yaSNlxySOF3RV00JpUuWsUy1bgjUvPmmNzB8hSXbmr+loUeN1WctjTyuLriEY0/1xUWD3mJUikPfyiH28+hUjWHHBg4Ai2Gbptzl3gmbYyvXKtWOnzAfC53Mmcggr+UvFh+qxFWbANKiGpToh1Y9Mhi8KoEIr9lbJlNluAl5bZ+zl6f54w7K9H3QIlCOPgy/Hx2xA3z2vnOaLAAAA=" />
<img id="flag_cook_islands" src="data:image/webp;base64, UklGRmwDAABXRUJQVlA4IGADAADwEACdASpQACgAPs1UpUunpKOhrNgNUPAZiWwA0MBBzE7APUBts/MB50n9y1ADeRK6t+y9AF6dP8vzNdjnpOMDSg5hP9c9BL6G87/1B7BXSoC8UilGlMiml5tKIGEXfNR4xzh7k2f9J3NK0J/PVf4Lik4tGytgu8NGDv0u0VNNPU9uL9WiVfpbjA1ZVYJ6kAAA4n1+n9PwEXrA3xqn+GryqSWwQoRivf/RaihlgXAKmyGvmNFX7IkmfwH24ZH99xe4PioXI34teWO46/3u71ekhX6/uEksovk8/2MpWcUbfT6iljH6HzKyFk6HAUWncHKENM9BkgktQur+B6jW9tpcDdxsp3fRTBfOPzhlQC+0Y5DscfRBgZ6a1Ju1cRMx/GkKYAc7ErlDvZ/3zqVbikFb/cfIkwktISfHXj6asTX+1RLl0phJ9+xrO1N7/AFyViP8lOnZGpQc+/nJfyfSXJTGRsJD7ZVG7nxdTyDDQ+QTezInXX3h/HJ59dtYND3U2AIubJCbrQ87q+rtvPnbCGuDNMjZC5r/s6o6897yQH+sXKt2YtEPgYZEIHdf6Y7h2n0tFldZiobFPHmUAVGes3W5cHdn+cNI/FMiG5WYF97tu5i//82IsgFlgdccJ85paGimviVcClfMByDfWCjq+ra3+XcfHR6z88z5MpqnOa2NLXePfj7uumjey252bd8trZiKh5sCgYRxdJpWGJa1cbWHv0v5t8hndbL7/08Fi6mAdUYXNA8sMrDQajeIccSC5l+KEaneJ/kKxPt5mlPQve49z0NZPrwz26lVcFfd6J9VZt+gmt9saPMXW5hX0nEv7fO59//WAtdY6qxqJYNMyGkahCcI3n3jd61scN78EwrHW174maOasfcSBawULxgPsmYhgli5XMb79xy/oiUkW2xnCap7vXx7Wh1s1wja+Ijzwvjaa75fpowAYbVlfCcz0/BIMx8nKlLHEz+lZaSGnX3b04EDZ4DEbOGLMLcEHKCc+C3Nzpw2edhwydmRlejQiI/MfluKjFE2bHOIA7BCYCKfXXVc3a6tFrneGrzRQrxY6eh9Ys6258x20Cg2AB2v4ApRtjzNkf7ohXLCRXgYPmuPaCvctitAqwc4QKxN1WFKEtbHQQdP9jOFpvXjThy2AAA=" />
<img id="flag_yemen" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAABwBQCdASpQADQAPtFWpEyoJKOiMZi4AQAaCWMALv/AYKXaxaDfwtkVsd/SRHXtp/awM3IAAP7lCv/9avdf6tJp//84l/9Av/AXmCR9oH3ovvplpFCKnZ01fWPDsO6Hc8FOA3oCJTk9/zVpuYEV/riIAAA=" />
<img id="flag_kyrgyzstan" src="data:image/webp;base64, UklGRo4BAABXRUJQVlA4IIIBAAAwCgCdASpQAC8APtFYp0+oJKMiKrM7MQAaCWYA0FHAu244NgDbc3YBvKuRewgygeBlT+/dDrbe6TVHR09+w6iQpHcGh+gO154jAKj1V61Tu+Cl8AeKGHItydAA/uLgvdHVrVlc/9QZ/+QZ/+QZ8iUmnvWwFkOPbmnUpNEmTfKTaoDMeC143QinusDYT4i9ihBXstXTISuPFs+tys4MZvH8eOhZTiVHj1rSis+/FOD6bg6bh4k5eekf8LsL7jysKchsbDGMeaBZROtCM/3XbuOMNNJkBQCnTL9PjzjZ9+xsmS678iXq4KUPMME8JjiVf5CdTHAGBJz3oPUbrata9yAdjkdIe0fa0knO3O9lnsTdzElCY8mo5AK4dpfwiPdDRdbjOG/utIciVxEuPw33QzSrlM28dfjriaqKtyiQImSbTshnpF8+jfSZD7KuPzhRsadfsWeRPXnV44ua9qyTW+RDqijW0c509L3Pf4FCUXWF4ayIjladfHh6bEoSLDudAAAAAA==" />
<img id="flag_austria" src="data:image/webp;base64, UklGRpoAAABXRUJQVlA4II4AAACwBgCdASpQADQAPs1SokunpKMhsYgA8BmJYgCVA/gGqW8zkwFv/3cACNOMFXzKZHv3jY+EW812PA1iVSLgAAD+5Qry4jSZKv5xL4C8keti6Pb3XJ+b0XgPoyg/o0dTlH1/4Rb672/4RXjRV9gjSpsjqXZYPmkYI6He+O9hCdIz7CE6fAXn0j6YCZ5ZwsAA" />
<img id="flag_palestine" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAADwBwCdASpQACgAPtFWpE0oJCOiLvScAQAaCWIA1ImBvJWcz1AG8Uftn6ABMsbuAGBvNPOc4nZmGRb1BO4xsk4Kw69nJNfwzfwA/uz3LxO1fhE/biZ0JTJ+TJm6KoBgZm/8ZLd0hd85AXU69/st0bCE3Kuxo5mvzIcrW2avYfuvimowaqvvhyJ8iJRNgFTRFX8KPmG5fMaCi9rxrmUxVM7t9pqLDxLkMOF+pzXKGSHtOpynDDG199z2M/Kk1DC0oR7SgoTUg23KX6yi3Zf46AXRfpYmz4pccOde0mJU2EgG4rvrRV3XWKr7/p3YSv3teuw/zaPVXLndv/fzYX1/+Df9swAAAA==" />
<img id="flag_cocos" src="data:image/webp;base64, UklGRkICAABXRUJQVlA4IDYCAAAQDgCdASpQACgAPtFcpk0oJSOiKJgNEQAaCWwAzM1BPO/wGAGwg9QGcA83n/AepPz/+og9CXpTL9Am2qwFACGceLt8B5IAP0CZWBXqJVBNFdE3fyo+VXasgSlLCbQ6sIth7J0Sb2a6tYRkCueUStYV7DtlRHx/JCwAAP0mRUDXRQBQcFoH3dpLVg6/VlSFrh+BEjs1wpuVVLuh59uXzOcK5L2RmlU+CRn/396fTG/H/kBdz+tnm/ue/af26cbTTyg8zXN2MsHw97Z8R4Mwt0yABpeRWs9sjWgSPlaYRnz1xMS0Gw2XOQKJTNbcDU00ZZscr4U7+h6MHeTebwVP93lrkK3HW9zqJD1xRvC6t5ZYK1mNNitLXMTafsvf4tGbqWqXy4qjKnQb+kk0FWfs5ZPxs0Mz2MBnnmsuHgZzoYW/0K5H+b5aU4FAyAc8AQDFNIoSi4iQ8XwaV9YuGg7+KoNLOekO82M28jjIp/XtiWXXqxbzY3QjOdtPB5qM238rrq8C7EByh1z54roBvAdjZX4BzsZnmqMd+3tiIZv7K0DGS6eblSkdbhTgY9vNvwqMUb1wqNbJqQqHpQrUZ92cH5Sth1mAtW2WvFfL+U8JiwiXD3eDmzVKa24OJQREHkk6ceYOkhUfcPz1qdQqthAOZGGzfjIMOZRhRbyvfhB6hPaHVF6u3tidUku8nS7QZPMqwdpmCcu4g28nE4gCcZkpDZzRHmDC877gVdQiFlXbpwsR9OiFC0AAAA==" />
<img id="flag_french_polynesia" src="data:image/webp;base64, UklGRt4BAABXRUJQVlA4INIBAADQCwCdASpQADQAPtFgqE8oJaOiJNVcsQAaCWoAeSH3b8ScBs4BtqOfY9AHngdSrvNaNBCAcptnm2trkWEGEPt5qxKLR6Hihzd8YxQ4P4vKICC8qnkKr+6VfrOFy/2BhmfLz4DIVcaIAP6cU99dj5NRgVf//wqV1W9jJH86H//56ZXTe8JheyDfOpOVH9or5G1TjG4Yg/MBfu/f5AQaAa0Kn5mkcsOYbwzDuGAFNlrMCwvbrhIfzuZu4kKFSXU0Jm6MqP75J4Fpnbpl6xqXdOwT/HJnkvB4ghrgiL+yKdGEMjora1fAI5lsyKRiWF7a40bf4wYU+QIEawFxzv1v4NSnAuHqxwZf3IHToK2nO45epR2J8LcAMWg0i2wfWr/GL/EWihgCtQRfkpwGlsKf9Jb0VNZW6uOXC8iMIwFH0ENYSILq29XHX7Z23wij2sHnrtyqXMI+evy5bWtX2HX7le52X6KRWYs9YcYaUCZxAlyB4uiixr+/pGi78nNfJhnygqJl9ddXIcd2sw7nyGrA+uW8qblk6bAZWKLSpdxXL6v3XxIAsbjcqEM5Ut5qTzuLDjuPbD4osQqKIDmRYf4Awgl35tMGWwoDCRr9yEHWSJOgwAAA" />
<img id="flag_united_states_of_america" src="data:image/webp;base64, UklGRhwCAABXRUJQVlA4IBACAAAQDACdASpQACcAPtFirFCoJSQnJEk5ABoJaiyAFnVFWG4IKV9u4gPe8v/28tpu5kD9APf/u4f9QKdw+senq6BvgfSW7c/8byp/Puoqgs0UGLslPvMX41WkogrDyDt2mM1zld66CTvpngAA/uoyh5WV4EtMryD2QhC4sH9Lg4N0aIYL+8PxqGVPhNa/lhVVuqKdYzgIDqsH0+IdCLvcpUzGFB7oO3R0Ty1jyz8LauCseH4d9naX697ADCRCoHPHFtL25Qnz7bLJ76oloESlpcErS2+O+qkrq4fZO8oC/om5tuSHjt028G0xf5A1P81WnhMv+OjeefGzXrGOI518WIlX7rqUfe1HblV5LEaEt5DYCrTOgCiSB+/8uslQEl6L4sFGG7mtx7gGDoYph4z8JV4xGUKSYWajCraX8WqKnQO/KsLYx/5VhKZgK/7DHdobsD0GPjzPr032uret1Qw02Ph3BCtYW+3Kb6mz1z/r75YrpUY5FW3xFUG+rqqiB6e2YHbZ9FQLPEiw9nZYayXKFxS/7kdwLt/+yO4Wx/NuTs7eglQX9//yOOyu3ox8/qP2/mXpH5pa7cz76D9B/58VkZ/+/5O+/Hv2iSeRg+LKwgze6JDSK3yvr16DJ0kZq466m2ldD3gpAyU46kDYDU+87zDdHyvIXgcKnLUXgaXBxWvSlGyZ6qVLujoyt+STxIYAAAA=" />
<img id="flag_germany" src="data:image/webp;base64, UklGRpIAAABXRUJQVlA4IIYAAACQBgCdASpQADUAPs1Oo0unpCMhsZ6IAPAZiUAPIH5BJgLf/BDMwMSMiw4+XaHXUu6c6ZrijVtO3peS9PiAAP73wxCf3GwkZap1RH/7sAp8a9LP7O9//+S3b/8pLZujx//qktm+SPTTxi7XDIQtW6aah5pPTYmMSZgErqEc5pAHQqeUyCgAAA==" />
<img id="flag_armenia" src="data:image/webp;base64, UklGRpgAAABXRUJQVlA4IIwAAADQBgCdASpQACcAPslOoEunpCMhtVmYAPAZCWQAdkmTAf4DCQPX/AVx9+mdzs3MJcSzZHXc8GaOlu66XfTXdgAA/qiOQUYqh//U7RDTlG2x5aP//ziX9gYwnPNFELmV7BJoA7PX30gnlwWzeU/pJVRpo59JKqEwef209WcF5n6qInoyqZUg2/fUbarYAA==" />
<img id="flag_switzerland" src="data:image/webp;base64, UklGRmQBAABXRUJQVlA4IFgBAABwCgCdASo9ADwAPrFGn0unJCMht+oA4BYJaAC/cUF+AflVrYXRvyg54DjTvvaAPU1nAP0lyWDntPaDCipvp9ktrWOM6CKdy47/32P4o+jEqe9w8Q0Uh1zuL4TqsAD+0Lu/tpwspLj0rHpWHfH1i/vHQVz3OJXE8T62IbpHO4K1hMAqmwV6xkOOymO8p6yaggeH5ct/3fBjEA0eBgYmfXDXd/+9k+CW9i624mIcH85lHVM/H/4BHD8OX+hZ7JKb5ZWwRcG+e6SX++fbTVCQ/oOXwq+Z7t+81i5zgROq4YYzmf//U5kNvtO9Bmjb1o8laBgGLfvkvwI5rba6REKYmyeTyY70/pcHoWDI8d+Wmnh9FNOQ7dupRyWc94ce6ey7NWxaLfodomOvY6z546guSH0wIXFoV+aQVuOdR8y+lFHz+TjaNXty4v3kvlHDdWv3MoYs11E8qHeAAA==" />
<img id="flag_sudan" src="data:image/webp;base64, UklGRvgAAABXRUJQVlA4IOwAAACwBgCdASpQACcAPtFcpUuqpaOhrvScAVAaCWIAeKWMffrsRtYRvV7vv/CmhX6mXBLAvLvB5zSZCIiV1hqagAD+6hPR5hJ3/LAb6s4o9sqmN/v5P5lGI0IH/DVPGeUwXku+D5ftckdwpKHvn5HRONwT/MTrUEYRSLJ8pLyr5rfiDwW+z8i5WAHYsH30x5uQOElx+EseBHtOninlPA4IYGrwwPAOULd7atFCEFZgsxLp7WNtgJf23Qf9Gt24SBR2cGnox7XvIkJyF19iyE3dNXswrsKl/S2sfSL8F3MRI78ND/uQ3K3v5hTLYCAAAA==" />
<img id="flag_seychelles" src="data:image/webp;base64, UklGRp4CAABXRUJQVlA4IJICAADwDwCdASpQACcAPs1QokunpKMhszOeqPAZiWwAv+lxft2mJeA80Wm/278G2kD1Afln/d+ox0gPMB55npE/42+X7y7+5lhWZ4O9H35Jtzhz0o6JbiHk7mlmhf8FGGxUWf8BTUUKfMi2jCvxXNfUaXgH0EO/fF5us9cuPuMd+5ifLOMZGuuB6lEgAP7wOEMEFEFDUhoHGYkr/AdoTxpKQjm7P+LY1uo1hcflJrs5mtmdYt9Xs7i+Ch64R48LEeg2ld8iM/4acUM2wI3cQ2uJJPBg4e2/ogGKRzGVeq+o7xb5YPkhVDFVb4WQvNEdQqmq67AySGn42oeyV2juZSybX5QAhHvhkV0pIC7Wd9PV3nO06EW/OuEY0cFDS2tN9tAugHQJyAyjmdk2VbvrMa2UnjUBzn6kugOZpuW+9BHu+trzDkps+f+fuxNJL08Yg60nXKkjbVcniERYtHe/VCrNTv2pHVPDzYCVbhCbTItJP5O9YHDjTaOKvg5vBeF+yRZbYcZOTxL0YgvBdE3y2ZIOIR/34xbLbfYlVq9pc619ONjFM9pO81QmC3mlm4U296DO65tBJSLzq1E+MfUSHjt4Y5y0xVTgej3oyRwZfiB6/uvAd1KRxRI7G52kMBpilB6R47/OuEbNKbSHbwXjtzhf2eyQfzp+jh0rifOLukumYnWZ5cACotaYNnGdJPST4DMqvCti3tC+2R7tF8xoRv8UXXO1OHS38pMlP55PxqerE+24LKFkBGyLg3vhCvm89WU37/qDIB8hD21Kzv+f+8odU/WARh+81/hJdSqF+CrNCBCosKuYGd9+Qb8VibjgmArE6OhsUYO/BJgFRUAl3M/CIYvSEhJ+C0h1NACiHN/NEm2B5gAA" />
<img id="flag_tokelau" src="data:image/webp;base64, UklGRpQCAABXRUJQVlA4IIgCAACQDgCdASpQACgAPtFcpk6oJKMiJnVd+QAaCWwAuzmW/t2tMd43y6Lc8B4jHSA8wH7AetVpgG8kfuN6OSehQAhkXji1A+kt6Gf6gHfzcftQHXoFLB05gqGMKO2zSUuqTTGqRFUuJ6ZPiGWj9HCOwy2O3Vg059KiU3b1aUA62AD+93cNKJab7iMdtaTswLsaOxWOT/Qkf/fP6v6l1lFDhs4IJaqUJcvuqrWdZecyxiY2d48KnVu5GrkdD8zF180R1h95J4B/zSldmSDXHOAQOTFz0PCV01Njpgnnk5ryTYYK9ioUcfE4VaFZsGf0qpXqOVuBxTAIG1uxzbgPkaJYkd6YXoL1sLGg4imBAoA4eHs04l6qMh/fBr/8fgAgDN11Z6wyP0fl/49aOIlnSd9xcbXHxv1fMDGQlmg+kC7y6P1YisyDyfonSe36P9qHK0xt+JJ9BoBAjQ4wWF4UIy6IC+t7nKjGKWm2/LZgFKcuveU/kngkqW/Indfn1hyrfeOPFsourYJftnph9lSUnUlmk3gj5zKczmBTXBl2D5BfmkCdndEpGl4KbvXUUjnL3xyk3V26u3VYTOyFXOGp12JlXJAzuDSi/sknSZHwV/3uFSfjErHvdhF7fWr3Nj+eE0J59HSscAFhMQP6/5/5jmUfe1PH0YWCsJDdWTfqityxoemLOLdCM/faXgw4nC9yQb/SkJmDxRYkvhN+gaYvV9vbfRBOV/F9y0AE+v/ke0DwI6bb2MZv5fx7DAES9Bxl0/NCfAqd+bwAOHQUF5T7/Ytlrh6tERa0GXBsebDdm2CF9KWQe0Xt3tbjrjc+2IasFRhYSkwe2Vin/Tmyzn/L4+jUyr//LADONMJXgAA=" />
<img id="flag_mauritius" src="data:image/webp;base64, UklGRrgAAABXRUJQVlA4IKwAAADQBwCdASpPADQAPr1MnkunJCKht/u4AOAXiWYAlQP4B+AGxY9Npf/bu/oFx/2P+AewMy9egFpKgnYV1J4q2GzTYLJ62PC3YADs8yw9WVSjmvXTEyImbdXRd7u6JuU9TA/bkbYAEZc0oRhhho/+c1LiFyKUdf4LN/Bv/zTW/+CzfwWBphJ0RZhedC1cDyWvxmyS38f03KJ3vZgsQd48G7dwuzF2GxJKLgbAAAAA" />
<img id="flag_thailand" src="data:image/webp;base64, UklGRrIAAABXRUJQVlA4IKYAAADwBgCdASpQADUAPrVInEunJCKht+gA4BaJZgB45fdKX/2wLf/sf8EoiHkTkTuGY+/D65peIWOjtYO603t/iZ5gAP4Oat2uexZu4s3/+LOpMe/1uZ//6En/QednYlTUMnm2os/wNLoBrWa3O8I8VwrSCFt7xc5gH/Vr5F0CF9xFHvKXe5WUrNMCzQ7zyzZg3pDYgoVG3ouhMDlRohujyISXb3f8AAAA" />
<img id="flag_denmark" src="data:image/webp;base64, UklGRi4BAABXRUJQVlA4ICIBAACwCgCdASpQADsAPrlMoUunJKOhtmlY4BcJZgDRuUF+AfkBrnfAPxg/gHQmaBdq7QB+oHuAzgH8A/gHq56bAD8k+kUlAWcK/OIKGaypi8I6Jlhun2oJe7DY1y46CUwAAP7Lrz+Hjk4CVzgPN/4+LdvRZfNWFcygH/BcT5GbsDHEbsDMlgVRiaAwEkmZF2dHoO8Rc4Dh9kZ2grni+jaxgfOPWUph8y5Xg9g1Kg8SjW0HV5t6oX/3uGb8F0IPbtM/N21fSPfq1VXB0sqEBvLYlwegDtRGPjSnYC5f4nwJxMHWK9TqvqV7J7EGS1U2FZNh6poqwXE7iL5U/galH5S70+3HQJ4c8nCnppe2nbrjMjuGdyw0g91ikCAZGB34/QZCAAAAAA==" />
<img id="flag_botswana" src="data:image/webp;base64, UklGRpoAAABXRUJQVlA4II4AAACwBQCdASpQADUAPs1epEunpiOhsZooAPAZiWMAlQNXQBvw7zaF+lmYIII9K/KN7P03pc8TfEAA/uaRx5juqi3h8qDhKV+p6s+qZS9KROmJ10P3C0t3ghAAnvTAtOykC1XDCEIRD0q5Fv/kxcgs+laJ3yI60mbRVT2DrX0X8wMW2ZZIQVc7zWYisKTAAAAA" />
<img id="flag_nepal" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAACwDgCdASovADgAPs1SokunpKMhsrScyPAZiWwAxrAYRIj2OWHlTrMYDbReYD9Uf1r95XpAP206zj0GvLW9iz9t/Rp6gD//uJ7Fo/wBYU/VHUpTzrWhTYAF6F6b9CzjW/SFJbXvWuW3xktYS6nigpWvGRc7nfuuwjfBEeom4VgA/Dco4dQED35OzZ0aoaDmGx1ulN8yds3/G2zCy+uJdeXz7T9DKTUIYwoTS/NV7W/H4lcAau3FURIGu/V+ZFDC/MXpq/f/JuxVZLySOech0OnaNb/Fa61It3NsIfN3GRLNkua5loINoBtW6ZexGtQb08ucjnyHOaUVqCKoqDxmUgg6iQ067bIrJlhyYEqc6z9u5Ud+1gwiwbc/uUeJl4wPGTjuZ3i4fWnL4pFAk+FymX1JSlQB0GG+Aw+TgLFrkIoV2gF9Bwq5uBRHTX6M3APHtLFSD7PuUfKGTEZVntyjfMZPgkf6ilM0rMvS/V2Ybd60CmjemybjTT9HK83j7Gxd4FM3YSq5On27W1uGqaO186FZiNvAXmQN30KX8ZkDWXk84n98aKPISVS3BYDjrs9oREo5zYcgHFNSd1AA8D7hLYp0thyuVexX18dULEBD0JQsqcoSe+ZYMngITxl7ij1K2RowEwVALc5HLIkIMOnYmo2HbLOiXLUQfFOYP/DKc03t9MCyYz4zi8IzdQ4TSl6IqzoLggqwB2aOg3naXL1GvrAmB1UPtHDoFUEZISgInMak5mQwFCFr++bxTOTEFLjjSleJKjXw+J5SdvSbqOwkqAQQYvwZfDrSMGPjSwerc9r5yIC/hGpc8ZPzioBFL54vyZjF7bZSPsYZlhVkcCNC9JI/q6GvGSgBAQdau4zMuGf2/oOMIW9JsIFE00+Bp1HiZckM8T5Lm5DIXbGAAAA=" />
<img id="flag_croatia" src="data:image/webp;base64, UklGRsIBAABXRUJQVlA4ILYBAABQCwCdASpQACcAPtFWp04oJCQiKJgMWQAaCWwA0BUANVv6rgNsQPUBtgPMB+yHrq6YBvK/+fR4IQDWRP3Su19XHp/xZbCcdKEigHB/thz/RqzDGHHIHFh2MtGr17ra5AhCG6AA/nCf9774fgv+GSn+FalVpAFBK2u//6tD/locG2YmDxqLMDJD5JNFFnUmLdWlgFDW7zh7/3B7o/QYiLSxRhjgiDDlAQsJgw8z3k71EAWRet3nTv0MwWoswJbL2IMfeuZ312/f8UgOM8gvsPc9InLCUEyjvMyrHrDrkOPE7KBaJ1GH92NoqCYurFdf9Lp5uxEhVtvdt6+M9IhqPk13SDHsV8Tp1PbV+zB1zhq4s/6RsfSpf9Mh/0GIhRCz3+weOaoPSD7YGEQZRcpxlqTywTXSo9fW53ie/K/buSPppTW3OC4jv5N7+k1XcqKvIyrfWzP/6iwUGxzprdAGLwJLWmz9vEVtZ9stFS3tQYMl6fL5lshe1NQg/fIguxTYrztQO6RfLYsUeswhQJdj+c66k8/3TjtHpbP2YQfbdAnB5j22naJx5O0C2JRLRW7imi6KI+gAAAA=" />
<img id="flag_saint_lucia" src="data:image/webp;base64, UklGRnwBAABXRUJQVlA4IHABAACwCACdASpQACcAPtFiqk+oJaQiIiwBABoJZADS5Y273/AONndqu8q/tuTRjx0stSrfSIKp/qjOtJhybmUmOhL7vKuKEXVaydM1SE/TbxAA/u4KZ8N/ky1wdd9SgDupCdbhemNqPEEvI+Hhz98eAnJgr58O+Z5WSj2cVVO1qX1VKoNzV9AGhwFjKd14tyX6ss4UvggRQMl4k3+MIT+j+bsa07sgtXGeeYR8GXYRVJo/YTc6scGTqxgfi1DP2oEOf+fUxkZvKaPBDEBZxfi7dzKpiJhWlqtBBNo5+0+SXwCgq+r8C7SAvrQczM2ou9ySYTjx+HB0qn0B5VZl5FvN9ZNBIS89wC5MTqrv3DLqWoaUvdtPsb+KnNjGwy8L5GOpOLfPs9LMhz/Jcv6f8OP+fOIoGgMNawxKCwPOxiGaSwTX82uf77TQ/rMmXPfLmqenpgAyEALhJGSX6/RtK/gk/e1/+f+907bRmS92GB+2DbEAAA==" />
<img id="flag_suriname" src="data:image/webp;base64, UklGRiwBAABXRUJQVlA4ICABAACwCACdASpQADUAPtFcqE2oJSQiI03BABoJaA27Q1TXqu94+Gf+A0QHPj6ZmrQANCw4AVGcqFftpndZV3iE5P3Uxw9R7uOsi6uSzuEtrcAA/pxzdxqQs8KRoN40gfvswoVsZRr//5BjQMo7cPEKwXB6N58Vzn4psUxTWIIg1jnk4bdeu80u08qZIz+AR3pWhBUqCowjh19hvAkZEkEhqeI5XyavsKSXvTSE66QBChzrM/qGZdo+BBzA/k6MMVKZpjT3htwWzEaXxjotGfBXekjrvUVkXFEqTrX5voCwZ8rkv5QcAK8/lBwQjCQKarTPBr9s1RZh9++fv4ebVMPjeNkwdv0ZFtxW9LsgwG0YKPlXtT9N5x0NNajVAZnNDCwgAAA=" />
<img id="flag_democratic_republic_of_the_congo" src="data:image/webp;base64, UklGRjIFAABXRUJQVlA4ICYFAABwHACdASpkAEsAPs1apUunpaOhrrv6iPAZiWwAzJFBfxX5AdtZS3qH5R+zRWX6N95uYqQz6p/EvmnqAeYB+hX+C/nPWR/mv+y9Q/8p/1/7M+8V6Mv+R6gH+s6gv0APLk9iz9s/3Q9ln/zdnVwJlmTnnhkUQb+DfoxwOBM2R9/PsGx5Tu6fvRsr+A9xOkLzFT3x/mP9Cmf+mvk1r7WgkZnD2VDVajO/kWSmtdUVVhJ5+6DBlT/96QO89CD8VCllabeHVQS/QXV//2uX4jIhAwZf5hYRS+V1PnSrvCYQ+3pivkn/1A+e9fuAYv45AAD8gGzKrd4kSlDpVOHob5pLAEWlgG6qxad+08TjMwmWS2YBLk9C+EeCokMsfmuAQ0CFrBgqCX+RkH1xOiuqzYdAY4ijeP9Frn7Xh+NhTC2ssyxDNdCGdoANHC/icFJydG3b3dYDrGWXiZCp961/1nlN757+mEIwlVBgQ285Q/1bff0eXJ02dPnfSRdumKk2cNsKaXYdtMqhSrTE6QjeFp4A2i2Tadqq4wuarFV9d534TURFadh7yIilR6i5hq6dfS/lN0uthuZgUE+YYk1J+kRaFZxsEAPvuKS/3niQS5trS1QLtrO0ptHvAd+Pima8XzM1/DSpCaa/WwV+9tdHu+pKC2zZ5w4tZXQcP4SExenTb7kN5JK8OCq9DBfKV1Jj7cHNXAO9OJeLrfn7PNZg5OrUHYmWvuz3GruMdGOSn0+XV9XFn+/nS0mNKR1RyxUQynMKmFrfqj9hjClR6HBkYfTwcLuxtjaL42btxTWoVmvKHJ8YWCUPg7MH+vCSop3JWiqXA1vJ6VIVvHOShGUbOxQuC4eJlYSMSO5N8jUXMNoZiuKZ9QcyRnfkXJjqvyQhO7Hng8iGTl1fdXVhSYAMYRjcRoe7pHn7lxR8rOhkeHRi9H2L9fK9J8rLez1T/h6eYlIYSLLWvUb2YNJy6Q+B6zArtM4oDRpHXiNoGXilNDzypXSP/7G56bN3gEj5vXisTl5mUqeaYEEqDTgDu/wqF0J6Lv//i+n67cma5V9D+si0/2q/uBNBi2BZtsXArVdASnUpjcX28E6HVJykLdPAG/BODiTl0/IERUPx40ApXYDu6L5Ip3Grrhr+31bPpxt4u/fdjCBlFJhjdvySuJ6Vi3akBQktgV3S5nix239zusYw1mjLbZ46dIQn7Z6KW3AKtICXB4cxWTCcOmhSSFKaI+HKLv8GIhB8vd71M3r6F01j6WMIxuI0Pd0j0EqRd1DILNFGycjZsCkerQ2m0UcNQoA25NOprEHJM8iuVxD+L9nGz+5Ukwmb1BUAPgeswIhPqMDOhsI2dQTkFgY/S6qtqiU0ELjZ/5HaYf1h44gVoqP34Ir9jUSiBm3QfezEOBAUjcl3eH79xqUv7eyrhBTZDHeS1hHYdHoU1d+Ds9OKjoKWC+4y8GFwftnpIQ1n0eJu3zus0Vu6OE/TAYANdVunP/MPcngxU7MFbdGzOkNIV+eHVk/RhZr7OsiNoN/gZ4EKmXSHwcyo0B/72MeVunblOkdq3lCPUa2kzd2jdwJjn48ttkx4n/KW6GKba2S1uZzamgx6dZHAWgd26LlgSSSQJrvcm6T7CAAAAIQgesJWre2eMGqqhkFmijci4OknwV0+fAzae+RECVtyhrAQ5Om7eMtXCk2OwKtdvEq6HgOTLeW2yu0m/+WI+kQndq0sXVQmAEkLi2uJMDAs4a31r7i1eLpAHZ6hUAAAAAAA" />
<img id="flag_lithuania" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAABwBQCdASpQACcAPsFOnkunpCKhtUgA8BgJZCzAAgCuTAW/+BQWIZgHJVRCSgbkonqvsP0AAP7uDvrv/mpcRVdRr//+YJ+/27LxJeGOdUy38EoKfM9Ghr0rlYuH+n3jH55+Seg7O1ydHuZljt3DZX+0ls233e/7SWfLzM4ERYAAAA==" />
<img id="flag_serbia" src="data:image/webp;base64, UklGRqICAABXRUJQVlA4WAoAAAAQAAAAUAAANAAAQUxQSBQAAAABDzD/ERFCLJjkLz2Hroj+BwC9A1ZQOCBoAgAAcA4AnQEqUQA1AD7RXqdOqCUjIia2bKEAGgloANTFQTxeQKBAqB6lNst4un7Ae+B6FN5G3nJ9BmAdlaYEq0GdeMH6i3/H7HG966wrX0NgMNDQrXRUfLzGUuDT66v2AK7jDwSHU8vL1MWYpKmzG9eCmGwwaw62tH1a1rDOAAD+6WkVklC9H/ln/4u/stvSyNaRSDTyC6i6cNC2zDYmUAM8+P0/hf2G2LPpgeg+XEQcKSJnMQUisH6B9bTBw4nW4/FtDen3iB+HTi+BzFSvJ4j4BJBPWH99urKxwakgKBeixg7OSHaN3wI5k9Vom+JedqiWoYCV2aRL/AdNFhOHxVZJQvRydgh6KF61W9F1jENSHP23F1TwsMzENuIiqKihecQDSe8ayiZeUF/u+rgA0N+DG8GZ5Hcm8NaYZPVr65+gciogSVmk0/phKtlyvfIMVMfBWBRhsO/Caxy6KbyemjtAesgc4GvYMgWqw4scRk8bWSByszLDOEA3gkH7MELKPRCtLgibauUQ5ppP6klrr2IbHVBBvGzw/LP5js6Lx3GBbIf1VmkLR1IrJ8Kv4BL/S3xCFRiacd2bwcUFGvEattSeRbO/zKgeFKiGvZdWRkqMZ4QbCJB9b/096drqBGOtlhGgklSN3dDWRhtdT8kndAoGXGZL9qTwOR1wg61v5qFS+ytKUYIf4yVh9sh1IJ4ZV5vYg9hzrPT4lwII9b4vsD8Tnl6mRNuUVFrP7erMhiWjw42QwxvVtT5sWaAIUndH9cyM29p+hlcqOxBNgqjPGj1Kyirw5kktX9dGELr5AyJRB5FfIsxbBAAAAA==" />
<img id="flag_ghana" src="data:image/webp;base64, UklGRh4BAABXRUJQVlA4IBIBAACwBwCdASpQADQAPtFiqlAoJaOioawxABoJZAB6I/KN7u8QMEA9dUWtpWgvAI5lLQQKUrzU3gYzQ/oSDzpaowT1BNuwe6QgAP7p7P//2Jhzgo///q0P+Wh/y0PT3sNW9HXpuZsom5HPUcwAN9p4ToizJpoMjPmeKfNay6RynnamcxPzfrVEhPEgn+HpqMX7QZiUDDQKjXJSIJnxuP4tLHJChBfkjOLqmYw3od3SxjwyNTyKd9K50cBWabxDTlyA5BLnW3HHl3HTBp9QTrFx7cUVmdvgJnAP+6PNHGuxa5weC3XNOuNWN3GLjqx3auuQmrqg40z9U6u28ze6gvrY0J/cQGTpUhnwEhekxlqQLHAAAAAA" />
<img id="flag_monaco" src="data:image/webp;base64, UklGRnwAAABXRUJQVlA4IHAAAACwBQCdASpQADwAPtFepE6oJSMiKb1ZIQAaCWMAdIBLALf/AkKlmjXTnb9wpUGcor4aenIkfgAA/q4X//4VrEhiQrt//+Zo+k3sh5F9aMADr1PnNHAOWOpcpCd/4itcFCcBVgGcqR0jhOwlC2SAAAAA" />
<img id="flag_swaziland" src="data:image/webp;base64, UklGRoACAABXRUJQVlA4IHQCAABwDgCdASpQADIAPtFUpk0oJCOiKbgNIQAaCWwNv2Ws3ggmlabWA9QG2A8xX7D/sB72emc7zy0AO8GU6DXzRPJQ2sHYg6wSIjPQsJhINW+GWA7YzcQv9r76/zDhxyECeH9LW0tQgtqHb2JqsyftVLc8uOuQIvNLn+w+51NAAPcEGsj3l+7LK9xmnP31K/punlG2ulPKNu4egv7L44Wbfjv0YReaHw7y4R/hbDGLBJ8/ONa/YRYJ2i3ZELM4Y+WCuehWcD+MboeSzkQ2iIAMe6P2DtVsuwYBsEj6V+uUtNTnlmrlzeaj6zWqYic6HJlKHwQJ7F/4kvflin0QKRDNz4yCEWBpBlD2USrT+E7ovWWspGOfp6m7suvUkCgvpTnmrQtRHSoCeGAgMmwckownd7y+0pMPR9v2CH2XcE3OYXdG2+/pGjPCsDKX5LoJOOnktX+F1eStVem/7rZU27pElEfiKRJS33n4XXTGl43odskqjqvzDkliXkqL8+r6KNO0aDPQPU5Z7f2lOeuHDYYcNjy2vyBQ28Ex7koi/wX7XMn9vG2Wcav8qfbnNi+z4LQi1XMVsVMe0Ot4WENWlZ+fGC1Ctu3FDly0S4PcTdl7q98qQ8+2Ex9+TC9UfZrrZh43R10wZLUlfADBkrPwd7TQTWmiK7dRcyyJNiNt+AXjKSpvs6rqqfJZh9tknT6yoEUTGAwTzKHEdmUOZGrPQJy/fXzeVjRj8RPsj9G8CziNSg+zfCM6D26Xp/fzmP1CoU7NPiapvBUhoNhd1gZ3QMl7KGB5sa5PNK603hcU+LZuGcnkEFHodOKXg/uU1PmswGA5GKIAAAAA" />
<img id="flag_tajikistan" src="data:image/webp;base64, UklGRuAAAABXRUJQVlA4INQAAACQBwCdASpQACcAPtFWqU0oJKQiMRIKSQAaCWQA010AFLzWTQBuqIXfcL9uTGsP9Ar++oO50W361zyPe20dafciXhsG1wAA/hWU5v796O40es3c7XvaXz/0JP/+CT7k30hw0IfjagUOOAd07OE1t+12FcYnRBSmKVnI6uYvia5CJrlZ4tmWwtYy4e+Pc+M8Pd5x2LHJDgUOe7sOzdf6dI34sRTSKNMObsc9WEMoPmCpdrONJ+hX0vBsP9eh87+5RgJpdmxKKqUXvK5LbthPg3azfmwAAA==" />
<img id="flag_gambia" src="data:image/webp;base64, UklGRo4AAABXRUJQVlA4IIIAAACwBQCdASpQADQAPs1SokunpKMhsYgA8BmJYgB34XIH9VAhWBkxLsGHaQ4Ud6LAZ3y4+08ulAAA/uUK//1qyZyZKb//5xL/YH+gXc99OeO7N/v+5yyeplc6ud3d33s1z+hxpWk/g43HsWKM3lUt/jmjsqw21D0KDdAaQfln6x3eAAAA" />
<img id="flag_soviet_union" src="data:image/webp;base64, UklGRrgAAABXRUJQVlA4IKwAAACwBQCdASpPACcAPtFoq1AoJiOiqJQIAQAaCWMAd3nOAbxQRDIGWhcyJsqdVS+exC4r9XZueTAA/tjL1tnRfWERqZnX7BC9ydzfxrtN1it66vRq/0scxyWpCOvf/X07wE0urBGdiP//5xL++T+Aty5Ml3fOoYJl+HTgkfai3qGDo7tj91oIJ8G2rvWKGfKIFNf9LWjnoXuLp2Od/7Zd1aIPhYjZp6gR0qEcwAAA" />
<img id="flag_burundi" src="data:image/webp;base64, UklGRnYDAABXRUJQVlA4IGoDAABwEwCdASpQADUAPs1So0unpKMhsBTeYPAZiWwAwcRHyA+2eapbP7l+D+SuPHCA8Q3pZ+YDzePR3/yPTV6kn0AOlT/dXCKX1dslzPv1diU2rPrSVbTfJfow/rwoKR9td1fZZKGCqD+HjvDlJ4dnPZ4es40LG0OYSy/tgO7LXuOYKbUe47anM6+lqqDJOC1KnN8edFWsrICaou70t98paXDuXonzAAD+4ds2nKD0OSv7bGmUnnnpW2FsAqu5678Hll7GkxdApW+KAzoSpfO9qZUKhWkWax+VSwPVTXn6qK4AW9p1eCwZ13JJ8XG9p0uPSwQlvcz/uppDBLuPDl4SZ8N6GcS4Qp2IpOEcfvi7uJvx+adAfQx0VvFUaSO4MgYcF7kLwEEGvZGpaASF3k0Xs6pckHnvSKTQRJrNCLGzmejeu7oZ2M1OyZRw9Y8fZLqZgs+oQGOxd7Mokazy7fy/fS1iiz+E4U4YFLlyypnGYbcQ9V4P3xpceLwN795LIuczpFBpHoJwbNQwsG6vJNwwiEWEm57A0ak1lfAphzTvZlp+jFzkipLpHbr2rrfRjBDIq+p5rBm3TPIUK9w27qZS6M1Q6gVhJKddOQ0ngKTU66GMtq9hiNCXXbP+/9wA9goC9pHTVPqZr9eqoex7YJ/r+OD2hvu/d0l2YbXJ91CMfLoRadR5oBcetDjsaRwayUO0g7v3kpWh3oOjn5iap5sbCwcr2xeL13NBmUqLPR8AAPGr7Rcrv/0BxCAx2xGMrF3u6PwbgMLVgdnsPi++sZPt6pQmT/OMoEk2ehciefgobZCxo1lo/oSTkqpTN1i43fD/bPH630MGNL2+iBIt5Du/3Ip2C+jRWYqMYPNkcWqnO1fRUQ04iaI9F/+RZKh69TC4N5gbkvB3Qx4wS4CcCCR6hOhcDiZ+a+ba+Jf3t24BcpZP2GOp1ArWtkkB5dRCrKm/ta/j+JFCg29TdR/rDS9QtZTNcAhR5yQN9z8bmLseqTl6G2fDZ8eKFlp2JfQisR32OfoGiZKJwciFWpXvvWaUntjKoBdU75DhpWJFry/V/mK2fFydJ4h3+LZL17frCvq3pCyFM/X/k37cFtBZJmMawQAAB4lPbWCg/wNd9B//OxTT0SvLO+AwLVwIifHj8Ue3yuPMysZl8/8GSYAA" />
<img id="flag_aland" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAAAQDACdASpQADQAPsVWoUunpSMht/M4APAYiWgAd9HxT8oP5nzfWqfhTDAsQH9kxBf8A/m3+U9nb/JfsBfMTFABAxdi3cFLBCQ0e6udb5/i97/ukxDB4JNkr9ApZ3MZAsWBEGRWxNEikAAA/u6mP//a3bE8P/8P3pnB7j0leb89Hkz5yBRVvJAH4LI3L/j+DGppoBg2RjS9/Iuvaw/J0UQbepB2dSdX9XyoC/OAkOiEc/LB124pBvGkA8+et6LNWY1h+scDOzHOGufCzBHbUTIhKVLPvgcsA3dqdFq965Xz7DjVqFRikxgbe279/20CtuQU6l5+H0onmUI41G1/8ETjP+mc8rkK3V3IPZnTJUbVg21CwaUmTYrj+k/GzDSHDQHv61OwK0wznHM0hVlyOSPjiUMf0sq9+FsrT9myMgP33uTI2CyR7EPeMs50PfZqA5Hr/kcyw1Ze+/wYNORftfm7Fu6P2IWlGnqc2Tp/xSaH55L7w9Swfw6XTB+bGRg7R0MN8HfbD3PBxjg8g6o1vEAAAAA=" />
<img id="flag_saint_barthelemy" src="data:image/webp;base64, UklGRooDAABXRUJQVlA4IH4DAACQEQCdASpQADUAPtFSn0woJCKiLnxsWQAaCWwAlQJTqzv6FM4B5wHRVdQBvJ/+B/5/7AZmbt1tjnlBgdgQYFJv5AhpvjZ1Bejb6NP7MpvDzJ26LFayUj/KkuEE0TRXBtz91OVfPEA9V9XZElxX8iA7WjDjoeiqait1TJtwYuya9UCL2oYhZbdvMVChmTvFbLpyZRmCAAD++gT999gAQvCw0ag/rIKAcbaVPBCplgBCPg5X4Rhc+9KlNtk9K0Sxobw7cfX2W82uNj84Ji4lfb6SlmypgEQ09dJEDdxnSl1n8liGTgiKVL4FwdNp/2guXNnvBpMuvnVTxr4gBAnel1VpCare79xFkByxx4Fj+w8KqMmZdMv3F01tVRuP6twQqAE3A9Vw4LpGLQoMZ/ZP3zjh87GtuROw4AlJPI2YtCD5mhZqTBj7Qj9JTq3rru51ZDDIiTi2RF9pQA6nv/jfit3fhGEaV1TbCg8SiHf1TLdBbVRzqUGY68mN9cAI2WtHgMsMRJUpOzsepovJ9NPu2jHMl5rs1rF0hYxNnVr4WzAIKL6qeTdSHSMzJKnhPopafD3Z0HyWNJ6qqOYTo1RZnug2uRQqXGcjnynlaeJ9kn7HnNULidNn+g4d3nACBliJVRFQ4dVeoPRPnOKXmSOYCCxpeDp8bw/yOLL+9ynh+Jx8C9p/mOYoHqanlbeJylcOsW6U4AxZKpIBM3ca2Du52sPnj/pin5KE5Me5YuSbPP1kuWyoFWbWTvljrbhJfVHfa1IusqwhHiJbBvwhBMjHoVByoSuWPLqbuMn7rlQS/zZf3Qg5/6EYuYhg6Hk5Qt7shNVSXQy6gsG8rOUfoEeY6uXwwfiThz2UlZdVCvp2V18eSddESUPS9EZeE+BOD1QsdElknCO6qkCewrU5ezbjvPRDLw+fWKTtMsh7xz7GLCudHRgDuBPcAOExcXuyuSLhzRsR33RxPnRVKFz4cDfWx51tAqmXcDIFD0DfA3rJisFOMI17jykyAZh7+ELUBt1Vyb2xS6DaTgFcruYCraB+vyj8eyrrb9V/jSiDyUnEIaPU+rYdqR7Xfc3ThlLeTcVLgNSO10O0G0rM8B58ndsKDxVmBiBAmTPMqI9U19qxlkeZRrc8qn1o+mEDU90Ghb52UhyUc68O7JzgSdVlJATinIUwrG45ecOygZAr6pTyAAA=" />
<img id="flag_moldova" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4IDQBAAAwCACdASpQACcAPtFgqU+oJaOiIiyRABoJZACVA/gGuI9P4+EzFQ6Wa0RFxNdnnlX3x9z1JUmoL9HQ1hxglCb1N9ebZuyOx9mqAAD+795fhbjqt4GQ9+FL/Ei5xTNI1Gv/28yHdaUP/t5kN57vlrkMKdPlycSX8WgFm/nhErAjMsnuLDy6cGkfIDjxoZEjdkJ4fw3ENyzrNK7kd/Idjx3FJcT2wLfhu+oa/B3AyA0PC2Bd4712YvxjiUhWKS8bU6P56PqWbY6AebKuwdyACiQfX/zYQomZMW2Vvc5sFKwa+AZ5F69NHSq4uChN+d1NgaXDzuxryP2h5XN/ZZRDxn12B+dcxxs6jBlDYshao1guy7y2AqP5UpPFLwzlucJ88jyVj/6EV+ivAOxEuyqIBhhyTKoAAA==" />
<img id="flag_malaysia" src="data:image/webp;base64, UklGRuQBAABXRUJQVlA4INgBAABQDACdASpQACcAPtFkqVEoJSOjpFgJ2QAaCWwAeDf1Xjo98nwrwNuTaK/0A6gH6d/sB7+N23fsh8Kvk5N8aWxi1VPqve8fqxaNcOs9lUkJ2iJ04o59l4Rfh8O9Hw8NzNouSEkMjTiKF8AsAAD++EvXizOCD4ks8vJsmlf6dlaQHFGNfn2/A8ud/9oMel6TWx8z11EbW02JU//e9CMTePv2x7Y/w6sR/0YFj+KdnH/4CacVfBAJ24xaEfMDRnXCQM2jGvFHKgZY31CBYHQuhkVAC/DDKg3r/wKDzBGQqJuGkrYW3YNEPMEFORvnULvEYg0+0Gvfk58KoRlrIoNwzpXpZ9Gd/PV1YzF9BAGE+LWk+LEw6aQ72MS7xf4NQGbqTfplPWdZZ8RLF3z4IhG9A/ldBb+A4zx11kFQJgtwLxWZJ1m/dKPLatTroovZ5l4G0xIZyfi6Zw6UxngzrEZVHnNepRwWmO07iBWgOTGhCpfC/o/IO+EZ9xcxIiG9/J2Q+Y1fPByAVxNjRxQrOSJT/Ym+paq631w5E2SJsdQKy0TQeMH/6fcZbbuTMbec+3XnKm4cEvU5V/iWd6B7DJnDDsmmstfW/ztVwz/6bbLs5oCjoI8caKcm6AAA" />
<img id="flag_iceland" src="data:image/webp;base64, UklGRpABAABXRUJQVlA4IIQBAABQCwCdASpQADgAPsVUokunpSMht/M4APAYiWgAeWnznin9fY2r4BwD1AeXB0PP4B6APNV/G7LAPPSYhWIF1XDL4Vww7Ao4VXqUvA1yFn60Qme09W/d0ZUpB8LfGl8R9D8ZHIAA/u3O3/+jo9kXp//dzVIKvFPp+f9Ae/trXehLn/jBHmgul3Vu2T0SQwiD93+c6LvwnDr0Dk4PrPoveV38vVOKOI4NDB6R/LxInIfy3+ajX2a+iWYip4MCWL1iyQWI0Uh+jtZpBlLtkA/m79/KMdtFD+UV676TL+VafFj2yAov5o18jv08eczsv6lwEgfPXkolXCwTSRCPh/J81i+6e0u3cduqkHtK/wZeMNZ1QXTE9RsfTuPjUY7FEwOvAUH6l/yO976FaqocRf2RcCAKVd4L7XHIrOdpZNT0ejMcO9UZ5MjA2eTSmAx0FHEwnI5GtDuvkYwgY4Ft9+HRBueK7Ep+TV1a5dFLfbZW1hegAH9ren3T8goC5RD6tPex6a9jsAAA" />
<img id="flag_martinique" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADQAPtFcpkwoJSOiLmgBABoJYwCVr08AILn0HYSB5tT7uF9cmn/IFgxNlHsAAP7u098j0x3Z98N5BquPQ9tsnWokne2arw05da3TXFi3Ts2ZjYzmdT/bHHA+P9D749jjgfH+hr+RddQAAAAAAA==" />
<img id="flag_grenada" src="data:image/webp;base64, UklGRnICAABXRUJQVlA4IGYCAAAQDwCdASpQAC8APtFipk+oJaMiJEzpABoJbAC+fACLV5b+QHNxW/+b/OW8O8wHni+kT/r+n/1AG8sRv+yAigx+3csel71vHEm2EuzmEfTq69Xu6ik4uJfbCUbWEwQTf+UytLcQVKZynnESY2eCpOxk5raZWWi0mTcOXAF0cGLcaQAA/XwENAL6c5zwUWqI6a2CeH/+UpMsCKGlf/9CRijEKE4JDoDmCoCQHZ8JPxYHo/AdpwIid1glMzlOYNg3JoJlHse/Y6thg1IFQrj4XxLMcHheZvHnnbGxq+1tKo6lx7O0zX/cWgPaY0eG0sIt6ElKhCWj4gDFv1WHAIZHTCr/tYYLHumF6SkHQbdsJD7cdiO62yQCcDpMnP7d6ZTntKa9cRGzkC0MsIW3V5RdGDF3p6YW1zO6lTrUzyV1d6dZp4qCAcVSCypTi8a3kEGjRaJ2egHsjX3UenVqLPFr2firfEV6WmUgpDLnOcSfJNbUWt3H93QK+DffPM49d6GWRAUgyury5WsPO5vZJjWzCz/AEoB6vZF9TPCO6ffNOL2a527Ao+IDcv75Nj5tQ+Mmr5+E7hNnXsr9pB0NFEpT4cubJYxurs19sagrh7j4ja19wW5JyOiRMfFX8TP7046Zzy11DV59AMR8L6/8SFbqmOrallFiNdxAyOjd4KjeWT4AitLrTXbGCGJoW3Vw/UUzGZk9D53HLZFxqDqW07FEbgdcPbFFU3StgSlAtzdsBsUvMidPNjVa1TlJkLziyC+KZzddCb1Vf4FShbyyauR9guCSXhR6C4Ih5cHW5haNRepzSBP/hAgAAA==" />
<img id="flag_fiji" src="data:image/webp;base64, UklGRu4CAABXRUJQVlA4IOICAAAwDwCdASpQACcAPtFWp0yoJKOiLNgLiQAaCWwA0blBPI4n222mfqA/LW8A/YD1AfsP6I36k+6LeAPQ58sn2QPLAueGM76YGvyytKtM78e+a8FP/RJLZk4qgRS6uA0Vef2OqVDH+Y/97O4C86RR/CizbrsGUAJtGgk4fqpN/5BHDBugAM49rLWriXfXpv6VuAYMm1Q4pb2TWntrd9IrievvY43u91ZW7aJA9laFod6p0qDre8kMh7TS4d+EL1ccQDwjFJQ+Mve00LLDTrc8mps4Hv1c2kHFkbePdh220+xU+xLrlPCMoLfVF+hHSPSVOUdnsg5f5kE5RjEVIX1T9amw4J3wz2NEV7ati4drLZncPl9vFzbBX7gsVhOSxpk3BovP7gxlTaevMIT4i6cg6f7ZWLAu8DzL+6wn9n7NYe/XOdwT2DwJK6Lh5N3EubiMsc4lNNSGzxKxcoqo75B210s3vp/9Ixs/OTt3z/lnOho3R++ts2hFyajoJbJRVtiLQq3+gb16KqBQ+fQKYoDZI4J0clkZw0ggrowLhHcacEQeOY6tC2lDTbvF61EhUlvZaC3xETBfH83hYvwvy+qqEZSEnPscjeyb6dWXjrhChgnzikTEhWBF8db0fvp3uhCtG9kuYyjf0eXh8uEmRtQHXwc5vy8/MKPkCzwj6FYS9MjmmZlSP6lpL/49dzJp0ohKC4juy5i8wjvhKjxm12vHWlBZjp49IZUXkVHecIKyVwFSCqmOgMea359eUwCHM16/qOzmEF3I4q6VLtqu6mwVIuy3SkZtQDT5fhl5u6yG9TIIZ/7WoLzeVYE6lHz0CeIdeMVKcVIWhTWFWeZey2ckH2Qh3eu/xYd7nDFXaAeVJpQlhsUiu5K/zdKwYmsN1As2U2ctzzS6dc5e7iflzVuKH9GZjVrFq4KuxDvCEtfIinzCzxQGBc7nqmEiC5OjSojdKX4n5pOrwk0E77wYWxivpkAAAAA=" />
<img id="flag_british_virgin_islands" src="data:image/webp;base64, UklGRnoCAABXRUJQVlA4IG4CAACQDgCdASpQACcAPtFap0yoJSOiKrmcAQAaCWwA0ieJfEcPT0E2Fy79Rn453gHmA84X/AfrN7gP9hvinPmftv8G37i1zvGpNLLhPcaNUlgGzOwPq/550+2Vz7NbwC2nMS25FGImv+z2tCFdpz6sOsw+RJEg5oiPJWa5EdAgAAD8+d8k2GDFGf9nmoQrud5Ln6ZwqJ/Ar1dvvw2WSyCI9AsBSD5aZEOsjdC8jk3T7uPqTfWP83uIK/fZpyRLDRD4UsJtwWrruIji0VJu47ESEKOBXEcuJSazoNJV7Cev1yrL9Q6ykvR/ne76MG2/1hOCg1jlHIekhLcg+nlJohVbA1y7rUJbuGxPnegWvsS8yBf7jCwTxC2cJZ4vArv/Mqnjt8EFRIMhfMGXTkNeLHlaS4JSwHsdfW2+hzx03btGnrtzsdijMLzfFPXo6j0ABfJ27fbUcB3Q2UUyH96+XRDr69vIpYBKPNtVT/obC9sh0P+swtn4oP6UC2JrYiqV7EcMd0qyzBv6OdxT80aoI8SsOJhFJ111ZwZaDH6nBi3OjT2LqDKuHV2j5YPyntGkucXXJz99ds89Jrf/D3hpJZhAyNBXbnulAmXZE/GteC4QNrO8UGEnv7RyL/MPyaOGheP/TowRUmD3vGRbw8njx9fF14qzLaX+Of8iFilWbz3tzVCxEKPm/EqwtVq2lioA4xt7cOux+gqWDj88hygVbgycwcUaA5UUprTILQ35F3Z3aVnBW5I/BJEVCsdvkOyy5u4198oIaK30y8rStYoSlt/Y2un0aRdzLlFQUSWreSOz/x8qJP7YAK3A+qdejm+PAAAA" />
<img id="flag_vanuatu" src="data:image/webp;base64, UklGRnYCAABXRUJQVlA4IGoCAACQDQCdASpQAC8APtFYpUyoJSOiLvkqAQAaCWwA0m0ANbw7Nxm6jvUBts/GK9f/z2PTA0sf9t/gi8pyJ405b7crjgBpPmWN5GH1Rwa2+xgnPAwBIFU3jk6mDp9htuTLPP2bOpHLjrBDjfhei6NI/RJNc1F3W8AA/unLRpwINDE7oBDylD+fB6n7xYB4c3fYgin/LWhs36FdjzNyZoItU6Dm/ryBWPqgQ9tJUFtE3609/53dKkmzGqAdO7A4HoR5AvRN7G1r6uFvnjrvFITn0ggdojMba2uGWv+M5ZADqKC9e1PTFttjBtAiuzcKKou5XdwkUarSOYnpfQ2+f31r45RxLFqcp1kKD0ZagFeJ2oeWvvGiKrgkV7aBaKtTXs63+VnFCOX5n5YBal/wrUc9eEwqiEcmB3/hJZsp2clA72V8uRAmvh9+4zyzVpbjw+1KOXe1l0d2pSTfFvqdW6o5NTLllhLvWFI1Qs7MPSWLM3q7hHeEGUBxTgs7iaPzYAwCcSwibL3fXO8JEhvBLswtg2rvzxOawt8J4imFHz0Y7R5tQWFaQ9rlj1O43aOK6WorKUTgyiF46zueHf7vfEcOgBkVRopiMV2ClXBBMvg2vpKvLTkDgzOkx9l+Oe9pHx5vcrWW7ORMGEzWvDbJa0c7sQ3bjH23gwBjzAhorjL77gL5su4gpuPdx571BoeKZfqKXXwd2AWyLccU0d+o9NW7sOoaJAuF5oQbeEAuQzs+QP2u+HrRanw/KilTyWtL/fNJxtgvLQxuPo/iN4spC8JaDg+Vx7V9bpJeI3n2wIbergA4Qo1TAKNCwlgAAAA=" />
<img id="flag_pitcairn_islands" src="data:image/webp;base64, UklGRiQDAABXRUJQVlA4IBgDAAAwDwCdASpQACcAPtFSo0uoJKMhsRYMkQAaCWwA0XPgqX+vbpewD1H/jzeH+YDzc/6N6mv9VvkvoAeXD7I37l2EF4PxnVgQZAq2mgeOAZSUuVoIqskiP712GXGlnCEIBphY66WuAJgxcHnQRyJYVEOLJfL4ZezRgzxGJOzKcvVX9wUAAPa4T6tp46Ki4LvO8IuUJwYKspRRtV8M/mB74A6LljRMqDwNC0ET8cO7dSVoaA3EM8CsD/v3foHbzV6l8QoOreAq1WKNbWNJjGfGbIGp8aOm5F2is/tTmJTzsoxhs2X57jzbP/CMQTJd2ZFbx3P0XCu0RH753uykbd1+Gc88vQBVKcYKkUduresTIus1kVRxAgCs1xP3p3TZL+8t7Ewsv9lxBYGReT4v4uxPVg5e0bEssL/0jU86O7rrgJ08Gbw4SdT5/RdGPgSbYgzG5Nk4PhqTW2cvQhZ43NdL1loapadA4sGk6PJxeeH6Xn3QcSYxUrQNYD1d3s4d+7KoVp1ZD5nAutmc2TDtssW1Vor3/BXx/X8fXMNj11lYPZLwwB8gzZr9P+ZQrPOXI+/Wkd29RAB8DYdEGjj+XAHOImqmqgPRqtJspxUWdiyUUNO5/9zM8+iSUMJ9hjZSfROkK1v8hWrZyLqLII06jfjzSiC1VlZLhtAcEHIzl7dNyxN7KFMWWz1Bxue3WvzirYZwY+Vm3fUBZ/5W9ZJyqEmpLXJpHvbrT7aRrXIZLfFebo4aB4OSbngPHXnOX/AQeoSfBpUYhZ8422xfo6TJY1Wt4vQF+wT4Zy9Kta5Lh4rH7MB5c8PRUqYm4KmhI1ewb/hRUeTJlWYzbAupnOn/oEUPOPuZ7mMWoBP/tmAIx6cROGwwZzuARDwYB4bbSk1atdxmH/Rnov4K26HYgNOXZBEpcKYnjeKw+hCdyKrr6ckLHJ7n+WU0gwHp3MvS3sctVWcftczjuCLYm2x8LzsUIstaEn1Dh1ZXgqc2PL5f72SNIAWXgAPtK7JgdmGhUoO+PrMMASMMu8MEDTGSEU+Ly8VZZOuCCYancAAAAAA=" />
<img id="flag_angola" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAAAwCwCdASpQADUAPtFeqU+oJKOiJngKgQAaCWIA012hfquqL9Pvw2HOgA8YDJL944IiDeIFTlXJcHoMetj7NJNOUSpmtYlrFdZFqHcwPRLqDPVNqE6RvD+kQ9lU3lzNvlQbGAD+6mmoxztdlOzGwV+rQ/1aH+rQ/cqqF0kNSgbG9n9GCxwnOfBQIp0+zT9sbuGF/MLV38G/TRpHA9vV6wpVprOZbWUw1iQ/mhhy/U+gqbigCgVHEJQMLsYq2JaW1MmVT86HcX8kF687MdM6H3QrahDkuWybWTu0rIuQEEAMOKttSxRj6u2bJmf1mPrXAYMSmK0YXcpVV9nE6f7b4eUvZM5HdKM+xkzB8n3ABBSJLXP9obPk12ZLiyyEdIV4f5PADzA31uEzz7e/51Q/koPFZRiH+yIpHx5nd13TXMBS7QyTCi20HtpLoTQey7vcPsX110FrwuYRx57wI3qx+BJ+b9l8bkcHbvTatRN8DOzyaCgYfvW5a/xjZcbm243u6PnmPOCuO6Z+B9rUNv9D8pcEIIzbbR2uNRiceiRAVNKwAA==" />
<img id="flag_palau" src="data:image/webp;base64, UklGRg4BAABXRUJQVlA4IAIBAACQCACdASpQADEAPtFcpU0oJSOiKynZABoJYgDUxYG+/+xxIDbNbgC9YAUtlf/oeSgn5B81KX6Of8we+KGMQJRo/j4ugkh4LFQ1WQS1QADhLZlUnT21VOXofhbJPGXbFnJAiid9b4y/CfmocYW2IM75xmpjgc3E1bSusXcRb/jjz5yAoMEyVWL3bByQbehpi/Ij6KwJMwAQutUQ2opRtKUsEB9xoSprDgMbztbQqqOXlAzi6Gm+XbxAh9geOA9r/Nq3Xd992slVwXfnZmJvXwZjI2jdY3duO32coxo+z/PefLVL39vw6yxMuoISoKC75vP5XXWPODUyj6Uyam/8AAAAAAA=" />
<img id="flag_netherlands_antilles" src="data:image/webp;base64, UklGRsABAABXRUJQVlA4ILQBAAAwDQCdASpQADUAPtFUpEwoJKOiMzQLAQAaCWgA0uWuuW/unE18x+QHqAzgHnX/wDJAPBAuStQAP5XPx6QB+syrmzWm7ECJMiVuj5eZqxAjBukwetVA64b0OHoRgz+P3DhgVoR27L/h9wiuZUnicl4JRgAA/vhNtc6xeecJCNdg+tIDUvDmepvYHwFEOB/hGwfvcgFtyoKIpKmGDnMy/m907XuAsf+Zymc12VJih8fwPunrIQZaxdPkh1snNjqji2giZkji/RwBRnCknNskuDN1FKLrmfVYxzOu2Sc7Y9R23aevc281cn8S14VN32/tsUfAXmMS83uHxLDs6xH7Ln+vr8qfYhAvV7yLYBQpX97cFDwp4hZvqijsXNKAK5Tca0sQ+yQUnxCvgiwad3ChX/iyIb2a8pSQBm7WRhfrNBtK99FcGjwcf6wLBBV/rnZPd2BfqfdgfS7v+ryX3f9XNUo+MwXOVrqBy5hB6T3eI/FIpVmhnTlqDU6uAdr8nDARyrx1HgkWPFM+ApyV2whsDV8pWJJLmCWQpmjmXy04V45NohHLcJu7OZznkAycGuu4KgmaAAAA" />
<img id="flag_ethiopia" src="data:image/webp;base64, UklGRngBAABXRUJQVlA4IGwBAABwCgCdASpQACcAPtFgqU8oJaOiIi0hABoJbADRuY2/T+q8mDs2ZW1vf0rwyD9t/eq0wDeSGcAtMb6aUr9+6d3StYzlRRZl0tGivNg8RMlmoZjjaE4KxYchGpbYAAD+nFPeUdhqGuV+pV1oV7UXZ/8e34wLWfHPj0iQsV7+JHUmDn2QNUI2wlJEE42LjS75RfZwfwrYyAXrtBbfEsSq3ZGx6QfQLQI57sRGlBoulDxgBd4/nPMyWheD0G6vBY5xzw3Idwkykt5gS19VCp2y2v6CB5pdf1h6hMLforHgS9lSe0SfjP2s2zbBWF1l0aQmUzajgEFYSWBKav6YgyKTUbASCqL7J1dr6LpVX4YI/BMHdjQj6Ry04zkolMpkA3Sdpkev0ko8LoFr8kfahLOC1+iheJFyzaIrQ1DLX+bmt50q62/RdmNxjb+Blu8L4uoiUQMEcPvVQ5jQy62K07DbeF9PPDwHXPIGc1AAAAAA" />
<img id="flag_burkina_faso" src="data:image/webp;base64, UklGRugAAABXRUJQVlA4INwAAABwBwCdASpQADUAPtFkrVCoJaSioaqJABoJQBq2sD/M9BL8gDP/7It/7YFKQCvNvv4QCrPFfzkMdd+X52cnWbc2GrXbAAD+v499uI7F3Oh79Js5O/J3+WO7sybwlpFTzPALGsGpKr6zb/w7/BZlR9BJ/a/+CzKeqiNUsYVYBOs7TDhB98Ky3dx5OMH0hNSNBtiBhqCOADC5GUc2IUPcjeOlvoKT+9Q7xMP2jE7OCVodyR7a/9xk28aaMz4P7mUfwei5b59dACTEbFjS9dNBJ/znNhQJt9OEEr70AAAA" />
<img id="flag_maldives" src="data:image/webp;base64, UklGRg4BAABXRUJQVlA4IAIBAADwCACdASpQADUAPtFgqU2oJiyiJNqssZAaCWQA0MmqfsH4zacnA3bq54DngMgAAYYCdL7WbmUMYYESMvDaQ+CDqLfhCPxeQ2xLLRQF0aXMAAD+4cJKRnPZVPCZAV/uX+5d17OJz/v/TnoZHvj79+MAE7g2mNYvAmBemKQ5b4WQp9eBz/t/zAP0wpaOvZ7jMQTkS/hrv/pXZ27A0DEpuPlE3H3iRgbEyasgwOWWgjyPOesEZRc27QI4fnQlJ3txsaAk9nl8ZtywUU7j+zNh2YgPgUzGsem64eXyUE/+8mXxOuSExmY8KzOpWq7vyi1q+iHSRppFLgAqmP/t5l9QIAAAAAA=" />
<img id="flag_new_zealand" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAACwDACdASpQACgAPtFYpk6oJKMiKrZrMQAaCWwAzyVBPS4nyomtj6gPyBvAPMB5QHqi3gD0OfLJ9jqsyN0HgBcIucsPqX7dZXktlVw61+NJorE2dXiLneiuSVf2dLo5LIyvtHdcCLDiCzcobwmeAADOPWjPdibYrKqQbnnduy3Ok50gbwqqtoWS79ZD8U3fvsJOjorGRS44FpDKgNi3P0r+wJXGpy51TcyCIqVt4ti4PNePApAsUG97H9kQahf4GPcRmXKhZRKTsTUkP61uBxNOvRhFN9cRK83+YynbB9SeUf53uyFWT+3GUaxzVtI/f/kL6djdj9vy46PiRj6yDYgrWnyfFQSDT0OeTsyJIulHt4DmGddExUcv0UbwMTrfu8l4QxsFzGxEhR5boTYqSNYMHE+6OoL7Kspqb5mya3V864J5cZnOG8q5XgG2qMT8tqr0SVSGF+++IodYJTrUip0AkNj6GUk6aGH/r1efFswmVNCByHvlXWRVLHbXUmFnXCvpJsTFrvXR/1xNNwvecAOov6kEhsJzB+MR+d4wXTSfH/cPqSNFLBpEQLKsGl7WYReOxj3DLnUt+jYfJOV6yqgc2ES1Mvb/6lLZ7ocxBFBR7AX2xBLi/R+VLHysuw0+p/RXUaynypDhxV5GhSEZ4uW+3uLgpV4T+iU9wO5gs3qZ5eZFiKpbkhloDhYj7x1+is+FueA+o+MT0EighDnps59FPZyiLlx50iEnhFO9NWKM8znJzKAAwYw1j3aXVTBsSyJzXcQdmehxiScKD7PhMlxgM4XpYy/GRLR2UMlae5PA5wojxVkAgZgTCjvNmD39SZnfQAFY3JUEbzAbpQ5182VnhyAlP0+AW+qnlL+j8UEMUAD4ei9j6fwIvy1obqtvSnawGnidbUZM+fmAAAA=" />
<img id="flag_tonga" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAABQBgCdASpQACcAPtFoqk+oJqOiKJgIAQAaCUAPEESA3gDecQDSw1pIRnaBrJP+O7wrR65qizUVXdXCAAD+9gdsHjKatnM6XCh0Y5rdIytWGXlv1jf4ks7POb/v/tiFwS5WHZf/JmOe1kskwSCfbe2kjGP+JR01VC6p/xuhucmVGpdVBfB+fdd0RLWmlUtptkERO5WfyVuw9ZecSz/OJDkUzpjGn4Q6nliyCVEwN7F8ftmXpZnXU3C8foMfH5ChF8FafH1iO33Ok5kwMCf1yZ53aHgeDJ6oTL91RbVEij+Q+zuH+S7K0dAjczWvF3hblH5BZA8ceT/xT7GcfvPIVd0RbAAAAA==" />
<img id="flag_niger" src="data:image/webp;base64, UklGRv4AAABXRUJQVlA4IPIAAABwCACdASpQADsAPtFYp04oMqOiMZLoAlAaCWQA1Lwzegb2dCiUA58ADE3dus3H/Dm5y+Ihaq3JfJna3XBd2Ua//zg2qabKzqTImedgAP7qKv//mCfIPnzQb/9wLKcYbI61NW6LS8CBd+f1vsAsfW+o5Uh38XsSIbgUKxuvk4zPGKQJEc3qBhmrESn/2u1axgKLLlRDtxd14/DrEiDU8R7mEituNofsHZtevOqFaILntYq01OZx0Gz5wuuDX7DtaLGOtqUW2wWXmRdnQw6DBTzUkncfY/cMNLl0gkW1JwlY05U7NU8ddsfXLR0IYw3mlTAAAA==" />
<img id="flag_cameroon" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAACQBgCdASpQADMAPtFkqVCoJaOioawxABoJYgB5yfXGOAZYABS+VskdeY4h0Pf3DcMTAmNeOTQs8iz1srwAAP2McSM+P+aLVY//+LQzD2866usfYm8+n6H9mbDszOs6XixIofmGw//COlI766C/8I6S8axKZvW/Q4JiICwMUjeaJlHb7yR+5ZdS+kfrh5qyIWwuKvqACHe0wk+rC2cthVRTQ1F6T9z/RPdIDHOzLf9fs2hTXpM8Scupav+82VH2K7ddAIcR1gm3CyK3p+apdblT9Rrz6tLO7cDkoUoj0ABEmo+vXgAAAA==" />
<img id="flag_norway" src="data:image/webp;base64, UklGRpoBAABXRUJQVlA4II4BAAAQDACdASpQADcAPsFUoUunpSMht/VYAPAYCWgAeAfwD8jfyO+UqoPw38W5SHyoY9P8BogP4B6APtm918lgAgHh7aV18KKZDwI07EsTZjADVYy0julRuJ1CRZunlXdCJpT4gNtjtpdc4AAA/uUK//+Kz2yOv//+kU/w3IIr8A7UwECz1xNq4n+eOnbZJSt/hFSYlMorL15LquXnBZdS5/nBgqZ42LkNr3xPM72Mx/yy+P0Avw0+G+M+ftA1AbnToVLGwrP+ngAP1+R6dY/k2S/GLoQ/t47ZPxHbGr1YEEaqhHbt2vkHyNf6jdzKejtxox6y/PRREyzsSWcWVKZSMD9x5nQw/Uu/ALd3r1iaTRRXKv+PElMtQ26BIeP7SAReX9gMnvgEtAETkGVD+2nh15MVop7F5l3DzQ6j19mzjLlCppfazMDo7hJjJ+qQtUvQStEk1ZOf6dSLFKmALILwF56EYqX6+/teKsgC19mxRy4vj+m1gJeZvVBj3zy0cKDjCf+igCxsYXPs3JmbKAAAAA==" />
<img id="flag_saudi_arabia" src="data:image/webp;base64, UklGRhQCAABXRUJQVlA4IAgCAABQCwCdASpQADUAPtFgp08oJaMiJMw5ABoJYwAu/9S66gRwK4CVaOufO9592b56mJMPl56FERp4QT9i5RnQvPe/kF+rE8dGk+ckEctcw/eOansBYeltX4m+g/pxik4ZYxP/iAAA/uVJgU3//wrX9aH9GGX5MblywEKv8RX8WJ1r1tW0Qzk2QOEsZIdCl+0yqbBvGZU2gQFWi8kgBVWwpd7i0wHQ6xC/rjs99z8/bj0rCV1Y0Dc8FJmLAU5CitzRSKlcR+cc75lLF1NwAQXf+5tYGwB9CZBFKhUiGuHRZlGpxLxbnSteebVB+SM4dCqvfnJggTGwfCU0hRiPzjPbuY5ldAWczdYGkkvLn9/HoAfDs7DssysB3htJgirocqi/0CRFn29Ah2bvOFFwyIBJXIWuNAkJue7bREPGjcI29q1LvJcKdKdSpY046/cuCs0aaqlu8p6fUvPZZfxCq782vtXIsozz2rhpULBAmCwEcewgGgHgweJfSj0K/dqlT2L81DYjCvPD0kLOmos0fuxzQEAf01idj2s3WAnGP1S2PY/4h2+PR2irKoPhVoCRpfq6BXPVtBHSKcxxQZE/U/df1VI1FpCk93K45NAkQbPWQlJzuiCLU9o3ERjhkQ4OSccJb1rwUvWfv7Tv59gvHccp1V7zMyfdvozZ6L+hGvQDobpILBOPPU/8gAAA" />
<img id="flag_finland" src="data:image/webp;base64, UklGRuQAAABXRUJQVlA4INgAAABQCACdASpQAC8APtFYpEuoJSOhszOZWQAaCWQAlQNUGezwB2ATP/0Of4ACY9PC+rr3tYkgYWDBqc0NbC5WWw70ji/5Jdnqdiy3RsAA/vhPJf+OfKDClM7UwTCZUkKTABsXKnHj4AOmF00UNVZ0vflCoo6/wNMqF/cOgV5ZC0V5ZGEwR8l54BkPsIE63i2I93d1cq3da3h+Lp+rzL5FNeVrwUlBXm0TvllYN9bSWVV0yISsthimWxowpnwWD0+RDmlDoq+S17RExDv3K91TCFtB01aisV4AAAA=" />
<img id="flag_israel" src="data:image/webp;base64, UklGRrQBAABXRUJQVlA4IKgBAACwCgCdASpQADoAPtFWpUyoJKOiJngO+QAaCWQA07mJX6vcO9VeFgIAlYfpnzfMPOkBLY6P7dWTpUymU9vHitB/RtlBssCt5OGST7AVBPojVYfjrPwN2+O7PVUKeG/QAP77KuebF5NSTm7JnPK9KBq+x+/AX2J3kgwPYTod4hQmg7HKb5NcB4+fbnjZeCNWoEuShyRqXQmUKVF9AVyz8e2AXHQfs/b2pziDwtIIPyXnzMFYND1qWjkIf7EVmMc97piFO9KLMvkNyru+536/v9Nt8fAqPdGO5DQ8olrbCgNk1RlVr3cfdC/rR0klxI2e8rmicjZfg1olmCFQSGQALhyeV9ypJcapgbkThHWaQhVJ6gvfvMN+1s500vVWYuNeF/ft4ObtPwAcEgbtBscTWhLG9khRsgDZRLRFktGqA+1Y2nc06zqq1U7qKEXFjb9zrRm0mBm2NC7Hx51yz+XvCPhJcxMCW+X2kcXDgRfXC/losAo0wti2sPslmEjyameqNYtFiFLhZfjMzz5Q18aPPUpYLcC8ZH+XJv/kGB+T1+Omj4F1S5YAAAAA" />
<img id="flag_afghanistan" src="data:image/webp;base64, UklGRrQBAABXRUJQVlA4IKgBAADQCgCdASpQACcAPtFeqU+oJKOiJnVbUQAaCWoXgAF9YjBCo5h9AG2A53rnQPVP9U3eaDaM0gTPKiTMXoPPqsjghfZ9uvYQnkHaLyahJ3Aj9LduWYNS3kI8ybAS2WYzgAD++l0BkjP+WgDD/xJRVIr0OAp7zDpTn1FOvT073/71hs5FkDT//47fHA6svQrrohxKsCjVSzxa/kd6tb75cfZKaBZrb1xfJiYxnKv8fN7068kFskKRt4NeaY60aElHiY2tBxpKlm0l2kZenCA//1oi+/zN/7dnL/nqbci3xc/7dL3gxY5VfZANTSCJjkYFzWW1UmesjQM2u5fMg1feiJ78jRziXt+ZuUE7Sk+tmgJ6vSp/GJ27o3HNV1X+QfSzJaYvYMmQBvA/918rCg6KR/wFJv8MsaX91wngynWMLOxorTwWIy61/Aah9K+C/17rYKHFzW3IVWB4hhMvmwpoWFxAWp/SCMbRxnFCffIMrsJQdr5Ci06sz0TnFVfEDPSSLXuV59EWtv4MFURufVbnDP08/ofYqhjK+MijQmYD65XS7Isk3kSwAAAA" />
<img id="flag_myanmar" src="data:image/webp;base64, UklGRvgBAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCCyAQAAUAwAnQEqUAA1AD7RXqhNqCUkIim1W2kAGglmANFBwMAP7T+M35AdXrvv45eoDOAfrd6//RAaWh7Pq/AHcuTmEbeSlPeZPGKP9eHhbcBzqBOs9D4VqEeU9URt7DBoJSGAggaTCn+yscMwbQQA/u89b/1lY2rR6YftJ98AmPue9oOpuYCxtOfmBkV1ke84/4cLmVu7x9x8pYeOqwQaPWjvA0rx6GlkqWBn9EaU+fEckheEgW7x3hIGOKOnzeXaRHEARVFtg1ZfChfFfxDEu2SIacBe4Qs5l1/QfXC/w2Ja++D5fXVwAVLhQlU5+e0u3PbbB8oVbpNkEJkOPfwLrLRybn2N0PMhTf5RinnQz6rau76VQUV5hsfwfpK0wDl9zm3Nnl+krJNof/NoeC20Twbeu9Sp0cS/+yfv2Pf6wVmwD10l/Exsr3FROUkcZOuHNGqgZAGFMlv3N5UY7Eb1qpKzxUKY6ufUAKfz+nX6PldRn0nHe1ktxnudvcnu+VgE0v8qMlT9vNUrGbLxYBLumFzp2AF5ItL3te4/7ZArMfWNm1it4jLDIpmu51kipakw8qIAAAA=" />
<img id="flag_spain" src="data:image/webp;base64, UklGRpAAAABXRUJQVlA4IIQAAAAQBgCdASpQADQAPtFWo0uoJKMhsAgBABoJQA7AH4qs3/AeSASMsCPK8sMrPph3yPaI/QUZSmC3igAA/gxLebKx5EP/8a3rT1s1Qe6rkWDX//zNF1OW9Cf/IF/PFE3WrV2r1UwFaFRnX7BGlS110zHSYTODBH3NP50JiyuHGtm8qWiAAAA=" />
<img id="flag_san_marino" src="data:image/webp;base64, UklGRnIAAABXRUJQVlA4IGYAAAAwBQCdASpQADwAPtFipE6oJaMiKb1YkQAaCWcALv/AkJyckElZxRiiZ3ia3J6MUkj2oAD+84BXXmig36sAYhz3vCT3vIfrY/D4/Hlvy0sX+cB8ynmVJOhJmcoiqKdvPyw0SQAAAAA=" />
<img id="flag_luxembourg" src="data:image/webp;base64, UklGRmwAAABXRUJQVlA4IGAAAADQBACdASpQAC8APrlMnUunJKKht2gA4BcJYgCVA/gGkFcAAYHkM8E2Olft1cRvRgD+34A5gfm1y/89M9beP/Ly1KVbXxM/494OMEKUNtV61FghTr5qmEzPr8U7YUAAAAA=" />
<img id="flag_kiribati" src="data:image/webp;base64, UklGRuoDAABXRUJQVlA4IN4DAABQEgCdASpQAC4APr1QnEunJSKht3dMAOAXiWwArDPagC7Sfxm6zYreqBoh6mPyBvafMr59Hom/719Bz53mLDxJV8QO8HaN/vu9tce/pfEPpApovj+4jerZki0JfzWaPLK18UP/XGP6A0xMg/XE0S3sNtjEVJrSOfjGzsHt5SbK2C+YvyALcBd19XOqnNgMdG6eramAV4/XCVJugAD+7CZf/hWNhAGhn/+5wLv1Nv6naAI0sCsaRnG++turzbXblzfXOr743ghqKkIOY/YPoWc8OgfiyGd3nUc/nXGc7iNgbMszb84XJY3tdVC1hy8o2twe12kFnpSQuQR4EHL7dvqwd1rbqG/6qQuhRPi421/ULN8HFG7jWUi7LlUyq3iFM/q+y9QBGEya7J1J6P48/8TrQ9qdv1UGH7qah43Xgm0w94i7reHerHwZ5iV6uSGBZtpiL2V5tzN1KzqhVAIi8ivfGGmPJmVaBm+NxVyQf5t4fONUIrLUZ3Wvf7NI5fpN964dNgHYlSED/D2OrFeOkcpHv/0sjbgGoj3Uv/ovA5eNtPOmdkbqIjr6HJej1nBHy9rs/GhcsQSU4RuuwszBAcRHzLzoFrhEQM/o3YK6KG1vUFkMMTc1M7I9F8uQ6qno+EZ3IjvzFyaI3lujTqPYwI63dYd7dEGth5PdZC4nEyBcTJ5kKmk+CLa81esoAM44ZqhKIJuROOQa8Ax6jQEW2cSQZnJPyaLjdw/ImpJie1nb8eCE04M9XJ9hUGArmkW7sRdJVIb49yWpRLCPA7+AklHl5lYffEq0aadnvxQCcwGO5x2xL3ixDwccQeIGSoaas1XVLHFB1+YRPwz+ZyxdqpeadkiIhN9SBjxOzFMxRcqcf3VZasVj3rxQgQH1g4Bfmx1nV+1x8t6Oiii8Ia5wsASz7qrb/QjoM6k821bJd6c454F+8PJUjfQkhPDdPTj2WkA/Axk65FfFEK7TTsgZpTf/NVCDyy1knyLpxsPf1qXMv4w3P9UIHW/ZTnrEUmVfuMrIK2Y1nt/0geS0SA+87wYaFrznm37/k8uSh32CeGaF39TRnPrLTuC6d7pqoHUuWcoGFzAzn/J7jlifaKAabMejH0UNQ9cAyvhRwJEDuwcRLolPlP2P3aUZsa7QmoZQPweA2qLuXfOGd/TmTcftk8GxGuId2J0OHYq75KHPuC6mA/L1L8ov839FXmSVqpeR4UX5xal3887Imo45y/2p/ae5usMCpFnYN/IIQ+CXLXXMudUSVmjNkNAyvcFRWImgTW1qAQv2dNOpOiMZf/YHcZWhLT0pi/JvJrfnJAAAAAA=" />
<img id="flag_turkmenistan" src="data:image/webp;base64, UklGRpABAABXRUJQVlA4IIQBAACQCACdASpQACcAPtFgqU+oJSOiKJgIuQAaCWQAPknLKu80I0EI7rJRJUR077UAJaAxWXZgxSbmaoB3kDsvR5BdJVrLvku8ruO0p1E3AAD+0Aje6+eNXJkLZi8Dds6TsmMIi6MZg+chV+/5/mW3q7T8lkupyrI9wh3GeuF1OyA92VjucXihGkir/368tdnc/KNVT5rNX2SjVyq98EWO3QqDgBE05lzysQ1NWIgcAyEbzW9YjAqkFEOfW+IukQnudkFVSR//CJeYyf/ZldJsFJ3tRa+L+FrdXg5gLt9ViVM/UyB+5WyBfHfcPzt8SohZ7aVLHzQrTYDofaDoyFBzo1WR12H3nsGs9H++qtD3pvGwHWIxanarATWP1+g4tlEOV1ISx/dPzZu5ByGdyWmtqdOlMttFiSVU0+S02TgHfmAVNW/nHbozsq8cPz9VsnSST9xhEe9eiBvIjuuj7fmws/p5Fcgi7cgT+GASqAd+TAugHBcToAs2A8ElerkhY4qwkOJIAAAA" />
<img id="flag_costa_rica" src="data:image/webp;base64, UklGRogAAABXRUJQVlA4IHwAAADwBQCdASpQAC8APr1MoEunJKOht2gA4BeJaB9BUgDBZ4E+AatjwABhujn50X5+eH9j2LYzaQNwgAD+5LN//7tX40Id8Of/tAmmCCft36CBlsGRaNmWKf/FWBfxLzVz6PxwtLDziXsD7l97SYA9fitD/XcTGT+vf9QAAAAA" />
<img id="flag_andorra" src="data:image/webp;base64, UklGRm4BAABXRUJQVlA4IGIBAACQCgCdASpQADUAPtFaq08oJKQiKBM7MQAaCUASueevvF5wJn/zpl91YoLLi0qVksfSbhDdI1kgOnRcB3MvJ5vnFbRx54u4BMdupQUO+EL9UeEUjqhVdQUtE/tOjYAA/vCFxNsQhUh/FuiWpn+HOyF3tJyLOx3VrZtwf+GZHX3v7+GZHWxV0E3PUPZUQpytsqf30+MRagnQJWdLl1937986+yMuanh7/FGX0rmOLtz+Geq27cCOpGL4/vPEBFQIjU0n/kxPA2Wx71NKPo6cKMhLCEFFPr4mTGxxJzQRGwUKKKXAZjRfl+H8ww4EfG6HCx81HqpTWj6G+cfl9ftVIgQjEAynjRhnEnf672ZMGzEQ00Zmvnth2Tv3CNR9jrVxefBWM23HZ9WPfmNFdDzavcSJWmRHlw6YmJkRyUL7J4i+PxQZ+I9SujEf3MfoJtD8H1xt+bWnB5Q3aO8Jt1qZEQAAAAA=" />
<img id="flag_iran" src="data:image/webp;base64, UklGRpQBAABXRUJQVlA4IIgBAAAQCQCdASpQACwAPtFoqVIoJaOioiiRABoJaj734HVVkDwiy8A1BfuzjwG6DKBOhm5Yb/8iIzW87F2IRfxuKAzXZGiON0zUzZh48+bzbmASfxgA/rhrv6CBgImlmn/MwtaQaMgxJxbtjKUT/zBPkHIToEsh9fiYw3/kaesVvnPOWdKyZ1fvsd2+ay18Ye1ze/JV5KJHKR/rHUvXr1Lsq69+dPofArL8RIIvCjb61lkzidELniu3K1eXE/4Q1k9Xfug2CX4UXD8XoYDKjMOW/kUF6Y/KV8FYXR2lWGRKXSWn1mnCsyTLHLCBcOEGw0+RUrYzEnAqSBCyLPdnUnzKvBwG017McjjVKiIDeghtXwr8Z8mBBLm/00TTVtl0kXXclTXWx3cgs1knR2LiYzfc1ssQ7CtTcFT5rDQ11ro0iN36wqM3KtIjmi1mKOoxe77uBlRjLsi4sH4zZYoIBGwe9FtlU02ycX22onXc2OKwcTlI9Zdb+u7aQFDsliWAPF4F84BWCKbDuAAAAA==" />
<img id="flag_jordan" src="data:image/webp;base64, UklGRmYBAABXRUJQVlA4IFoBAADwCQCdASpQACgAPtFWpUuoJKOhrvSc+QAaCWYAlQP4BpUnZIkB4gG4A/Xfe/8kz8h0mXh4HSG1J8uerItgImYdJD74BWCYJsiUVG+/jTsatCQt4JPJ7hgAAP7mT5Fis+qw2Pv1+Jl00MVGOXLaZP12mWeXfhTIf5y6bwUC5uN+6PY/+rQ/bvAVE9NCk9PBex+z1tMgZE6saZO+QEqwqTdSHJWuQzuqteDlRRBe5vUFbtkVgx7fUpNXag+KsvOL7bj//o/M8/qe3kG7oqP8Yyz3AajlFjgi7Bn7dw8E/L/yR+VvKz9KhKbUjv+l5AGJhimJlfmbc+LcV+4U1SAkINDPh7RBx8IMnEcGRu2qS4SUExhP/ucKibvJzE9kvoeN7vctHeKIV1n6te6H80XQaOzjmci4xgF/2Fix/rnZbGH/NEX18ZdSoLbyh/WixpdX6zP+uaY4tTptAAAA" />
<img id="flag_anguilla" src="data:image/webp;base64, UklGRoYCAABXRUJQVlA4IHoCAAAwDQCdASpQACcAPtFaqE0oJSQiKrZsAQAaCWwAhMVaSwbZJob1AflXej+YDHOd5Vrss7EYe9AnO49Jgr1fo/qr4rvxtu3AcXtCzybZkpD0Q05fqxBD3heeEXTnhNMeHn9Brtm7k/3lURZat/Td3pznAAAA9q9ps51JjQ8ok3YjvS0CcEcBD9Aq4zIUKANEUfeP1Xg3rAKl/Xg55b11YvKOzQtfu24hmcPLXGQryl9WuiwWO+GmOaCb3WgCUDty0xGzuzGBK4ci9DrdxdPz8EJADCp/WbZMk+dln7kWyP44X4AEFgz3+B/W8pNXuvwz0aB2JxcUgPjofTa8VC7v7vXYi5imGJVoctRD1YNB1bRbf7o0wUq6Q8FAAdqV76rLmcjn6ahaaA8fe2UxyAsoCcEipSnooF6rPFSIpOtKxCpZ+DbPybBrjqErXdQX759/GOxuP/W/uNcG0/bVyd03Be6bVRqnrI2MFVFwZLL7OHed+yY0D1MSFcymM7iAdbvk51F1CL7DhPOhTwhCQFoKSsdWOUOGJx7MoWVgAXriooeaZfUPD8FVFZw3Xbbd9cYPIe7Bea2QCO9YQBjPMEjuR5DIVSCATtO2Lym3jfw89wWLi6xiH2LAY28rXYqyS47IF5B3tP3/i7606+nzz2UBW0x7UAvHls3tP35O/CLcYuX33BypPbBn9DRLZu5QDe4/ZLt9k3g8rmJyui+vv/6uozw7f5C9tVtVKQFxpnz7x5VlRhtUTJ3BHPZpctJWWeBfGeGzkEJ6pJiGO+3Bq9zNgrW8hfNbU64OpDmMXkUO/ItwFVjyx6n2yHjCaEGHQ5Hct+hjRK8TjAAAAAAA" />
<img id="flag_czech_republic" src="data:image/webp;base64, UklGRjYBAABXRUJQVlA4ICoBAAAQCgCdASpQADQAPtFiqU4oKiQiKzSZ2UAaCWQA0X2W/t2t9JJ+2dUA8QDpAeYDn//Sq6gDeKPKAJmsEn+YbF1iWqR2MyBPH+45Z7tWlkd9pIhnRgzIhAgAAAD5cNhzuNOSOCEB6QSnxMaL9w4S0sWZ+/SdfdeCPQrq9kPrKzwMNM9noksGuVLg3bzwJVABt9E0OJpbiOTiOpO05ZOd5I++46AjnpUTdAoAsdiYojaUyNIIHOvNxdxmbUnDQCwvi26cqv89e65uOL/q59dQkiFSvUd42E2O5mX+mRyR31FZnmtTO8Wn5zReqkqD2HmJZD9IPPfAY/zFv7It3gzrOKj1PlCZd1jGklyG0WeUTqf/YUUN0sCdRbj6p/7Q6zWF9781n/2MWBQAAAAA" />
<img id="flag_isleof_man" src="data:image/webp;base64, UklGRmIBAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCAcAQAAEAgAnQEqUAAoAD7RXKlQKCSjoqRYC7EAGgliANLljQQBdgG8iFeB73nOQLwazg3Vv4QEYR0R1Y5gYL/RfDvsPdDo9HAHMPtXIAD+7kMb9vzNl3/z0z/7l/+tvUbmDN7ewmQEcnByAj85BjBjBzhmyfmY+mHpD/e8diBY6o7y0h59K2g5+A4y9feZeGSKl1GLFEsLLtT4VvddiF9QWEJsV21olYepyTDN+CDbGz85PbdtW2fOZXUteX3hsi20GgCCQFnQgWW9KL76NjP9nsp/hErfGui090s68AJb0uR2axkCkbXozkFwiYs996Es5Hxzv/xdU4hUXP4co65ZMjRFbSkIjmC42bIKxLjsVIq3hK/LlkWEmGZNxUAAAAA=" />
<img id="flag_bangladesh" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAACQCQCdASpQAC8APsVSoUunpKMhsygA8BiJZgDRBQA1qPpOB1SY0Kr+AcAB5WvsgfYB7AGrglY6m+mafP9CbhrVViXYBXEVPsfaDhR/ZjZP3VNVOykAAP7uP+8VMF1Jy+J0un+Fu/fBuS9julN1hfDNSvc8B8OuJL8D6v57ObQGlTx4LQO9Vm2C5K0iZ6mix8NlR29J76Lb0/QgmVXiwxYRz6kfoypNv8Ld4BS5us2pwfW1Za79W1+XmYn/PY6/Eau9SCEWHsp32fd/zGPzhoqdD/M4DsJtTGDOXrB9F5IxBZE7WWQAAA==" />
<img id="flag_curacao" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAABwBwCdASpQADUAPtFeqk+oJKQiKzJJOQAaCUAPEAZQSFe58TOZDggtETR2PUMQm9fLqbuDpjxLm0uD2gCI+ap+CjiYgAD+7pT9htkpBRP/xa7Y8MM/JXdMwbFCQ6COPwHB05LA8bAPQ8YJvHUPCoDfjcc065uQHFTnD/7U5KwGZ7djrbjTv7zf6dr2O76+523X9WdpaPZonQGs9U+nkbqKpWN2oUYHbRosC6z0CvwhuGB+NhRDOPJbpEcErGTaJ6zeLbp56OnqJ6h8jz/7RBXNB0JFRJNTWsLuwGCfux5yHmAzvwertft//9jfYz+xxuv/o32M/scXtZEn8wQom5QKCAAAAA==" />
<img id="flag_south_sudan" src="data:image/webp;base64, UklGRmQBAABXRUJQVlA4IFgBAAAwCQCdASpQADQAPtFaqU+oJKOiJnQMAQAaCWgAeY0jnglmAeYDzqvQBvAG8sAv5HwlvzIRLPM5CixN9u0V/cAzJPo3kJZctYWthgT+M6AEs/mgAP72y0LPrfR6/9qg6N/EFNH+57V3VHkj3yrly6D8iRUrS7yqasWkI1VH+yfq9gR2rQB3u8cRGCmMlDl4r1NWPMGzCtApS+QMOwDbHONPcZj+KkKmKB7OvxQccEE5fncQVmNHww1zVevQ6g9rvs8mdoxWpBOdris5OCj4oOXM3Gh/OpPNk09SP7b+RJ2s6b5VZf5sFy0/fYS7uIeFXJwtYiFtJT578MtNey4kCYl+bYFiKs+ER7Eeq7brMjrheO1nSgOfm8PU20PP/Fc99PscmK3xY4TxCSlMkoj+GCu6GDtF1EBFk6Vr56O3vwfe3GPVHA3PSb/a1H2R4YqMZNes5TxxmAAAAA==" />
<img id="flag_malta" src="data:image/webp;base64, UklGRr4AAABXRUJQVlA4ILIAAACwBgCdASpQADUAPtFgq1AoJSOjKBM5EQAaCWUAA+Q4NcBD3yLcAPr0LbfGffUfftAoo4NEqE0mtZjhBJjc0AD+9gmy1QkvP3p2nS+87YvwWU4k11j82K/bZZV2ST7/Cfxet0ilXRg0uHXFcm+J2pK+cfU75rZYMGq3daOe2lFfXX1mlGGEHCpGKn/+tXxzAHp//iZea+2U5KEzjfgnM9Pjr5R0AaZd630KQ9cq7U9RdgAA" />
<img id="flag_bahrain" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAADQBgCdASpQAC0APtFkq1AoJaQipmipABoJYwB4T/dJb/tAPwAsgDeSQMhTZCtnHlluGjNs4lcLw/yajvaKRgAA/vXO13rU5NhkHKb+I5pwNhQPiWViT3bsIYLZ+hu8MWM8iKBmAFKf/cp0sw9k3CVqKTm//+DXbYFj/i1D/oEX26TsP3H9h9DWj+sYGrTs7OxeNZRkSFGj77VwD/N9NvrSOzBCR9uxlC4ueMNg9489lgrRqm9gIAlaC0/dLzGvs9EatkJILe5TPtz1o9ihQ/cj7ym9yVBYX2BRyJMKrI4GlGVXtATb85NTwgKcKOS+U3sZ70D+vnSqjjD1KZzagAAA" />
<img id="flag_tibet" src="data:image/webp;base64, UklGRm4EAABXRUJQVlA4IGIEAACQGACdASpPADQAPtFYoUuoJSMhsZdKqQAaCWwAxy1BWf33fQvyG9kqw/1/8ScfgWLtA/eeb3+4ewj8a/5z3AP0e/zP8r6yP7AeoD9cv+Z/mffS9I3/V9QD/Hf8D0OfYN9ADyuP3M+Dj9vv3F9pdomzvUAHubfUFtgRcIROAY0hknVfHw5U8/y/q8MX5eZwzH76TqrUjJepouHJjd0ETIB0ETp7LPotfT/A65a0qR3+bDu3FS9MybmpGuG8J3X4Ro8k6qU7Omi/YDpUbn4AAP7zfnZJ+bMXEEs/wc6zj/m24HN6TPXpRydQu/wc1nYuSVwC4Y6/CdBI+OA0flOF0C+Fh3HeZPMHitrlML+8Xdhr5jTL9ZzJv8uk8HNlVwqQT9mY6DJSYrxXQvIQSEz27wP1H8PhFAuZWXCkvJxv4IXwNdfHi1olV7SgN/r/gcdQnX/FTBb2I6XiPfxkH/P/qEFLsj+APPA+b2/2SRRvIhlqJwvPyk5VPjKJmbiS/GrKcrmVg/yLHLtHFimuMiSfbCPKZBGnZvk438D1/NWv3y57bvCd3m1y0doIUGTDh01DzwI4m8G80qsgcuOJs0A6JkJR3iy4VzTlfwOessFSAfFrCrIRteWQPm2ctmei4IkhEmZV1SQXk2hmxDbIvckXqdHDN/Oru4va7/5StSONMZsZRBJ83tSU5+ylH4gEvY692Nm2EyUMW4M6/U0IA0L7hmURm7uWHx+KTjc7lvpJlhZqxb8GLJdHHkzoGHzxMyPzPlGC43/0RINyiLo8ijRkjVpQNpQ1vyzhQ4ei7xTzGxaVg9TcnjOgP0iotB/XraeWYlBhkLi3+7q1uIHrJume7JZMh4SThPBBFgX6MrFjJn807I8dzrBRYl65zFrdUKKS2VvsShw+Q/v/xnr28VqkMhnbTNB6Hcoi6GitzFmAdfSO8jiyxDRsvIKYvj6Jb6u+InFYKith/NjO4/0gTzXoNhWIu78EFNn/3F98F+PL+49V2n/LOfy3Oc83O9lpyFW9Ho/EBPiSiDRkf8Ssjfsiiw9NQrRCAmP1XSsu/3VLXUovnT6xvc9j41DjWpoZA9PIFqvj5XM4mRXPlsnOs+HQu6DWQgB2w/20A4/wcQ/t2lDTENaH1oN/BRI7Fe2w3RK5ut7MCYyW0VYA15+DJsUCdjGuAiThUp0uqWj+Tl1AfJiCkpYH5x6xqUdXmvEqnXhInDB1D1+PbPHnGpjjqjRMNwXyhBzJF1HbPelSCf0p3WsK/g6pfrpyxjqRxlQCs+M4jNbexCBKh4GvN7fMEmFabxiEezZaubffnnj2+klYb02fZHyJfFEO19pp4vg+y/wsyA78wXP94WBre9Z1S1ZfRsIrWh2Voo96/sWgxJ9u4WZXBaWi5t+ezFYasMrLuUXnEK0jWbuiINnaM7qYicgRBdHrjN3MXxNBTe53bBLieluHULzj9k2wSsB9YBtig5CwfsUHQm9ULhPT4AA3IBzcA/wAAAA=" />
<img id="flag_serbia_and_montenegro" src="data:image/webp;base64, UklGRoQAAABXRUJQVlA4IHgAAAAQBgCdASpQACcAPr1On0unJKKhtUgA4BeJQBK5/wDVrRALf/AoLDgAh2YXCrth1iIqQm2mpyhV8QAA/gxLe9n8lDqJPj/lYGGMpnUbTtc9mFLzlr0TlZ9VJO8NXYl6t/BN//9UifxN//9UfjckA9/WL2usUprCwAA=" />
<img id="flag_guatemala" src="data:image/webp;base64, UklGRlQBAABXRUJQVlA4IEgBAABwCACdASpQADEAPtFeqlAoJKQio1gLiQAaCWIA05lBft2uDdVogAcKXqywdxzPCkdQD5ye+8r6trwqgIwqPhpnH9MR08/ROgr5oRhAAP6uFwtzFlkt87B+PfejxH6sOTbAPQw1uWC3wLBd8CuILvhoKSN0zfDKOY9Wl3tevD1Yn9gb4euJRFRklUtuVbu7l7eqaT2JPTlccVXyWSJvXbYidv5GE+A4eI1YRJnguYjS3l7WXt1gxgVfQbK8yCXHCQK7Ff3z5saEGIEx8xm9nT7iBFdy+AYgSyZ4t5Z9C5e34pBEdrsntKvig3+3pjLHaf35KtZOvY68441wcb3me6OEzH1oV5ZhC7znRFSdNjWat7mxTXr2G3TqiAjipCOGJXS00U8qg60QzlOyssAGiTreT8bUjkuAC5ZVc39pnJXo/gufP+iBAAAA" />
<img id="flag_north_korea" src="data:image/webp;base64, UklGRoQBAABXRUJQVlA4IHgBAABwCgCdASpQACcAPtForVIoJaQjoiiRABoJbACUANKk7lw1G7rYZ5r9x3HcFA/QD3xbJuRoBYrVurNAe+cPBaL48xvR3NWjxLIvMr50secGejqHWW+s5KWXyN1vMAD+69g8v3/vDBG1qG/jVxMV/yf9l61iUIDz9iViee/xSfkxJnrjawQoWV4bELBCsz7cArcr9xJI3XJeljmuFSXobI7EDe+kNVt0HPzBnnnPfhm119zHfIbEcONHo49OvaTBo/2tC+fqMoVo0BN79LThNQWb1yt24U/68P907rZWbdRxeBiMjfemGPNRxMY5oUuFm+nq7UHzl9dfEUJ4WMt9N90Sw+4+45EWDGChYZXzNpgtuUIWNQuy2HPMrWDmVJq+/Ya3xfbm1/H0rVx5OL5BK3vrImB8/EDwN/mXLBmXXdLVRYpfByuNnJsEO9zGRzOBMHj8+e63oz7iXktY7j2rIEono73gONf2ZBoVGz41r55ABLOJAB7haWAA" />
<img id="flag_saint_martin" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADUAPtFYpUwoJSOiLmgBABoJQBq+MDe4AbAdKqlNAmgSOnGTFnYkYtvO2JEAAP7wG9/q7wo3slfv2/vnSv8Hv17zbJ/qV2ep3Zk+k4daqgOdHBZnLlmOd3s/Zf32WwTjIWr013Cz8AAAAAAAAA==" />
<img id="flag_sri_lanka" src="data:image/webp;base64, UklGRjgDAABXRUJQVlA4ICwDAADwEQCdASpQACYAPtFcoE0oJSKiLNgMcQAaCWwAwQ+J72dd/Y75O2z5E/13nV/Sv3GbafzAfpx6vX+S9QG8FehF+xnlAfDF/h/OkzQB9A7M4xpVi3YzWmpd+BN5EY4WgrDYySRHmRDQ0K95Pj+JchFyW/t4a3qqaxv3a8v5ndgvgWXVeZkpJqXwcI0ZTaw166doAYHvt1a6oAD+yKRDxtRhbCyStjrB0PSUB4//P+NDiSS/e00XnRrKx2z49MWm9+8zk6RMc00fUEOE9Nk6pHTMFrrXj1vEGlx9vIT2PvsO6BvJWxOuhzVJ1xX+i6fjn+DFw+ycTvdEy+6uPu6FRFWFf+J1DLaXvjoOqoEURej3JOIQs/6+Oy4Uwz64KxrMloQCkVQLxE6QSIG98/nRNXeJubm5/R/XWbBG0ng4h+659w8Ky9R+N7hR+afaECVpj6W2xK1bbBxf5PNmAGBeoh/xotXOMYk95t5gkNJKBSeILtKAYD8ROIG+FtlBxsQMcq2OM6jYcvOoazohgOUkeOGpuWBTL3PE6ePg5RYHvq3VUEWqeVqbvjT73sFei3K1nnwZ5I/bKvOq59J6TFaM0ey22YXiWSHriHrQCZlZ10DiY4NC++SrSulO8priALYwX4/x/E5d8IXiiuFNb6qJS6aj25MemxYpGRfFhH4Xm7sjvAYrYdmA46JyXzP2YWxKaydWMCslQ3o763DhS2ZcSbjS6da9XIt5Bmz48AhzCC4whFIiHEj1kejVc5AGfAHPVKvlw2wcnXj97Os7SVatqAr/B7eXUqzM++FWnenmHaLpV2SeBjE+jv9gDFJD2CNGmPHlUrQ+WMGqEtDj1UdQdXU9LdPeOsrC9djXuR3RGM4FoqKxdTC0MkqoL2mPZR38+TyXXj6b+MlTBay3pRU/3LX/0hD9vKWwfmTsRhz3Gamoy5vqF7XJvnHhdwB6S/i74pZR416oHDWnzYqDe2xXj1u1YjJPwOx6ATI/4IPlI4PSiJIPOkiELKkzgQQLM7hsBqgdBBlYVF3WZDJ3MjO6dyuuPp4g9ja7PnfxCppGYH4q2bFc1aQLjMBfiLwAAA==" />
<img id="flag_new_caledonia" src="data:image/webp;base64, UklGRoQAAABXRUJQVlA4IHgAAACwBQCdASpQADUAPtFYpUyoJSOiLmgBABoJQBq+MDe4AbAdKEW1Q97vjwo+coVXYk0J90+NjwAA/vAb3+rvCjeyV+/b++fyJ3drbJ196wj6815/+Gflj43TDxOhuzHxwYkV51lesfvNIr+QfmFNJhZvCWoKCwAAAAA=" />
<img id="flag_south_georgia" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4IJQCAADwDQCdASpQACcAPtFap0woJSOiKrmcAQAaCWwA0m1BOt/vPEO8INhcx/UBtk/MB5Lv7Ae5r/Ob416AHlueyA+XDGyxz4i6E5MNVcmvvNEPVEhSwe19AXiLzjZScxl0MafGaXmgytczVSYgRct5rBcKNMm/UxCD+AAA4mx494r88v8pD3Zq5eGIcOBY+/EdhzUP7+odGWRSRTWDLLQpxpPqAAtQq9PnYyt32nPE0Ar140APN3iz/3p5JCSduv0OjkMJLm0LJXs0BUJ+FvfODNpQQlzXLRZkzCaRt+edO8REFhSzY+2ge+d7tXN2+i/KMjWGT4P6lM1XCXdPFw71NQnaWSHYHaf3vOpn9HBce4GnZtOCHPxsnEAV6/hLzrSS3y7Xzb1w1lrchDi2J6AKDfytOSQTHeRP3yH0+UUltxuDMKhpED5ItHhxD9MaZS1pEItOc7x0Yh8250exN+2l4TGka2aaoLfAoIJWwhe6ZC7lRRAr+D8R9LosjppUkGJqEizo6FDkDHXeShvt+821MEP/f4o8lnUVr8AuzKMU/nLQLP/i3owBJYJNf2/CwsTrSFrGkE4fHPPHiE+0ePa35/63/VyL/jY2/32v5lXMjoGDQGXgawVdeOZL4XW/4hyr1Oagf2/6qsVRkSbsCgHJn/FbyBOlJB9sjI0eOlZiCdrhrV/r/rD8+1C2YBHYFS0oApxr7XJ3ENAT2CTrNGqzGiBkb6wigI98qOnyiz1rtWct9Ox8v4cwS7ZXI/c8I0Qsh10k8TutJQoMjYY2VE+ouLCue8Ssw9fTzSc/4SKTW8UO22aKiatwOYNGdk85nW9FIC3NJzaEbFmfSWuCq3gf1nAPARtHE27S4Avlno/FBDFAZUAAAAA=" />
<img id="flag_guinea_bissau" src="data:image/webp;base64, UklGRvoAAABXRUJQVlA4IO4AAADQBgCdASpQACcAPtFaqE4oJKQiLvSZAQAaCWQAdjlPQG8tAeb+AxnpXCEU8kAY/Q/hS88UVoXNxH5GgplkoiAA/r+PgXKCcECj2v/9bZr0jdlAIZ///SbP/E2f+Js+F4reeuF+R1r2vac/5u45bvzSLfzMskzqGvpPP9Kh2hv/Oiom9SbO6wArh3am9BDwQf/QMttg/667XyY35abWTp/mj3RelJnoR/Q3rsFR1SdBi7HscuAUOZoipYYLDyfXiwRolWbfFeKFV/R6P4etUwanFwPc5xQsOmMhGfPhhBVzvNZmVTwIvixFvSiFAAAA" />
<img id="flag_peru" src="data:image/webp;base64, UklGRqQAAABXRUJQVlA4IJgAAABQBwCdASpPADQAPtFgpEyoJiOiLn44AQAaCUAatqgvyvWKuNUQDZ/2VnmjOyZGhhbKH3yaxyEXXUtjamniuZFPzrggAP7fgAnnsmSr5xL5I9Au6z9vq395jLyvtcz6v4atg9P/wTDQIL4//BtrN18B5SeLTjgFRGbTtEvAf8G/fAw2t/g39hnSUay559M+ulmaCQADHEuAAA==" />
<img id="flag_liechtenstein" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAACwBwCdASpQAC8APtFeqE4oJSQiLvSYAQAaCWIAlQNNn7ofi+jQQimsrUIfONL2r6HlyupXcRYIHYnqj8qCTSnkI9mZVYgAAP7ucjKb5/k2Qtbugvs5IOZJ/9qPW9DH/DmELCLZ9zreN+C2+LaqyD+ROl6wKlbUraYApj4ckQTsHp7Xtu6QpUV72e8n5sbSdOH1e7NwmtDH4/OK+8S8Srsceonvvf2CnNaPMZA+Oip8vVAF1jx/uko+Au/r+eYInrIZ91PLP4/8gHytba5BG+JqH1H4w3tE79T2jJhuEvS3JRVOGNX5lHTDShij+d6aADkYASEyB2N7sBmQzTr4sPAA" />
<img id="flag_british_indian_ocean_territory" src="data:image/webp;base64, UklGRjgGAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCDyBQAA0BoAnQEqUAAoAD7FRJ1Lp6MiobVeaADwGIlsAJ0yqq+vKQhTpEnn5JIl/5hhm/0nqX/IHQ6eo/9mfUB50foe/7uogeXD7NP+A9My6ZftHgn4VvYMjW4f6t4oH8t4P+4/QR/jv+X/LDzudgVkX9s9AL2z+s8QulN/7PGA9VHPlqIfrwOi+3gwjga4Mi5YZhdIiTykiPjZh4C5IACN4S1w3tkO/Su66Um7606oaddRmyqiXp2oJ9+oO0DawhtSn20+Y5f6eDJyalg10QoIT1l8EgKK3hA8NPIN7ibjukjFAAD5OlsNtLGpQ9O93BeJYf3e+hFKPJ4Jl65CWyqvUPRXsa8i0H87uhzg7o0d1B1LQb5r7raWAZ7avI7oFpBW/d38wlAv5O5Fc79/iS1Yj3+zNmuXq3+rBKPr87+MPSxf97+AvsaUmPxDxTUYPeH6Tf2OPNtAER3B1okGaF5jKYqCfiKC0K3R2zC0S/DLxJo28WFrbDbiLvohY0gfFmr+NLXFOqxvXYuvzRUmzkKdPb9W7ZpwlfCYf9OYWDKSYFZG/Z/uf8XZZYjhJzG7r7yRGTrY85Q8dcXqunykeYe8Nq6+GlVxd8ks7HLGdBrc/1TvmVnPa5pCgJ9gu8wPEC7xO7Sz9FkFZ3GQP5gEEfQBs9zIXJxxJCTW6SB5hBUyRC+OhP4RCu4mX85ENBFNvU+jvN3qOS4vRbCUu0kBd0LfnhimJDJhASqWv/jy+8baR8rZP+lNM9Tl49w9EFKxCCqMFsp2PDoGClEcwg11IXyhgJ+pPzbWGDBxibC8KSYOO52SgX4n41XlTxwkm3h+ElKA0k/tqhdGoxLGQhhQX2qHpELKhJxPf6U9Ga1o5JTP4frhjFTN4YKrGdsrW/dHsaYzQINpnspcH5rwDQtcHmRCL1tT0sS+a/rqW3LkObIipVqDD7jruE8GBblKNIlwzfM+YHpSCy5OQSDgI6QWKDXePPlN5zrMPLlIXta0vA1e782dSb30iAsRi5LvNElm0H+HpJ8FNud/Azy3oBwa9qp9VGbZo3Htgyd6lYDM7dFLUIWm4LZHsCp8eqTLbI5SDhcisv/0jNKUWPUt4InJKForoEj4kX3Az6oQYWUmtkkns81hUjXGpkiNn7gBGN2rIFI8UT+Dtuo86blRuW6bd3PMdSp5TuBf8IA7WZnVpJushyrW/NdnVmgqh8XJ8mXh3b4RogRZ2ltm8v3LGj5nU2fO/s6hbFUzkFsrWp9XTs9dLfZDhbJ7sy4EIE2O2EKNzy4cyxqcTHGDrgPLLakkeXk599mbCyfaPCofYKLw04n25utQ0gpbPnYv275iRHbWClIP0kdwaQ7vAicUx7zV3HlhyzqJPFQlwNjvUkJU06m/g7lcsUkWCwiA0QH5l675Y0iJPy+YZ6I8tX4V5FycUhpz3xsQwKHzspNd630NL2vkbGCEQfQtvqgSkZ1BEV9Wne0BgYwsDxFJlQqordUU+rFSCN1ecsEzLvdrWiT1blPmL8f4vg0kzmgwmUtoINgbkPIdFKcAsiR/z3xpmAQ+n9Au8iBTJ2bK0b07VyzUxchashngYxGY/f/Wl5pcmeFcHEK0W5aKUW1LFYt4myd1Gvbp5a828LtZkyGOgJUIrzFMciXUqFt+Y4DRhcAggrychDpn9XGuQe3tFHU4bzt+wSGlGfsSkf5IjujLKK84ghqLJJ4Kgt1ESf22mu9Gffu2iW+X+3R4YmJaV4DTUB4Sdni+8u8O0jpL4yQkCOxo4Y5d+QQQ1RFkcGGn2laRbHMWvymiKW2SSJ/nQ3AC4IK3rJJZ8YYuZUMWfusdsp6O9BFdQDv8hTZRL05PLEQpePJl+h0FCayid5yVhJuj7h3PD1FMtp66+8kWiP/e419lRMUEET+XxkGAKjSlzcFTuBAdZkVG/JvXTe94He8LS8GrpG8WMZ2yDCarFiTSmjKfj4+7j4aDltua2GASyh+sMIXiVFBvcQhFLQ5KNmVdjrBaKyL5ICtz75jkDzJZOBS90zinCviUovAAAA==" />
<img id="flag_bahamas" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4IBwBAAAQCACdASpQACgAPslWo0unpKMht3LoAPAZCWgA0xeXyx1lNtfNOREXg2s7QVt8OCzxsDc9DLhz15v2yuR+r9ek3n+xLX5h3UMAAP7xqD8d86hsmxLdLCgrak3MdsFb5XLJwnNFcX0ZuPgKezMzoej70Mc2RZI8CEWwsiLFeZ3+ffPE9w6KJaK5ghLfKm5NJIiqRMFYsKPbvVCJE6KuhkbNBu8mixUXq2vQYyceEIS3A6t1LoXh5iXniRgeRakG7BJ+ucVnd5ZM/e/0tlFs3mQWc2mj52qtPYyx6T5uhrwPmEl2/hdPdXxzWKd/gNDf7M/Rpo/pkI88UzVG/WLCx0+rjkw7lEEWIMvN6pFtGe7frW2A8Y5KOljiJOAAAA==" />
<img id="flag_ecuador" src="data:image/webp;base64, UklGRloBAABXRUJQVlA4IE4BAADwCQCdASpQACgAPtFiq1AoJaOioitpABoJagDTXUE7b+q24bDP8AMYB+yX6Ae/DpgHPUeyZ+0SRA2g61CW5Grl47VFKwAt0o3e/OIMEcXS9c+ASiE0JDVgAP7weQ/+sr/1lf+sr/fI1c9DQaaUgdHnmh8YSTRRpjCEtgLGY0VCYg0P+Y8f57YP2cSy9VoQN7+EFUhGF127/zpu0oRlZIKcS+mGe5fU+upNT/66Vf7rb0bvJ/tIzRhapUwWb3Rl1EnGS3WU1ClW8BnEFqE9WRuM7hTf9AgijVsNIp0uu7t51JA0wGmgX5aKraaJ4+Phl4jr3L3h+krzp7EJsrybI2cMkGsmSGrxxB4yojtsvuVhsQnqctHM0ge8ytlwplIScJulqkfW9JZuD08vSZ8iwoKZ8WAWzwwdzRIrzQrjXcT4wib/zuS6Cubq1kmUMAAA" />
<img id="flag_azerbaijan" src="data:image/webp;base64, UklGRiABAABXRUJQVlA4IBQBAAAQCACdASpQACcAPtFUpU8oJCOiLvJLAQAaCWYA1BGNvVvW11XCYAGLOscQoS5ENFXuJKAC0m6Tmb3X5y75XgiEBDsz2sbKarvAAP2McZ702tqC4OLom35654Fe/+LQ+q8lwvBxaDff4ONvfiGStRxZL6700pCLTpzymhlc62J6lkETo6oW4+oF+1z68ima+HwhAv7r6IKBa8RB/+Un+4Irao//jY2IeCK2lQwIr39XxHHrwTxc3zO7CJAOMO9ntWBYdjmlkHocaXX+kqAOQ5zP1uevamntfMuKI41lYp0PwNXQ1+vWotfS1/fgO7SqCSlpOALlrZSwzeIGnpiyCGCgw/RTSX8GmYsMa0o4YpqoROAAAAA=" />
<img id="flag_montserrat" src="data:image/webp;base64, UklGRjoCAABXRUJQVlA4IC4CAABQDQCdASpQACgAPtFeqk4oJSQiKJgK6QAaCWwAec88X0DhpTW1pfUB+Vd4B5gPJ0/Wb3N7xRz7Psd1kluhGHrYqz+DCUvru0JQ/50bHMQWQmIv5lv0GMvCVoi+MSrRapOXkQIkURxImJQ+U3syxWfuki8gAPz/bePjivd3LNHTPDJIlHTrFTeObA6b4lpl7lXGi0wAyxPKVV6bpe+2L7xOAwlaJSXruA8U3Wt/4x+5CJHX7Lj5adp3ZghGZ8IAOUIqgflibTk2vNgliyH1au9yCWgEJpaWPzKrILcN9YPo+8x4g4yiPirc4El7qJYq/lPsdnNZ1Px7Ws7wLsUQeE59ZdXus73bACaCukVejtBB+OmcsgO03Hu6niOugKT35635po7z7IyY80aeelwxIWxQhkpz9TfijkcfL+HB/SS/IrVHMezuRNxMaHqFvcIbHRs5jsDleR8hR/pSmk8E8ux8S5mjANQppMsAaxblnvXWeF+14b6Lm8RthgQ+/64zmmYPyPvzlEOIsA+1IrLYIyWqoyKzwoYmSV6dAC37BFN2CtX6o8kN657X9gWkKTCdajxWNGhBK4KHkNsIN9fJuxf29zv9jAQGq5ZYDmcMgRF4Ky8txJcKbBzu4nnyFR5TF/L9wEjWaTv2ig+t1RG0CNQpmyTk436IBDbJHkT78NqoiIHtgdA1263S4nrrnTyPqJVCx6PPEoTBfYHSNJHi/501JUKJ1aGEIBBiobIAAAA=" />
<img id="flag_nauru" src="data:image/webp;base64, UklGRuAAAABXRUJQVlA4INQAAACQBQCdASpQACcAPtFcp04oJSOiLvJJAQAaCUAAfDNZB+jyUN4G4/mk6MVVFPUQXxlbQhFSgAD+8JtD/+HP1d+ds8vuT9EeJr+zUceh1GfTcXU1BE+07EHm0YE7n4uh1xN/ZBc/3cdtUeso//u47aalXPr7N9ja3bH4MBIfSpFsmQvhnittyUZy/u6tkE93czSNG6U+oZpDoiT6AUeB0/IFZAz1eo0Y787xAubgU6yfLGY2N+COPDp0Xuwib8+AI7rMYbKt03qW5KwmSdNFIzyzl4uAAA==" />
<img id="flag_malawi" src="data:image/webp;base64, UklGRiIBAABXRUJQVlA4IBYBAADwCACdASpQADUAPtFcqU8oJKOjKBmaIQAaCWgA1PfH+q8IU4ZNXQNc//6GN4ABAA6pLaTMZpQlc/pAo7lNp8rEx4AWSOuvB7Zwc9Wm7qRrgAD+93p+OOSu6FmcfypJ+7ibp2oqCJcvRbP5zC3DNa7ox+wFnZCFopf8rj7MHlTP16FuxSojn+FoVPvuXFqPZW2Cpwu8eATxMaE63uHS1L/jhOP2rVUtj46iCZj351T/9W5w5D0sHypOXtcdxFmF3oJ8s9NBf+QmpaBUQi3Wq3//PXE//lJbN++H//VJbN/y0PmNI3iIZNlOwr88w7WIFtxXbDNbdBkcG19jRPSSf8m2SD+yn9/k2yQf2b/8MP0Hmw9YAAAAAA==" />
<img id="flag_chad" src="data:image/webp;base64, UklGRpgAAABXRUJQVlA4IIwAAAAQBgCdASpQADUAPtFWpEwoJKOiLmgBABoJQA83dYEz/5yABEC+g7nen3xnXqPaj+mo5H9OECqN+8AA/u2QP/8ktSeLIy/3o0BXV9b3HW+wSzz/OFjuIRN/nCx08fNpqZS0F1b+G3zqJBSvBfq/pablK8dpG/l8cTS990mRaDucOeOcY4ZfUBE9wAAAAA==" />
<img id="flag_tanzania" src="data:image/webp;base64, UklGRkwDAABXRUJQVlA4IEADAAAQEgCdASpQADUAPtFcpEuoJaOhrncboQAaCWwAyNGhO6/tPHlcjRBXkfEA6QHmA6BX+49QD/gdQjz7PsUftL+4XsZ///OTetP+n9EP6OPeogVo3/Fb1MMFND8V+oN+on+5/lvaIR697kR89TPf0sEici7q/hHE66r3Qym6r7+4Iom1r+/TNrMr8GS7PyZgqV/L2HvE4N+fSAAA/unrtxil/mCe/3f58BCVkMl1sUW6sx0RqSx54jTI3BRjV+Tuwp/zwh3ANYegBQz7WqRsRpGGFEuvRMVUy5qdHMFWTfOr/sCJ1yDssfx+2gcjiZkrugHQgTcxo4xwI8Y74YXWC/Hob9HJTisEq0rsaKsETyjAZVHJjmqteergU8olOcqwaMLx03K+4cuYBrdrFbuQOgOKN4lnzzq4Ed4BxvhDXzeYioIhpKaLMxb3tdz53ktArYq7+G82oskzpMkDbycEGKjtaomzFgp/X2i9wQC0d9wxpJvSF2bOfRHOebtnt64q9rByAJcZQEPJHs07M+qC94QSrlkqAe4u/NeyrrwlHFz5/u31m5Wj++528jLADwB4OshiL3ONHTtl8wPdnRcKD/sc8HKRsNWDgn5CVm5ayq4IxzpN8z1aPzr9g7JLNzryLpwdgCNwFvBK7tYCB7cVZZ3jJOro5arYzMWEESfbvNe5SipzRBs59wduIgrJHxL70UudvFsVCpFMpnl/96sZAEkJzotiaOcywS5ak0tHGKQJlWPxRxTQvvwWSgp61uQU1I0zhDLV123XybOu6Oe0rfmMwjhDF0lndujhWN/20nlgENI/+BeQcFkcDX8xGWLgbd07lwe1gCpVGUvUsMp8617JRl4hCYt9gu79vZCYGiUTKh1tby0jb04YwqX9yAiUZ2zdd1Vst6Zt0672fwdg35WVLX33eveEdPtj5X0ON+RyPTbeHlqpi+9LGc0Et7vpssyDFhp1agi/z8PRG2of8erRUNikBXQKD6XjoHArjkF4fizH9kGqqpkJZg6N15/ZC/g4rxNFInTE//NEXjF5S+RJXqGAWw7GvHguK9K/wY4D+DhjM8qxxUJsVW2u9Y4reXfa4x7UPjo6q1pEcAAAAAAA" />
<img id="flag_guyana" src="data:image/webp;base64, UklGRugCAABXRUJQVlA4INwCAAAQEQCdASpQAC8APsVYo0unpaMhsRYMkPAYiWwAxRF4/lfVAWQ8ByTXJ/xDhdTzQgPyL/x/UA6QHmA/Z/9gPfb9H3/09QD/q9QBvGn7h+lo0QVyPrWno9KWOZ6KfpslD8E38a11QMEwufU1t8mt+eBjgnnZdyDPYmMSLuldu3yl/FDnqd5Uz94B/iC6MU3bFvYAAP7eA0vUva8S8u5C2dAEj1U21fI4MR+f6EPcgxf5MYFtopfHTVaXE76ZUJmMKCAgtV04GMXhYhlZ9Fp/hee/WL/j278PQ9QybAbWuwFUv8Ib79jOm6/WRVM5Rjz3Wi4T9HgX68Ni2QvpEvLK1Zd9qzliYx4sOG/HHKMPCXVmCWj3ymXAXmADEf+hDAXXhTAoq5lUVTtbRiCtj/Oo5uAbS0fySvbVIP5rYWTSEm/IegNM9NCO+F9RZWi7v7MKnZqL+4WoCyLKYCAnQQOAoI/cW/9aVS4DfPR2YbslP9JwXio7ph6S9tjQ6+Qz9k4rr4m2RwPohr+vnWbnCFqseXsBw770GKPwav9BUJJz3W1sf+v/jR5zwtoYTl7p033Esc9IY039cw5j6IYpnkwabCkGEVa++GE+zsCdkb07dUXG7Fk5Z73b11ZnWt+ZDxcLPjsnsfBOVDcgSTV78+lswBu62uSlc9EVkjqQhEtCkKx3XTR5p3pimeFlxgoE3AxCr0gPFx3CUn0l4BIpKetwQa69dW3N0UdqeK5P/t25/ZxGCmK90DOcLrTljZubkPtrIe1ks7U/wU9Gfrnog8dBo2AZ3tCrsClwj2Om4h+RsfT6U0fBlJHE/mMZJ6zMj8laCRI5jWfqR0zeiW0s0h/E7nZ5pH3W7zko61YIGln+29RhbTDzhfTv+QbRd49Bk5LmnmurxuFLhwGIrEZrJnYyTVLrEQwa779AvhLWwa68m9DbklIMo+e/kJJmLqTCX3wRw4zkwE+UvLrxMCoAAAA=" />
<img id="flag_aruba" src="data:image/webp;base64, UklGRgoBAABXRUJQVlA4IP4AAACQBwCdASpQADQAPtFmqE2oJqQiLNv4AQAaCUAPFNaA/QDppdMA56D2UwFXtu0QTQH71sJwnqanIFhM9gRz+llEKA6ZSTAAzVXQRenxaCCuGBm72F++iyIaKmebYz2r+9LluYG/pwSIyLau7ak/8i/xTWoxE/4fjER7t9/67T2F/n1ahQnc3bgph/vAf340De2rDKi2hRJhPZpvuR/YLvCjp6AgOFG16aD8N/yaAzSKFVHuQsLcLu2zwpfndrjALvWEyJHTX2dUznz1mM1fp1mM3LT8q6P0bZ3+VdH6MtT/yfNhz/yfOQkxIJDX5h5AVZnIlInG3I7c/y1474AAAA==" />
<img id="flag_somalia" src="data:image/webp;base64, UklGRsIAAABXRUJQVlA4ILYAAABQBgCdASpQADQAPtFirE+oJaQiKBZpEQAaCWcAAEyOBbR1GvnTG7slXTO7QKLJF/+i7F1T8JmPM7JsAAD+5cbafps1ZL9meymh52PcH/8GyRTXZH8vtTEkndxSP1hoOB0bqH2kUJ3BmjrQDqkHIlIoHMe3KgZJ3mOscbeABy55SZJp9AKmPb/3vOaaqDYevT992oGSqkUQePx80aJTfr7KjUBuvmUFXPjHDgw3x+vBzcNR+TAAAA==" />
<img id="flag_libya" src="data:image/webp;base64, UklGRgQBAABXRUJQVlA4IPgAAACwBwCdASpQADQAPtFcqE0oJSQiMZF44QAaCUAat44BGDPIsnn8B8fVvaFZppmVnXoMulK1TYJH6U4n7EMMPcuSD1IVNIrgAP7ipPcAgURff6+8oWnaq3DL//pNn/9Js/oyfSMBXl8f8bs+JGW0IitDI/Ytv/RhRxdjxlVbQ4zVinvafOCA+v37zPwvVq5CtDMWKMyr0tZ/nNMt+9fb8dO/v2XtCs9ZFxfrHDBe9BJs98/gzdWpqPWs85zSRwpNZw18emYoH7UOb+LnzHqiWghrbKRbRFxdYLVgWaoDJMmoxO5v/u/CHvB78FORMExxSqyXEWcywQAAAA==" />
<img id="flag_slovakia" src="data:image/webp;base64, UklGRhgCAABXRUJQVlA4IAwCAAAQDgCdASpQADIAPtFgqU+oJSOiI0wBABoJbACVA1LHjXmT01+u4v3VA9QG2A8wH6wfsz70noR3lD0APK39movEnxMsLn0klKDkejd04IoTalFYVzbBdYfG1n0aznr6G5gnGUbx29StxrRnxF/19VoBE4aNleg8Zno4AP76EF4fjmLcYNM1UVsLZ5Ph/AZ4r/xKOl1BuAu4/gzseo8ccnP4wo9sgww9a3zqClsfRC7m/3SFMO7QziV0MYh7urvFFSqz8/5hrNoQrb+KtNCsZ5BKlkjXU5UEfvqPV06HyHYGOQJ+oi7j/8VOy/5N2GgXiEWP53nG6DJ72vO3P6d+oU21E0HMWc2xssCVLV7ZsefgSuvpbVFakkxQXcSArwzox1qj06QGtHi1vP7+/ABL5XZ6NozOvAiwnWT4Wix4+ICrnljlbWIA4Pzjk4GmxQme2GRth80sRika3s8Qa9vUvoTvsm1jRAOUoP+tJkUj5869aURubNdQL+gdPyiB677fS/+bnzf6lgYcw1EW+fajqOJ/eRsHvZHBlAo7/lX+M8ZBQO6kMwEwBtkm5s9e4D+os5rea53MJyytVR+5ic3lvvobvV+72BvRNZ3UhO6ucqJ9wyR+Tl3ncnFNtxuFE1SXK1i51xKRu+XwMEA2Bf46X8p3Be3t1naY9mDqJN7B/LlBbrf37jK4Yl0BNsAAAA==" />
<img id="flag_american_samoa" src="data:image/webp;base64, UklGRswCAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCCGAgAAkBAAnQEqUAAoAD7JVKNLp6SjIbMznVDwGQlqAMxVgdy+KNDWoX6X+oHub5XL9Zvcx5gP2H9fH0J///Hv/Zsrr/8T0JyUN9XaY72f6AZq1NKVA99WmR9vySoe5j4C7AjRBMF6k/t80yOi5T+30kLl44IJkw71PPOyMxvr62D636ghXlUbQZ7rL8/nORGAAP74I2/4hzxT9ylVGHuqW0Ip/kacnXdS+tt2U7s7MSrZzZiBV+OeOJ3XOfWYmDTU4AGbIcB9ap1IpJ5X5K2TWIDbMKLfwihZagXn/gaRNlu8jQc3lvQoan/NTWFtLB02SPA1EuF4MRoS8In7Naz3M2GwwvxKgLq1f0T2DLLS6fILInybchstinPJRFRnNNeNq+h6f6ykCoEPUwT/uNwr/UAAQ4fu+7s3s+ViOwo6B9jtfEBz0Q1EM0ygOejK+Vv4PaYIQ3wlwmtVkn/fT9diVMSKUoTCzYpIEdLA/Vpx8eW1/swUBwaS9RbcAkBLpIjEk0pOeXYQzv4g8DUS4Jk55w1sUXUV8SPNB1I6FrPzAOc4RNc8LOesrbNt16zbohNM3eggF+Kgi6HS/H5zp8/iX+4xYozbHu8GQPUoLSx/R8Zv2zr3Ebkwnl7wJbvoBsajCkfkX3cApYs2r5gkpUdxggIV1PsfWMc7g1Mri7TE5Zv0njww8GCuB6qB8Jx4eVQv2cQ5pVoD7ZM0/gMGt06mNwbr/eKIBrvPS11lAgwHrOtFEiqsEjYOZBnquQY3S63kvviggKgUoWZdx2aRwPlzaWx1zXPRiMIs0aCShqwiQxvg4+97KhmooviR5oATTX1M35chh4kqeBw8zYQfZ7ifoOHd2ALb5UAAAA==" />
<img id="flag_hungary" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAAAQBgCdASpQADQAPs1Uo0unpKMhsYgA8BmJQBKgahb2aTAW/+BY0hKNHy9C48B6EvLHzJSHKD82g8AA/uUK/7oJf2d7/+cS+gXgL0B5dQ/55fxsFECVS1jsGBFs/H/wkqnLh3/RJUc29ubNjR00eeBROEoqXAom/hNo77jQsAAAAA==" />
<img id="flag_guyane" src="data:image/webp;base64, UklGRqgBAABXRUJQVlA4IJwBAAAQCwCdASpQADUAPtFgq0+oJSOiJnQKgQAaCWYAlQNTd61+RkYA8QDpAeYDoH/9D0gOoA3jvI3qjtlgMXPs2mpWibBhPCLlBcFAZdZuih6OEITi/Nt9/AZAxM9b1L0lC3UAAP78Ls8SPCqHAC4TcA5IjKNQUTJvxgLGlX//P9zcmM0tWB/Jx/TZAzyMda1vq2ufLkmst49it/LaVK5JjzZKrkg9o/nKh3i77lWxi5qaVFEOjhKuh0sAFMwJCJMoCysG21wAi9141Hjklu1q8gVBsIIPGqS5c8HxlIDKVCTprWvq2BlT3Dx/YJdHaQWxoL6xD1+n3c/Z+pGl/ni+6vz6PxxHl/vN0lXBhjwBu7d7WraP0Lr7x9+b7R8HmiS71J+b3/OY/SA9RP6rvZrR9DitOoA8oE3i7vhsRpZ9f97xDEaM8DprJOrTsNB2qnfeVPLLTJiXMf0DcbyYVy1ERb5e7BBNpvPGlRvHWXPT0sJ/KRvbBvJ1xDKvdqoUDvReKAU7SPVZj9Hbud78QzLMAM8RP3sR5dPVeukCAAAA" />
<img id="flag_sierra_leone" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAADwBQCdASpQADQAPs1Qo0unpKMhsZ6IAPAZiUASoGkhzAAfmYGI52xv7XMJSucwCdJCStpUpSq/gAD+tlf/yDH2NfQ1olbpbfCIHM/SRxsHKrM8b1MjLOdW5N9jHTIijADX4UoHZH2AAAAA" />
<img id="flag_togo" src="data:image/webp;base64, UklGRnYBAABXRUJQVlA4IGoBAADwCACdASpQADAAPtFgqlEoJSOipFgJOQAaCWwAeIX2a3DYteoDbKc+9pgG85kqP8j5vebd42aB18Yrsw5vkH35xCRhV/WG0GoA9cgPjcIqyAD+uH9Hrj3BySpDw4Sa58atXUUk+F9w3Kf2xJGieAAsv/+LMVvgYZX//+rQ/5ByL/yGVhvtJxoXxBS7nssZY76Wm75LsVD+hV4QAuXHfaLSwByHOWWPTDxTT4TKif/6sWnqbSFW04lE+2XYfbFT5ZCPDNv5NMHzQgKSGfFu9sxVrXC3gETDaN0eJ4UO8mBI0tAPvmAfOZnu/Vx6JFADjJwgpy6AV5DCHYPnf5Wv7OsgrCcXzBGuP1OEmIHBdE1gQOF8gpNXfECDaD3TGp5FEDQU7Uzhaj3qpfABP8ShmtCCZgnrUXVYFW4mgQM1BFYEYouM4+qmOHpIlw6C+ZwGj+B2kPz5gKyHcyzBy/VAlov5QYeQfUSSAAAAAA==" />
<img id="flag_uganda" src="data:image/webp;base64, UklGRo4BAABXRUJQVlA4IIIBAADwCgCdASpQADUAPtFYqE6oJKQiI1gNwQAaCWgAlADU9uJ70eY4/4FxTDJ/tH65OmAbvi0IFqCX/L+aoZXxH8t94OwDwOJUtN6cocAoHH/7GBxLeBdm1f8mgol1DIXZx8AA/vrmu/xgcZirMP/rC6v5hc3hGq4rYIqOi+nPQudpOBYq1R/f+KsSxtsCMobD2Q2Ijp3wgADF4P1ulS1ux9qFJgzdtOBe/5S6Mlbjwc4KxFsMDV2w8wwnjuUC4c1MjXJhVfg9koabNTqqM9Hg2b2Cu6124B2HEsohFoa+/HB0ZwAsP5hgdRNdELOuC8TGsrxwDvm1fuDfwR9qZAECKccbr1PPrM0H1iUR1MPzvU3NjFi2jjQmrM/zGCiLidlxgMzU+kJGUNh7RMKd8RN6GPRBwLMxVJpuek0YWeFhJYPrFMrsTsdd2J2/VEc2GOYcxEdFjyhf4/C8fnvioNeQUdVWjZ8IW2fNACdwlMkb7vP7f6Twmkk8TdIRZKrsXB9Ek2iAAA==" />
<img id="flag_tunisia" src="data:image/webp;base64, UklGRsoBAABXRUJQVlA4IL4BAACwCgCdASpQADUAPtFirFAoJSQipNVaWQAaCWYA05l4/qupldmk1egA8wGONbybMPOkDSds8j3K63yxjtNZbf/BvjoON0H5BXN2NZb1kxgVUnihD55qpKHjXrVTN8kAAP7paRMPC6cPfqDP9QZ/qDP1Dn6MJ4A7fQfE8Pu2vrz8s67xab1565VOQ/PklA/E78+IRVd/id+bHJOzIUHoAIGrivVaN03Mzmy4yPyI1rD30Sd8cHXGKijMZQmsF+haduUNsV8PxXlv24V3O9he+96oDNUAx+zYy+F2KlBIoezn+3lzspqE6Xi/czu5kS2syZY0UNUlSproYN5hOFfJ1goI62XKtDeoCremIf/dV/dYrgASyW0KNAtdcZz1uIPq9yXS1zQAC7pH7r1Vy3S1ghQUZNRk5nhuKqzRnjkEiEfgofBfexFsHLCb6NaDE1UJMRtZwxok3rfnYT/2T+WQgagyaG2Bb2aHzCuAiYbZGfpovqeddGx5C/O9oJ5BP76hZEME+ak+e3pPJoy+A8CmvY67fX1E7J1Lbx7b7jrqd+j3Vj+51c7jC1q0g3g2OMv9xJPywR/Oilx3qSfg80AAAA==" />
<img id="flag_jamaica" src="data:image/webp;base64, UklGRgwDAABXRUJQVlA4IAADAAAwEgCdASpQACYAPsVSoUunpSMhszOeqPAYiWwAv3GB2d4bfb+NV22MvO1icB+afQA/x/8T673mA/jf9i/ZL3sfQB/0fUA/+fUk7xl+3fonf//s/4Iu3bRTORf/SsAe35jntByuHqvZnbqABf7fXpaj3qof7TNt9Z2MtPK4WG77DMwsF52vrFc8Ei5ZzTeMKZA0POKTamRTYXGwAP7yXVt5yxuxAVd3xlqsFfzDqppOeECG6ZHkeyuEgyf57fvf5h9z4bj58dUQL2Ez3cYCiN1QTuQrenyKDNC7jNRw7xY17oH3xD/Bk98kiqzJpf1m9YCaj6AdtQZy6nwbNExvzSm7xUjhIgza82qcqW0AwJ9tITOmMcxaEX6YuXrnGZazSd/WTSVoam2FU1zmI/rZZNVEtcYA/vXsWxFnzlAAneaYnH3IafDQTDGhpxgufFjIy1mM4BeHTSDLdJZDdm11a6n/5UjDmPqkllxleGrRc/aUuMK5GK7thMCcBTYKwXqsUar9/vLruINuuAGsJhZhyFs0tLam2BfQuEYw0rLSJo6hEs+/Cf4t3fa/xJCbnynsYrfg7P1bT9jY3GDhfLtYXE7gb2MGa+BkpyMtqouYwZyGo44AOuLw9U6wmG04HpKlazKO1a5ToNwANRwsxP5fdv7jTzAmF9bOWJDXiPwx+MjOweTas6y9U6q1ai21XHb17xrx/HwzZdIsS/Ds7YvO42QzTWlkatTxXFJbm+zI9vR/PqHJGjyZuPEPhqOp+ysSdIbsBoewHCM66WHoBNrRLBuwDWt2zFYO35P57Zmr9vWgQYg9+iyY8Nis8zqueTXOwoDUVc8CCLW0a4NGrktVKit9Y85Zb/epBZaDLMwFzyqFe1sKWIWxNR6D8BfQtp38pLUaGVuJubKoWTOD/nUpQzuVaWYDWtPJhqZOWJSf2JR4d8HNA21lNGCgNmqx/wkDlmbjyTOSzXkVeUjz0TMZ8zdizOtjUIp2rEEmQcXuNtM4+nl9384h+jLqHZoqMdigAAA=" />
<img id="flag_kosovo" src="data:image/webp;base64, UklGRkQCAABXRUJQVlA4IDgCAADwCwCdASpQADkAPtFeqU8oJSOiKBM7MQAaCWYAaR3zPGsUi8wGOM7yp/r3EAcAYw3nIeivYA3Ss1Ire7LcEz6SPkVdQTxl3EOq04Qcjo4B6zMJjEoMJDayRmUS12SjOt1RsBQPAeZwAAD+7qY//9wfqD+HiD/160ty6Lb5AkaBSLMbppYWCMgvlOp2G+j+jAWgbviloiGMyPgknfVlAem07FQFn/nA+GEkq+yFkKo2N+Y7oWTC3hqMk0os/v8jIBhtsg133+ri8deoYuUUm95AnhKOfsSE8zx2FsderZxirPCUc/YJb6349PPtSPAV+xsBSiAh5hGwiZKm7B4ytiWr12+EAO/0GxguVM3DcV0pf7mwgPWNS89nyFmhjyOqWwikzWHkEjTiDSb4HkM4zs6X0JZMF11N2f9Sx0w9oYU6NXz7i4ndXbYoM8Kx0/mReEJRcTUspg+nl0x9OD9n5cmZtv0dhGLW317aKcItl0KQEhADranmwMqJpZkE5pRqESuWEGUlNQBAe8dAZBuvZD7DWsx9GUJibAg96OCqN7WvfbRbvosBhS6G/DnOA8wDrOn3PY0ClCSETwBjRobHmcvwCKzAcPaMYKWSQ+D8f0S5QaE0yBaKulSTwAVSZrQqay8lq7R9ptX1a+dSTwmLfvG5ewAVazXFH5StDIZ957DzOMHJ3fNW4bniw1gUp/JQN7r9qzXDE1+w1WWRpTzgpgebGttdk6dLqMjbZqmuDnhdpNBdygLo8AAA" />
<img id="flag_uruguay" src="data:image/webp;base64, UklGRsABAABXRUJQVlA4ILQBAACwCgCdASpQADUAPtFoq1CoJiOjpngIAQAaCWwA1Pded/9uz0M4JoGuf2Uw3wDi5cT4s2yJxpK9LsdHXRevV5rAJKii8OzeNFq/VJYiYfTPAbB5fa9qMgIUPVN4SabUAP72CQQ5PL7BEr+GjanA1CPd+xo9U30YjvzhkA9fmSwFLN/HMqSyIYGvwre68jUzPD/i+Zz6ZsealsaaaGdGOiTfIJxdRV4FqOFBkxJi+JT4RFDKc3yva07ZcGk+39poxWivEv0ntz2wVTGPSyyI729SovvDlkrrMLHBlnmBZociwrgCsGT+qsvsUOAERAinru88vttU47UkEDT9sjcJcIVJ3eB3WRUEsBN5JBVMruHrx7TM8pT53x8ZCwjJkNtOQGkdjRRFNqTW+r/OUYnkC43xygsqVUVBSZNLSNS2FDK8e69tZyYNcV50QgudxhwX/NPnx5gDsCa7xa5FwPHAL+6bU+WIgBO1GU3nr4r5AlJgSnUZxT2YwTj4daOSCP2+8QvJ/UiQcVUFz20br4okNDF8w3PbS/pa4r9UQ2xX6fpf8Ib+/+EPFzCQFIBOnfbFAOTiAAAA" />
<img id="flag_indonesia" src="data:image/webp;base64, UklGRm4AAABXRUJQVlA4IGIAAACQBQCdASpQADUAPtFkqU8oJiOiKb1YAQAaCWMAlQNEK5XJgAGrgkyaGuW53iar9r0iE5yD8AD+2ib+aIlxX/8zR2G3ydDiBuXqFzQfssXr6KIf72Q5wtFPowaSOe5aQAAAAA==" />
<img id="flag_poland" src="data:image/webp;base64, UklGRm4AAABXRUJQVlA4IGIAAABQBQCdASpQADQAPtFcqk8oJKQiKb1YAQAaCWUAQgC3/wJCRzOq6BIai6N6xyZScUaK2wAA/vSgvBBZRdgnvkDlnvN/+xktV8aIAv//8cXP/5SWzf9Nv//lJaoE6OxXehgAAA==" />
<img id="flag_gabon" src="data:image/webp;base64, UklGRpAAAABXRUJQVlA4IIQAAABwBgCdASpQADgAPs1Mo0uno6MhsZ6IAPAZiWIAebHxreYfAD9AAMjvxO86zcTEcbTcXqVEq42eA8JVB4AA/ru3/+Nm5lLX/6D64boyNWnGU6ytDLsRmHjXemMWF+BaSteZk8YBG0shp9H5I+bf6OSP8Gqf6OSL0atH9aA13yWhV5WAAAA=" />
<img id="flag_mauritania" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAAAQCQCdASpQADUAPtFkqU+oJaOiKbK5IQAaCWQA09V4u9okGEA3AH+q33LeN0aCEAGqIzEyqGXwp/Cu2RypB41kyS6Qo30PvFq6vWQ44sV8gAAA/YxoRnZ8jxf/i0PmH+DW5pGpj4V5fRFX43idXo6xyAkKGSQabDViws7qLYZmSTY4xGh2xFtbbuH4ASg3uN9gzETegFlnjLHos3X8BDLySlCXMO8Pa2iMIofk/UxNEnoUXQrCBwWXCNBPjdk29ByqcvqyCZHM8wTnrvKsAjHuLmX2pmdDa0va+6m5/e1UL87do6zeKS4ETigE0OnCQ8fIhlTM2LRNDLctMLRtletpLm7XeowFYJkyIpbhylrpv8wbej/aBN9OcFCE3OQ1uU6sDJbZEtqAbgyL8SbD6oanVtHuIP6Gs1GAwlqL6840tGsC7JTYoO1EtYFim2aeqiaNwvCBwE9NIEcYPt8o0uQDsMFzwg5ND1SnZGyoAAA=" />
<img id="flag_puerto_rico" src="data:image/webp;base64, UklGRtYBAABXRUJQVlA4IMoBAADQCwCdASpQADUAPtFapk0oJSQiKBM92QAaCWwAePFEh2/decGNwBuYHUAbyr+0RG47twQHXmWY0+SGQzW0AcDtWYPiKDQPDJvFUlDrCsQsaT5rFyLjb//JdQep6nvZVu6XNWBeSqNAAP7miQJAJ7wW4BrrDsjIx/rXJwgEvsPxYFd5r+p6y81ZGgbC/+db4ITTbh//WpeZ38dnWkFwABzTOaNZgleWB82M980QB2U27UTEpP0eqZzLyHCtTf1DTHubQf+X8Jdd0yOqne7/7CEAuWmjXnYE2zzSwP3YiIB+zxefmqgK8Gq8rLBfgGkR9c9p1xE7kEm8lO0xpZtjwC3eCPQ/j1PDZlFJBchyLlwBR+d8+zWHZdHrY6nMhZbVR5ugGfm8ye0/YDKBCrqbirYQIPyv4OPsY+x/Q5AVIQsO667AZwhWTowagwYEe5jCJmt1xRrqRSC50vHDwtC72rexDfDOE0xHk/v+ea84Qm+s6OfH8pKHLkVUMUPpm/ko3speTYvT6Z+9H5RthnEJ7xsX/DXbwsjxlVA0GQGCryUvhklCrOJRb7WwhxWi50akgSRDayFcexjXwB4u2v0HtzpoIz1/UcoUcAAAAA==" />
<img id="flag_cayman_islands" src="data:image/webp;base64, UklGRu4CAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCCoAgAAMA4AnQEqUAAoAD7NVKVLp6SjoazYDVDwGYlsAMyHvar/wmMb1gPUftjfMB0IP9vvgG8sV1h9Lxq2jNnxWM5t35KBwC9sqH26MnnuEdiD3p5VSyo4C0xkyO/PSX9Ju+r/b4SeGH7O5u5jkSz60CbfNzFpdLYo2AYAQtoA+WIRwOKE5AXHdmdWopeNQsHzfjPXVAbEHQfbFqsoR+HS5ovPIeOcks3pnfh85yO+63z6ASkw6pkplxSvV6NmteMI6rnh3a6jUOOeoj7NPSI+1OIA+5jMIXjzL4svmP1jfzAd1+GXdouFt6CCNirx5pDTPxafxDdECeuvPRB6xeQRdfRo8GdwtXisMwuC/6Pn/h0kccaxWv2qKP96qm3c2O/Z6MgSFoGK/JPPKiFrJ63TznJvOrrZINIjWNfMxlnIJPQMk6b5R+G5KszP6Vb3+2/s+dwzLZAKIr3aOPTmGS2k73VK++/n8JfvKtpTMy+xNya3lnJ3bnPJwHHQ3DMgKiwUu0XgOUyMew9+6EBXdpvTfrSO5agd47hx0Rj0LgFCB3W26YGm8xciAg1yl1C8F7/XHG2X/fdlmdkuV5mV/2/9vKVdnQMKVPx1yRN+7KamwBD2W/fBru+Zh37eo55r0UeVo3BOYPssFF16+//rAWt/nQRGP4pElP4ZKbERLwSgNqpLoGF+SHyiihpP7+iX+mBNvGKR/aJHdbOzhcMdAYVFgVLVyphV5RohtDIUswv1fht09ILB+6eRnfE6TtxVOmiHU7qhsFlPuahXzXJM1MDMbK0G6En5QFhRCL5elzHdcX3+Rv4SLgR+0CTssW9XRmugbdWeBlXmCvssDSdTiAwUhjH6osIMzcYij2PpYBqkxHdlQKQM54Uqgd4RVyE9vgWh/1xLPe8lkAHwAAA=" />
<img id="flag_laos" src="data:image/webp;base64, UklGRiQBAABXRUJQVlA4IBgBAADQCQCdASpQADUAPtFUpEuoJKOhtNToAQAaCWQA0fXvfqv4gbCzZn+IEuq+wAQQe6AMKg3LLbRyjz9Lc+Zr/vPKyRaTn+F/1LhObejpBSqaS206SRlELTAA/rhrvY01DbT/f/Srif7VzVM0KPr2Dz2Sad2Eg3PVOvCwARkSXdDrO1hxPbZOjikmd5dwVbN7KNHvMhOoSm8usd1GZNAz5J5M3UWOmmR4guy21UB08UCmpmZunsz00PryawOoyT9IVF6Miny5SVXDR0Af28p1MGPXEGNnzWCdJ2ehlKH/hdiRmOqc/ARXOmqTDj7r6k/k6DqUoEeRGzgEh6y2SYEzTOLSdJlilt429QLSBGYFfv2vhMmFmWAAAAAA" />
<img id="flag_bermuda" src="data:image/webp;base64, UklGRsoCAABXRUJQVlA4IL4CAACQDgCdASpQACcAPtFUp0yoJCOiLvbbAQAaCWwA0QVBOA/rPGq78OssqPUZ+G94B5gPJj/W73T7xn6HPlu+x1+5lhs10toMsDSuM2ftOFG2+KIMgBKCnSN5xSEXFg1bszWaZom9jKBuX7PNmr1vFzoQ9sGd7RV3hsGbVjk4AAD8/27g/F6dIrODBoejgVLC3SV+otV4IXyUw8nXnxOvKX2ukBZT8lc/rqZph+QukI7mexEBvvtdNT1fabjiQdV4GBmQ6qn2oVRGjUhioUp0iVxlsWTaXOv6ES3y9xlwSTcnnCyLvr8ihnbz/1rPt/f/DOtTcWnmMprRUzrGmlxwz2GSUJ9I1dYnBaXGcmBZNxw5c4lV/0i+63GXAAKo9IuroT+42ysiX7v0ZUL2hPbQ6YJNl2+mSBcN4gr7IuZamrZrxF9DCG4U+n54cMKE9a76vZVGRj4PDb2dP1HgAgwHyMTBgaHJWPieInb02QcdN+8obnzfOe34nAaFztsKkOk2g1O1UaYJ3wtlnbmXjCe12zM6OzdZ85zMQaSa12alaFBOBhKpPRuuAVKY9IcOUh08lLR2F7Pylj49FhJEeQUx0B6dLIcsrovP8TLW62K9voyNQ6FBJ9bxCLmc+QcAn+uEtUR8fstrjuHEzX/GDJhdlNlc40mu8KhQ9KpPy4sz+OiMRnBCkrj6Fldq++clvB3Vrbd/XYfVS0DK+Zp3Fvwb/ctGRCjE2ESz7yGN54flXw6/0GLoDSFgpQP8dDs8v4dcFmkVf9gwwCYIR4g3F+Iu1dtmZioOTQAvEUVJCkdJ6sICiAJVeuqHxfpEPJtuf1IPEQawzjP0xvMeIhPJuHccDW6bE6ZzRb92GNqQehgmYc6px4/gblYsi+2xOaE5xCeLJxlBqXgNcE+1bjMa/FrS+gjzKP/nrHm6AU5+gAAAAAA=" />
<img id="flag_dominica" src="data:image/webp;base64, UklGRhACAABXRUJQVlA4IAQCAACwDQCdASpQACcAPtFap02oJKQiKJQNEQAaCWwAyXtt/M8ctvxC/y8/xXsA2wHmA/gH9J/Wb3lf7N6gN4A9EDpb/3Erqps6ocQDBXyNWPiK5yPcGWfZ3mqrSH0c5USfuGJHoRX7s4/lKm9Lx+9ENWxj7hKofmA0AP6EZr2ePCr4oBF5jKpHt9t9y+4f/5SvpIKcJvuL9qSgrCSpXDlsIBV/m9WHDbLzp+Mpzz1xvv6H/C9y4TX5uRPW5zgDWReBJ8upd3Z7NM4n5gI6Zv97WcWhjnv+/0f/wrfzlL3lHANQOgjNw5fw4s8Rzmqalrn/f/ON4l2h/jfl8fxfoWzlo0+TUYPsR9yt1S8KxSSQAKRvZyV47zvnTNdwjh8zDs2oQda8+Zf7YNpQRl/k+HtouvaQ1888Zrotq5oky9X9R0Um4Je/zIFh5g37bR5rKAmH2xzRu8nDyojr5HvGORV8DLtgeFvMAIYH1AMFCUkWbrxO+Pfy6xbKEgQQcZWR87fqPhzjJgPLHn0p2rxCsPjoJ0AFhq7Rf8L28vNkx6Yj/cqYLMf5Qe51EXkmJebBPAgfqzVDiYmVqRQQQ3ruutdYcJhDmrGKKp/K5b7cYEu+E/3VQ3HskPW4yNgAaOaSZMZjbpX/4BDEA3wBXoLRDrdAokML31rtPlxnZoYhhZMtn574NSlmAAA=" />
<img id="flag_south_africa" src="data:image/webp;base64, UklGRogCAABXRUJQVlA4IHwCAABwDgCdASpQADUAPs1WpUunpKOhrnccWPAZiWwA013Au2/r3DhdBPFHgPEA6TfmA8+P0l/9L04+oz3jlfrAAJVT2iPmyU9EUpk+WhsZ8DTRomQOGURhOPC/nIQ9cTal0/axBGi350rEfQYN1iXatB0EJ4zsSvbW6hneTRYAAP6dUeAl1RFdpz51a4akzh8ffCkbs8AgcKwrutSpxw5A+biIGn8XPfmuucwPTh/8WhMsIEOVoGuMdiV50O78uxqyidVSf+Oy8SSwfqhKUOmitduTRHMBSyLPSOBhfbl8Eu3dPjrAVvQV2SwfHHPUwWW0Ak2WpqQFiDkM8q2oicQ5ZoadE6wKbF/NJe8XMtZMFb2xguGGIrgjHFRYB1GUcRCPv6KLVJXPE08zCppwh6Oj0Dgtb7wYimSmVaamAd94I8eJplTTPuUnRL6fuim6YY2UA7kb2Chk2srF3bNY02zo9blT3SCv8Z37WGQ9JbnpLSPTx7YE0yLLsO5dYruWsvwIo/UHCz18ypnIRGF4axO82ZijbV2VXKPxmwuWE0t9qwFt3Q9a9UwDAY2l0lYZQWM41F39dDsYztwCpkyhZTF93Mypz2eAduq9g+qOM+Nw6suXGFzupDgq2L27afzzF8/oZBhBydWr/mk7Mt/rnUo5SwAuT8nxCGNHGHbZL8KEQ6cDbVzOihNZe7jrPMMs11PU9Zax8pewIz6D9+KWgNpYo4KcL3qDQUQE23HgPT7qdUqP4mCx7K/pRJZFINqz32xQJ7jg0Iet4A31Eh13PXOZ6aXS007oj9FZad6kt2RPxhodOrbLfEZztKAt2BSj1cUwuaJxB9aIoZF6qKM7gAA=" />
<img id="flag_albania" src="data:image/webp;base64, UklGRg4CAABXRUJQVlA4IAICAADwCwCdASpQADcAPtFeqk8oJKQiJngLAQAaCWYA09WBvA/uXH2ZAbZHcYbxFvGX+PYIK1WWZpKWbiYCkDpvw+2mHyAOe9jYHN6RV5sTBr5ob4JYFT2q6LNX8WMuxw83zzxOKQQsWcgxgAD+6ez/7Ew5xOr/1aH/LQ/5aH1muZnXqsubkhQzEDwShL37QRwNyvuT4WzHXNmxfHXNzbsbNpAq+hXYCAkUb6nrLD7Z6S9sQSUzX1FxCavfvT/f8t2eyDuS7hWVjnWhQRqDnb92GKl813VWu17J8fUBWusgTgnfrIycex5kiPwJ1rtBAeZF/EmfBZQKjv0q/ia658bLEFSmit2ixMLtHInKIYgGp4u7Ox+NA9l5omr6qpVv5n8+QESGSO/+WBzWpHdviY4RJLSB277EC9JoiftfcwyfObvoaB2SRhjTz7TBPJdi+WOqb+5QxyiC/ZucUqlJS05k8tF3KZWS1eN8AeHP3sJplNxAzq4oimuZw7XOVsOL0qaS1WqTK/5dmkz3/OT4/t9ZvyqH2/i4h7yFPgTyaLpFvt13xJyX1deutu3VVKrKlfggmIgFT6oxSOGgaT2AoKg1EMlSjhVXsxlb9b135BOgqQF4ml/0cxKfnFRGjw6vPDPgPLhJ+bFEC0ITzPVxIOQ7whMP4Tjev0/4//LeaiHvdzBYoAAA" />
<img id="flag_chile" src="data:image/webp;base64, UklGRvYAAABXRUJQVlA4IOoAAAAwCACdASpQADUAPtFkqU6oJiQiKzkoAQAaCUAPI+4A/gGEAfoAK99LFrp9PP0nIre+0mzfr5BT52wMWTfysKbZVbKffGjj3IoMAAD+3HrI7Ff9fZD66Unzr4LpYcGBDZKPSZy4bnR//qJmtmmz88AP9/4dSz4N79JkL/y44p/eykqWp+zIGbYsCj72zVNnX0LdIK/STAThGbKSMDkdssjR3SmUrRUiXTrp44PWYAb0J+mn6s1y/nFlfoqBxkwiRfjMv6iambjxxRmngJOXTMKXzISMKXa8PWeDqo8ZFERnFwwukZq7cDYgAAA=" />
<img id="flag_central_african_republic" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAACwCwCdASpQADUAPsVWp0unpSQhsBTcyPAYiWYA05lBfmeuDd4wF5wL6r6B+fVz2T+b/q7lgH7KgGz/c8LkeTqZoZNl9mgGg5XvFf9R2uEjUwd54ena8Jd75bBmhFM4UuXfNezYRAAA/uvgY5bjmsqiP1vk2Xh9p1Embi/yCqVDmTZK5838bhuXoXPwaPu4PTs3OaInzamNP+Bj9b5aCxjCA3R2gF7FuLxCaiz6Dv5WVO3OMuGwFne/lOkUPSW8hLgndtHiXURfpHCVO5sMLowNGRC8Ssx0GiCn4BfRXYAAZ/b5nWfo74zINX/D+VellivPs0bw+nj1m7zFD+526+eQLVT+O4sod7xluHH4uzq61jpb/vJ/ulddDgENie0xDIFpeqZiHFcJA389pjt0U1tqbW3PJwaIAgvq66tWwnzfSafJBCalUFH68PuS26vDwdR4+nZw3dvn36yv/mOQfXdteucVUjD/TIffs3G/3c34IbIKmm7LmwUGRm4qQW9wEUyu0lkpTUzRwiqomY4KF6A0AAA=" />
<img id="flag_gibraltar" src="data:image/webp;base64, UklGRiQBAABXRUJQVlA4IBgBAADQBwCdASpQACcAPtFeqk+oJKOiJnVaqQAaCUAamLGpAHVr0EHeAFmCyAKZxk+eWp7pKhBiohq3uO5/lXDjGGG1gLSYBbO88AD+9lCyK19KIFLlEBkz4hhM5FRCGEtu8AmJ7R7ieCDv3j/gfYxNkTPvUG7rY4vFCIfz2tZz0afpMLtFZAbt0JWuKjf24CPPnGSXXnz/40i+06Cf98N9pzwu76A48LDUKwtBP2TbsrCOozWii3T0xEXigzIsqdJz3HXuaJwnnYXU/hPt9kkeuV0N+L9BK78+cuyyId3v9IaIAWqJ3wxsGbhzGAaA8v1ejvse9yZv5sTR68drR68lgNKepI10LvBmCMxNSisDds9yxjj9aUuceAAA" />
<img id="flag_cyprus" src="data:image/webp;base64, UklGRiIBAABXRUJQVlA4IBYBAABQCACdASpQADAAPtFeqE8oJSOiKJQK6QAaCUAPGkZlABtoND/yUlfgVN9moyprwY9UcasZDFDQ4Gh/AH9do4okSl1f5UOwtRAnqAAA/vant+8ZPjZ5HU+7fDXLPBr/cmTn/K81wrrX5+JPl+DJAKTq5PzDUMBxnHG0nv1i7ykT/5hsvboK/8vySO7L62WbcOhFttFclY91jCGLVEwiv6duKKEwYh3zVXDt65FbMgMNvJ95UlTFJ+HXp4ac9plrT6YGTbia8/Avczv5qnEid8acJfuckSPNrUIedcGrnFqeANd1GS5zxTyU91y7dmiTbasm/DElG9cKzZC6OA8leHTP7b4KHADyRrmcJqIfrOLzFXhSegAAAA==" />
<img id="flag_panama" src="data:image/webp;base64, UklGRrYBAABXRUJQVlA4IKoBAAAwDACdASpQADUAPtFcqE2oJSQiJnQM+QAaCWQA0UITfmbtn6ADnkNMA3n3/yo8EI9rSXm9rQILQY33yJbjW3EpT44F9n4Zm18nduqU1Tw+7qgg9e2iwLfC3w1XTa5qQHc6HmnEIAfZgcMAAP74/MsGZ3ksIypzxBZnhSzo1/CpcXkm+d0V7l1O1vVRh1oZVaAIM1f5Vidhq4mIcwYe4Ir8DXQVNEoANXJvmjI+Cj/aQESfUmbA1oFjjfWZi9kdp/3r/SQv/8RD1v2FDujt2yRvjt5OKUVTr9wkI1UZU7sT5HaLWV/46tCYyd6sSXgNhcPiyQE3tYN7Tmt/j3zE4hCuOxfF10u3jphAIa+qqsbWSosql0Svq141qJqtiXqO/SwJtrUsDiyDcgoigLWKXvSkddGNhTv/A6DgfusqE8z6E9VOLGgyUQsUcXhM7LrapeTphUuQ+aLo7Xl1u/J5x5irFKZuu+TKqVQcxxwzb6xPe359zWNZGefp7iB5Wcipr8GOjDbdSJbHT1WIaHbEu0jwZZK7B9/rSLPAYgKAoC1IweFAXp3WEAAAAAA=" />
<img id="flag_falkland_islands" src="data:image/webp;base64, UklGRtICAABXRUJQVlA4IMYCAAAwDgCdASpQACcAPtFWpUyoJKOiLvbbAQAaCWwAzmhCKvs+WWvUvtovMB5M36ze73/gb4BvH9ZAxsnb/DCDBIASqKaT5BvqMKMaGqEWamP8smLQknwQiBj+mQVBIpLtu1OAm3tvTFQ7I7TQ5Z+zTBqLIVMTug1md5vrYADieMrnqgZQvf6sWaSWGvGNUxwCUfJqL3yx7kszgP5sxCOjUp7irk647vkYFgNdv37uR6hlSp0Vp9PdLaFaOolTnrmSBpwi01ZEGuzPenR/7GdQ8KzF0kt8qJ0v5ij8maWiQ7V9ya8PFs2QVl46yrsfvfMqSLKPhnOJy39PX7bd8MMF2OubSt71x4AWr8BV7hnt74ZjmYSdPzpgoIFw5UtYmcgt9f32EyPrcG/eDxk47lbPrbxS3b/+Z8N0pq8LFkNUQg2hgX6GfU6nnaic2d7df/0c+Oy7wXno+Nqtr8cLGyM0R+PdkQGTlGVqqmT7ZmA9wRYv3MPaBtc00NMwZFvfAABDI73bcYeBukfIV/I4j3I4dKoeqBoRDapSJHQ2GafsyjQf1zn9w3H/2O3Tyb5VNpefxekEjc/cJw8+1d2X96apcJnQwp8asfKT51Pba4KdNXlKWezd35JkOSDvmzzwnbhznSJnbbDglQmpwlJbRmqoQSkf/WcXCWg8HtaVk1UdwJn1OvuFFFvgUcUuGo9DaLuUqsRvEJOeeyCRg0ZwbpQ9HmEc/LYrWG+3/y54Epb+StvY7pLaXySXxYvzjOzJobwSN2sb8g5aoOVkOB9BeLeml5x5jq9KHKQ7IR5aO0aAw9a+kp8d1mjBy9Evx59Yq5zkN/2Uqu5u52xM48pg1XmfN5Q/22lxLjEER7CHIIg5bkVMVIKuqkaPJf1PfoCFXsawVaXyjK+ahgfx/hFGHN2cHsIUkiacIph4X2NMTl/srAMLY5YAAAAAAA==" />
<img id="flag_guernsey" src="data:image/webp;base64, UklGRt4BAABXRUJQVlA4INIBAACwDACdASpQADUAPtFeqE4oJSQiKBZruQAaCWoA1E1BXX4N/TdP/v1/RG6dBh5j/OV/mfql8//qK/Qz8ID4hyI7Vdohb1xvjKuLYr99KVgr1ulmOkTvth7vncGXKLLe9Lc02zYbXSo96wa1lTJeEAD++yHBeT3gHs6qgaazbzNyzHjNaaFWO4mt5zkr38NSAqGjtmmSaaT2Bwtz262cTK8rmPMLOHOA90F30RD//LdG7yzcMtb5C2Z9gDLZnuAB+/CO04ZZaoiR3/6S6o7ShM+VZ0o/x6X7RK5B/FCQiyZHg1ccvJrOhlIwHhm4A61aFv24LLGFnhYL6X9nFgD4flCGbRysq28qCz5vzpSqMW0UIZ3NNfUuVV2cNcG9PsA4VjbUNoQ1cf4v0mBcuommQ8BYb4h/1ps8bZOtG0lqSsCJ35w+eIWkTCRyRQEQQUz1ZDX9Xb95dfh9IFQAWs9boQirPgeQWUj6bEhbzv1+NZihdCD7NLQrecRC+3s5TjOcN5puCjOP3KJvwxByIzw08ggjbC1SbwC3mNG4qt2TwT2CqLg+79PByzrVP250PMPudDzD8tHJ0Ab12NVnEnNDh7URnRJ/c9Dxb6k+mbCsSEae+AAA" />
<img id="flag_morocco" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAAAQBQCdASpQADUAPtForVEoJiQipNqoeQAaCWMAVgBQA3hQAz+EFY1AT495j53cezyAAP7kTUyeGyo7elJ/6qp6/G7//5mj/0m/7DeGokEbdI2EwvHfRbktIQwFCLXWShT71uzR//Kx79x6wsaibxI0ex5MHP16cSOS4MhnRkLl04ESADWz1YAAAAA=" />
<img id="flag_kazakhstan" src="data:image/webp;base64, UklGRlIBAABXRUJQVlA4IEYBAAAQCQCdASpQACcAPtFmqU+oJiOiJFgLsQAaCWoA0euJfEcTS4X5TbIaH/1DH6zcByjWlZ+8v1+1OXydY5EulQ7c5dDVcK86Fr9/sNPQQVSeyAAAzjRgZrA/doy8ThF8sdjwzWTA6ZFG/HXuWhRlDu/ugUvxwTQwedqJOW/mcmJl4YHnEeZurSuqewfcKTVuBclTHCLUZVslf1DXtAzdecItZ2e6hWRSKALdcLu93bzxE8+amFYJtB9Crffh+sxAkTb6UJZEH9yxTy+JMMyFxCyu21z0LucFt9am9dlvUj4dLPWFpDvdyZwFlXiYCN8YbykQSkotG8g2LfgTagdXXtP03G0WLmVWBN88InW4rbVsf1UGYm4WLeWRj75TLQnuvNjytjgIKV5GbTsB5QSg112+1t5dzc5MTvAc2YdfrAJwwdaAAAAAAA==" />
<img id="flag_uae" src="data:image/webp;base64, UklGRpQAAABXRUJQVlA4IIgAAAAwBgCdASpQACcAPslQo0unpKMhtVmYAPAZCUAPC35L+KrN/90ABd73sbAb8ie2Nh7c+k41sguk8zKAAP7E7///KUE4Lt9//+emNpQevQCxQcbfVVyRWpuWdCmCXlj+/7WLFMGWLP+Jp8uptne3zViS9iiAIkYRf+VHc9Rwf3BI2FV6nlymAAAA" />
<img id="flag_belarus" src="data:image/webp;base64, UklGRloBAABXRUJQVlA4IE4BAABwCACdASpQACcAPtFiqk8oJaQiJnqqqQAaCWIAeR9+ZbOe4V9YB0u6NBIwf7N4SRfHO5GOyVsdcF/1IN0IFdv+EsKiPaSpJU6P43YAAP7rhgZ/AAea9bWN99MY0ak76vrCXoAdZTcgbdXyII76ENkyu4kw2ko5dAk8U0/7z2rdCFdTcCq2+jmSDD/adOzmREQU0PEKK+65yX/5jNYWx/VGlX+d20u19Z4Kjk4iyvvr/ybqwsoEq+sgGTQSqRhntSOG+y7azJATrb/y9MJpmlNMCyV05X2D+y6ldFPSiNUfCTZ0O9+rOkbhCzoLNdvRAtLGR17/g0Deo7JvARXY416a+pNAPfimn4D+P+f+n/H/PDx//qbpG+BEkFafxzhW3k3W7T+kJUrX1aKfa0BaZZUvohfgG/iSBmjU9H3bC5NiQ/c/7w9zf6G/5EQbeYAA" />
<img id="flag_ireland" src="data:image/webp;base64, UklGRnQAAABXRUJQVlA4IGgAAADwBACdASpQACcAPtFYpEwoJSOiLugBABoJQBK56b70kA3qRZd9VGuk+MyEYoiX4+AA/uLev+LHecz7wubTrbufs7UcZDIxflVXiDb3jhmjy/vD2+hPYgitd0jJYHnp8yJtN0feMoAAAA==" />
<img id="flag_northern_mariana_islands" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCBaAgAAsA0AnQEqUAAoAD7RXKVMKCWjoizYC4kAGglsAM0JQT+/tV9jasNzoO16BfIE6nbAbkv0AP7N1PW83ftAwwVqctjSBM9m+CV49s5syH1UBXyFnC43F4oAFKRD8j2nprNhTNzfGmAZWopLDBzQUrI+llFLvSEwAAD+7CZf8PFjdvxSqf+UA689+mkkD9gRByQbb0IojIMxtyuSZH2JQhT729cTblUi5h2MLgIQgOGmAGkzvwlD+h74TxsmMwWgb1nT9v/q3c4TmTxOefu8ODpeYinIyUe3QIaMw9kAI9Vn5F8lYSnCcbqXGYFna0lxJ9O+POOVIMLZ2qFFOd4SaOehjSaNe99dAj1mH6xO47r3GxoJAZdOVpcMLZ6AGyVlSA9lSItYki6HLRkb7gkIMRt6u/A2hGG23+FzcYEWmr3hm05KejPIVzQCcvvVFh+m3JK4YG34UfdguY5j3k2hZ2fdGCVf+V1PS3J920lbzWj+ftLPCVU5p7UL4NBLYQq5zj8mbI8aUsH7cpabyNv7cFK4xJz27IP9kSnMYIxQogG4+ahIiKELzMz67wXntpZ4pzPDglKK9wzlNQXAxWFz+NMPpdqNIc/b4zsZps8/9Q6QLw9bN3h5jyM3j1JGeHgu6Ol9Jpt7o9Vh9ZQ82soUSDcPZ6jz5YKmewkFjd9e7EZeg4teWrjfp0KeZ5zeReFfIvhp2iyUqYLBjAFOzHL6vLYtUfxw/nSV0b6T5FoLFqW0G2WxOw4ZuL0HZtjR4L302Q0XPugQREuilao8feQRAdVDM9Ldqyr8WhYAAAA=" />
<img id="flag_bulgaria" src="data:image/webp;base64, UklGRnoAAABXRUJQVlA4IG4AAABQBQCdASpQADQAPtFapUyoJSOiMZdIAQAaCUAO4L5WAtIgY8I5lkqmaBkOg5WPyFYeXSgA/vULaD3wF/s3Jp//RYdiLZyhzzPUpPcunZghSa/4vHVVAbq1QHf+L/2ckkVn9d/2cknkj00N4AAAAA==" />
<img id="flag_guadeloupe" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADUAPtFYpUwoJSOiLmgBABoJQBq+MDe4AbAdKqlNAmgSOnGTFnYkYtvO2JEAAP7wG9/q7wo3slfv2/vnSv8Hv17zbJ/qV2ep3Zk+k4daqgOdHBZnLlmOd3s/Zf32WwTjIWr013Cz8AAAAAAAAA==" />
<img id="flag_namibia" src="data:image/webp;base64, UklGRrQDAABXRUJQVlA4IKgDAAAQFACdASpQADgAPslSokunpKMhsZi8cPAZCWwAy9f29leueazW37B+IOZ1tjnIeIB+o3Xk8xHngefb6bGSPfsxhHX9L7QP7JXYfkzyA7wdqD+3bwPAnSasrftF7AH6jdYxONll2xbtE/KCkXAaCQelDb5iS7y9sxhM39KJtnBLyDCoijQZvC9h4ZYMUPV/LPT9Mji2zVNNsX8yHIrC0ncKYW7I7tuE3qYAAPugc7e74/hfM8MBIx89jAwtHLTnZSyrp7/+IcFNqv/Hs9xS9Kuf+tH2HoewwtmuZvnZF4GxGTCvV30U99q6CgtxXxV83MG5gPmk8JBy816evuxBOy5NPvmXRRCKkOQkFBkJsLDGZrBiJI99iru8pf6SreGBD6NxI4oHaLzJKB2gV996Y5MujuDKACpeWfb6XgSlokuZzyZ0mqDQuUjwMUvmvaW4I0T8eYvngEUfhu0Aei7PZqenlq06HhNjIFrbsGhUr3FuDO6P4/jQ7lVns21O+W0ohr/o1jTSCMkd3giWJPrLkxRk9FmZY7ukjWF4bsxF/TKu9xLgwnMuc5nsub9EzG9k+WOqnH95R9cR96wCI85EMRjXwhhPSzg5a9TD/i3435kIjm607UEovk7S7594zwmQF4QtvtNISDr3ePiMsTF2YB4Giaq1Yd6yN+MRXE3EVcQluM7gQH1sZFEwgI1Jj+TfLEXeuFDz6xwpznA17WQmZRSAczL93GBTREEyN1z3r8IdTd3xkLP37NzK8VdAbMJFF0B6KwzeZ6L3fugiui/5F8B+wH0CLD64frYNzl3hBtuZta0n3ah26OHDbtoTCUbNT7f2e2LK3XZQd2Skew0pF2P3W0RcjYuAtmGaiR+Wf1UeUaROhm2Ppm7cNxb9tkHj/Va1PVbqaMd0eyqcg5Y1N7kYjmE3bQ6b9vyx0YIum7qhPDNdZ0C7BL26DvYZax/xswgSEGuKkoUJcQHADiok4tliRYBJOhbxHOEnijlXxY34U8M74HDI6H14dnRH6DP4Yt6uWILHTN5PE4i0O5RX6MY/UdcshU7zHYwc+0IlFMD0O8ThX//rT9vGEJCSOt5a9qtn5HykrwjLKd8pjNPQ7C7BDmebeI9y3df3gtTO/ULgTaDtSi4ABJVs51wQOXY4d9R46z5h0xQnH4DYc3kan8acJULN1u37v4/KA1C0fNhOemYu2aWNTETxfV5114XkMY2pMfxaiGqhUzKQrkYjXfScASFPAAAAAAA=" />
<img id="flag_hong_kong" src="data:image/webp;base64, UklGRvYBAABXRUJQVlA4IOoBAADwCwCdASpQADUAPtFiq1AoJaOipNqqWQAaCWgA1MV4/qupIQU0AbYDzAdCXzgOo33j9fgrQUAHuZVdowIwTnVZj/l3/DhDtkfxaQjF3+0mbF1n2PPdMC2A3EtXqYpAunK0oyIRhR6WAAD+5VE3ro/FBDFVfUeyPZGLf0mz/4mz/4mz5FTjNsn7uXtwTRNpUNtwvOFVHeiW1fQBz+ar0uM+q/z+55eP0+LzAb5DdGYZkBivI57c+91GGr3Xz0rEe/zn4GkUGnz4Qp/rbHeDRctxRMleF3OGzZ4lXToU46euGT2ZIoq8XtFyeadZDdzNMJMz4nvYgJQlfR3FzFkOPxYKX3JH7uNO3a76vcc9OXfp4eog8UBobmPJHw+mRjpMzQjTo+jEitaJS2HEDGvt/bC/+wYMRwHT3iAqq9lzl/+cYp7TQbB+XdgkI0+ob+GpURbFOTasrgKuu0eZ7w2kAiPvEASeBpF2vx5GqLHA4s9b04ZyouF6nOy8P0AfUEazNRD2UZ81w3zq2ri992CxpR5RtuSfG7lBYMWhX1RiSGRo5v7o9wQ1JUvC0YfWB/c1SOoPQy1e/IMmc2WN8k/n2JTD9fOmH1YXdwcFXXsyuJ3hv98dZOYy65TrO/saOr5xe7OnQ5q6BwngAAAA" />
<img id="flag_belgium" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADwAPtFWpEyoJKOiLn44AQAaCUAPA0D7l5fUv4xdk2dRbVW9t5KKD/dHxIgAAP72neeq0Jt3Knos/+NHapT0//N5qoueLw/CD8nvBAUWNw44ZaCyMYVX936h2l1SBeuzvkmTZq10f3NE3uOYAA==" />
<img id="flag_qatar" src="data:image/webp;base64, UklGRtIAAABXRUJQVlA4IMYAAACQBQCdASpQACcAPtFkrFAoJaSipmipABoJZQAL4A/2jASS+UHI347PGN+ePbla1PGhy7yIAAD+9W5l+WL7J0BdT9Oc/V+ecarWq2uI7zfxRnbZsv/YzHTn2fS8vMKnXyyrj/AKuy5eEDTTaghRYjDyaw61T4dTYTnTa6KTnRpyBw7gkaewJqyXIFtMs2b7O3BGp8JpW3InljOTj3s3GA7qOn5tqFx3RxZZ1dsgeCOxbth7UaIOsu87V9ZenuNmXREBnyAAAAA=" />
<img id="flag_sweden" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4IBwBAAAwCACdASpQADAAPsVaoUunpiMhtVgIAPAYiWYAhQY7vr32MS6X/AfwD3AZwD9dgQeZcSVuaG4xQxYgOjom/G2lRiGWNYXJvPagIAD+694v/yAaYSH/57ewen6HqDMcab3/Ds12h9z84BfFZXtue9cqX5wLSboz/9GBfOdCf9GBfPcJynQzn6LSUZM5zwButiO+/tcjt9p5v3M6eWjPczSRvBvsct6EAA8w3B5eChJC4qWcyUR3OPKUKWXrC6fvfAGpPh2aGCn4X80NRTEue4ycVXqcNtpn9uFD1Zvv9f78oLVLOZZjahghp/UFAX+C5H7qDtFX5XbqzWBAfhW9Ca8J9Y4/e8k3HYkikZBt7ksKpGRFRlduMVyj0gAAAA==" />
<img id="flag_soloman_islands" src="data:image/webp;base64, UklGRrwCAABXRUJQVlA4ILACAADQDgCdASpQACcAPs1YpUunpaOhrvbcAPAZiWwAxvF42/3lfgOPI318B9C3AA8wH6ueuj5//pwZKl+0/7Ve0zdrNICpBHArgJWA2xitVk32tR/NR76f2CJeKn7/bfeJFcpUZAsozvn/8QIRvz/hJAv+06oKLzt9C7QVLyP+fwSAAP6nCJwkWzLOiBR7QcLFzoo+aLoRCiWpp/g6vlUdA0xcrwNk4sf1toQeIHRBfohM+fJfEu1TMRW7rOni16Zj7XU74jAztWDp3Nl/o/TuhiAf1OTD4YU5KkvK/c7vkiC9/RHqo53ftEBp7alaPnwy6eo/dxOXycGnM5eRnD/ZJiFnxZJ181ZMAozxqBG5bP3LbuO9pZ9sIxvjMaFfLbZ2DN5ealoY/ZVx0veLX5JYpB+bdRoAl5ftw2Ph6cvHvG1d5oyUIqRDFdGzHirn/aVimaY0UeMx4en1zwBTN0t8cXkgKJ4MXyU9W3DUfoA9HxxD1RVTXUFq5M2rF2JWh02RYY33hjAzF+8izEEzujdD8lHogw7yW+Oo1XvLqwdLzMx7p9/wuNlYdDyld/4vaiCyi1AIvOzElMgT6BhUoJkfWDBfvnu9QqPVzT7T004nC6PoMniRZYLbuOlsGAPSVNFJl8yLHFkQDEQYjcnoUVQkqBwuo7EAL+9VgdGfw/mWlN0RRLHE70Mfs4EiwfA8TiGlctoCBqIYUGexCaPL3XF8V++dpyM76TYvTBGZRX6cBfj+H8y0pn6Y3RcQT6P3amTxQPbvEx9t4MjimF9Ak8/sayf24cck/w52J4LfgjOuIDsruW3cZ+HfkY0D6VPlDuwhfxiaDO2eRdrj/H9PlpaP7wlb4Uceb31kd5eVRWrdtDrGO7IS2lUQDhsBifRsBz+njZFbdWNhZb1VsJoAAAAAAAAA" />
<img id="flag_iraq" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAACwCQCdASpQADUAPtFgqU6oJaQiJMvBABoJQBKgfwDT3SAHrZ6YBu9CPBCO6u9xHF95tj3zKYutKKtcKveMD3QTNRnj0/v9qXXVTO63dzsvLcn8zYecwAD+6mX/ZeyPYF4/6tD/8tD/8tD9yrBVJkB8Bv9eC9I4JG632lS+kcVlL6fPukQqcufDtIhQ4eoJb504nH4uMtFl9pWWpplN78vL/EPeZntPpqbftwdzMguVD6pgSgiFpJgMcF1WbA8SbRH0cdrCgWE0aUE5zHu3Oq1RvgaK40tTxzgK0pS3XUuYx2zmPhYYKiEuFyHiXbGzeSQieLc5B85O1JSFoBdj02AVdBt/o81Fxytf9vhi1VQjDLB8nGNYc1P6KD9Ilj0i5VQQ6onjIJaL+fMqMyybvUke/z6dmtnILDwor0Ivpoi6KFByMjLGzIo97DMnkPsTPG8KSPYSi1dihQX0y5wt0D/f1p9F7JS57AIr6TedAAA=" />
<img id="flag_micronesia" src="data:image/webp;base64, UklGRiYBAABXRUJQVlA4IBoBAABwBwCdASpQACkAPtFerU+oJKSiKrM40QAaCWMA04FvCKbYAU7YnFWI+TH+maREBOGU2+RRi093L5Q7uM5iGxNh6GtMgAD+0EgKj/w59sfvZK//X3lDsSiTmlNou23OehsqHlGH5xOwVPVZgzCuhNTrGruH+jGALNWz3C9XtlvepFlG9JuOXlPvhLrA1nzjEsGtqqBFpd1SWtG5WeAZ6OgcljlAlfsN7T6PbQRn2Uhg2s2VDJmBjvG2db/kLsQ1oJLFigG44cHF+RlcTFt0psdYatRnsNzSJ/OX5qSH8G0bxgkoM7847LDOvR6wHlX9Z7aj9ydVlun/Md33lxo7WO0n47VDPIL0bj4mZMyc3aLYh9LvwzM6ZOJoAAA=" />
<img id="flag_samoa" src="data:image/webp;base64, UklGRvYAAABXRUJQVlA4IOoAAADQBwCdASpQACcAPtFkqE6oP6OiLNK4A/AaCUASoGpY9Ak6v8AuMC7QCCmFo/e6Pl5Ok4qhZypRaknpwT0r8thxaQI4/d1IYAD+680lp/pgtSlTvPrBc3XSLVef2nDyxb25XkZOOGYJDauZppX5NhP5Qe2ilh/qXr6hHM2nFSa9jeCrSueue/j1vRZV3hgQZeXNX/tE0tSyhDAdZhtBe//PtH7L/+cSOSEcGqAOgFq8hKAqr7Ujl2p+Vq8IZlecKVbpcou1wUuk/t/Qjde4j6AoWNxz1FKxSduIPFObWyckfs3RsIhHQYYIAAA=" />
<img id="flag_nicaragua" src="data:image/webp;base64, UklGRtgAAABXRUJQVlA4IMwAAABwBgCdASpQAC8APtForlIoJaQjoigBABoJQBpMeslgC0RJRgcotUAShn7ueAHEQ+7favOwIQHqY9GJM7AA/vdxfM/6H3hg4jn/q7vZweTXl+t5WTIuvWFo5yePqAWMRfprPtBnk3ajDtJ86QqjllL/gd2ePh6JHBUCc1/ibSUpp1qK4YYgPCgb7ygWv7IkQIBZNVev8nSRvZGgTJ7gwI0Pr4uV5WBICYGJAXYUJyaWEaaOUIY2Nsoe2vKT9z+UQZbDJ4Rk7f3ZG/gAAAA=" />
<img id="flag_norfolk_island" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAAAwCQCdASpQACgAPtFgqU8oJaOiIi0hABoJZADQja4o/kEg3tPfNZmPoT2Bf1S3YA6UGMNuzjw64W950KONLCzynJjsv1mu3IJPkKRWuiACBqeAAP7tzs6h6NNf7j+yP5ypZ/hgQ44xfq5SPopG5vkbmmb02fuRpXF1loYzqu/3MzNw62F/7BdPNZzq0j/J9STBEr58o5QWz6m27PJsyL5Py2wzv7hZh30DVL5sXnUQzTSvH6sxqkoB9quVKnpSt/Zh//ia36zT/2H+bJ2AWlVmX4x8tk/pCFjQcj2oHZ8sIGCb4xk0nb/d3+aDZjcrXZYibvhvlOrwcIhej9ZPdMf5vGP7Pp3jwIrn7N5qhn7fE0FpXi7exgDoIe4Pk8+OMV4PUJ1M20A2NNuX++z+F4nFCgolipeDmuiku7RPA2RwlgRiwmEZjmkAfr5iISk9upXJRfbtmWOsyjqKru0RDre+rJTxRSpTpVluWmtYAW0l1gEn3Ox6pxJ/0eYQ3A+TP6BC7n8MzTciLXoAabfE4vQAAAA=" />
<img id="flag_slovenia" src="data:image/webp;base64, UklGRkYBAABXRUJQVlA4IDoBAADQCACdASpQACcAPtFcqE2oJSQiKJQMWQAaCWYA08vWSx6xv0Aw2D9M/fusmMiOhAkVEU9IQlY9jXgp/0/1T/6Pplgp5kbUp3htGhbKGkeYAP736YGvrUlbOlCf6P2I/8gu55El6w8gX1nSIbG/fdfblzVl2+4/Bq09oWZhXMtGpbL5IUtxg/hbuVZ9rNawma2KBQS/hiSpUb2oJWEXySzU8QWBsa0o3VNWZlvtMiqvpRBq8weg3VPYbfabb9Df3kwpi3bTBJldedTd54oLw+gf9ooCV4C5bl2zH4VltzjZP1mQWWhbEhAT7cGGf3EamRCI2K6rdFj7yKS7MYDY05AE/Tcq+Zs3hKzaE2XoMQUdeH3FBccS6xgC9b03f/7eKGgT54fdlK008U4aF8AfwBpDXB3El+9iUAAAAA==" />
<img id="flag_turks_and_caicos_islands" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4IJQCAACQDgCdASpQACcAPtFYp00oJSOiLNVbiQAaCWwA0QVBXH4efeeMh3yfsZZ+oD8q7xTzFeUB6mN4i9DPyxvY1rlCrgICMOrAgwH0Z5/Q8Z+nSWoyxcvED1ojKJg2Ld75K+dvVwiCyoDVCnCKAvCV8PAB6GnchuxTs93p2tM0AAD+CN4TltGBXP23cnKkZeyu24ip8CLUajvaLJ6RO1dm4l+4VYDrmdI2bZVy9XIwVecPp/O8PYEN+GEkfXHUqVWtvdqGdzr6FlCCujlEBClHRWcF+0cw0DohwEgvNJG2K+gHbC/LvldtNCpHj72/DfgeoBQgWoLZ73eXlb2auoOOr43IV5mEpP5OThKraog2CBc8ouxvNCFXQdc0Ij4fq1ydFGr1LSQcXV2FRwP53z5nuBhrNNA4wcrRpYmEYr+T1EAt6M2yZFYZeeQSrcnFkuZLYl/317m4uqHAWCm+p/MH2h9BH+9OnfHNQ0cOHMt8YWTsblMIvVoeGxMCEPGdHDUWrg4H3HeU6mzLb3S835yvjfnx2ADvBxBJ4mu+WWVDfzYs9mnbd95aDS4dYrPyF92ml9g4DUIP11+4oP3HyhNUX072/zZH9PdviVlLSZFwKkHDungCwngk2LnXlduABEabVCbhkMCu8O+PokpM9SRkpJptb0z/o7Rtk+UhtrSbVgK0quVUPKo81+AkuKAu2Aux8t0Q0PgLyew6wKFxM05wpC3S/wmMGFsmfL4c/LjTpSAWuBbqHbQYJ5JCBimgdBoqo9VusrSSJ7XWyjUV6kZtNl6Md/xKRd+sJGtZ8wX3gTZRoZWE7m2Wq/705hk7Lb4ff2l8iTrj9ePvjPYgOnj+s+f42/BKMhLTPf7/J3x+QKHHRLCeAAA=" />
<img id="flag_antarctica" src="data:image/webp;base64, UklGRu4DAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCCoAwAAUBEAnQEqUAA1AD7RWKRNqCSjIizZ+VkAGglAGWQCmhWFDaJiyHRvYzKYYCaR2av5Lntw6Ha9F9bCN8jdqwSVAB+rwCF50aUbYCtkpPIK1+NIhpXnJZmCK4oXz6Ih8MpUyzxePoj5UIzJN/bVU2XoQRDQ5F/CORnq0sfJx3P2vRf5Sts/Cefo8zeDk7t0NZkVR7AAAP73r2x/D7eoOVVQQmWhvSr3vTfUO/wAsqm/V8/4obH8q80/Nr7JUiuzphVL8kduHo1Ef1IckAm9iC7FtzK28Bp+xsiD4KZ2sNzBM3I9epS9s8ae1wjlNWT+nR0y01l1V1szceAF0xUoMEScDMlH/bLDc44R5gNL2TTk9FYerSMCBZ695dtbtm9X1Q/k8Q/KZmZmRQ1twZ1YMV91viIk8kMn8uAcqmWeR0nLIaFGfSY7d0aMbx/pBnv/2Ckhg6ow6NCG6ITdFZU/WouGBNTowmIYTE/EyNMMCtopnVx+FCuOputbEppWgtHsntBuXDI2DZNRx2jDIHb5Gm2NzUAFt/HCb1T174n89EHIxf+c7Yg1VfdycQVVuAZ3aw33K9Rt0kyuMJ063s74Z2NyJQfW2MT/FO4uvQRBR83hZH4CLMIEYYq4JGHUISqw1vZ0WxOcri/W8i6+WkHdxdWBLO61aGQCEefPb5KEnm3Un/ToKzpTvjG3Bfp7K5t/FDhoI7KdQDYhkc6LnJmvgu+uyStH8K4obeWUORU0fYyLMWMws8Wlx9ocW0whzAUQ1w71zxIIcQWk5QuhXvLUIU4SZvBQs4NL6+/KPBE8pc5xRvuZijgTXJtxy3qJsQg/iMx6vROSmF+p54BY8Ik9Jne6OQkv4Jq2I2eWOXtgffxyxJF5DuMl2WSmccnf4rpZG5nJqg+OvcdCJzK8h9QxB0p9kaa0oE3R7xVqoGfK+HUUFa88CacG77Tb/l/Xfgy2U3ZIWuQQ+UwnQmcUTWtHmINfsfYOlTTFw9Khp4aszKRlRIOqCTKvhkikaPXlknYpElOdgskCtpBk3xeA4GA04wz6Htzk5sub6Ov+mLwHBWzkroLDRN8QpYhNjHzmu9erVvZPcTXN+Cp3NIDLtNrEUhuGFbBzKaaykb8VxhvkPdJMHi4BLKbkGhokkw9ADVCm1y6qE57gmbQ6oWEt2dt8UtYJhALuWXuuQ5KC8Us4stroehi5QSt599UzSzszPUf8oundOaIGx3WnrBRP40fEVdFIimlvH5gAAAAA" />
<img id="flag_algeria" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAAAwCgCdASpQADUAPtFiqk+oJaOiJNVbSQAaCWIA1IAeygYkvPhexfkVqw7lFhyZoWDug595fsL9dZqlTZ6aunPr8s+fbnoz8fAlO76by7zzWP9Q/aKAOUTyeAAA/n9SqXL85/W+F9nq2sknf2lJuPuClAVYOlDCX+sg3bP81YuirmO8q1J+yY7/n/gVzkNS75SXTWCe4jUGAgCkIWszhiLU0tXNkzv/8Gv/VwC/cRzsD9ufkVfP5ffUMe+fTcqi+99jmImE6LH3wZH/jaEG9i0VZIMvO2nhFZgp/omeYx1T0dZ9WX+HwqVx+y5m3jVdHN5ReLfxW7v257xSl0MWR36IqfkLjdsBE0b/dLJklHQpFmR8NEMbe1FwuO/4qGhLVQ3Ymz+i+4hFrbtzPJLlKBoBLG8ZU50ApqjzQ7qHXAc9vGdGLN+PAfUOi/dpRqTMnna46sdXpXFqzppR9cQ2lOcl8/QWaUgP24ErHQgAAAA=" />
<img id="flag_russian_federation" src="data:image/webp;base64, UklGRoYAAABXRUJQVlA4IHoAAACwBgCdASpQADQAPtFapEuoJaOhsZi4AQAaCUAO4G2AYQB+gHv/gc/zyTdn/SAVwoxWx2UtOwaBMjxA6tsFwAD+9Qtm0Ian5gfRCryMFJ/9VHajoac9UH/0WwgSsQPHqXLs8CMOBq0mnp1O/2qa0ZOD+AvQCqA4AAAAAA==" />
<img id="flag_portugal" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAACQCgCdASpQADUAPtFiqVCoJSOipngJAQAaCWgA1QGBvH4sfgDcW2yF2NegB0qExOtArgJWj3J6hk00G7Wa+LbwOEvQNkvc9HM7N1P20Vx78Rj3LvkqArdX9J+LEAAA41aj4qv2Z7KZtWJ/4D2B69peHTeqkDav1qLz5SBZLqqKGpVFFYoKgx8Zt+oWt6Ud5uk2EpgJJ/r9DnxPtIW3EcXMKM9xHhV/5Qq2TLWOF8G4uCsFXQ62wpVdGT01sxfas2fOprEYL3o7925xV4flP4x0zVx8aBrXm7WKyIf9xhmyNedc2xpFvrYC62pSUvTDZJ72ZQqw/wRIYhsf3azvAZZ7aEJE6XWm+DI9cKm0oSqRp330ixAefFwrZGJh1cMJUb00BaLqHtie2so7YAdh86V0KehXrD8Lps86rlALkoojApo4vGsh7N9hfesxVbzYEHAxhQffT5f2sOtTIZUlXM+1MIdWISFyHHrW2tK3Du+6UpfW8ffWRPPMnnkwxVMg795CJJS7GCsHB9coU5uURGXXSm2a5B80cyBUcg7joAAAAA==" />
<img id="flag_wallis_and_futuna" src="data:image/webp;base64, UklGRlwCAABXRUJQVlA4IFACAAAQDgCdASpQADwAPtFYqUyoJSQiqBzMQQAaCWwA0I2Nvj/vPmqW5+02ED1G/aBvgPGZ6oHkV8An+1XWtL8EAA67x7WAI/0GXUA4CBm6kY1/BTtD1XC9KlMei0Tx07s7KiNin+JaM+856mhhsyD8BVOMhm6ujYDAJg4AAP7ZV9TmO1ZKd13nY5AlY+R8sqUXHGWI47926H/xi5sj4hqst1/aaer/pq+BIOqv5yFOhMunNaCOwuAQKkLoP0GyJxOABKamTlW4Y+Hqe89FxbV5PxYDA9+BxSWROF+RTQUXQ72cmIF2SQumI0OIkLLv4mp8JTcSh10b27atWiRj/nD3I0p67YoFf8EnRl/wSdAOXtY1eNx/2BV+S3de17Bd7BZHeRFPEtzWzmhp6ws+BEAnzYJ2Z0YbJzkcJZJ96g8U20fYTEVFKDnC5p4FfemtyMy9SCfC7/tYXMlR4e+Ag6IuLGy8LXGA4XmnuDye0dtiVomS8EklPXTT8vPuhBgcLwNJDEa4kN6yTSA65i/1gtawzq7DqciKQDxsWKbS28gle3nFTWd+qc9bBUj0LGuPqsklT7aL9/LA8pHdELJRVHohBotzFgRG1gdHk2fVlxLWnRRKSMVmSvRTBsaDRJYhLAzRwGpVRtC4wx48KFl54d2KNqwstip4cDYN8edcm+q7rglBepzQTF01dexDXKTZVrEV+lq0Xf4swhG6gCsrOVy3PqVO8pK5qy+MtyBifl82S/Os7Hi5K1TckKlW0tmbqBIIGEEI5Q/ED38yjpUm0PbmAAAA" />
<img id="flag_saint_vicent_and_the_grenadines" src="data:image/webp;base64, UklGRmABAABXRUJQVlA4IFQBAAAQCwCdASpQADQAPtFcqU+oJKOiJnQLgQAaCWoA0uVBfgGru9V3gIhh/isQBuAN489ADyyvZSX4K0Ajj+AyVI9FfOpfn3t8YfDJC2oWy3LDFfFEhWfz0e6dG7/lSWT59N8gAP7ptmxccbAxb2HUjV/A/aTBf264/ub/8ycft1x/c38JB/kEC0J/IIE0d5Ty881mi3/GjWW/40Y+GqmZrJz39ra8EjrHo8ZbZ77A2bOIG7XlH9j7cJy0mu0CBbt/bHBTMhvk8dXtb6IRyLZDA/QDpMjvE8I9aR4KLrcCM0XqG3sdktJ1cx/BthP+qyFkgVDq4vBTnvsJFg9zcoH4U16RsFkDSmqLqbzTuT+fV9V+gU+LQp+sneCARiU1A4wWv3i0Dm4n1vvZvlqkz7ntkYkfueAd33IW0IXd8QsKYPpDuNDCtrojTJYkP2gk700gEN/eAAAA" />
<img id="flag_lebanon" src="data:image/webp;base64, UklGRoYBAABXRUJQVlA4IHoBAADwCgCdASpQADQAPtFaqE8oJKOiJNVcsQAaCWQA013sfmf4AadX8K+FhkgPEA9f8bwLeWZYyLXjTY0RhMqkFKKSF6b/7GR7Q2yEiD637vkBhPl0139V5jflM+XpHo4umAAA+daF7VvOh+mqYxv7BPc+50tvytLY/ZeKPPuUR/p/h2UEihWV3gLu0ofzC8bw8wpddT0X7YWpny9CIKa2Sq9+BKCe3yOkxxRjd3e2IIy5R4IH1B2+K4+1VCH8G+b5o0EFbqv9pN8m6M4Rb2rFLRpMdkEUrd87C1336yKza609u9DL9WHvqkxxh3QBehyDWGQJndiLvpICUxnYdEIP51OTYxDUEWKnIGjYErB0izLTdbxXWiYGXyxMJ2xLSrymyrcuMl9rNQdVZ6WF9awUD7csCo/jwe33njrESl3+Tj0N7Roj9jOyvqS5+9sKPCuBTqhXAcEZhrv9QQEK1uHSKFRLp70HoFUGLcozp6Wp4X72RamQhgD9A64AAAA=" />
<img id="flag_cambodia" src="data:image/webp;base64, UklGRr4BAABXRUJQVlA4ILIBAABQCwCdASpQADQAPtFcqE6oJT+iKBM8Q/AaCWgA0UHaflehGu92QH+A9gG2A8UD9gMtr9ABWAjgQgGt8kB6Tx3PxX83UiyRcgxQP3lEz8v5TzVpeZcJXQqfTBxq20gzJlkXdvAA/u1ZPn0jX5csZemd+LK51LXmlWL3t2CO1ctKW/M2t4lZmkOVh9dfqnvGcJlh93dBIo0awQWFSfsA8gtF5FoI7SUFqftJjpV3Jxa5AaN+Cl2de115sbx2EmtpnOcJnUTt1upJv8+hVMJBPi7t4Qn3/CHaKOZsLlQVt7OJFUjX1jHko9CWMR+n6xMEak010DWomdO6xdViVVTUnn5ZtMJMzfMvILxNcNwbmfsGt3HTQv7BM9z0gpSo2iwTCX1KAS5xu2AdsyUIQ/c0jDZU9+mA0av77oVLHMvkA/whZG4Qf+QZ+qTJeFz/sgH8GSMm3kWX9jE3idLqeLWDqsCRAp048n81dZNWlwYnK3Q3hnnee4zbYY6dgn89oyXiPVwjDaLBQZX+hOtFtlENSSy/57i/RH9qfhjd0fh2Np8ZnU/g7WnAt76M07/FszugAAAAAA==" />
<img id="flag_dominican_republic" src="data:image/webp;base64, UklGRvwAAABXRUJQVlA4IPAAAACwBwCdASpQADQAPslco0unpaMhtNToAPAZCWQfQAmn3BPpOqReGogHiA59cDSHicpd3xWKx8xMcxzQWIgSZDEMJmE+DaNgAP7svX7/sQ1qRTSdjkL51lryXSso/oaK+HXda+M7Bz0mP8f2h7C8x/j/K9RbJ4x34mmLRs9/n+vkimyk8p2we/hv3/4rLF8n6rbJNwJcgiTOdozUTP55dnfMTnH9x66hrc+PuxCiJHQy5gCPwBJ4/7P3WMtsSzq89M/RP0T5hQx+F/c3+NeJadoDWM1eYehBLpvGMZDy8Y6v7hogLSNsaCQK6j8i3GQAAAA=" />
<img id="flag_japan" src="data:image/webp;base64, UklGRk4BAABXRUJQVlA4IEIBAAAwCQCdASpQADcAPtFip04oJiOiLNYIqQAaCWIAeXslXdLrAbZ7nx9Mz3lUFk21NWsH3vTlGpFH6yOANLpGny9BxEDP5hwJsIGwaDSE37wCMx3gAP73HCTWiMD6akq7xoiv9k//zK0J/SUMlG+b1Zw43ye0Ak487FOw0utYrpSbc2mmDwT/cqtqfESCNWSsqfb4ppLW809JhYrRh2hOrUvDHOhG49eFy+omg9EB4+cRCzyfMk249NF/j/8m+BAxe+dDfs48fjfSkL8UzVL+sDc1SRk5VdPZ8HFz8S56WBLd08k7XAqFvsHTTuonlto8zSRY7FGzFXy0OXbHp47otGboslbIGSHlm4+dziMEe0i4o4bxAN2bK0/lLp6UcTQSPylZjrfAS8bDV/Fq5OJ3kHgVeSfFBYkHqIYzsO9bdygfwAAA" />
<img id="flag_djibouti" src="data:image/webp;base64, UklGRgYBAABXRUJQVlA4IPoAAADwBwCdASpQAC8APtFaqE2oJSQiLvJKAQAaCWQA1Af7VgHoco0ARzVSGU3Oe0sgeb6Lse9vxJfN6B3lYWuDOorkjA7qzbyowvAA/vP8DzgahePUhl7gD+JzXGuz6LhNH5fgvkMcg5BJE+SBK5SbPJrOPlO8/HFrUv3eIlKnwpA3rNpHFCRJTePfUQaMMbsZyU9rSHf2V7XrXDySTH/aW6XD89j+amfq+Cxq+oyO7MEdvQhvybmlsOditRCyEFPKhb/kSuUKw30+wFDlsAi3kQwpfQiV75Ljq4rui60oqTD4NTZeLRP7f7/bdIt7BohoDKItqISNc8YAAAAA" />
<img id="flag_belize" src="data:image/webp;base64, UklGRioCAABXRUJQVlA4IB4CAABwDgCdASpQADAAPtFYpU0oJSOiKrM+YQAaCWwA0fWB+AGud9gtw7alub+gey3bT/QB8AP0Y/YD3/+8A4wD0AOl2X4K0GWBpAmZDroN+08OGz5n+PWvmD79EzIuIlOzf/1daYvjoAGFzFDG0yvHcxuyT04riRlECtraD84AAP6+vC/6xHEx/GKKJ4G+454jTf3zPpv72bb5qjwIeiQ/YBIi+fMrv2tQRuMD0YSuuaEwhVMUgHkVSfwBsjWCWLwcRaEs3a4FjaJRfOiPrWoTnFVj1ApXPa8beEzxgaJ4NzLpIDriyE1FQdTGqHHRBwvRZsLJRbH+GQbQA/vOrNIM/cLN4L15fuogV5Yqntf1tL1X4mK0Hxodic/dTtrKH6unUHpP3mp6UbXa8opubxCTeP9WBvgXfn/FVX0nGk0PIJX13RFNJ0OJln5m0i1W8yHZkiXVuHggZGL1Afh62xD7PPHSCt4VwVRvg950IrsPED671D8/Sc9dfP/f0Vn7HiBnUWdA+xS36tX10NHdGAPncGs2Xm1DkeEiXHYCABrQLEKQha4i2Lhxm8780ibWjU7nLKhlb0DKFu98Xf/iPRNTui2g6AOwe7+FMq9Euxys3vtr+kWd0UCT8tHGmS1o+DWYWijU03YxYiusPJ4gKTWNxrkH5pBjUryvOyNjil67XV5+dpRHDgulFjYklMeDU0/0MjdvYC/2PL6f0+6OqxYAAA==" />
<img id="flag_el_salvador" src="data:image/webp;base64, UklGRtwAAABXRUJQVlA4INAAAABwBwCdASpQAC8APtFgp0+oJaMiIi2xABoJYgDUEY3+AacB2P7ALsHGADlFRSTnlTzKZOUQ/L67EpyZokWfuZxgkFmFAAD+6Diz+FQSe6Y2fyFCHw4h/2voLNMGjEDw72Pv4CpQJDNmgocDwUmimlYbCYgiQZtmSkeXoy0AsftHUPN5eaRxzHw9a+YnlJNusepq7Oyde/hJ8vMI1K3lwRqMDq2ZCoQoJoMAoCAIIMFLo2GDIfZGf1/teZCjN9mH0u/0BEZAeYYJbr9F3QYAAAAA" />
<img id="flag_iraq_new" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4WAoAAAAQAAAATwAANQAAQUxQSCcAAAABHyAQSFRHz2SNiIgJZgImwWaWgGbk9d3vE9H/CYjBjsD9czHYQwEAVlA4IPIAAADwBgCdASpQADYAPtFgqU+oJaOiJNVbwQAaCUAF3qi15r21mbUfLzQ4mEgajMv3AWZ4tyJwlK83TYuhxlS7JGsAAP7upj/6qp6/G7//6En//BJ//wSfuAkfaB/szNWTdvJsH25U1xP+EZjSN9t/wjMBG6UKSpowKmL6BreIjZAUMQ9rwaTaiV/qbw6RG3BSAwawdDc/PIi6Cg6B5F//EOOwnL48/a6MrAo0UrVCVQtJ06BVwmX1tjRy+QDM9Es6jWd+jpuYAD6Gl5qfPjOvIb8FnpHaqVcvEjfWdrwgFFMask88OyV7J06ssP7Wz6AdgAAAAA==" />
<img id="flag_mozambique" src="data:image/webp;base64, UklGRuoBAABXRUJQVlA4IN4BAADwCwCdASpQADUAPtFcp06oJSQiJnv8AQAaCWwAhQY1fs35K8pVuzuAeIt0mPMB5xXRJdQxvIf7b+hW0QVuXuTg+pAYV4CW05wkE+f7z+DnGW4/J57BUOidlzzrMZeZL/WLc+C3E7CkgAD+57Vs/+/otl3hWNOi3/+vff8DRaCXrPkXAcs+jb1dHVzWtoJ2+xcCVpAc1NNXoChI4ZA5P3P4ehyX4lk7FuWyu5CF72XkHwr5wuezct9Rf9O5OiI0nne2YL61eED74KG1OIpswcHwd6/P/NJbuWnwdS8eY/EA61xE00XlYrHQ4kL+AXS7urIIhahyxQPqetUilSwV1yOCDhSaxnVrMTey3P86J5dOUAlZV0isF8hKt1pBGdnLbwNC70SFejD3rCF9ezFClYQPfaUdRO72tA0K3XA3fHkzj+iGbqrF8UoMJLPN8wN3fEBrGYrp5E/8q3yw1bs7MwylK5vanajqGDd7wbsG9co+bqpHkZlVN0hvoDGMrXQCTCezQedendQHD/qd2he7+xMuuLoBRHlb1Pmue2YVhanYJtb0NYow+cf4An+dDuvKnars0M69fzZ8MKXAvFAV+DrbKVg4HmjzUDBgyPZTWX0weqyZ7ligCLZkw8WWAAAA" />
<img id="flag_greece" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAABQCwCdASpQADUAPtFirFIoJSQjo1gIcQAaCWoAd7n3rjOXDfIW7PUBtgPMB56NjnVrmaAGMuRnFeD5otfH/2ayfzl19mdqUi/9F7V2F5pASlP2X7Ce9CbHXmZ1CUH9NakpNMgA/uvgQlRe+lGrKssAvdHfqSh//+Aq24Fy7l4iVne/mnlH/9/Y2GYefXvxP+hi+3VFm5ezGqrkgVuLGgw39K6+jBpWXabamnGvkL80o2q8Sma2XbZJ1MqtKwwDTQkLgk9Y2IFEDLlC8KlFXV650eQg+0KZ4d9cmdr0tB9LAEDhVokql23hBNXMqadxaUdcb95tL9xeQnMWX4QM5j+puscHKZ2upwi9MpYGk/+Wf3J4lnOIvARXIW6lF6SRMS638WtnwWePf1DLIToInAmZZ4jrYLeBU0YCumnGDwYGhZ730z+Ampr3fU7fhY7vbr0DDS2hxyJ/dziICkuHx5mghiqI2co5R5urJQoAAAA=" />
<img id="flag_united_kingdom" src="data:image/webp;base64, UklGRvoDAABXRUJQVlA4IO4DAAAQFACdASpQACgAPtFYoUyoJSMiLNgNUQAaCWwAsR7COS/Afkh7LNYftW9Dmz7DeVXtO/kfyGutt+tfqZ/Y/9o/Zs9MX1AP/lvsfS0+SB//7rvXbZU/e5CLfFX8QPcD/a1vszryDjDnKLTvPjeRj078ynhDVxGo6/6Wu7C1PYW2cH14LBik8YcukbxPELa2ny7iigC6CRt69LgftSDqlqEZSohvDIi3Aw5gAOJgeTNHiG3BbK3ylhp68l9r4uO6lq55aSJ3PMoGclPy1OByUtBGIUzjU5FDNxJZwYW8Z+C6g/+Thh9Y8HPdHue2FmpL1OFLoX+x9gpIXHvwTd2PXKl49NzwxYHSqOuO5kzePj2Ob4DhD+3nRG8s7rk6Jk2k7L/HV+Fl6IKrEcYc6fX6/0I8ah2KafJ9zfe6pzl+JuT+Cj6PhgSqruvvY7Jm0AYxI6vKIOUH8Fj5hR74PWz0AqHQmsOMj0SKGzdLMVsQlAoufi7kYetxINUVHSxGUOjQgDb8NGlT8VR2YDcwhN3mqvhsnEfO9oBzHJ7mM3V8y7iaIMB687wNUFMdGwu1P9b4xCE4UHQVnTnf0TCZ1Qd9YzdKN1hkL4IVbFCVgAkx90evkMguS77JNXnECH8CqlcCITrIxDgIQcHGkC1iOlYXt4YNFbZ8DwjqSJWL8pfCRgmGf4OsKF2AIhLsoooYWiv/8Hn5Yj2TXL5wBn2g7AB3oeJ2cufeAMKJmuXp8vkxEbhqDJhJ7afJeBM8Oy9e3fr3x108EndnoCWBc41y+9PgdEWW8KjRGYCA4f+WBI45I0hy1UUJ5rQyV0Nr+87goC1isy4SP/i8lLuMwVhP9/+eu+6CPjUDP/gV+/SWnn29HDu6BP+v72/jYnDfdme/st/pX/w1+rUCEKK87JY5hD2GtxGCnH0fhG439EfzsO8bIEo7OPxFOwWjj6hrzBIlkuDOKN/6CG+j8opDJCfJkXk7QoCtXutXH2vPWiOvcXbsbJDjF6wsAghaFqOrG4QF98v4njrQm0nxPCdevFFc1+nol90pftTWPjgYETv3SqjrtDV1vFS6A2qXQQdwoWxB5Ne3cfLeN2mUZ57XxOsQBw9CrpPf5dkURxf8yX5gsHxeSEtRkoRY4D1g04qPJV5X1MhBXlKaZVv30z0omr9N59ggjBaXbbMSX3c/VQd7+0whwuU9OxzzpZAEGASGyGJC8nH/vOCR/7zSq4VaWSkM1Hmxh8Gv0dPn/hdvtRiYwCgZ7OHuvmmnPElJaihc4lRC9kv09ZPoiNFCuI9gNKzE2AODw1D+mHnrloOH6eezbKbqig+XPLiF1gy9+mXWyf9cAAAA" />
<img id="flag_senegal" src="data:image/webp;base64, UklGRu4AAABXRUJQVlA4IOIAAACwBgCdASpQAC8APtFgq0+oJaQiIiwBABoJZAB5jdldKAqED9AMsAAq8s/ty3eY9KYPoiQyixik9bHSwhrYAAD9jDFZM32zyp///CtKWUBomQS7PXrAJJKk5JTt1Fv2O8/kuMpC/yXGM6bcTNfYbiHy5NtRt8PVAu6vnTM1gu5N/MCiClk3+MBXCgnClPNN+Lqwn83qPINYDj3R5g+lrBmJedl4q0U9FYv0UVTSdk4wcBdKkQ6P6BKsvATOVJfyVPtYl7NgcVJBf6Jv0B91hPe15GGA+Mi7oYakQWC6ka17AAAA" />
<img id="flag_antigua_and_barbuda" src="data:image/webp;base64, UklGRp4CAABXRUJQVlA4IJICAABwDwCdASpQADQAPtFYp0woJSOiLNYMAQAaCWwAyjmBuz/xfKochwj0bs4DxQOlf5gPOv0zb0APLZ9k/9zHIKVgzRUfXr/5Ug/qXFs/B+MT8pUAVV4MtHvHBBQGAeO7L2nXj1t/p2tnzDEevA9V5s58hLXGOPPg0v4Xhk47w8guSmoh/AAA/vGuZL4i+/Z3iKMj9+10vR7hR9zSwI6zal0wnvMtpod4DWkjZxLT4uzKIRxyX9Jssme8Ck9/FlheLnya7naeiPvyCfop2o+v8+vbdSLkl47PTEBB0m+BlPz6ED9XLwwyqXO+9DJ5/FA47WyyhjOpyjF3egOzRX2xPDH48WitOOM70vkF+kwY3gYZgLGBz1L4mh6iS3sjy6YPmIJawigyi0hbTn/bu/OMaG+lqI8RxVKRFb/pi/+m4+KpRTn8T49m/VrjkEbsohhyB0oKDNzvsLMzacImgnsjJTijVQST6xm5IcoXeEQ0n3VMiO6k6D52N24KWFsAiTHLt2YsiUp1qaZ7N24S7pvv3DAGLfTwrghINOq/sWzBJCSePgUEdo+J+vVMcUZzfhBMJPx+O2PzFBz727mGgBiaOze3a0kq+85H2FVxuXSHts2tJYZVyc5NWrmje0hL/pnyzs4/VoxUD2Cn6ba7039MaWitW+Kakz68GIDokbm89ntNdJotiCaZiGH3sSz4lfi7pWhwReUVJvmGVTVN8AnCtDSOn5ST1kQV4Vc6mHBGBxVkecwMRlL159g8Vq08cxnFF53yR1cvLmnpHP7U4gqB5iqc6lkDQtUIhsyfBCNH3Lqt8FpcnVEk/umzk7IHRtR71/c77SSMFRIGRDJ+U+1PFvfqproUzLrAGfTYZrjjEN0wAAAA" />
<img id="flag_marshall_islands" src="data:image/webp;base64, UklGRvICAABXRUJQVlA4IOYCAABwEACdASpQACkAPs1SpUunpKOhsRYMkPAZiWwAyNGW294BzvPgN4CNbYP9Sv5O0RH7Y+v/6Of//6beSoeTdd9NHSpBWit3a4xwteGHhBjMef1TkUDyzymWziE4eedTMp2u1MLsnjneEe35KWqQbeE7d0v/BZ//pvugeHv30/0Ic/gKn/2sSupFyxBDgAD+9W0otX7baavwubXemDiZbfS5fI92TYXoMZWaKV+et+iBdQlON6AFGZAoSv92jW8g/V/Nu7fgry9kQcZxKMg1jrzrAfRm/EB4kpXJmZAtTEa5sLe0rZ/4pMaevZG9Ux240s/zLHbpsriVgw65VTaEFzZWMibtIQA+Rz3VaNHYsmiNkD+qlvBIzXOMamD/8cbMBxemfBulSum37dU29iPEzgrsEgrDHFhPEo8broyTmUy2VH4BYl/PBdQk9x8RmvX6RjE9FRR4A+hoy5n84efrsyUHCp/XZGZ7vbaCjOJg9kdZ/yYvynZn+u0F/H+w/WdleMbUoTgLC8t66DUhzIR8W+h/Vji7zzd3RArJX9u6naywwU5jR93enulXpIohR/Kp/ZuEYfgIHAfrTyduccGuRjA1jyonOb+pxKbFKxu8qZZ9sIDsMSWf6BELYmAJdJpLpee33mnsZjEPIgfqt7HXkEAMMh8P8+XXFk3yWRErPLEYS13CpBY++bSPCvxJ5zTde9Ef3ZLop97WkfkBGBZb+51IH6Y+4a8xAY0kyF7wa4miO/459EWs3G4mGhK1hnwLB12zhHMuK6fjV5jk0MBmTKvZtiXOJ5CMUuPdGTLQENlXusWq67e9cZCPHewossKVqIwgpJFpkpA5dXY9knt+lvNIPR4oFVWLkkVd3xXCi6+D64tu8moY2mscP3mmTMpGE+3kWoK7l6vku/JQhciebMgSolMv67KpoJRVxj3crAJuyz0yJonNLVjGK8FoxDIpzi3ADNcnAqtFbhKjcenuveUzoAAAAAAA" />
<img id="flag_guam" src="data:image/webp;base64, UklGRoIBAABXRUJQVlA4WAoAAAAQAAAATwAAKgAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7z/0IADAFZQOCA8AQAA8AkAnQEqUAArAD7RWqdQKCQjIqRYDEkAGglsANAVbL86Zb5iQgHiS+jpkgHSqAk+i3rSwrtLaEDltuDc4hx3BirLHTJJuYIqDCHOxC3VwX31nf81zXz6gAD+7PLtBGW22B0XrDsvk4dbsIC6dP1MP+nnd/H+1kT6g3b2DkxOV/jMh/wbTInwYn63xzbg2triQekJPsbjQYiXt5R8cb4JS8jeiQAvW7aALV8AM35KzRrYx68KegZv7JKJFyvv6ApBiP+S2pAt8Blww1mVm2iUGXsAL9zSzO2BvxzmOYdrK80iYWwllSmE/TcsOMY1lYwYplxtvYNjuAQexrLY/NhcEyDrTCmHzD7knmOX4FSqnm8weO1Ox94fhQ9ylflPdTpv/8uQWiv2zWl//iN9JVgySMAACTz75LWyqkkAAA==" />
<img id="flag_vatican_city" src="data:image/webp;base64, UklGRnwBAABXRUJQVlA4IHABAABwCACdASo+ADwAPtFipk6oJaMiKBv7UQAaCWYA0ewv1mpZg3i9GurgJXa34PKDo/W+ssM5MWpU1bZd9AyQmFbBfRwMChxXw+uCd7FwAP7wpdf/7Gb/+jN//Rm/sAf28my4AB3kkoIj/Jnw0+3/5Ji8vw0+3/5JhbnEvj526K9oqBKWP6yrJhAGeyNjJQWHkfnjsEGBaRJJDgFYchYreqT/Jz88ubNg9KoLgMdFs5F2ZZn05RS6QOab3fsoIH8vFsaEZ+GwdNi97HRm86gZ7ZFcDjbsX5f7aCHhliWkcydbRxqKdub2LUhdFOWRanXL5kf5mTIb1uvnhcpR+1fdRvRc7Gcgb4hSKgw4uynFORMPAQt1SubSu9vZh1khX537CLz5CxJGzgyFXQRpqHX2RotG8ksPP3o9QVjeSCwLJlaKrWiz5kP17pwWZEhm3ck043lruu9bImBQPlswObj8upjA9ykmAW+lngdRk09CxbAAAA==" />
<img id="flag_venezuela" src="data:image/webp;base64, UklGRvwAAABXRUJQVlA4IPAAAAAwCACdASpQADUAPtFepUwoJaOiMZRoAQAaCWIAdjn5QJiB/ALj/AzbuVh9ZuF3QHdF7L8XCwCDYMlhy+i2OD4RSwdn/dHIc1LtMAD+8JCj//6yv6j3mo/TD/gl6lmNMsXVffYt/aTurvnaf/4yt/Js9T/4yt/Jv1BfSWPTqFyY9rn/sEWgivhm6JyDq85Ftths4LrCeDNdK0pqZXa5nCYQOnu3MpDIcu3d+G70yRbdi4vZx07PcRE3DvBy1qNBgNL81xiFrjKsQSw//+CaN+BOCaN+BOjb8zHTlGTGvP7SMAa83e5eUh7P0oHdfsAAAAA=" />
<img id="flag_macao" src="data:image/webp;base64, UklGRoACAABXRUJQVlA4IHQCAACQDQCdASpQADQAPtFapU0oJSOiLNv6AQAaCWQA0xhOUHVj9tNzznow3hDeSl+bNXQMW858gaS/Iq4oo+G6RS3P/kw86TqME8RAuPUffGHeqU/5z8frg9ZhesO2NU66aqPBgaOoo/5feLdQEIkv5/M+zN6PFKAA/X0QLAYlBhTBr//kGP0NfgrvxwiHa1BfQ2H9dy+rnF3CjjxhANTWJ6cnx45RbflkGluZLtx/lf0B0yaQE5YKhutNDKb4QQ0YkOvq4vAI/Bbnc6uQoNxWjRlS0v2mM8m4NEa7IqnYOb0qXuJgD9lt3LTxaHsKRogwqqbKIXw6iqAW/6YMG2s0OJuo1kUFNbLjxNuH7p5Q1/eQ+YVPa5xNEjCEKy1TK6LaaIr6ak87elgpXSbKKDJjCstkNxqNDDOtVaWmO/795q9rFbaNOUFpEVCbY7ytukD6d0oGQSCjBaiGqIFTix+/l0irn147VZL9Ogj+Q0+5yASkWIMIdXB8EfzMWKb6EKEPHSXamopYaiB9XAztu2iWWyEwAXR12m4vhWtBtgfvudhdV5ow7fFzTA+pMZ8nSI2kyzrHZh282VS0/OkIvFolfp7wpwkVjgDOcezp2fhfXMn8qdTr+XWD4dnybL38uwf7vKfKkm614WhKXSq7z7Lk6SylNfpj7cZlr9HsB7K/zRjgQNZl2+YjnqG2s5bmMe9Y9rybP5pXRajHmdR9ujdwl0QuEd8pyQFwgEscBkPEd7XOgUitsLcg9fhYTSgjeX7gP7+swV+UUe4Ft9romT+Dh5wtoK/YjOmRh7bsq5AqaYp63qQG2gAtOwYVD7k6wHvwmJX4AAAA" />
<img id="flag_papua_new_guinea" src="data:image/webp;base64, UklGRooCAABXRUJQVlA4IH4CAADQDgCdASpPADoAPs1Yo0unpaMhrNgN+PAZiWgA05l4up/qtxWcp8QDpc7jj/4+mBkr2AZvqnZatzPT3sBj9h3/O+aQBhXQhaG7M0dxogTzpfpK0sWOe6NxZKnxVdRArKuYNdSw93NXmKqggxXEETV/Aq+FtYFJIEpx5t1umwqAAP7D2sYmthmkeviCOqZ1VkXcG7mrAYqt835Y73adImUrytr91GzNb7ceo8kvWMXsEsUuiVrVnJSLS6ztflWOvrcNMFpLpTiH5TPJVWaNEAptjVScb/xbNxVkXBw9iIF3zq0QLJdloVyPojx2OrwbDOcFgsajVQuOQf93PULfNWL5BbGzI9U+hJZWrN3y56aVZ7Nb0fpDhhILdtBTdr3f+AzGT1p6iax+c8hQFlIbvn7iG25pZy/jVu8ttHWPK+46mWWci0y59+E+92QX4LM0XjSG99iyYRsfCaOoGMEx6f50FVK5zQAhmUUN9lqBIGW+NX9uSfWVSGEQX3AuKCPBxJsf7Rv6HiN9RqzGUxmPlMm/nxFOMCR4Sl67rNiHptF3R+3BQDHQERcLxfXIu76evP/egZc/7KGWxUsJp9Ov9/zQZLzNb0ha/tnUYw+ldHVeIu+nu8B5wdU+wV5dCT6dP9LwxDgcM9++4oyWE9SPNan57QfGqj+sK81azE4g5zhjh4hVflItw/L3yx46UAS8w6qfDoJNsYVQ5Y0a4M7SHCdjhw92xQGiDQ565ScK6/TDMkOeYjoUZXyoFASqAcCOYxjmXaYuyet0M1SnfPfgAnFw8lvnbAvALA+xj5It7SHSWoM4lOsGWtlvxo+7DSxSjV6Tz6XDZgK0oYOlPH3AAA==" />
<img id="flag_us_virgin_islands" src="data:image/webp;base64, UklGRkwDAABXRUJQVlA4IEADAACQEgCdASpQADQAPslOn0unpCKhsZuccPAZCWwA0l/E8BjoKJE5KgH/qvqZ2znmA/XDqgegB/gOpT3kf/B/870dGkOuBQfu8OAFklsZFWXzjUMUJRw4EpJnY919JMtkzxJT65Yxc8aQAKOZk5kcHcurTyArnQBwVx9njBSG3WvhoFanNTCrWr5kKRqc0OwLIHiQ11zXNY8KlJ1y6dYAAP75nbWUFmpI6NFG+89UHGQ9h5nJwtfG0GXhXp9aN3HBHpH2y05zW8q0Jt8s5Om5zxA8JDE4+Sdy93eWYBWMgYt9CT3ib6+ZjmGsu8Qe3185PiBtAORZN/5Ggu47YW3fo4Z+if9lyM1L3E2R4XKL5ta7hpbqlvS5qJmMntfB5ecQFejyly5nE2S57/H53urSIf/+TxZRZq/vstjo1+A7tgIkj/0/kMC/XAbFoH4D/aTwnQc5HYMr6q4xnCpPgZOc58728fpkdl5M7I+pDFVcbu/ktFowO9T8vf9Psj42AdP1bmHxaQ11+1Nd0WoozkmHdH7F3u9krbtG74F0N+sFnvwPGqJZ5A3o79Y8K1vcvx+RtffLKy8ZNzRH4x3aXoq8qfqClBDEr6O2j2dWy6qemiZu1wGN0HKy9WPudnet3vlrWLG2q3YlMRttGxDLpsq4GBYqY61AS72xJj+5ZKfpXcOtpkDd1E4fETVeSPU7guzRnIG+rGeIdLrAWEPmRDHkjV2DClvGqfhPfIQ2hfteIoGMHuHUmfalGSOfZrs6ibZRr67tO/FZfogca3M+u/IxZbX/8ITYY/mO2RTq0T69LSi9CZjVZcNpmrxNoSmW/20OIRvdkjVEda67tUOnU7TYISjbSN4NZJwUIUO1dCVTqOrhJkCJeXivLerpjgrVv4dNbOLJVYluMjP/4IWfZxUhum9WqmviMiOLPhVXeNg8s9IMfqMIuQ4+rEOKXuaoxyioQlLtzN58Z78tk0tgft6HLsgDcWcN673+8232yIcp4UJ3bGzKT8B8Ps1XR3CCpfaQsJ/PkidHWmxYUYvTibvHRtsIMavwoja02CK7IMDrQ0IibkEA1kMXC4jg6YF5kQEL+5MblkDogKihxrZOu8VaAAAA" />
<img id="flag_latvia" src="data:image/webp;base64, UklGRnoAAABXRUJQVlA4IG4AAADwBACdASpQACcAPs1UpUunpKOhrMuI8BmJQA7AABNIko7c5MS2WXesVXuEfk7XkwQA/m1ZySo1LXv/xvN5vW2b///maP0m97Kn6/jdtnWlwnok/1G3Ab5wKRTFRCo1E9X5b9oRK6G0GlAXJSAAAA==" />
<img id="flag_south_korea" src="data:image/webp;base64, UklGRhoDAABXRUJQVlA4IA4DAABwEACdASpQADQAPtFaqk+oJKOiKBZqIQAaCWIBBgEmBpX7GtAG2A8wHnZ2SX+0thuV4NoMsDSBTBPGb9M+wF+rv/G9Zn1nfsgqJAN+ylpvkrvaS23woXK4YjA03lly2hzi+3dvdVLh06j1a5RWkSBXYgRoch7kkE64GWWES409g2c23kLjtjZpSSPMwAD+/SosVPDM+40ktYHCrV1QH5+I8NV+A/xAEYP32Nx7SJXPUfjLP7jJZrw7AbojSq5DSoYbi5iJJ6u+ELl5Rs/t5MfF7/FW56kHpPLb0u/DNrplq+OhbLMvjQld1lpXbO6uDgDd/tvAuMtSDHQxJBu/uxfP9sag3Wnef8QCGg+Mc1o6M9KqKoozhb/v6GkgtYJ/1b+w2e+ADwRQuSaF0sxb173xovXiD+4JADYg7o1ju5T4nseuA0s+Z/dwisGU80WSMU6yyEOEtrn+A1lbx/jZPOUb0t0bHZi1903+h/Fq+Jz49N0H6HegGMHog7uLiOmnOp8ly5Md8WABa5EFKF+zf6H7/BzMh1/JzffjgLs7C9S+Qf8f/WI7fc+Nf761L0BBws9aLUZ+HH43DbOltmEcwh9x3+yX/zny1UrghOjfP/P0a7+uqmPZA+yB2PAs8fDimqe3FsDNGPnqCD45M36Y+oPGIDUGgrxdeOmBMeBm6OhBRviUcD1SczsE3ZUZ37no8ELUE4ejvRdR+bOJLfS/r/ngynxi8wiXKdf9J3nCeHgyXST/04PeitsCXek2zVaI1AE/MnioXoh3OdccJPQNjgpStNBGeBlV0FlGf+5bqUMex4niNuh94WFHsHflN04AOw7CW6oc01zzby0APS1IYLBcfM585Or5Bz6Xoc/Ff09k2GU3s/Prrw/Yf8OZFAizsI0cf0gOpUc/Waz8y73tLbAUZ752D07wiHDiL6gg63tnxMzXOIwZKfCDlm+z3P0s7oAO2eNTO4EVfe/jXodZ75hQNj/EfLz0v7L2z9B3mxqe6e/kDRdFwC3Ig+J9XT4mOUVQWcipTK3I3J4FNAAAAA==" />
<img id="flag_haiti" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAABQBQCdASpQADUAPtFgqU6oJaOiKagBABoJYwBCAP4BhAAC6kfbMH9H7+AtXVNeaj1GOAAA/vBsr//V352/U91n1evFz212Pi5ifChA6XVBQD//4JB7/4l4V2iYsZNyS9POl6SMaRbi7pkyqBl8pp4AAAA=" />
<img id="flag_zimbabwe" src="data:image/webp;base64, UklGRgwCAABXRUJQVlA4IAACAADwDACdASpQACcAPtFmplAoJaMjJnqpWQAaCWwAeS0zp27dMS8+wH8R9AH6wet30SXUwb0EvwVsaDRM58fX03qEoQDgUygkWdU+wp6ymSwZFn6EJQj/uGt87Li0sKvFgqGR9tkJtlUfjdsgHi4nFd9UAP64RhKsT9vlQyy8Wj7cf7K/YWmQhU1OC1PeUSt819bexNr7t8+8Z8yCWbDWI3/0N2Zi96x+foffuhZ/3BSPih/gFb7PsI9O+7xbHzYMPTD98aefZcPUstei/2LXpsCwV10e7ywS8EyeqRAZMYB7l6DqPVx1N2pc/8ZNPNAKVf7iB4RxgNmSnZweYSTaC3sRlkMh90aQvhay4mANMnc7EMwdzIbBBr2O1KXCwu67ojL6TocVjIG83lGZYnlnTJpKBrWuJrP0eiD/UEUqkJk2StT6GgBtdfX9/ubVYtELmgq3zJNocNXZqxJTxj2cfOs37wKSTwa/heFdyH58+Ez6OcEBWpwsLAi91/iAl9V7AejG+Tf+4xun3SPvzFIZx9czoYQkPaDhBNYu6T4KvS5dH4UvdTvM95F/ynSvcM9H7kn5/zvJroChb+23wxNt9TF4klUaElFrlEXuKm+mzjP5vgmIQ9Eig9NxUREKkrERp/VzQ4E+GLMgW7ypRCTTpL7eBclHaahOW7KkYRBfEAAAAA==" />
<img id="flag_cote_divoire" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAADQBQCdASpQADUAPtFYpEwoJSOiLmgBABoJQBK1/zPVDOQAGwKwaFguUPvk4PxsoVXYk0/5AqAAAP7n5L/FoTDwa3NdC9AZRMQ4fqHVarp2wEd6+eTrQknGoWag7hcaGcqA+F3oQPrclO+wYm4IxfwAAAA=" />
<img id="flag_brazil" src="data:image/webp;base64, UklGRmwCAABXRUJQVlA4IGACAABwEACdASpQADcAPtFapEyoJSOiLnVboQAaCWwAzQlBPg+1X2QKm0w4gG2j8wH2Ae+B/APT/9QD/VdQB6AHSueRm0QVtN3nmrf6P88k8viceeyEvGeWU9rRkN1uh6I4aoMkgOXRHDTN0ybuMXAtyYu821zI5c6vqRz9F9fhWrgos5rGHeAn8AvBgRCYQADOFqpSFWz/CtNFcs+v/kGKxZdT7nSgXS9Q4xrcJQP52srLDWsYgjtjXGQRq0YzMlatKwUpKI8nLvtpQsYEkE92kKgk5oPg/z/Q2Gud8/0YfgRM/Wz0hGcxEekIUHUDUIYPTn14SlL8O64AfMj4WeyvmRw1dIibJvbY4R1FigXvpMb2PXkss40NxBB4HQnmwq+gLIjDtjas/Y1rX49K+R+oq8iy+TDvUkH8FkqnyTXxej0eeP+XN70GM6NCRvqT8SLN5jK6obmgLet2yaOwa5AITyU88lQp5AMhz9MSqL1fHQbgeM5fyFFw991gcRwpuW/Jlc0elp01I5fw17jbJ+ox+3YAgyD4PFcF9I7m5waNNve+m1PcmfsnWqZtj7AOsrLDgCcJzLY/Rg9T6zpwMs+bI++T/6iilXKjuY2sOlSRjG4XnTURY7KE/txK+0dC/OMP/zn28O5WadAtGzUj0DdSvJV8lv6jIOraBKrOjYirN0/hpdv3yJt0uuKApqR99XHfxKvLfIJzuuf2pJPGUzeZ/ekvG5hk409OXkuCwxAvs9/RfmHRC12Z+K8GiyuzHrPEoEzUXXT1HwfPJu2x/tdKr61ivcxFAivQgfCsAOUgD8AAAA==" />
<img id="flag_mali" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAABwBgCdASpQADQAPtFapEyoJSOiLn44AQAaCUASoGnjRAmf/OQANYjx/BPOA3T8VBVRHxJx9bMpe7iojOAA/YxxIz49BOQ//cfOXnKoIJ49oAbv6jqSnGo/rHCuwBoNNN2sltAQokFJjH8DKRx3iUC3fbsSsnFnNMJBAsQTIizDKkhGjiN3mYAAAAA=" />
<img id="flag_mongolia" src="data:image/webp;base64, UklGRggBAABXRUJQVlA4IPwAAAAwCACdASpQACcAPslco0unpiMhszjoAPAZCWIA010ANaY8PRGPTRzf+cvZKr59ABCjymmJ8l2y6ML7KKXNFzCOuSKTbSwExLkggAD3BBrxdk4vcUZ4BpYccRHIq59R/cZ6sPNV/xDmJsEwCxTpHk6Fj1hVGg4x6wUCocCBjGVejeqwVi3/sfJXo99kzZ3RKfodBO2IrtwnVK4uEdVGwF/+5XTHsgPIas4AkYsk0qLfpfijtnVAc3dxzppedUO5PkhkVkUiRzQ/mHkXyOg+/ogoka8y6kroRd8yAilZIGF+TKKHGr/FVPI7t4CQJaX9YDM1Zcz2N6LH4YxAAAA=" />
<img id="flag_sao_tome_and_principe" src="data:image/webp;base64, UklGRvYBAABXRUJQVlA4IOoBAABQDACdASpQACcAPtFap0woJSOiKrZsyQAaCWwAzyWu/merY+A4l7gHurwezAMMB57HoA3gDeWivA92hs8bvLb+KyQiAeWC7ZwxETvkT2R7fAjPH95RY23EdyEODF0dAczhED+5XQBEpRbcAAD+PWc7ae31l2dyoBRv0K1qkPdBJXjUCuTatzGd63wlHB+1XbRJ97P+g7tsSf3Eoj93YBIbchBYs4TzBzGQne4iNgKq2RAvJgLkSnZv9/6w9vmcuy+8bdn+y2/kCT+Try5y7T+QWkmV+4M4E0qiAiYH75gFs76yir/uZWk09Ug1sMfpV5f8ium+U8N34EaClGdDWq1vmshg1MWdFHOTd98oq0Iv3Ghw2KSqbYJwdmrWvUz2lmBZ45zV1zcnC9yvZlwj7uyI9CICcPO9YuSowbWMvl5TRa0uWFDk9USm8pXxDRbvtktU1WbOjiNYSTsC7/MIPFrnhK5i7/Jeu1ob2UT7vKaBcZsDg2RvnTzlHPuv5O68+bCDdhv1qesJkfuo2ndJFWTas1JqFBawY5yK7c+6geBZv7yKjuegwufgOgB4miMucEtAOyn6Iu7rmkaKcedNZajd+H5TxM8lBxxB05McnJtmK9n1hYv8/9VjiX0WdPK9y0yqxCd+1gxaYAAA" />
<img id="flag_saint_pierre" src="data:image/webp;base64, UklGRvQEAABXRUJQVlA4IOgEAADQFgCdASpQADAAPtFMoUuoI6Mhrvts+QAaCWwAwrlBflfQMRw6Hxy3AL2LdXzWOV+cB5gHOJ8wHgze4v0AP7v/YOsW9AD9kvTA9j3+6/6T9svZ7/+1a15o/U0lilPfP99iYMmNxIaSCap5APrb2DBHl8xY4hW/u/956j2q1M4NT7YmHEk3Y2gqPSPNALbiFW7oOEGQaj1agF++az1sjowvuWUBuGeGfU7RQZlZ4wziRS3mSpNYhgaJ6PtKfvVHAAD0RKDjS+B4Dq3Xmf+S0+JPj1AxPGxRFX/IxGSbCtYlLfDI1Ij7jMmaLBHTODFWZPdDPYPs159ziuw32dOFRYhI+q9ZSbNfJylOAbJIHQr4mip2UYh56R3ZI3eT/Fwa1y/wLFW2aNGWDyzzGI/UHSM3MNEkaW6mCOqcBOzaFS/sIHzKxrIGe+0FrulBC0ptd0I39U2vFXEIWnfwTk3b3v56fO9tF1fhC0MN3vHk+JKj8DkYj+9xhqMFumz8y9WMH8uGxf/oPZqk3C+va10jjevj+rrply4+BKrF/pZY+6eYDU5uYXgP2KPMZcBxmajjMDRen2uFFiaxpbGapLDotyDlVZDG1Z5wPs7uumVIIThXtRDb+Q1gO6YGDHJHiVIpCEJ0S7DiCqgVyZpImT6/jpAqPfE9FxoJhiCwxfLfDl/bdLB9W+dfjt8SsDPX5J/vkPdSCiEYqtHb3WnOLXi7YTBdX0QuY9jqdER8ORQiTTrnFZ9nGBKfes81TZAqyOTzb9zT51z7tiJ+ytoUKof+jSXzgpXxk3yCjhaEQworIfLLH/LGF7u30Dhp9X3ugDxKF8Gk7baljLttOBGR/4vI58ts7vnlqs59OeFmXew6egwucpZtMKhtiM0gHthw1/a5ao4X9E99C74i2fxyW8mkabAc1JFMXeGEX7lD1v08soJzpIjm6NOqZu4Vjykdqbopw+M0MtoTZPRPFj1LpcNocjp4+ikkL1hjHVvz5/ZJRflYeqgQw9HkAQqIAlCwjSFmODMzQr1RGlCS7McPrdBXXzrdQrc6/bv5E8PVGH2NroPZZYaXF75PVwelYC1x8vX7u2g5JPBnL/kEoiCGazfCY3gq36Oj36Zp5plufIWenB0RH3b753gU4PYn0p2+M8vRYY5wtlKp6KxvkBt3sdXg4/9xdzH1D4EibmQBSmr+yjUcushHmteYAsB5tt3m+lh1B7PUp/bmKxToAuRZU6tPGJ0oNyom9CocMQUS06s6xPLnakFE8zn3/XMflnTaRNOYHoxNF+p+w0uybQ1wZ62u354gR6w04isVWZWKnwnGI759JI7ObHES4mmX9gb0T26/8j7x6ly/5hy/hKzecOOITDXGJWLNIe3EX1KSst7yAP5jD4J9A3Wnt/nxFa3NQjjL4fHe2W+whzUWcaotFQiIIFHcoRSR6uzNcQR+lxby6FN4ObKKz6c18sGv3qoHBdioZc4wVL80+PypKTEKvOvkqKE7tQUSpkWXpx21wBvPDDKGsZUa67rPP8pISN/3heCiFdbWx/fjAeD++DL10qEZdNbZFsgFGWJmejbmK9USzeVF5fdrjLsaaPKCamsUR2ZR0Prj1sKT/hczz3EI/xP2GNuhZLM37/dZFuew0qf1iR6mDxJsMF76YmRbzSntqODU/Hjx9lswfm3AAA==" />
<img id="flag_philippines" src="data:image/webp;base64, UklGRmoBAABXRUJQVlA4IF4BAAAQCQCdASpQACgAPtFeqU8oJSOiKJQK6QAaCWgAeVxC6CvCuuj/6gDeQ1+CtA9vZb3G1bdMO9+aekuJBIzVvqhZG5tTb1QbuJe/4PtXhYis3yAA/sqemnNXW921n5ms5KyO4cE3gjcl6P+hPXqbrnc+t+KKvxXoqbutGsqHEP3f5+zbwC7Zh6hHp6TRiqy76vmAqpFnPJSBxcZCKc5i0O3gzGmAJEvoBPPIWKYW6EvKBg4FCoQ+X+efZlbud1B+Vhr4HIkczEyVW57hbsFfrDvNCK7FIFMP5hwR6wwp2mnEVtmt4zlYxYyWoODNgY6RXWeN9apK5VIps4DEXthNnwdd5pd5xnJ5bMBB/uZ2ZAiubwfizSf7Zs+0nyqGl87/gQ+80elQwi+SGQ86o5RJokMBD3MZq5Au0F7U6KkQcbqWQUYP5tbBIsLn/xHc+UFETkBNjSl+NWsvfrhTTcAAAA==" />
<img id="flag_macedonia" src="data:image/webp;base64, UklGRvYDAABXRUJQVlA4IOoDAADQFACdASpQACcAPtFapU6oJKMiLNK7iQAaCWwAnTLLsfe0fkp7ItK/x+2+GYr9eoD8TehB5gHqA8wH8L/xf7b+8t/h/UB/p/UA/6PUQehF+0fpx+y1/dv9/6Nl4Yn0TAOxAJayF1T/efJjpSq1KLRtOLuvgGuGGtrwWWOtfoX/c7zk+3MG7MoCSY//dbhcfgMSOw9RDcAXpheh47/NIwf2mnI3WbS8f2mkQXo3PvkQAP6sLbfca7cRd0y2f+mwtfSOe/gxP9764FSxHs+VDH/8a/aXK1/+QW9ccMfHP7uJLbo9f/q7FxvT1mY7BZjm2lFbszfRxs8KgkglEEJVwKnhMUg6ak+utg2t6mNzB7KdivahE6v9z/NqZmXfa9eGlVUchX6sq0X3UgxxSAD1DXHSv1xC6wnZpC1hSHw++MHRm2PsEoiZ3KFi2QQSHdc2nw/DWUmcrN+HcJUwOyrU6kuzibDWPrtGYcZyBUX9beOg0eLO18vwZzhnpr9X2ALDVLkv6kq8QEIRfGR+36rd9TFRnuZeJ24pHKXVewrbf+vSlCkfMmfd4jk7lbLXVYeI7up5U/y+jT41lvwSejiIDCvMfV2Qx+SdGSedOUXD4bPSOU1QjC/KYV7zLR5DnzxIi3FEMRftNwV1E/Bjtd+3JMfHODIUUY/riYOJbTmAGhOaYXA+kPJW12hoTi8Zlgau3pvx70+8b1zdXgkO8Jm2Iw5ZPQ6RPCcC6DNFk39x657c4J5Xj3vxUbJH6iu/0hQC9qbabts5ENVmH/nEmnCXkje1E1yOT1QularTzzNrweREUhKWwOsmiaKJF6rX6aRXkzkVTBgQiZKbExJpUeVdI8G100AK0Gg5oGrcZxq/N9YUZsnaqdUy0OdhO1XoRqYRDzoBSe169B5IWU9zxbVgKmh7RwTYN/i7r1g/2aGAHy67y4D6qHcMWDnNkAnBDIcHpZYxt1kflToU0dVLsOtYcWK94/J4xdznoNeAm/4ShjPj9g82hasJrMVIaA5uc8PiXjiBeRHDyZgHNIaTF8h6Um/MR/Q3GJo7pfPsIkdDRa4mOqj3uu5wstvY5Uj4L/TPyWlfqbdGL1uD62TAhng8SSj6PmqYPD2X22vBvH7t4kDkzMYLFHKCHue/eSJgY8pf79BYAD+9cXiuMzmpMWyDNdEX3YhhhAPZgnBs+VMqB/IqSY0YREvWbNWxuoU0yUEsTtpUGvFMD+YWOmRUHPnCc5c9BdYB4kXglMpzA55Aq2j1hwJdwZaEeSs1Lyw9wsGkXrbP7Ynwf3dLCw9hffuA7/dKzCs/qrR+NrCDJTSiN9dFXwQdybr7sh0AAAA=" />
<img id="flag_kenya" src="data:image/webp;base64, UklGRlQCAABXRUJQVlA4IEgCAAAwDgCdASpQADUAPtFWp08oJCMiKbVcAQAaCWoA012uvL46vgFsM8DbS/1XsY21HmA/ZD1qtOA9ACyui8Ckn0BPeou1KWYc9xUEIcG8vatY480S1wuu4wO+eBlHML84GHkHJLYIDnrI3qEjhV126NBDtrZS9UM4DjJLMAD+98rb1xxkYnKG/2sGG3jd/imFuDQN3aptfArC9M26gxj+t/MzASB6MVMjW8bd5AY7kgCWULwg/2JvC+8tt//LvVi1/3lO7ZkHxFp+LkVIS+8bZIj8Ww2sXoIHjWuOOH2mI2KdlmbszFlpmGgrQ44ofz6OW8gpolbV3yRq7m1N0h/P/wLKm/SHZX/drNODpukjO2ktjlihBIP1LHXoYSRSp2bfvDNJ4D11a2ZS6YIoi9MEeOmnB1hTwlC/M/Y15bSg1T+XMd2FzAYhdMnf+iu3tS2M1/yP8xiO5a46N0zZNNwQMMlurq0cCMCAbH2yHqHdmyuT/CY7m2UPz+d4ts2jq+KHrvfATvEqz9cr+y21JHPRX+6J59xy9d0G/3fZKID4jw+10h937/ZUF+pWyIeXonVIQWCUYmWqz70Gro4ZzOIA9hsUAtfZT/WLn/Gcm2lL/Mye1+/SZjmkzWqH8Tn73UEUeZtafMOY2vkivmjQY6ACkV1BNKp3DzQ0EGXoV4DTr4HI8OQTt3bZdoOoqHaFJfKIW2MYKgvzN4+/InLChMhGkNZ06rKXbTnyywQatffapvhBJ/0gC21o+yeMuiBGhqJFKVbXy5+KAAAAAA==" />
<img id="flag_canada" src="data:image/webp;base64, UklGRqQBAABXRUJQVlA4IJgBAABwCgCdASpQACcAPtFYpkyoJSOiLNgLiQAaCWgA0I2BvE/t29ZvrMLndVf8z7MG8wERWc3fMel9QBNoFeoKeSlqM6gq3KzInI5PpNmHGo5GKUtikejX0LJHLOUcmAD+6Di4VVIl/64D/nAf84D2h35Jd+S0jpgeHe/MTkF5ywOgHGtXTX/g3beY/8G7fj84X4waxmZAez5DdA174BqQyUq3HRJFbet+jp84fh5yha+/WBNGpRicKS5I2/Zg7DlKkdLdjrbBp2rnSyVy0+mOVDjDSmNGmFt65Dui1h0LimZf3TzfiL1TXrRDmEdf0eNS4zcHMjXvku1hq2C1bdLemHu6lZ/aFxo2PsIUhaPqmb46wQIf30t+fbeH8T/Alr6W6FO62Nb8VtIdIO3FQA9MHfXPpLyF24BzLznOQuSrmTHwp4/u8BkiAEMlxnA9ovGcDh7LS7zHobVRhoDWSyf+gXS8okLzSUeev6/Kv39U+/z5jdHvNFB4FAxOVsi4DbQVdBX7QJQQ4gXRQrdaFi1AbKBQEl5axgAAAAA=" />
<img id="flag_bolivia" src="data:image/webp;base64, UklGRlYBAABXRUJQVlA4IEoBAAAQCgCdASpQADQAPtFeqk+oJKOiI1gMAQAaCWQAlQNTd55+RXCBd7uULXBgoHrQaZXu8YIW1l30au52X7T16cYYUlTw6txOMt6OP6WrN38zP7TqS4dZmOcJgAD+qIaXf6A0p3ZX/6EnwSfBJI5WjJ7sneUs2YRn0l6PEk0XERHn0zb4BzDqRlwqWgcHoxEduiQW6uIw81FrKFok0zakgY0RgQVIW7ydnaKXuIqR2Khj/zvCTuMUkTk/S4p5bHhmxi839bzwVI/3W6IHLqGgAKt6xpFf7mpl69Ctf9wZwa/JgndAHz4VmybYkmoisP45svRr5ByjQ49YkHY4xdO/tf1PdomgA+RpXyHTjF3Wb6XgmM+oyx+gOkBz+58GKRjelrIMj8wdlXkXXAVv1Sfkh6x+lAp740Smzy3XEYmaSGEQxWa1wyIe+JAU6AA=" />
<img id="flag_estonia" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAAAQBgCdASpQADUAPtFYpUwoJSOiMZi4AQAaCWUAdgC3CQ/wGCl2UrcMPACzhFbHdNWd29KgLM+pdpgA/txR//UREFJLD/8Qu9jCgw+7T2jxvYLuITWYhSI8linZVLqwT2ez15iHskAnrAAA" />
<img id="flag_brunei" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAADQDwCdASpQACcAPtFapk0oJSOiKJQNyQAaCWwAxBeV/AcdD7766MZ+PP8Vv0vE7/YD3o/QB/oN8z3mCsvV02YpyCb5/xAXCRo2+TbLJU1ciqtMNwjRj0bMSj2vo75bp6iiczg4ZVfXlJ0C3kM8GEzk6geghmsUhsxKzc/VIGJN/pAbQeU3TaAA/vczONm+k92YX7FdxN7IcOiSj3r+szxlFpj7ELGWeuLb/228qcTwHQ/fI/kvQgaWI8BkojvLwn5418+E9tyr1QJnqOKgunL9ptc7vWIWAG2m9uuPkb3efHO4gSa83ciFzMPCHx9n5UPeylHhtSiR9kf1T1GExOLXMYQUQ6NyXYQHo+pBqaLh+qT2BP2xIOVag6NJ+3aFnKPoyZrjIOnAkUHtrSZS636OHp2pX8I6eL/TQUEiHQwfP+xfr/R/5nU+EnpWzYs5HAufTvsEqOD9dk6E+Sp+a/DQvN94n4OLlbSjJd/8r2SKz2Q7v01S7J4gpyPn8c7EHHoJp31JmO+jlJo9EYKDZhhUtfpqC8Z4H4/XuI732hu5KH1FAm8Bj497g6ungnHFBDjiLUMjraJJDN2s/p66lwCFj3/3ACFDIwcU+Nx1ZzzAya20pcPkwMQy4fL6NRcc7Lmm5XMdXbY9RRP8lHa2QGPbjP4maTYRmxeQ8x9/TDbD8bOTBH24er/kOinKiYFHswb5UuHoBYiMcn9q1l/GG5B1Kq1HDsljjkhSMi4Cx41I7rKEMRZq7siRDvPeWEfOEnusGcDpd37sJwvXhuaI4p1Vd1zgGII1UXzF+5sJQ7B2raqcGxnza45/VcCy/O5U/yCn+NhMAdL8SgEeQqjFzclgEwuXlBarQ5aWI2PsI1/lWa+j96weQneu4+ZhdvdYmlHdwQM56/vHxbl6AAA=" />
<img id="flag_italy" src="data:image/webp;base64, UklGRoIAAABXRUJQVlA4IHYAAAAQBgCdASpQADMAPtFcpkwoJSOiLmgBABoJYwCVA0uPptEA2f8BwN0qqPE22lM22RBFTx4i3nT0/AAA/tom/MgEaP61n+FMdPg/A25U1P+MqaoEhbtx2hpQzTd5jNP7x+AxX8f6G/lqwfH+hyFGa6Q4hBgAAAAA" />
<img id="flag_tuvalu" src="data:image/webp;base64, UklGRvQCAABXRUJQVlA4IOgCAADwDgCdASpQACgAPslSokunpKMhszVdUPAZCWwAyNGN2n4SflPNKqHcxED1pfUB+FN4B5gP2W9FH9lfcV/j/TA6gD0HvLO9iqu66561VBl73hwGmX1NKVEfEkz/6Ck4ZvogVF4MQ4LV1tt1N3tE7Wc32kwO+5+Bkutf0q7xPC1JAAD8+v6e8jU5X/j+IKY6s/UraPrzE9nuJ79Iw3QsvjyqZWbUBKuEEHiGcgH6vEnhgSUO6tW4CcqNNh2dI9VRPdxpDC+nOgZgWmEYWtTxpNgGkip6BWLtD9yUMckf+5TfnIA92IMnEkHlitKT9bcWG97+GbHTMvLtUaGz9cmMynbtCia42PEjk/MasTw4XApAUHSfK31h1REUnFeLkJU/R+/5XWAmMDsio5ZKG5fzlJVlKoN2/4QAEsJoOGvMC6+KOdUxTqT78d14ZNcv0Ojv3R+gAED49jVNvkrF8WnIGaVarFElB08T96HneQvqoNJPSwUuF/z13N0t24GZz6WMyG7OdmtQoMRonKVL7xEzfhgVOoO/q/nQfKbtfFB6zP/DQYjq+9/vk5V1OyzDAeWowH6VqiuuRe0bzyfRe7KEnnZeDWhzjkGZQ3pMURosufmS9TJlRLvhFwAqDHm/2cHKQ/4nhhlBcEp8jBrsImvcI/1inCzkQDVv6MIyrp/ZbY4Q7e53EnSs0t9kXUjiq87KXmwDw7YVAiCecjciXIyORiVWx5y/JerOF9+dMbleuPT0mu4HzpEbI9bZbto4aPbJBREDnUums6dW4JI4goBz2oUOC6TydsJSV2m23dnFfdr7e6+RU09j9yGOIfIytzuK4jMPVmOKqZwmAAwRW3l2cYnpM4zJXJKTQXym1Gqos04/x7PF0IxcZxQNmgBOTyuICOigke9cX5APBp7Jn+EUBSp/QKno/yIVlv+rarxNZ15EUwfUeYKokjR6GLtDh81mbi4uf+OHu3fnPVtaTfnbK6NU1EgVCE/AAAA=" />
<img id="flag_syria" src="data:image/webp;base64, UklGRi4BAABXRUJQVlA4ICIBAAAwCACdASpQADUAPtFcp04oJSOiLNQKAQAaCUAasb6qx/8AAMCviM2taMvCv4DymR/fk74FPMaEQM1M3VMK5qw8xnr372RAYsfWAAD+5AF/6Fesvvpsf//OJf/QL/wF5/WQZLcy4yXl/1tIWTCswtWQRw3uP+EAm/xP+D7vJxZY2mG10lBmGKPYjq0Gqvm9qsFJKLs7lQOXGlORSdp6V6KR/DRumD0NrPJYltjMFnv4hVfoibu247PL39I03B4TuzQOFBwxakY124JZSyfLFi4OtI7uZyO2eIhMy1jryv8wTlCCMeLmNluEIaKnIAe0PwgGnu08GXwAtIElLSZIvj7LQP0HvxoOJxAWnnFrHTp1l2A75S5vylBOgFInLZl6tUEAAA==" />
<img id="flag_transparent" src="data:image/webp;base64, UklGRmAAAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSAkAAAABBxAREYiI/gcAVlA4IDAAAADQAwCdASpQADUAPtFosFKoJiSioagBABoJaQAADHThw4cOHDhwrAAA/vOdgAAAAAA=" />
<img id="flag_uzbekistan" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAAAwBgCdASpQACcAPtFcqU0oJSQiJEzpABoJZACVAqP7zwBbBInCh3MsxJsw2z7Vg5Tmg7nO4pNLlWMAAPnN5mu3WOZLy3YSy6hTiE8O5IX8Rdjl9dkEKQYS4WtDwKEXyEyfga6E4ghzsPXJeUTBurDxPEBpfs3/xEWDfvPOkh7c9sMeu6T/BjWZCQr/QsY7erhJma6qaUbCvcifnVMP4AIdj8zWrLNuTZ2D07OlTbK3c2ONBlydyY/ulDDCL0P2d+cYwbc7dDxGy1jlvsUYEFT4Es7HzQqmiBhhYacKFpiNOd/0Y6JFXZ3X9BN12hvYjiB317aQMhiA7pZAwLoiAAAA" />
<img id="flag_argentina" src="data:image/webp;base64, UklGRqYAAABXRUJQVlA4IJoAAAAwBwCdASpQACcAPtFcp06oJSOiKJQMWQAaCWcA1ImNvGubALkALb88YQ8v7P7DAF/mDQpUMrtYwerXlBb8kWNUPeAA/vBnwQgSi6RQ6wAb7RUjL0zvtWROxmlq5tdK9iz3TX6P5/82E/+iWCag7CvT1rL8maE2XQ3joGJW67B81fdllBVqssF4xKBTmGeC4sbZEUjwh+MAAAAA" />
<img id="flag_paraguay" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4IDQBAAAQCQCdASpQADQAPtFcqlAoJKOio1gMAQAaCWYA1T1BOA/wDjm8//kAHSk/7MirieF8CPbOX10zh4wXJx/Y+jSV77yTrMI3YiXvbqfUPQWPzeAA/uUK/9iOzIwV/6TZ/E2fxNnxzFd5av71nwLNhRR9aXRr3Evz3c/8JKpy54z/CSoI3gJf+hBpGIKFm7ziklyATy+CK+a4AbrYpvifD/j/IaMX5VeLOAJ0C9ji+2hAHADL23KiUqnwCAfHLDbgYOIIVszasjgsAZvKZ8iwh33tCdBNrnhElVuKLOQMGWXoRWDOu6dckhCSmotC+fAPx3qtzxKZOLFivk+nN+j5IutC0b4GhOsjV7MMsLfTyaSs0cL8S8i3EWxES5kX1tjQKBwQytTaIPC2xxG2JybBWbckwAAAAA==" />
<img id="flag_equatorial_guinea" src="data:image/webp;base64, UklGRnYBAABXRUJQVlA4IGoBAAAwCgCdASpQADUAPtFcpE0oJSOiMBTY0QAaCWYA1EQXrB+l2CvmANwB51Wmq7zeBuFzURcoD0mtH7LzN1BrglNhhy3srwpvSj6DhPsRWTkreCAGvLSA8HubhgAA/j1nPqowu5BnUnrPY0D//yv/ez0Qf11KqoJJWuT3O+nTtfDZo9xgAsPKLV6ycdpaytwCvM/JpVZY3FEuTS7fI9//njKPyGbbxPfnfSwfcwRclM08bQSu33lQlVIQqbx28tn33t9y4smcGeYt0T8h+PeDv/5etnJpbTGmZ0NO1icKFlvYdQxJWqsxsO65ZI5x14gcbw9u45A6G6O8G3lkBgkpkV9hBeuwztNj+vb+7vIMpkpYOVPBoHIN0u4ynJ1oQTTiV1DGdLTIqjGVw62Jyosh+yh7/ClAEnZp7NTlz7X18cAeLxWeY3Ureb/MGfj/8GxYz/1E//c/8//fwqZ73gP7z+mr9//k3YBBygAAAA==" />
<img id="flag_guinea" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAAAwBgCdASpQADQAPtFWpEwoJKOiLmgBABoJQBKgajfzl9f+cgARAvoOvrUXmSlssfWRgT2VfowmaxiAAP7mOdp+j8UEMVV/xsl2xNP/zNHwF0m88VykqdP/ujcFLN1/4yiPmURP3zXL1Hth2sA05Z0YWdwMq/P1BVWM/DAMOgj04nJwnnNZiaMAAAA=" />
<img id="flag_china" src="data:image/webp;base64, UklGRjQBAABXRUJQVlA4ICgBAADwBwCdASpQADUAPtFirVAoJaSipnv5AQAaCUAPC38A4wG4Y3gDeTyJABxtc/Mbpt1Ew25lOFPrz2Q8MCnaO2S27ejEhylkg5gA/qiHSTqccvTPAwmVK2gbQ0qYChelUCvY4erQ6bL/+NshfjoNGjrf//ziX2EYdnT4IkxLJPR/uU12B4U682MiLO4XQOdltEgCo/2UDihrzpr/m7jxFS+nympKqWqTB52qlOrhLS3UjkdJKI9GidToDW3NVrSAQA/VAbWzuSuK3csAWc9lGMdEXDV71IobFxazuySCF0lDGu4/g+07bsrbTAx/zTmxsUwuu7Qe1t1TKs7wUo35JuvAWmSShzrHDPDT1r4VG2Tof9xhBgusDPkr7izlpIxkh4aV1pHBMAAAAA==" />
<img id="flag_vietnam" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCDiAAAAMAcAnQEqUAA1AD7RZKxRqCUkIqNYCVkAGglADxp+k24ZwDbAXYBvLAFRMOSnYYYkoZZGeaIGuFC5TesOFgLKLYawAP7q1H/+g+uJin//84l8kegXaA2nDnGLuxSMAkK5CeoOwyUx7E3yms5EomQVq+lzxMmWlpG+8MEMFFP3ipVshWFTGxaK8BChQ1PJbSYx1OgI2iK6gMuLXL4zsG0nBmf6mOrbuZwzTkKDQqiNY4CclglHJzNX35xBn0ZaVFckW3YqKY7lJGLEEWa6jdkkOtho+Qdoi69eky7eNjsqOhTgAA==" />
<img id="flag_cape_verde" src="data:image/webp;base64, UklGRjoCAABXRUJQVlA4IC4CAAAQDQCdASpQADAAPtFepEyoJaOiKJQOiQAaCWwA0I2N3F5yfN/yM6CnkZ+G8Bt7/MB5134AawB6AHle+yyjW0nGs0sAvc+DtY240DulG95CdVF2K8NcgHX3lVpslXAVLTfcvxdCOPweBDHeM7a+TCxiYAD+8IuvBdH4oIYqr/4HVVK4fmCBp6Cx/niOqdNVr9RSWy4ekB/+LdosCMxuH0QtmAwBU2tHT8eQXAv/64rBKtfnjZn5fdysrcR9kMkUh6KddvOaYGbfQgiN1Q38Bxdcb8fA73vD5t330AZVJwukGsoPerJA96mLOWuJJK0kq0jKzDX8r78gJUXrHKCX3VYzh07HZEd3bFFj+SfKSocdNEVRWCi33tcwVqsNVieWkJHNxSGxxF791Ay099sqk95X92PiqrhXZKEyD57LdrjGc/xUWI8h+7Gr7ep/xcXzgPysSIDaP2ZDl0ugHD9/ofD32j7m+lzTuJ/M78I9giS+fju4j9kpYxP4fJxi4SYCm/P1lLjP+V4xScRFIadB4yaAmkLM1AGn6tuK3A7Jip/jdEdWG9Yy6xb8pwvzT40SHMQJxi4Hbkh9NRPBP8V+nbOT/4ivopfrs0d/2tv6Ltu8DWPg6Ph1n/aAak56KrWsDKWHNa+rySB4TcoP20LMD/OO5cCt0zkdm5M7LrTz/Bdd2ZcGCtn3531j4VxnQDCeexf7/6Y+j5SZ8PB0oFFN1aoPmhByvINfzaud+EAAAAA=" />
<img id="flag_comoros" src="data:image/webp;base64, UklGRtwBAABXRUJQVlA4INABAADQCwCdASpPAC8APtFmpk8oJiMjKJgKMQAaCWwAeGH2njfOZHZ71gbPbZ+YDz4/Oq9P/qAN5V8kAwATO+8AB9UcANfI+da7U+FDXrfU16Exb8YXbWA4ZxT7CyN4uCTNpriiYh0snK6AAPv81TuLDEixNQJNg9itmBzW/7r9BDBcenceH/+3z/QMT//+56B2GDkhot4vXf/eUX9/4wBZEBoSqbbmIqO0yC9JRJNW61MYZ8rdTZ/QUYH/tVh1vcnUAqPMVC3QfqFTjY7Vh5OMnZMLXj69MjVUg29MBkV9ss1GDcg721DCtYC2zw5gnJZijO0rrq/CbQTtMIFidLpf13srpV0r3WKyo5EGf4s72U4Jd85Iq+u0LjZUE9Bk8h8Oh88uFmMwYZUBiHflUzSexD5uIwhxsw48W5EqW+37nGZ+ZaMO23qjOK16UZ7Bw9ElZO9CKtkmTFovPwuQPX1ppVXWWXu72seIMn8OiPp342DRa9/AK3Cr7hktar2v6KV/Y7xVAOIsJP3hr9YZztx0b2Q1YWkKSWVgpiJPNDdVBoshy54U/mvTf77/yh6eoQ7mGKTicNGaKof6Y9RWP+qW3m3K/QbOtrXg0L8l2O9xlQAAAA==" />
<img id="flag_lesotho" src="data:image/webp;base64, UklGRqIBAABXRUJQVlA4WAoAAAAQAAAAYwAAQgAAQUxQSCkAAAABH3DV/4iIg9JGUqA7KqM0OsddzvKIiP4TTNJU2zF4PlJDRYZ9NUHaFwBWUDggUgEAADAKAJ0BKmQAQwA+0WCpTqglpCItszgBABoJQA8cSn+gY/9ytQEaq8ZCn/yC/M4WuaAo3QbCnoEKQ0i4Dr9eSTdlw+fvmdMYv1PXVeeOwEcIHpemPP/rnTm0QAD+8LA3//4hz4p/cpsU/8FxL6USO/agilnb8ZmYrORIxUBjau+VJXsc/yZFh73X8k9/v/2aAn5vwzu5z7234hKbP/OXj42Ue7XaD5NdS4jgfAMX4eQUtrvz91PrY1atmjPQ0VAtrsD1j49zxU2DzmOkUjbGPrY/D0mhz1pxjcDh1ZW68zoC9EQhhzNc4Cfd+xRQdZcA93/TvCwyvdOJYF0GrgECSi+B908418viuRHEC2rEXSKYV+DdiLChPo5euPBB0OwAuqm0eoNGGadflq9M1kjXuf0gZ+wp0v3O08SQ/6cQPm9Gg1nGezcJuWHHKIx9alhJAAAA" />
<img id="flag_timor_leste" src="data:image/webp;base64, UklGRtQBAABXRUJQVlA4IMgBAABQCgCdASpQACgAPtFeqk8oJSQiKrM5mQAaCWgA0yGNvw/qsSAzgHnK9Ez1AG8Yt9IdAlQPaU+nF6mV6WSGXUJ9I2WQvCgniy5Q7lQ5QOpSmv5RzjjuXb8GbMnAAP7xo+bTk9ZZCQDLp7JpdW21tiAeRkYBpB/V5fa/S11gSKwAx8jmQfxSsHLSNCi+9aDs1sFGtX677MOhSZza5ztmiZb9NZNIBuaNTTEdC/sxcEWokYZrrCwCJXzLDV5nBg/Xa8WYpVDlqSkyfxB7QilDuS3yjx8Dcz/nz3iHPSPdm1JKbCmMM/3AHypp3NNHQYiuxOHqtjP+znKuUhavQ+T+Yw5uaVaS1pgg0i+Y2zjDJJUN2WfkEH2WsVLq/L0F8H1PgpWB2KX0r3moJb/hBgEFi2Kl/xd3Nge1Yh5ETb1VA8bKa19CD4hoiM4/CFbwzKUvhGjJQ2I7cvGq4K7MCnFjexvQ6TdCBFSyBXKKYHNJONAhHJ0iXlxkGhPCYzOruEDWLFfNMfbSY8cjg94yTNdY7EW0ElrThLMW3UO9Ylp1O6YE8twdadRf8vvQ9MDpMUsh1WSD1RrQNu6XbX6g53RLv5e3Ozk6JoBgAAA=" />
<img id="flag_liberia" src="data:image/webp;base64, UklGRoABAABXRUJQVlA4IHQBAACQCQCdASpQACgAPtFgqVGoJSOrJFgJOWAaCWwAd3c8RyrhgP0o/VX36bu0Y2f9AnLJ0YDNyAlqkuQa6aDoZjpGofshB2VySrQLo7TI8etWqqE6c4WAAP7yo9H5rc5eoTiFBhOPtXiSPr0RysPE+6BhTnMnCo4G1pnhmjLdlIuyTS+mLZn6gCdfT+sBF3KZDStklN2FJHcXBAFBW9/zpXKZ0rf+fAtioLv+LJ27V2KCqRed/h9gYFJ8//B9y8WH0fQLOfAIF6jweWd1rCN1jbV5wMfGclxMS6Z/i65PC6VcO4MBmWMgNkVR63DKjtFHB/K86A3oBoqfGlL9RwNLfsHJrGyY0APa8EvuYrvcqud804k0UyzCSlrrsF2TozYl6ppsS9r7o04KHhn9wUHo3JuXj7I58SEPKIQEGdnb7n+yHM35jD/XBns0A2S4xYYDL4FbPITjsZ1kWZUBOqMPfMLRtBN8pTi7MG+j0lw/BgFppuAAAAA=" />
<img id="flag_france" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADQAPtFcpkwoJSOiLmgBABoJYwCVr08AILn0HYSB5tT7uF9cmn/IFgxNlHsAAP7u098j0x3Z98N5BquPQ9tsnWokne2arw05da3TXFi3Ts2ZjYzmdT/bHHA+P9D749jjgfH+hr+RddQAAAAAAA==" />
<img id="flag_australia" src="data:image/webp;base64, UklGRt4CAABXRUJQVlA4INICAAAQDwCdASpQACcAPtFao0yoJSMiKrmdmQAaCWoAaS7+xYD1AfkveUeYDzefPR3wDeQq68/AV5O+zLDOHcIGmJmheM3NjCsCvO7ScnBJTnz76SK80NdKxFO9aZOQsuQE+wUdS5w8nLjq35qPhf9CkJ6ucJ0a3qWCGqyqGhx1YqXc6AAAzj2sT7WyuL6hDYcReAcVWacrDMJtPsCkHzPnFJKdyhXbKiaaVPO1djhJB4GR5GaVNXjCQ/jeSWwzzCSxqnIrrCVzAdMEZ0igQlye4aFCfUAMDHTKns0dZf65fXJvRYq9fz4uvmma+8k3vt4ve+XNdKx/hnBcH1SWFX96XyJY80c7bQUfxQXieO5r3ewv2woIWYXF3nfCoH3aXE+1RqrOVHgNauwHf7LEp9EROYBpmD/qsn7VqD9L8TRfCPsPYRGtvz8lcv2HwZeQd7Pr7+cj9tq7udC9cm2fLE+G+8XZY0drHOG80fb+FWnu0znnexShs+rsHlLwdfhsAaWm1Kq5YJNV2rsYNcvV7+YXeIieOOdqkuAC1xaxOPZlGhcjKgouEi4b1DSOD6fEej+FeXDtPzt/w01w73RJPzg+Q3tjWIk5IegyFNHdZ/TCBWEyCT//1WNyXHn0yPKsa9naKqXXI2kH9oawqMNhVrzD1UGPxHK0As1SbkTqt7Zd6a1GYst99xwbW+fg2dZFC3HuYptXE1NDX78YRXqz0lavrXPfB8vT2nWCefJfjkTE7TVL/NbIiJfJbrkdWldeAFXkLi4rE6icrTt42g9vyaqLIdkbVAIjl4bmLuqOCAHPfTHuMlvNNS0dmGFzBFeRc8PvRVRhifR1gdYf1xDkNn9j819qh/XlwkG/yKkiw3wzWvzrkrG9F7gp/6nGo+WryHPxOxkAKjmbDd6hpX6tOGb8sTKi27gpSKmvX4yYSacuxgH7WLYZpawPIjNAleop8pMY6JAAAA==" />
<img id="flag_romania" src="data:image/webp;base64, UklGRooAAABXRUJQVlA4IH4AAADwBACdASpQAC8APtFWpEwoJKOiLugBABoJQBKgAFh0HcccH8GDTLqzpc+XIKKqMygA/uuOXpytj7Pv5w7s87NReIFZ/Y/+/qXvH7/t90n5meBc2ONjZyuPDS/+k/Ps1odKbP+GYEyinazWGFr5jdr23fI2rXo6FXVgAWEAAAA=" />
<img id="flag_india" src="data:image/webp;base64, UklGRiYBAABXRUJQVlA4IBoBAADwCACdASpQADUAPtFiqlAoJaOioawxABoJYgDVAYG6f7Vaj/1gGGAeuKLZArQXgEcSwURBH1lU7ybDNYuld08apvxfiORuiu3/MAnnLEbGIAD+5mnf8wTtDqd37f+IcQ4hzLFk95R3hMqHsbvs+UTC+v5Qz37PWmyvtKAlwafnl5WmZYR3cswJtnqPeUloNTXbOce2V+PGAdbFugTC7uj9MkhT8yJP2v0V7ICTw1S/rDNPB7XuBA15DfZrvMivdoF2hYmPxlv3xtlgdDtC+9YflbGc1DtCNDp4NjVZTyPgOCwWSZJzbEnR1KLva/U8aRdKJ7mGnH1nmbzghpqvu+jCPA5qHl5/XICxAlPE3eAqazLSKGaQvqAAAAA=" />
<img id="flag_bosnia" src="data:image/webp;base64, UklGRh4CAABXRUJQVlA4IBICAADQDACdASpQACcAPtFip06oJaOiJnqsAQAaCWwA0uVBfgGqW9Nv452jSjygGazayNz5nsm/uNXRsWTLuTPfHj9NlA0JzSywf+KBYV4Cg8/EAcxzf8+j8ihxW4enWq2pYsPqnG97PyHKAMQ13XASa2AA/umIYedoWHb/H1PD2wXqZiVhakI76/5VxNyiOjvZ952ANnGohmmD5dVKH/hZw8R4dvFJg66bkf+iFel9FQgsJqdqre4XKXMyJXi3+SXPqhoP3QQSOZNkYsCpTR3rjuv1X/egCettKV0dnpW0GOBh8jfQMtoGKKX26H8kJvHAyM9rc+eQVO8473bT2ic7SZ4ShqoE6cRWYaF2M3g1/2MtDwM3v7GWh39omdGETPDSTgYKtxQaLDTHiB6MQHlMTKS5dm1Al49z/75mCtsd+1DAoS4+udEIriMg8DEBo6Hs9/CZ6cKIaLHSr4QArFAz2DoO2fnfzKNCbm446HkABsPN6tM9OzgiWoJhdVQvEZpPvEJQ/NtPaIhZawT9DmLZ9BTccN5ra6mAwccCzaKhaESZ4eyxe5Ux1H3bT2hbDFGAS7amRNjjkQ4teRj9uNMaEmoVLeEYjO6DCD0QYkN6lqbBpNG+rXdrVOlkr22Z/ScbvcBLOhNlD6/zG0INHXMauOJunjgd9j5/8TiZx4wIh0yjT9ycP3Hhb9WKoYHaz5cFnQAAAA==" />
<img id="flag_trinidad_and_tobago" src="data:image/webp;base64, UklGRkICAABXRUJQVlA4IDYCAAAwDgCdASpQADAAPtFapEuoJSOhszVYAQAaCWwA0X1BO1/vX5K8vxoL4DxAOkB5gN0A/oHUAbx9+yr+YMA7GAxf+BYWNk2mh05fQgMWMhVzmmwL41fWNf7mziMt1uj9IWCQwlrWOMx6iMy/shV7vsdKun4KPy01Tk00SAD+bQm2Ul0AHINTBFDonJj/1SCxhdNnIhJBfAQjX7/zIiZUXqnVPZk4gVPVCFAgfajI3ltBsX8vf/8TGe2QjEZI8TSnslSnXAo56j0d7yPwd+wHi3PxacGSDyH8Sl939jNiygKUxPOfd9vmAThP5mtIbJPLRbYSXKN/EMqksobN8pDB1HX+HHz4Iu7m3U3zDIkcY7VyU2f0qiiHkBAU55O1m9hmomZaNrjDF7oIBAsM96CEooeEjQnjAsDQpW1jFLR0k7t2IIcWdpAZKq7cYuDT4ZpBaNANGGGaJpkJvWjAwWumTiJ0zq/82ePKL29NZua18DkqRoChUvwE5+rm9Aa2zi4vGRh5BAJ1turG7gmGlQKsfWbvT88eNCwrNuDTxpyYETlhJTsHlcFsJD5tzkBB5HaZpLLbqaM/F7c2YqNSIY9Fw7NUNBZaH8yhb8nCyTw4Pz45TzaOvjGzrN2f46UtkIez6WknZIyh4izeA3c6XM9zd2HbnYpv0FXaulFzmj1K/PiGufmpFmfCsiNZtNKyugvovWJxwj3BzU1BuHmvanW4zuftfql6mFBgjCq4yHAJeL4gzT/nXHaAAA==" />
<img id="flag_nigeria" src="data:image/webp;base64, UklGRnwAAABXRUJQVlA4IHAAAAAQBQCdASpQACcAPtFcpUwoJaOiLugBABoJYwDUTb+BBi+g7Coa2XiUv0Nk/suGX2PYAP7a0848NlR29KT6+8odiY8W1IChrLGaBcMMECciishdr/T4d7l1TjnnTuwKDRDF83jYOBrhqBBaMoSAdgAA" />
<img id="flag_bhutan" src="data:image/webp;base64, UklGRooCAABXRUJQVlA4IH4CAACQDQCdASpQADUAPtFWpU0oJKOiKzksSQAaCWwAyymT/umkFd04+KoDwG2z8wHnM+iveKd5Z/yz8zMA7Lg0pVi3ezys8sh24rIn+wAqp/Cz72cOsGclsBSNRlBilSUU9fy9Yqoxw1zOtgF+u+L83TC/WeTTegAA/vDNo9nd/07v+nd+2/S45zoG4iOiv17cbGRgWCrNqZ+p4ZcK8NervJt8ElPBk6xcfoSmfZQOCZDmQT/IZaPTsrG5CLgLjJBWrELMakSjKOFbx7t3Zb0/etiI7YfxMw0xcP5fpdUX96iw4DPKNFXUtf4K2w6jmTWt3yTgL0WIApbUY8Cy/e4kRcLn5oO3Fr/kjXtcDRE6pT4nG5G/j6twf+tKwEhgkw6X6HT0AAnWQCCY5UYA+hmi8leIplEHbBP7TRZwBWejcbnpy/8gGSI0fWejAV5f4P1DLgUo+PmpQumXJ7TMITYrHiZQoZfIJe+xuB6Z6QDRzjC5datXuC+BN3KtsaCIifYiarw9Y4bcVqUAxiRIz1xQgsFJVPNcfJOX12SCYOcw8+EsV/Vbyyb+p87SKnx9rzf6QHKfIrqY8vBOdu6SynjUwrC/xbNigSey0AaCpzBNAFOyNJhBzLciSqkhZZQ2PvdcOtgWanU3GtYLXVk5iBQtWBLBkMyUPoy9OJ3AJZM02GFObLJVs4p1ju0yHNjjzTr1PPnCWHdOTkjiCjjvlr2Dxm3B/ZL3EiG0YRe7h8U/0R+mO+wF2WG4k8GMNvIrNf9I12Y/Yp8BtTq8CwcCNEBGZTnOQrMTHKHnHhVQepWs6Xw//KHGPTvmJLgPHacUiFKwyS7lHjOlzkpJk8uAFVAAAA==" />
<img id="flag_benin" src="data:image/webp;base64, UklGRqQAAABXRUJQVlA4IJgAAADQBQCdASpQADUAPtFgp04qpaOiLNn4AVAaCUASuYBtLm+Prjv1H0VuElkSQMitwuYNLDmrc3oAAP7NW8F0fighiqslosi/+xfsD+JZw578HSZoDb9vtSIp9dIP1pP6bjR2H+m4L9TtvHojpjqhymZkFjdVWPT/sObyBP2emp/cf05lDW2n9evFO+gDVfOQBmgIGj4OfjoAAA==" />
<img id="flag_kuwait" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAABQBwCdASpQACcAPtFYp0uoJSOhrvScAQAaCWQA1InAuAlo/oAEDqCNdGdWoq5QutPMdkPHpP2FQoHR5odS7FSiA9gAAP7qTmXL8oqODPJkfkDo5BnJoCqSFzUOEPEfDmYntLrGImpYZ9nZ8z50iKiip/WR/GdnBL19wNXmC3dW3xFd9RgFlYq8N9wqe4woJglVe82TWQ+UMxsCJ0N6YMt34idsuXp27nA5a/7fZ9wY6Y/xgP8NBU3R2EKO2FWtCsVuSX5OTd4fRCcMMXqIcPLysD7vU4lBdXJW+bY+00EZ5QkkAAAAAA==" />
<img id="flag_ukraine" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAAAwBQCdASpQADUAPtFmqU8oJiOiKb1YAQAaCWMAdgCTAANXBJk0NczGFEBkrqmvM3OPwAD+3FH/9REQUksP/xC72NYeRVYanqHgqRSM7F3YX9HJio6l3YX9HJiohQDcoDeoIHumLI6lEAAA" />
<img id="flag_singapore" src="data:image/webp;base64, UklGRkoBAABXRUJQVlA4ID4BAABQCACdASpQADUAPtForVAoJqSipnQJgQAaCUAKtMoO7zgjQNoURACcNZPQ6rMOM/Gbqw4luh1mtr73GDOsNw3DWnGbNDYHjaIsVwAA/g+hk5NM4a4f7Sjs2QM90D96IWGn6D6NZNJEqN5TsDJceE6P/r7MGfJ8lC2M1P//5mj/MSp5M+53M1/vsQrjZ0FnB82Gb+BrmOQpCqqgYV9wh7WQsofdkJvj3JuquR2hKOtcbh4YHAdqAStiEXxX+ZQI88Af8Gj+Hi6KCDnDVdxSRtFZZhlKAUaLU6c4L6grCAAlfW24veV90pNPjnLXMAlaMSCmUIVkO3GSJP5/49gWN5HrJ0f/Bxgio8Z/g4wNa5RaxsAZQubjZ8+GbnJgorQCoqa4Al/qBQWNvKWTkvK3sUUQLJfgAbhAIyCPyAAAAAA=" />
<img id="flag_greenland" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAAAwCwCdASpQADYAPslYoUunpaMhtNTqSPAZCWgAz2HaQA/unI4/yeA26XPzdH/1Ge8ukSajZHAm/7LOlKQe84JAN3PEcq1m2YcLTg5NLDRM9argiHlW4GFblLod1NLnSi6zAAD++VhhiqUaqg4TbCMsbR775L9wkATjJCcHhUMDTvIg7uR6Sn9CN528xU6a69RhbIuibaY3KfKQoIlQLMndpfbQP+TvwE3Pp75OP1lMAra2XlDQ79+omVEu3k8/IK18lS4Oqwtu7DNvtSOldaiDsMzKcaEik6WHv/ef3kkkVkb/PkJBxeUjuCZVQ73AWcF5ec5YWrlydirq5U3udD+yI4K5hRbmE5sRhPqqaWISP3gKpcmBWq54lzNnPOnp2Ywf7P9eTLfbq3zax46XcvpLuAZPwZZ1wn4YVRXvsuhS8QbOJY8a+1r3oFNbbexBcTt7FyvSnvlaAwFTxArbcGfa67E0o/G16tveoGy77UAFq6Zf4beZu18Dxz/WAqIn6N7cqk7sUoQylN4Krys/ZLplXSgLLFA9e7eVXMgAAAAAAA==" />
<img id="flag_madagascar" src="data:image/webp;base64, UklGRoIAAABXRUJQVlA4IHYAAACQBQCdASpQADUAPtFgqE4oJaQiLNgIAQAaCWMAlQHf/AdLsAw2k4t2QW1q5RK+f/d/3T2oAAD+8/iN/XVokn/uURq5xGv/iY8cDZ/H/Z/28yCjIEyftL4tX/xi960eO1/49+nitwgfJu4NUqOYnleP2XyQAAAA" />
<img id="flag_jersey" src="data:image/webp;base64, UklGRlYDAABXRUJQVlA4WAoAAAAQAAAATwAALwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7wf1IADAFZQOCAQAwAA8BIAnQEqUAAwAD7FUJ1Lp6SiobmUCqjwGIlsAL81wNseas+V4rb2zE9Kc4DxGP0A/gHtAfoB1APPt8//1AP+P1AG8a/tL6AHX/5mfO0rHXi/7XvZ8D/9euRd1NQpPRtqQ5N4IOQgls4OpOshP5n3Co3zuWpEPwA1jWrEztiX/zn5xsx0VEwILQ6oK2vnILZ1mHs+Pn8POlQ+/gaFx9FwyAD+z2X/Xi+9XjxDIYszq4j2O+z8Qtt/sa5Xp71DrLhvU9h923jY1UAkSodb+TBKtX9y2KkatM66jGyxu+6XpboLGP3LZ1IV8euUwHPf+W24I4/J2dkY20/BTQI6lbOcHCbKzL17l+aYfbJxxaPhmRTiNGuBEfLPV5xovsDNF7e/mpjfvC39csxHphaQDmNMrbED3MJbbwgxfhpY8IJVBz+daBpJNlguizB1Zw1W5YG5YR4GzpJYHQNB7i1Kpb2JJHrQHmqjPDWNM+Rd/JaSa/hZU6jhftp/zl/3A/e8E9LMnWrr8Bq26u7z997jZfD2At+Vm3veZewksON6IW2nFm9y60SKbPi5ko9tarcm5eAozcVvSeRImTn6uZnHdTdLhW6xkf21adh+9Qho1uyHpSxSFQZQjwJFMtViw2+M2sMVs5B/kYY460Mgea59XbPx/ttXLWZMuoi9yjljgTE6FxKaut+VTprq7zQf/BPEGqEaRBZflqsbrZkLdRm22GV5ZOiSt/cR7RpdDRnLflSULp7vq86/nYurnj/wSUOXtf2D+ag7K1C/mE3eazAWbcsDZZzv4VVuoLFONDNrdYyP7atOw/e36EPMCuSVX0VPzAg+ILkrEQBpL7ITaEJeU5Bwn8mONmaLo/hnXve4ybassizdVxpl34B57powDD1NFSBEeMVqyI06ZQJKtSjJMve2Uw6wQ3XgQ2HVSe/0BKkmFT97loOoVKJ0XT8Er6VC/Q43sdIMaebxxLCUB1/tgctX+tbDY8R8A8RwdzUmIBGqoRf7Gxwf/GAUvSaE0hGeyd1tmp/emEdzQ389084cixAAAA==" />
<img id="flag_barbados" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAACQCgCdASpQADQAPtFiqU+oJaQiI1gMcQAaCWYAhTpS3nnI34AfX/PAcw7qIG80+QA757UALWs88rDWUB6qCJA0DpGNpGGZ+qvf/51u8cta7sNIfPZv/rz1oRMbjqgA/u/eX//nUfp3g/+DBo2v/EinrOhch/mEV8zvDn/rC18rPK7LSqjZ+8afgt5v3tQF/mDKe0GBsMiepKVWanFvzZhoJ+9j+36xOQRBJ/jAonIKwqjJmq3dMtAxf/f6p+b6Gx+Yt4bU8e1FQt665Vk5emhRgAuUEkqvUYyAywOmVES/b5ofLr9NymVJv2Teo9DH44f+TNzfZqyFiDDW/l3VY8J9a9pjGrwP9TsZe2dWil/dqZGzFBtVk+BMf4oK9ZcNKzucmvu3uINIA1pdp7iCPlA1/rCqmlh3SFdrYZso8p5Ts1c1xP4MLZ7sxayyrrFLSwnD1qmyZCXsF2FBW7JQFDixFtxODM/bj5KgG5F0FWXtNd6MoA/3WttQUuQ1WOF5NY7H0gYESmcY0hP1zj8p6F7/iVywmqs5MxVBnCALbAAAAA==" />
<img id="flag_oman" src="data:image/webp;base64, UklGRhYBAABXRUJQVlA4IAoBAAAQBwCdASpQACcAPtFcqk+oJKOiJnqqAQAaCWoAegRCdGA02DeeACcjIP0eDryw1mP5oz9rNpfCSYCu8AVG1QGioAD+FSHGZzCyz6oJqF+6Kg3xt0Bxapx76HZgH6+OMZK8AnfPEpZaDxlu//G+ZmNTm40YH//8zR+6RD5XVyf9GUEbKYrAlGIVaneicgUoSk14T2L5mowNJQPmLZjk5zXCoRKz2oW8q42FuatN5dLtqvx8xt47lbwCj9j6utlS3G8wkEmrGaVlOoMLrG0ju4dpSjunwYs/LO13snuV+QnX8f8/9P/x/vuP24JhbZZRy80wYRkmKIG10zmEAX5mws3Jq4zx5LVZfAAAAA==" />
<img id="flag_saint_helena" src="data:image/webp;base64, UklGRvwCAABXRUJQVlA4IPACAAAwEQCdASpQACgAPtFSpEwoJCOiMRYLaQAaCWwAz8/PfD+Z3af7lwOa5PUBtm/Mb5w3op/2G+S8/B7JvlM3f39DnyLIEcCuApHP+A8FrxDoDM1T0n7BX6qdVX0UP2jDLKSRPmcP6RW/+m4xy943Kph06cMSS6vj6z1AbuTWHln9eLBhHK3509srzbMK6RnOTPKoAADifcv0LnfEWG4fVe/6MJxXT97m+c1cbCBnfmQt6k4l+6S1G4a+ty1MpXBTIl4L03OkY+Qn/Rw1R/Zg8Pb4Aj6nOYK4CavWT9BmmZ3M6tQX2lIU0FPDVeAp9vmn40J3iPRBaYyxSEnhFr/pWdMF3zsFBfMf/oB6sFvI5MPNnEXo7mmsjXYuByouHWM+xAX9tDUEdBkreBI8Uma8VJDv9y+Lb0vWENI44kFzjonzoe8hJjTeomLb1GR0SN0nl0vaJ/I+gzmvw/Jb8+8+bZpRIoQGMAJUHXDmnXe6v9o4mYUCL07Tjyzh6UGvnYIi2wMzBLkOKlpfzevy3zBeO/yumpvrbDYWQqDRW9Zle/y0yO/VhB+ITXYr2N3Pwfm18gIClD9ObowNstg8U+eIsrxS9yfP7vvPlz8F9855ep1whwqfx7kf3rH60XMBpLRmpuALtzbDv532H3HQiAv/9XLqf/ST0w/+H3Pgh7+/lNy7OTdXSECqjiXwwVmkfW+aRC9f4VOt+/41mjme/kq8KGoQVOsT4EZ84sOYLuSRjz814q2S5UrXzlQr7NZ1vRKNZoSX19/8v6AhYLdxpAmcX5+S87U16I8HIZt2MHqnf6C2xQZRswxlVmNXIxirO1BIQKmzBz80XdHPuPSL+VVltnBoW05uJG0ApRSkaWJkldGUEd0NP0agXVm9q9geJR6VBvnoObvEZIUqA48/am7OB5sCZj5VSLiN7fE8RTJ7JE0OriuqPrxOJnRQcJvc7dygMTI9ZQhjHAqb8TxCrzzAxNS55fkg5hf6PxRlJpF5KgAAAA==" />
<img id="flag_turkey" src="data:image/webp;base64, UklGRrABAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCBqAQAAcAgAnQEqUAA1AD7RYKpOqCWkIis22TkAGgliANEF2jVU/EYiSSjs4CUZW3N+RxeuWUQ9lXes3IA5zpAKBiAcCI8dM3YgboDsOE9KwAD+7kMfEP209H/6gz/5Bn/yDP09G8A9arAYObf57Rpg4qxCZkPvjlx+TXn39TiiyHdwsV/rFgL21kcNNoj0HH1psDQjIHgiJ1h5p0bt+c/Ow9vrBXFAtR9yiukgFhCns60Ar1hoGYkaJgGT6Fbjf/UZHSEqVlf6/48AiQS1XkTBtvjfsiM93eeXMwPplSw04+AEP+ENJxo3GovRWV0ymM31c3t6V7Ik8imvykhRz45QqdN6ryA6TEAnLoKOHn/IdWOOXpu9oqKO5P1Apqud6Ecar9WjnfxGcSICPgY6VWQzWDlrvd0H4PILgoLRQVjh+qEM0Llrl+eyepWjx1onIq8Mu30ZcmEKl1eMPMk6ESnpm0vq1HOktASwzo9QAAA=" />
<img id="flag_republic_of_the_congo" src="data:image/webp;base64, UklGRuIBAABXRUJQVlA4INYBAAAwDQCdASpQADUAPtFUokuoJKMhtnN5WQAaCWwIcAF0fT75nkTOLigH5h6f/QB4hnSA8wHnodFV1AHPs+zBgvcd/maS8NyWK7iiJTP96h5OXcopZacJ1EF70OvGhALBZq8plrx7zXtlX26QJ+p1RHdSIuAA/OZoM8VX7M9lM2rE8JkDTf/zBPkHz5OrckgmQSKQm0Abl1QvxEFE7oKqZk04aC0r7Xt4V0dMY/GRkpefk/DsaeoETf1r89z5dqLU2zpceJmW41hmBqQuTotDSH5fBRqInCx2BNG6R48FXLZFaJUhhX/jUdX0jOKiNJ6jIaoF9J26bO/hSKLfAAsjxBtjXA1bk0cYvSQEV1f0f2OeryXUjYxdgkKPkVBRMzlic9G8z9Umo/f4dWZ+qp2OETsx9QH7nLpDkbCs2zxno399wl83+Gm83UPq/OFl+ujnWFrDq3frseIdwwAJvFdTgGxyyZo8BWHKPCvYu52uiqDcCJveO9a1pb34xT7NX+VmXRL+g1GUUCVhEBSDTLRPaGu0OeT3/O8BzeSw0OItZ3l3iekwqPz/MBftxWc6hFobpcw70fnobsgmSIy17u3ijIa+dgr5Uh3y0aGkgw/BqJcE6Af4AAAAAA==" />
<img id="flag_pakistan" src="data:image/webp;base64, UklGRioBAABXRUJQVlA4IB4BAACQCACdASpQADUAPtFap0woJSOiLnVa6QAaCUADtWUaAXGjd0+2Q214vysc/OZiUDwki/dcEV9kHEe28IYcDgWXPwy75opq3l5T08iUkAD+9x6iqcdWIUX/4Fmu5B+eGiu6z+TmiHgpHVS8JhbjP8cxUkAZGXA+KDA9EcL0E0ws0tzJmG2a3TNpTO3R8I8NyoAHRQAdnPm8RFffgzMHju6wDf3PTJBNgDydMFTxM8o3KWvXqw+YbvS9hCLPHdt9CyiA6a8gJ23CtZcup2lsnmgYFBh86j64MbGhiORR/lqt+mE9Ok4D5sbVegzcUYAqySdjJDIeV8BbPex+rUHC0F5yz+UjnjeciyhsFVWc8SjMeph6CVw5EICIWbYQg4AA" />
</div>
</html>

266
contrib/ui/mesh-ui/webview.go Executable file
View file

@ -0,0 +1,266 @@
package main
import (
"github.com/webview/webview"
"github.com/hjson/hjson-go"
"encoding/json"
"path/filepath"
"io/ioutil"
"os/exec"
"net/url"
"runtime"
"strings"
"strconv"
"time"
"net"
"log"
"fmt"
"os"
"github.com/RiV-chain/RiV-mesh/src/admin"
)
var riv_ctrl_path string
func main() {
debug := true
w := webview.New(debug)
defer w.Destroy()
w.SetTitle("RiV-mesh")
w.SetSize(690, 920, webview.HintFixed)
/*1. Create ~/.riv-mesh folder if not existing
*2. Create ~/.riv-mesh/mesh.conf if not existing
*3. If the file exists read Peers.
*3.1 Invoke add peers for each record
*/
mesh_folder := ".riv-mesh"
mesh_conf := "mesh.conf"
user_home := get_user_home_path()
mesh_settings_folder := filepath.Join(user_home, mesh_folder)
err := os.MkdirAll(mesh_settings_folder, os.ModePerm)
if err != nil {
fmt.Printf("Unable to create folder: %v", err)
}
mesh_settings_path := filepath.Join(user_home, mesh_folder, mesh_conf)
riv_ctrl_path = get_ctl_path()
if _, err := os.Stat(mesh_settings_path); os.IsNotExist(err) {
err := ioutil.WriteFile(mesh_settings_path, []byte(""), 0750)
if err != nil {
fmt.Printf("Unable to write file: %v", err)
}
} else {
//read peers from mesh.conf
conf, _ := ioutil.ReadFile(mesh_settings_path)
var dat map[string]interface {}
if err := hjson.Unmarshal(conf, &dat); err != nil {
fmt.Printf("Unable to parse mesh.conf file: %v", err)
} else {
if dat["Peers"]!=nil {
peers := dat["Peers"].([]interface{})
remove_peers()
for _, u := range peers {
log.Printf("Unmarshaled: %v", u.(string))
add_peers(u.(string))
}
} else {
fmt.Printf("Warning: Peers array not loaded from mesh.conf file")
}
}
}
var path string
if len(os.Args)>1 {
path, err = filepath.Abs(filepath.Dir(os.Args[1]))
} else {
path, err = filepath.Abs(filepath.Dir(os.Args[0]))
}
if err != nil {
log.Fatal(err)
}
log.Println(path)
w.Bind("onLoad", func() {
log.Println("page loaded")
go run(w)
})
w.Bind("savePeers", func(peer_list string) {
//log.Println("peers saved ", peer_list)
var peers []string
_ = json.Unmarshal([]byte(peer_list), &peers)
log.Printf("Unmarshaled: %v", peers)
remove_peers()
for _, u := range peers {
log.Printf("Unmarshaled: %v", u)
add_peers(u)
}
//add peers to ~/mesh.conf
dat := make(map[string]interface{})
dat["Peers"] = peers
bs, _ := hjson.Marshal(dat)
e := ioutil.WriteFile(mesh_settings_path, bs, 0750)
if e != nil {
fmt.Printf("Unable to write file: %v", e)
}
})
w.Bind("ping", func(peer_list string) {
go ping(w, peer_list)
})
dat, err := ioutil.ReadFile(path+"/index.html")
w.Navigate("data:text/html,"+url.QueryEscape(string(dat)))
//w.Navigate("data:text/html,"+"<html>"+path+"</html>")
w.Run()
}
func ping(w webview.WebView, peer_list string){
var peers []string
_ = json.Unmarshal([]byte(peer_list), &peers)
log.Printf("Unmarshaled: %v", peers)
for _, u := range peers {
log.Printf("Unmarshaled: %v", u)
ping_time := check(u);
log.Printf("ping: %d", ping_time)
setPingValue(w, u, strconv.FormatInt(ping_time, 10));
}
}
func check(peer string) int64 {
u, e := url.Parse(peer)
if e!=nil {
return -1
}
t := time.Now()
_, err := net.DialTimeout("tcp", u.Host, 5*time.Second)
if err!=nil {
return -1
}
d := time.Since(t)
return d.Milliseconds()
}
func get_user_home_path() string {
if runtime.GOOS == "windows" {
path, exists := os.LookupEnv("USERPROFILE")
if exists {
return path
} else {
return ""
}
} else {
path, exists := os.LookupEnv("HOME")
if exists {
return path
} else {
return ""
}
}
}
func get_ctl_path() string{
if runtime.GOOS == "windows" {
program_path := "programfiles"
path, exists := os.LookupEnv(program_path)
if exists {
fmt.Println("Program path: %s", path)
ctl_path := fmt.Sprintf("%s\\RiV-mesh\\meshctl.exe", path)
return ctl_path
} else {
fmt.Println("could not find Program Files path")
return ""
}
} else {
ctl_path := fmt.Sprintf("/usr/local/bin/meshctl")
return ctl_path
}
}
func run(w webview.WebView){
if len(riv_ctrl_path) > 0 {
get_self(w)
get_peers(w)
}
_ = time.AfterFunc(10*time.Second, func() {
run(w)
})
}
func run_command(command string) []byte{
args := []string{"-json", command}
cmd := exec.Command(riv_ctrl_path, args...)
out, err := cmd.CombinedOutput()
if err != nil {
//log.Fatalf("cmd.Run() failed with %s\n", err)
return []byte(err.Error())
}
return out
}
func run_command_with_arg(command string, arg string) []byte{
args := []string{"-json", command, arg}
cmd := exec.Command(riv_ctrl_path, args...)
out, err := cmd.CombinedOutput()
if err != nil {
//log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " "))
return []byte(err.Error())
}
return out
}
func add_peers(uri string){
run_command_with_arg("addpeers", "uri="+uri)
}
func remove_peers(){
run_command("removepeers")
}
func get_self(w webview.WebView){
res := &admin.GetSelfResponse{}
out := run_command("getSelf")
if err := json.Unmarshal(out, &res); err != nil {
go setFieldValue(w, "ipv6", err.Error())
return
}
//found ipv6
fmt.Printf("IPv6: %s\n", res.IPAddress)
go setFieldValue(w, "ipv6", res.IPAddress)
//found subnet
fmt.Printf("Subnet: %s\n", res.Subnet)
go setFieldValue(w, "subnet", res.Subnet)
out = run_command("getPeers")
//go setFieldValue(w, "peers", string(out))
}
func get_peers(w webview.WebView){
res := &admin.GetPeersResponse{}
out := run_command("getPeers")
if err := json.Unmarshal(out, &res); err != nil {
go setFieldValue(w, "peers", err.Error())
return
}
var m []string
for _, s := range res.Peers {
m=append(m, s.Remote)
}
for k := range m {
// Loop
fmt.Println(k)
}
inner_html := strings.Join(m[:], "<br>")
strings.Join(m[:], "<br>")
go setFieldValue(w, "peers", inner_html)
}
func setFieldValue(p webview.WebView, id string, value string) {
p.Dispatch(func() {
p.Eval("setFieldValue('"+id+"','"+value+"');")
})
}
func setPingValue(p webview.WebView, peer string, value string) {
p.Dispatch(func() {
p.Eval("setPingValue('"+peer+"','"+value+"');")
})
}

View file

@ -0,0 +1,4 @@
RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
It is lightweight, self-arranging, supported on multiple platforms and
allows pretty much any IPv6-capable application to communicate securely with
other RiV-mesh nodes.

View file

@ -0,0 +1,87 @@
#!/bin/sh
BASE="/usr/local/AppCentral/mesh-nas-asustor"
CONFIG_DIR="/usr/local/etc"
MESH_PACKAGE_LOG=/tmp/mesh.log
echo "start-stop called" >> "$MESH_PACKAGE_LOG"
exec 2>>$MESH_PACKAGE_LOG
set -x
whoami
init ()
{
config_file=${CONFIG_DIR}/mesh.conf
if [ ! -f "$CONFIG_DIR" ]; then
mkdir -p ${CONFIG_DIR}
fi
if [ -f $config_file ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp $config_file /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/mesh.conf"
${BASE}/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $config_file
else
echo "Generating initial configuration file $config_file"
echo "Please familiarise yourself with this file before starting RiV-mesh"
sh -c "umask 0027 && ${BASE}/bin/mesh -genconf > '$config_file'"
fi
#chown -R admin:administrators $config_file
#chmod -R 664 $config_file
#sudo insmod /lib/modules/5.4.x/tun.ko
# Create the necessary file structure for /dev/net/tun
if ( [ ! -c /dev/net/tun ] ); then
if ( [ ! -d /dev/net ] ); then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
chmod 0755 /dev/net/tun
fi
# Load the tun module if not already loaded
if ( !(lsmod | grep -q "^tun\s") ); then
insmod /lib/modules/5.4.x/tun.ko
fi
}
start_service ()
{
init
# Launch the mesh in the background.
${BASE}/bin/mesh -useconffile "$config_file" \
-httpaddress "http://0.0.0.0:19019" \
-wwwroot "$BASE/www" \
-logto "$BASE/var/log/mesh.log" &
return $?
}
stop_service ()
{
pid=`pidof -s mesh`
if [ -z "$pid" ]; then
echo "mesh was not running"
exit 0
fi
kill "$pid"
}
case $1 in
start)
start_service
echo "Running RiV Mesh"
exit 0
;;
stop)
stop_service
echo "Stopped RiV Mesh"
exit 0
;;
*)
exit 1
;;
esac

View file

@ -0,0 +1,6 @@
#!/bin/sh
echo vendor=Asustor
echo vendorOperatingSystemName=ADM
eval $(cat /etc/default/nas.conf | grep '\<Model\>\|\<Version\>' | sed 's/ //g')
echo firmwareVersion="$Version"
echo model=$Model

View file

@ -0,0 +1,76 @@
#!/bin/sh
#exit with zero status on auth success and 1 on error
#
#You can use our cgi to restrict access to RiV Mesh configuration page only for authenticated NAS OS users.
#==========================
#1. use login to verify authenticated NAS OS user
#
#for example:
#
#root@AS6208T-RD:/ # REMOTE_ADDR="127.0.0.1" QUERY_STRING="act=login&apptag=mesh&account=admin&password=admin888" /usr/webman/portal/apis/appCentral/applogin.cgi
#Content-type: text/plain; charset=utf-8
#
#result:
#{ "success": true, "account": "admin", "sid": "yPgoWu95eXxCxZJr", "isAdminGroup": 1, "model": "AS6208T", "hostid": "20-16-01-21-14-01" }
#
#explanation:
#apptag: application name
#account&password: which you want to verify
#
#2. When you finish verifying authenticated NAS OS user, you must logout from NAS.
#
#for example:
#
#root@AS6208T-RD:/ # QUERY_STRING="act=logout&sid=yPgoWu95eXxCxZJr" /usr/webman/portal/apis/login.cgi
#Content-type: text/plain; charset=utf-8
#
#result
#{ "success": true }
#
#explanation:
#sid: same as above (login result)
CACHE="/usr/local/AppCentral/mesh/var/lib/mesh/access_key"
if [ -f $CACHE ] && [ "$(expr $(date +%s) - $(date -r $CACHE +%s))" -lt 3600 ]; then
exit 0
fi
#we want read e.g.:
#HTTP_COOKIE='access_key=sdu45KJFDHksadulf='
IFS=';'
for x in $HTTP_COOKIE
do
eval $x
done
#we want get e.g.:
#access_key='user=admin;pwd=L4edNyoCC15.kDBLIN05480'
access_key=$(echo $access_key | base64 -d)
CACHE="/usr/local/AppCentral/mesh/var/lib/mesh/$access_key"
if [ -f $CACHE ] && [ "$(expr $(date +%s) - $(date -r $CACHE +%s))" -lt 3600 ]; then
exit 0
fi
IFS=';'
for x in $access_key
do
eval $x
done
if [ -z "${user}" ] || [ -z "${pwd}" ]; then
exit 1
fi
export REMOTE_ADDR="127.0.0.1"
export QUERY_STRING="act=login&apptag=mesh&account=${user}&password=${pwd}"
S=$(/usr/webman/portal/apis/appCentral/applogin.cgi | sed '/"sid"/!d; s/\s\+//g; s/.*"sid":"\([^"]*\)".*/\1/')
if [ -z $S ]; then
exit 1
else
export QUERY_STRING="act=logout&sid=$S"
/usr/webman/portal/apis/login.cgi >/dev/null
touch $CACHE
exit 0
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,35 @@
var ed = {
partnerId: 1422,
applicationName: 'RiV Mesh Asustor ADM App',
nasOSName: 'Asustor ADM',
useAuthNASRichScreen: true,
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
getNasAuthUrl: function () {
return "/";
},
nasLoginCall: function (nasLoginSuccess, nasLoginFailure) {
var d = new Date();
d.setTime(d.getTime() + (10 * 60 * 1000));
document.cookie = "access_key=" + btoa( "user=" + encodeURIComponent($('#nasInputUser').val()) + ";pwd=" + encodeURIComponent($('#nasInputPassword').val()))+ "; expires=" + d.toUTCString() + "; path=/";
$.ajax({url: "api/getself"}).done(function () {
window.location.reload();
}).fail(function () {
ed.nasLogoutCall();
nasLoginFailure();
});
},
nasLogoutCall: function () {
document.cookie = "access_key=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
},
getNasUser: function() {
function getCookie(name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
return decodeURIComponent(atob(getCookie('access_key')).split(';')[0].split('=')[1]);
}
};

View file

@ -0,0 +1,4 @@
#!/bin/sh
. $(dirname $0)/scripts.sh
_install

View file

@ -0,0 +1,20 @@
RedirectMatch 301 ^/mesh$ /mesh/
LoadModule proxy_http_module modules/mod_proxy_http.so
<Location /mesh/>
AuthType Form
AuthName "DroboApps"
AuthUserFile /tmp/DroboApps/apache/htpasswd
AuthFormProvider file
ErrorDocument 401 /login/index.html
Session On
SessionCookieName session path=/
SessionCryptoPassphrase "exec:/mnt/DroboFS/Shares/DroboApps/apache/libexec/cookie.sh"
Require valid-user
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:19019/"
ProxyPassReverse "http://127.0.0.1:19019/"
</Location>

View file

@ -0,0 +1,40 @@
#!/usr/bin/env sh
tmpdir="/tmp/DroboApps/mesh"
errorfile="${tmpdir}/error.txt"
base_dir="/mnt/DroboFS/Shares/DroboApps/mesh"
config_dir="$base_dir/config"
config_file="$config_dir/mesh.conf"
prog_dir="$(dirname "$(realpath "${0}")")"
_install() {
if [ ! -f "${errorfile}" ]
then
mkdir -p "${tmpdir}"
if [ ! -f "$config_file" ]; then
echo 3 > "${errorfile}"
fi
fi
ln -s $base_dir/var/log/mesh.log $base_dir/www/log
# install apache 2.x
/usr/bin/DroboApps.sh install_version apache 2
}
_uninstall() {
pid=`pidof -s mesh`
if [ -z "$pid" ]; then
echo "mesh was not running"
else
kill "$pid"
fi
}
_update() {
/bin/sh "${prog_dir}/service.sh" stop
cd "$base_dir"
rm -rf $(ls | grep -v 'host_uid.txt\|var\|config')
echo 'update successful' > "${prog_dir}/update.log"
}

View file

@ -0,0 +1,121 @@
#!/bin/sh
#
##!!
. /etc/service.subr
prog_dir=`dirname \`realpath $0\``
base_dir=/mnt/DroboFS/Shares/DroboApps/mesh
config_dir="$base_dir/config"
config_file="$config_dir/mesh.conf"
name="mesh"
framework_version="2.1"
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network"
depends=""
webui="WebUI"
errorfile=/tmp/DroboApps/mesh/error.txt
pidfile=/tmp/DroboApps/mesh/pid.txt
statusfile=/tmp/DroboApps/mesh/status.txt
edstatusfile=$base_dir/var/lib/mesh/status
start()
{
mkdir -p /tmp/DroboApps/mesh
# delete edstatufile before starting daemon to delete previous status
rm -f $edstatusfile
rm -f $errorfile
if [ -f $config_file ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp $config_file /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/mesh.conf"
$base_dir/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $config_file
else
mkdir -p $config_dir
echo "Generating initial configuration file $config_file"
echo "Please familiarise yourself with this file before starting RiV-mesh"
sh -c "umask 0027 && $base_dir/bin/mesh -genconf > '$config_file'"
fi
# Create the necessary file structure for /dev/net/tun
if ( [ ! -c /dev/net/tun ] ); then
if ( [ ! -d /dev/net ] ); then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
chmod 0755 /dev/net/tun
fi
# Load the tun module if not already loaded
if ( !(lsmod | grep -q "^tun\s") ); then
KERNEL_VERSION=$(/bin/uname -r)
insmod $base_dir/lib/modules/$KERNEL_VERSION/tun.ko
fi
# Launch the mesh in the background.
${base_dir}/bin/mesh -useconffile "$config_file" \
-httpaddress "http://localhost:19019" \
-wwwroot "$base_dir/www" \
-logto "$base_dir/var/log/mesh.log" &
sleep 1
update_status
}
update_status()
{
# wait until file appears
i=30
while [ -z $(pidof -s mesh) ]
do
sleep 1
i=$((i-1))
if [ $i -eq 0 ]
then
break
fi
done
# if we don't have file here. throw error into status and return
if [ -z $(pidof -s mesh) ]
then
echo "" > "$pidfile"
echo 1 > "${errorfile}"
echo "Configuration required" > $statusfile
else
echo $(pidof -s mesh) > "$pidfile"
echo 0 > "${errorfile}"
echo "Application is running" > $statusfile
fi
}
stop()
{
pid=`pidof -s mesh`
if [ -z "$pid" ]; then
echo 1 > "${errorfile}"
echo "mesh was not running" > $statusfile
else
kill "$pid"
echo 0 > "${errorfile}"
echo "Application is stopped" > $statusfile
fi
echo "" > "$pidfile"
}
case "$1" in
update_status)
update_status
exit $?
;;
esac
main "$@"

View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
#
. $(dirname $0)/scripts.sh
_uninstall

View file

@ -0,0 +1,3 @@
#!/bin/sh
. $(dirname $0)/scripts.sh
_update

View file

@ -0,0 +1,16 @@
#!/bin/sh
echo vendor=Drobo
# get device model, e.g., "5N"
_get_device_model() {
for f in /sys/devices/dri_dnas_primary/dnas_adp_1/host*/target*/*:*:*:*/model; do
if [ -e "$f" ]; then
cat "$f"
return
fi
done
}
echo serial=$(cat /mnt/DroboFS/Shares/DroboApps/mesh/host_uid.txt)
echo firmwareVersion=$(/usr/bin/esa vxver)
echo model=$(_get_device_model)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -0,0 +1,25 @@
body {
color: gray;
background: black;
}
.nas-apps-config-form-message.nas-apps-config-form-message-error {
color: white;
}
/* bottom */
.nas-apps-config-form-partner-logo {
width: 200px;
height: 82px;
margin: 0 auto;
}
.nas-apps-config-form-auth-id,
.nas-apps-config-form-location-name {
color: white;
}
.nas-apps-config-form-field input,
.nas-apps-config-form-field select {
color: white;
}
.nas-apps-config-form-field select:focus option {
background: white;
}

View file

@ -0,0 +1,9 @@
var ed = {
partnerId: 1046,
brand: 'RiV Mesh',
applicationName: "RiV Mesh Drobo App",
nasOSName: "Drobo",
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh"
};

View file

@ -0,0 +1,11 @@
Source: mesh
Package: mesh
Version: 0.4.4
Architecture: amd64
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
Depends: lsb-base, debconf, readynasos (>= 6.0.5~T1271)
Section: net
Priority: optional
Installed-Size: 20000
Homepage: https://github.com/RiV-chain/RiV-mesh
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network

View file

@ -0,0 +1,61 @@
#!/bin/sh
# postinst script for mesh
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
chown -R admin:admin /apps/mesh
if systemctl restart apache2.service; then
# success
event_push app meshd '<add-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="1"/></add-s>' 0 0
else
# error
event_push app meshd '<add-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="0"/></add-s>' 0 0
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
if [ -f /etc/mesh.conf ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating /etc/mesh.conf"
/apps/mesh/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
else
echo "Generating initial configuration file /etc/mesh.conf"
echo "Please familiarise yourself with this file before starting RiV-mesh"
sh -c 'umask 0027 && /apps/mesh/bin/mesh -genconf > /etc/mesh.conf'
fi
chmod 755 /etc/mesh.conf
if command -v systemctl >/dev/null; then
systemctl daemon-reload || echo -n "daemon not reloaded!"
systemctl enable mesh || echo -n "systemctl enable failed!"
systemctl restart mesh || echo -n "systemctl restart failed!"
fi
exit 0

View file

@ -0,0 +1,32 @@
#! /bin/sh
# postrm script for mesh
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
# for details, see /usr/share/doc/packaging-manual/
case "$1" in
purge)
rm -rf /apps/mesh
systemctl restart apache2.service
event_push app meshd '<delete-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="1" reboot="0"/></delete-s>' 0 0
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 0
esac

View file

@ -0,0 +1,32 @@
#! /bin/sh
# prerm script for mesh
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <prerm> `remove'
# * <old-prerm> `upgrade' <new-version>
# * <new-prerm> `failed-upgrade' <old-version>
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
# * <deconfigured's-prerm> `deconfigure' `in-favour'
# <package-being-installed> <version> `removing'
# <conflicting-package> <version>
# for details, see /usr/share/doc/packaging-manual/
case "$1" in
remove|upgrade|deconfigure)
systemctl stop fvapp-mesh.service || true
systemctl disable fvapp-mesh.service || true
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 0
;;
esac
exit 0

View file

@ -0,0 +1,19 @@
[Unit]
Description=RiV-mesh is an early-stage implementation of a fully end-to-end encrypted IPv6 network
[Service]
Type=idle
Group=admin
ProtectHome=true
ProtectSystem=true
SyslogIdentifier=mesh
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
ExecStartPre=+-/sbin/modprobe tun
ExecStart=/apps/mesh/bin/mesh -useconffile /etc/mesh.conf -httpaddress http://localhost:19019 -wwwroot /apps/mesh/www -logto /apps/mesh/var/log/mesh.log
ExecStop=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,12 @@
RewriteEngine on
RewriteRule "(.*)/apps/mesh$" "$1/apps/mesh/" [R=301,L]
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
<Location /apps/mesh/>
Include "/etc/frontview/apache/Admin_Auth.conf"
SSLRequireSSL
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:19019/"
ProxyPassReverse "http://127.0.0.1:19019/"
</Location>

View file

@ -0,0 +1,10 @@
#!/bin/sh
get_info() {
rn_nml -g systeminfo | tr '\n' ' ' | sed -r "s|.*<$1>(.*)</$1>.*|\1|"
}
echo vendor=Netgear
echo vendorOperatingSystemName="$(get_info Firmware_Name)"
echo firmwareVersion="$(get_info Firmware_Version)"
echo model="$(get_info Model)"
echo serial="$(get_info Serial)"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,9 @@
.nas-apps-config-form-app-logo {
height: 110px;
background: url(logo.png) left center no-repeat;
background-size: 262px 56px;
}
a {
color: #692782!important;
}

View file

@ -0,0 +1,10 @@
var ed = {
partnerId: 252,
applicationName: 'RiV-Mesh App',
nasOSName: 'Ready NAS OS 6',
vaultUrl: "https://github.com/RiV-chain/RiV-mesh",
basicEDWebsite: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh"
};

View file

@ -0,0 +1,8 @@
RedirectMatch 301 ^/mesh$ /mesh/
LoadModule proxy_http_module modules/mod_proxy_http.so
<Location /mesh/>
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:19019/"
ProxyPassReverse "http://127.0.0.1:19019/"
</Location>

View file

@ -0,0 +1,7 @@
#!/bin/sh
CFG=/etc/default_config/uLinux.conf
echo vendor=QNAP
echo vendorOperatingSystemName=$(/sbin/getcfg System OS -f $CFG)
echo firmwareVersion=$(/sbin/getcfg System Version -f $CFG)
echo model=$(/sbin/getcfg System Model -f $CFG)
echo serial=$(/sbin/get_hwsn)

View file

@ -0,0 +1,31 @@
#!/bin/sh
#we want read:
#export HTTP_COOKIE='qnapuser=admin; qnappwd=L4edNyoCC15.kDBLIN05480'
IFS=';'
for x in $HTTP_COOKIE
do
eval $x
done
[ -z ${qnapuser} ] && exit 1
[ -z ${qnappwd} ] && exit 1
#exit with zero status on auth success
#2-pass auth
S=$(curl -s -k -L "http://127.0.0.1:58080/cgi-bin/authLogin.cgi?user=${qnapuser}&pwd=${qnappwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
[ ! 0 -eq ${#S} ] && exit 0
AUTH_PORT=$(cat /etc/apache-sys-proxy.conf | grep Listen | awk '{print $2}')
if [ -n $AUTH_PORT ] ; then
AUTH_PORT=8080
fi
S=$(curl -s -k -L "http://127.0.0.1:${AUTH_PORT}/cgi-bin/authLogin.cgi?user=${qnapuser}&pwd=${qnappwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
[ ! 0 -eq ${#S} ] && exit 0
#fallback to plain password auth
#decode password first
plain_pwd=$(openssl enc -base64 -d <<< ${qnappwd})
[ -z $plain_pwd ] && exit 1
S=$(curl -s -k -L "http://127.0.0.1:${AUTH_PORT}/cgi-bin/authLogin.cgi?user=${qnapuser}&plain_pwd=${plain_pwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
[ 0 -eq ${#S} ] && exit 1 || exit 0

View file

@ -0,0 +1,12 @@
#!/bin/sh
log_exit(){
echo $2
exit $1
}
[ -z "$MESH_USER_NAME" ] && log_exit 1 "Credentials are not set. Remove aborted"
rm "$MESH_APP_ROOT/bin/mesh
rm -rf "$MESH_APP_ROOT/www"

View file

@ -0,0 +1,102 @@
/* encode function start */
var ezEncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var ezDecodeChars = new Array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
function utf16to8(str)
{
var out, i, len, c;
out = "";
len = str.length;
for (i=0; i<len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
}
else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >>6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >>0) & 0x3F));
}
else {
out += String.fromCharCode(0xC0 | ((c >>6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >>0) & 0x3F));
}
}
return out;
}
function utf8to16(str) {
var out, i, len, c;
var char2, char3;
out = "";
len = str.length;
i = 0;
while(i < len) {
c = str.charCodeAt(i++);
switch(c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += str.charAt(i-1);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx10xx xxxx10xx xxxx
char2 = str.charCodeAt(i++);
char3 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
}
}
return out;
}
function ezEncode(str)
{
var out, i, len;
var c1, c2, c3;
len = str.length;
i = 0;
out = "";
while(i < len)
{
c1 = str.charCodeAt(i++) & 0xff;
if(i == len)
{
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if(i == len)
{
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += ezEncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += ezEncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
out += ezEncodeChars.charAt(c3 & 0x3F);
}
return out;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,104 @@
var ed = {
partnerId: 1222,
brand: 'RiV Mesh',
applicationName: "RiV Mesh QNAP NAS OS App",
nasOSName: "QNAP NAS device",
useAuthNASRichScreen: true,
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
getNasAuthUrl: function () {
return "/";
}
};
$(function () {
ed.nasLoginCall = function (nasLoginSuccess, nasLoginFailure) {
/* encode function start */
var ezEncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function utf16to8(str)
{
var out, i, len, c;
out = "";
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
function ezEncode(str)
{
var out, i, len;
var c1, c2, c3;
len = str.length;
i = 0;
out = "";
while (i < len)
{
c1 = str.charCodeAt(i++) & 0xff;
if (i == len)
{
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len)
{
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += ezEncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += ezEncodeChars.charAt(c1 >> 2);
out += ezEncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += ezEncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
out += ezEncodeChars.charAt(c3 & 0x3F);
}
return out;
}
var d = new Date();
d.setTime(d.getTime() + (30 * 60 * 1000));
document.cookie = "qnapuser=" + encodeURIComponent($('#nasInputUser').val()) + "; expires=" + d.toUTCString() + "; path=/";
document.cookie = "qnappwd=" + encodeURIComponent(ezEncode(utf16to8($('#nasInputPassword').val()))) + "; expires=" + d.toUTCString() + "; path=/";
$.ajax({url: "rest/info"}).done(function (response) {
window.location.reload();
checkError(response);
}).fail(function () {
ed.nasLogoutCall();
nasLoginFailure();
});
};
ed.nasLogoutCall = function() {
document.cookie = "qnapuser=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
document.cookie = "qnappwd=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
};
function getCookie(name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
ed.getNasUser = function() {
return getCookie('qnapuser');
};
});

View file

@ -0,0 +1,42 @@
#script called from qinstall.sh
#SYS_QPKG_SERVICE_ENABLED="FALSE"
QPKG_NAME="mesh"
CONF=/etc/config/mesh.conf
PKG_PRE_REMOVE="{
killall -q mesh
rm -rf /share/Web/$QPKG_NAME
[ -L /var/log/mesh.log ] && rm -f /var/log/mesh.log
}"
PKG_MAIN_REMOVE="{
$CMD_RM -f $CONF
}"
pkg_pre_install(){
killall -q mesh
rm -rf /share/Web/$QPKG_NAME
}
pkg_install(){
exec 2>/tmp/mesh.log
set -x
if [ -f $CONF ]; then
mkdir -p /var/backups
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
cp $CONF /var/backups/mesh.conf.`date +%Y%m%d`
echo "Normalising and updating $CONF"
${SYS_QPKG_DIR}/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $CONF
else
echo "Generating initial configuration file $config_file"
echo "Please familiarise yourself with this file before starting RiV-mesh"
sh -c "umask 0027 && ${SYS_QPKG_DIR}/bin/mesh -genconf > '$CONF'"
fi
chmod a+w $CONF
}
pkg_post_install(){
ln -sf $SYS_QPKG_DIR/var/log/mesh.log $SYS_QPKG_DIR/www/log
}

View file

@ -0,0 +1,120 @@
#!/bin/sh
QPKG_CONF="/etc/config/qpkg.conf"
CONF="/etc/config/mesh.conf"
QPKG_NAME="mesh"
QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f $QPKG_CONF)
KERNEL_MODULES+=" tun"
load_kernel_modules(){
local KERNEL_VERSION=$(/bin/uname -r)
local KERNEL_MODULES_PATH="/lib/modules"
for M in ${KERNEL_MODULES}; do
if [ -f ${KERNEL_MODULES_PATH}/vpn/${M}.ko ]; then
/sbin/insmod ${KERNEL_MODULES_PATH}/vpn/${M}.ko
continue
fi
if [ -f ${KERNEL_MODULES_PATH}/qvpn/${M}.ko ]; then
/sbin/insmod ${KERNEL_MODULES_PATH}/qvpn/${M}.ko
continue
fi
if [ -f ${KERNEL_MODULES_PATH}/misc/${M}.ko ]; then
/sbin/insmod ${KERNEL_MODULES_PATH}/misc/${M}.ko
continue
fi
if [ -f ${KERNEL_MODULES_PATH}/others/${M}.ko ]; then
/sbin/insmod ${KERNEL_MODULES_PATH}/others/${M}.ko
continue
fi
if [ -f ${KERNEL_MODULES_PATH}/${KERNEL_VERSION}/${M}.ko ]; then
/sbin/insmod ${KERNEL_MODULES_PATH}/${KERNEL_VERSION}/${M}.ko
continue
fi
done
}
create_tun(){
if ( [ ! -c /dev/net/tun ] ); then
if ( [ ! -d /dev/net ] ); then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
chmod 0755 /dev/net/tun
fi
# Load the tun module if not already loaded
if ( !(lsmod | grep -q "^tun\s") ); then
insmod /lib/modules/tun.ko
fi
}
start_service ()
{
exec 2>>/tmp/mesh.log
set -x
#enable ipv6
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.disable_ipv6=0
# Create the necessary file structure for /dev/net/tun
create_tun
load_kernel_modules
#. /etc/init.d/vpn_common.sh && load_kernel_modules
if [ ! -f '/etc/config/apache/extra/apache-mesh.conf' ] ; then
ln -sf $QPKG_DIR/apache-mesh.conf /etc/config/apache/extra/
apache_reload=1
fi
if ! grep '/etc/config/apache/extra/apache-mesh.conf' /etc/config/apache/apache.conf ; then
echo 'Include /etc/config/apache/extra/apache-mesh.conf' >> /etc/config/apache/apache.conf
apache_reload=1
fi
if [ -n "$apache_reload" ] ; then
/usr/local/apache/bin/apachectl -k graceful
fi
# Launch the mesh in the background.
${QPKG_DIR}/bin/mesh -useconffile "$CONF" \
-httpaddress "http://127.0.0.1:19019" \
-wwwroot "$QPKG_DIR/www" \
-logto "$QPKG_DIR/var/log/mesh.log" &
if [ $? -ne 0 ]; then
echo "Starting $QPKG_NAME failed"
exit 1
fi
}
stop_service ()
{
# Kill mesh
pid=`pidof -s mesh`
if [ -z "$pid" ]; then
echo "mesh was not running"
exit 0
fi
kill "$pid"
}
case "$1" in
start)
start_service
;;
stop)
stop_service
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0

View file

@ -0,0 +1,14 @@
location = /mesh {
return 301 /mesh/;
}
location ~ ^/mesh/ {
rewrite ^/mesh/(.*) /$1 break;
proxy_pass http://127.0.0.1:19019;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For-Addr $server_addr;
proxy_set_header X-Forwarded-For-Port $server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Original-URI $request_uri;
}

View file

@ -0,0 +1,5 @@
[mesh]
title="HTTP"
desc="RiV Mesh Web interface"
port_forward="no"
dst.ports="19019/tcp"

View file

@ -0,0 +1,11 @@
{
".url": {
"org.mesh": {
"type": "url",
"title": "RiV Mesh",
"desc": "ipv6 mesh network",
"icon": "mesh-{0}.png",
"url": "/webman/3rdparty/mesh/login.html"
}
}
}

View file

@ -0,0 +1,18 @@
<html>
<head>
<script type="text/javascript" src="/scripts/ext-3/adapter/ext/ext-base.js?v=1401997094"></script>
<script type="text/javascript" src="/scripts/ext-3/ext-all.js?v=1401997094"></script>
<script type="text/javascript" src="/webman/dsmtoken.cgi"></script>
</head>
<body>
<script>
Ext.onReady(function () {
if (Ext.isEmpty(SYNO.SDS.Session)) {
window.location.assign("/webman");
} else {
window.location.assign(Ext.urlAppend(window.location.origin + "/mesh/"));
}
});
</script>
</body>
</html>

View file

@ -0,0 +1,7 @@
#!/bin/sh
echo vendor=Synology
echo vendorOperatingSystemName=DSM
. /etc.defaults/VERSION
echo firmwareVersion="${productversion}-${buildnumber}"
echo $(cat /etc/avahi/services/dsminfo.service | grep model | sed -e 's/<[^>]*>//g;s/^ *//')
echo $(cat /etc/avahi/services/dsminfo.service | grep serial | sed -e 's/<[^>]*>//g;s/^ *//')

View file

@ -0,0 +1,22 @@
#!/bin/sh
export CONTENT_LENGTH=$HTTP_CONTENT_LENGTH
export CONTENT_TYPE=$HTTP_CONTENT_TYPE
IFS=';'
for x in $HTTP_COOKIE
do
case $x in
*EdSynoToken*)
eval $x
;;
esac
done
[ -z $QUERY_STRING ] && export QUERY_STRING=SynoToken=$EdSynoToken || export QUERY_STRING="$QUERY_STRING&SynoToken=$EdSynoToken"
[ ! -z $HTTP_X_REAL_IP ] && export REMOTE_ADDR=$HTTP_X_REAL_IP
[ ! -z $HTTP_X_FORWARDED_FOR_ADDR ] && export SERVER_ADDR=$HTTP_X_FORWARDED_FOR_ADDR
[ ! -z $HTTP_X_FORWARDED_FOR_PORT ] && export SERVER_PORT=$HTTP_X_FORWARDED_FOR_PORT
#exit with zero status on auth success and 1 on error
[ ! -z $(/usr/syno/synoman/webman/modules/authenticate.cgi) ]
exit $?

View file

@ -0,0 +1,10 @@
#!/bin/sh
log_exit(){
echo $2
exit $1
}
rm "$ED_APP_ROOT/bin/mesh
rm -rf "$ED_APP_ROOT/www"
rm -rf "$ED_APP_ROOT/ui"

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,81 @@
var ed = {
partnerId: 1126,
brand: 'RiV Mesh',
applicationName: 'RiV Mesh Synology DSM App',
nasOSName: 'Synology DSM',
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
getCookie: function (name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
},
setCookie: function (key, value, expires) {
if(expires) {
var d = new Date();
d.setTime(d.getTime() + (30 * 60 * 1000));
expires = "; expires=" + d.toUTCString();
} else {
expires = "";
}
document.cookie = key + "=" + value + expires + "; path=/";
},
getNasAuthUrl: function () {
ed.setCookie('EdSynoToken', "");
var url = ed.getCookie('origin');
if (url === undefined) {
url = window.location.protocol + "//" + window.location.hostname + ":" + 5000;
}
return url;
}
};
$(function () {
function params(obj) {
if (typeof obj === 'string') {
if (obj[0] === '?') {
obj = obj.substring(1);
}
var result = {};
obj = obj.split("&");
obj.forEach(function (pair) {
pair = pair.split("=");
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof result[key] === "undefined") {
result[key] = value;
// If second entry with this name
} else if (typeof result[key] === "string") {
result[key] = [result[key], value];
// If third or later entry with this name
} else {
result[key].push(value);
}
});
return result;
} else {
return Object.keys(obj).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
}).join('&');
}
};
//Hide URL parameters
var query = params(window.location.search.substring(1));
var refresh = false;
for (var k in query) {
if (k === 'SynoToken') {
ed.setCookie('EdSynoToken', query[k]);
refresh = true;
delete query[k];
} else if (k === 'origin') {
ed.setCookie('origin', query[k]);
refresh = true;
delete query[k];
}
}
query = $.param(query);
if (refresh)
window.location.replace(window.location.origin + window.location.pathname + window.location.hash + ((query === "") ? "" : ("?" + query)));
});

View file

@ -0,0 +1,5 @@
{
"port-config": {
"protocol-file": "mesh.sc"
}
}

View file

@ -0,0 +1,17 @@
#!/bin/bash
DEBUG=true
SH="$(readlink /proc/$$/exe)"
if $DEBUG ; then
echo "" > /tmp/mesh.log
exec 2>>/tmp/mesh.log
SH="$SH -x"
set -x
fi
BASE="/var/packages/mesh/target"
LOG_FILE="$BASE/var/log/mesh.log"
ln -sf $LOG_FILE $BASE/www/log
ln -sf $BASE/dsm.mesh.conf /etc/nginx/conf.d/dsm.mesh.conf
nginx -s reload
exit 0

View file

@ -0,0 +1,8 @@
#!/bin/sh
rm -f /var/run/mesh.pid
LOG_SYMLINK=/var/log/mesh.log
[ -L $LOG_SYMLINK ] && rm -f $LOG_SYMLINK
rm -f /etc/nginx/conf.d/dsm.mesh.conf
exit 0

View file

@ -0,0 +1,3 @@
#!/bin/sh
exit 0

View file

@ -0,0 +1,3 @@
#!/bin/sh
exit 0

Some files were not shown because too many files have changed in this diff Show more