Compare commits

...

7 Commits

13 changed files with 622 additions and 114 deletions

View File

@@ -50,8 +50,6 @@
name: collabora
image: docker.io/collabora/code:latest
state: present
cap_add:
- MKNOD
network:
- traefik-collabora
- nextcloud-collabora
@@ -61,7 +59,7 @@
io.containers.autoupdate: "registry"
traefik.enable: "true"
traefik.http.routers.collabora.entrypoints: "https"
traefik.http.routers.collabora.rule: "Host(`{{ vault_domain }}`) && PathPrefix(`/collabora`,`/browser`)"
traefik.http.routers.collabora.rule: "Host(`{{ vault_domain }}`) && (PathPrefix(`/collabora`) || Path(`/browser`))"
traefik.http.routers.collabora.tls: "true"
traefik.http.routers.collabora.tls.certresolver: "wildcard"
traefik.http.routers.collabora.service: "collabora"
@@ -70,16 +68,32 @@
env:
domain: "chef\\.heaplab\\.deib\\.polimi\\.it"
aliasgroup1: "chef\\.heaplab\\.deib\\.polimi\\.it"
server_name: "chef.heaplab.deib.polimi.it"
username: "{{ vault_collabora_user }}"
password: "{{ vault_collabora_password }}"
extra_params: "--o:ssl.enable=false --o:ssl.termination=true --o:net.service_root=/collabora"
extra_params: "--o:ssl.enable=false --o:ssl.termination=true --o:net.service_root=/collabora --o:net.server_name=chef.heaplab.deib.polimi.it/collabora"
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
requires: [container-nextcloud.service, container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-collabora.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -84,10 +84,24 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-drone-runner.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -85,10 +85,25 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
requires: [container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-drone-server.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -89,7 +89,6 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
names: true
new: true
@@ -156,16 +155,46 @@
GITEA__service__SIGNIN_VIEW: false
GITEA__service__REGISTER_EMAIL_CONFIRM: true
GITEA__service__ENABLE_CAPTCHA: true
GITEA__service__ENABLE_NOTIFY_MAIL: true
GITEA__service__DEFAULT_KEEP_EMAIL_PRIVATE: false
GITEA__ui__THEMES: "auto,gitea,arc-green,gitea-modern"
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
requires: [container-db_gitea]
time: 3600
requires: [container-db_gitea.service, container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-gitea.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-db_gitea.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -78,10 +78,25 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
requires: [container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-heimdall.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -0,0 +1,183 @@
# code: language=ansible
---
- hosts: all
name: Mattermost server
tasks:
- name: Stop running containers
become_user: containers
become: true
ansible.builtin.systemd:
scope: user
name: container-{{ item }}.service
state: stopped
loop:
- mattermost
- db_mattermost
failed_when: false
- name: Create podman volumes
containers.podman.podman_volume:
state: present
name: "{{ item }}"
become_user: containers
become: true
loop:
- mattermost-config
- mattermost-data
- mattermost-logs
- mattermost-plugins
- mattermost-clientplugins
- mattermost-bleveindexes
- mattermost-db
- name: Create podman networks
containers.podman.podman_network:
name: "{{ item }}"
recreate: false
state: "present"
become_user: containers
become: true
loop:
- traefik-mattermost
- postgres-mattermost
- name: Pull container images
become_user: containers
become: true
containers.podman.podman_image:
name: docker.io/{{ item }}
loop:
- mattermost/mattermost-team-edition:release-9
- postgres:13-alpine
- name: Create postgres instance
become_user: containers
become: true
containers.podman.podman_container:
name: db_mattermost
image: docker.io/postgres:13-alpine
state: present
volume:
- mattermost-db:/var/lib/postgresql/data/pgdata:Z
network:
- postgres-mattermost
env:
POSTGRES_DB: "{{ vault_mattermost_db_database }}"
POSTGRES_USER: "{{ vault_mattermost_db_user }}"
POSTGRES_PASSWORD: "{{ vault_mattermost_db_password }}"
PGDATA: /var/lib/postgresql/data/pgdata
TZ: "{{ vault_timezone }}"
security_opt:
- no-new-privileges=true
pids_limit: "100"
read_only: true
tmpfs:
"/tmp": "rw"
"/var/run/postgresql": "rw"
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
names: true
new: true
- name: Add a mattermost container
become_user: containers
become: true
containers.podman.podman_container:
name: mattermost
image: docker.io/mattermost/mattermost-team-edition:release-9
state: present
network:
- traefik-mattermost
- postgres-mattermost
volume:
- mattermost-config:/mattermost/config:Z
- mattermost-data:/mattermost/data:Z
- mattermost-logs:/mattermost/logs:Z
- mattermost-plugins:/mattermost/plugins:Z
- mattermost-clientplugins:/mattermost/client/plugins:Z
- mattermost-bleveindexes:/mattermost/bleve-indexes:Z
security_opt:
- no-new-privileges=true
pids_limit: "100"
tmpfs:
"/tmp": "rw"
label:
io.containers.autoupdate: "registry"
traefik.enable: "true"
traefik.http.routers.mattermost.entrypoints: "https"
traefik.http.routers.mattermost.rule: "Host(`{{ vault_domain }}`) && (PathPrefix(`/mattermost/`) || Path(`/mattermost`))"
traefik.http.routers.mattermost.tls: "true"
traefik.http.routers.mattermost.tls.certresolver: "wildcard"
traefik.http.routers.mattermost.service: "mattermost"
traefik.http.routers.mattermost.middlewares: "http-compress@file"
traefik.http.services.mattermost.loadbalancer.server.port: "8065"
traefik.http.services.mattermost.loadbalancer.passhostheader: "true"
traefik.udp.routers.mm-call-rtr.service: "mm-call-svc"
traefik.udp.routers.mm-call-rtr.entrypoints: "mmcalls"
traefik.udp.services.mm-call-svc.loadBalancer.server.port: "8443"
traefik.docker.network: "traefik-mattermost"
env:
TZ: "{{ vault_timezone }}"
# https://docs.mattermost.com/configure/environment-configuration-settings.html
MM_SQLSETTINGS_DRIVERNAME: "postgres"
MM_SQLSETTINGS_DATASOURCE: "postgres://{{ vault_mattermost_db_user }}:{{ vault_mattermost_db_password }}@db_mattermost:5432/{{ vault_mattermost_db_database }}?sslmode=disable&connect_timeout=10"
MM_BLEVESETTINGS_INDEXDIR: "/mattermost/bleve-indexes"
MM_SERVICESETTINGS_SITEURL: "https://{{ vault_domain }}/mattermost"
MM_EMAILSETTINGS_SMTPSERVER: "{{ vault_smtp_host }}"
MM_EMAILSETTINGS_SMTPPORT: "{{ vault_smtp_port }}"
MM_EMAILSETTINGS_ENABLESMTPAUTH: "false"
MM_EMAILSETTINGS_SMTPUSERNAME: "{{ vault_smtp_user }}"
MM_EMAILSETTINGS_SMTPPASSWORD: "{{ vault_smtp_password }}"
MM_EMAILSETTINGS_CONNECTIONSECURITY: "{{ vault_smtp_protocol }}"
MM_SERVICESETTINGS_ENABLESECURITYFIXALERT: "true"
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
requires: [container-db_mattermost.service, container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-mattermost.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-db_mattermost.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true
ansible.builtin.systemd:
scope: user
name: container-{{ item }}.service
enabled: true
state: started
daemon_reload: true
loop:
- mattermost
- db_mattermost

View File

@@ -1,6 +1,7 @@
[Unit]
Description=Nextcloud cron.php job
Wants=nextcloudcron.timer
Requires=container-nextcloud.service
[Service]
ExecStart=/bin/podman exec -u www-data nextcloud php -f /var/www/html/cron.php

View File

@@ -106,7 +106,6 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
names: true
new: true
@@ -134,7 +133,6 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
names: true
new: true
@@ -185,8 +183,8 @@
SMTP_SECURE: "{{ vault_smtp_protocol }}"
SMTP_PORT: "{{ vault_smtp_port }}"
SMTP_AUTHTYPE: "None"
SMTP_NAME: ""
SMTP_PASSWORD: ""
SMTP_NAME: "{{ vault_smtp_auth_name }}"
SMTP_PASSWORD: "{{ vault_smtp_password }}"
MAIL_FROM_ADDRESS: "{{ vault_smtp_from }}"
MAIL_DOMAIN: "{{ vault_smtp_domain }}"
TRUSTED_PROXIES: "traefik"
@@ -196,11 +194,42 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
requires: [container-db_nextcloud, container-redis_nextcloud]
time: 3600
requires: [container-db_nextcloud.service, container-redis_nextcloud.service, container-traefik.service]
names: true
new: true
- name: Change start timeout limit
become_user: containers
become: true
community.general.ini_file:
path: "/home/containers/.config/systemd/user/container-{{ item }}.service"
section: Service
option: TimeoutStartSec
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- nextcloud
- redis_nextcloud
- db_nextcloud
- name: Change stop timeout limit
become_user: containers
become: true
community.general.ini_file:
path: "/home/containers/.config/systemd/user/container-{{ item }}.service"
section: Service
option: TimeoutStopSec
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- nextcloud
- redis_nextcloud
- db_nextcloud
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -70,10 +70,25 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
requires: [container-traefik.service]
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-portainer.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -38,6 +38,15 @@
to_port: 443
rule: allow
- name: Permit traffic from any IP to mattermost port
become: true
community.general.ufw:
direction: in
from_ip: any
proto: udp
to_port: 8443
rule: allow
- name: Pull traefik image
become_user: containers
become: true
@@ -88,6 +97,7 @@
- traefik-gitea
- traefik-collabora
- traefik-heimdall
- traefik-mattermost
- name: Create traefik instance
become_user: containers
@@ -99,6 +109,7 @@
publish:
- "80:80"
- "443:443"
- "8443:8443"
security_opt:
- label=type:container_runtime_t
volume:
@@ -111,6 +122,7 @@
- traefik-gitea
- traefik-collabora
- traefik-heimdall
- traefik-mattermost
cap_add:
- NET_ADMIN
label:
@@ -118,7 +130,7 @@
traefik.enable: "true"
traefik.http.middlewares.traefik-auth.basicauth.users: "{{ vault_traefik_basic_auth }}"
traefik.http.routers.traefik.entrypoints: "https"
traefik.http.routers.traefik.rule: "Host(`{{ vault_domain }}`) && PathPrefix(`/api`,`/dashboard`)"
traefik.http.routers.traefik.rule: "Host(`{{ vault_domain }}`) && (PathPrefix(`/api/`) || Path(`/api`) || PathPrefix(`/dashboard/`) || Path(`/dashboard`))"
traefik.http.routers.traefik.middlewares: "traefik-auth@docker"
traefik.http.routers.traefik.tls: "true"
traefik.http.routers.traefik.tls.certresolver: "wildcard"
@@ -127,10 +139,24 @@
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
time: 3600
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-traefik.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true

View File

@@ -21,6 +21,8 @@ entryPoints:
permanent: true
https:
address: ":443"
mmcalls:
address: ":8443/udp"
providers:
docker:

View File

@@ -0,0 +1,154 @@
---
- name: Online project management tool
hosts: all
tasks:
- name: Stop running containers
become_user: containers
become: true
ansible.builtin.systemd:
scope: user
name: container-{{ item }}.service
state: stopped
loop:
- vikunja
- db_vikunja
failed_when: false
- name: Pull container images
become_user: containers
become: true
containers.podman.podman_image:
name: docker.io/{{ item }}
loop:
- vikunja/vikunja:latest
- mariadb:latest
- name: Create podman volumes
containers.podman.podman_volume:
state: present
name: "{{ item }}"
become_user: containers
become: true
loop:
- vikunja-data
- vikunja-db
- name: Create podman networks
containers.podman.podman_network:
name: "{{ item }}"
recreate: false
state: present
become_user: containers
become: true
loop:
- traefik-vikunja
- mariadb-vikunja
- name: Create mariadb instance
become_user: containers
become: true
containers.podman.podman_container:
name: db_vikunja
image: docker.io/mariadb:latest
state: present
volume:
- vikunja-db:/var/lib/mysql:Z
network:
- mariadb-vikunja
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --max-connections=1000
env:
MARIADB_ROOT_PASSWORD: "{{ vault_vikunja_mariadb_root_password }}"
MARIADB_DATABASE: "{{ vault_vikunja_mariadb_database }}"
MARIADB_USER: "{{ vault_vikunja_mariadb_user }}"
MARIADB_PASSWORD: "{{ vault_vikunja_mariadb_password }}"
MARIADB_AUTO_UPGRADE: "true"
healthcheck: "mysqladmin ping --silent"
healthcheck_interval: 2s
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
names: true
new: true
- name: Create vikunja instance
become_user: containers
become: true
containers.podman.podman_container:
name: vikunja
image: docker.io/vikunja/vikunja:latest
state: present
volume:
- vikunja-data:/app/vikunja/files:Z
network:
- traefik-vikunja
- mariadb-vikunja
env:
VIKUNJA_DATABASE_HOST: db_vikunja
VIKUNJA_DATABASE_PASSWORD: "{{ vault_vikunja_mariadb_password }}"
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: "{{ vault_vikunja_mariadb_user }}"
VIKUNJA_DATABASE_DATABASE: "{{ vault_vikunja_mariadb_database }}"
VIKUNJA_SERVICE_JWTSECRET: "{{ vault_vikunja_jwt_secret }}"
VIKUNJA_SERVICE_PUBLICURL: https://{{ vault_domain }}/vikunja/
VIKUNJA_FRONTEND_BASE: /vikunja/
label:
io.containers.autoupdate: registry
traefik.enable: "true"
traefik.http.routers.vikunja.entrypoints: https
traefik.http.routers.vikunja.rule: Host(`{{ vault_domain }}`) && (PathPrefix(`/vikunja/`) || Path(`/vikunja`))
traefik.http.routers.vikunja.tls: "true"
traefik.http.routers.vikunja.tls.certresolver: wildcard
traefik.http.routers.vikunja.service: vikunja
traefik.http.services.vikunja.loadbalancer.server.port: "3456"
traefik.docker.network: traefik-vikunja
generate_systemd:
path: /home/containers/.config/systemd/user/
restart_policy: on-failure
names: true
new: true
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-vikunja.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Change start and stop timeout limits
become_user: containers
become: true
community.general.ini_file:
path: /home/containers/.config/systemd/user/container-db_vikunja.service
section: Service
option: "{{ item }}"
value: 3600
mode: "0664"
state: "present"
no_extra_spaces: true
loop:
- TimeoutStartSec
- TimeoutStopSec
- name: Start containers at boot
become_user: containers
become: true
ansible.builtin.systemd:
scope: user
name: container-{{ item }}.service
enabled: true
state: started
daemon_reload: true
loop:
- db_vikunja
- vikunja

View File

@@ -1,95 +1,106 @@
$ANSIBLE_VAULT;1.1;AES256
32313436663665626438616435613133666539396132346261343233383836326163306130616564
3737353664343838373537633061393531643366353434660a316537373738623362343966383162
61366162653237613437326562313737353663626332623833316230613639363639623336343331
3239323034303463620a653066396534346338313165366161373036663232323333303962323437
36336139333663353831633539346464366534623932366230313562646636623262306138313930
34326130386631346535643262333538383333323835333436346662336365643166613432613334
39383732333137346238383166366237623363363533306464656364363834353537316232303630
65663837623032373063373339616436343038336430646537643464333834306233316236316138
39373238356534626562626365353333643038386134666239623438363762623136643466633066
36666134346236333336323239396433326334383061313166666565366538303331613330613861
39666439326435326239663033336666326539396537393731613230313037393365343231363931
35313261633764346564653831343731323037376463373331326662386435353764666462393832
37353034316232383464616133613234336365326334343563343233653862633865356266353361
38303634323861376336616466663264626166396433313036326631646366623332663534323738
34643533306437633337366530323936646435363636643535396666323632643531356631636261
35373663653430353863626562633636363537376435326131373438333132666137393661333563
65366634633064656432626539323463323033363263316330646430633039386236633237356534
39373861663064303963356137303364306466393633656563393965333263373862313066383832
35386362386439633530326536636431356261353463663661323666353835346138316131386237
32383730653162326638353463343734353361393961636331333530336430643032396133343365
61343237626666363965316662313039633263333165336562313738393238306365623866373536
32353138636631346264346130333063653139653064653039646630623762643730346630383161
61666563666233336531333964303261613365656530353934633264333962663239363634666637
63393765653038653730393836646133306464653166633839326264623439666265653034646530
34326666393961613862316230343963363739356637386336646632643234323139633263326662
33353933643336373337626535643365306662353730636665623761386639373664386465653830
62313434303263653762363962653132663939613137636134636639383235653363383733306363
61333538613566336132616465396533356566306337373634343233666339646533666564613732
66656461623630383033333232383435343938393933376130616639386464363734393832663764
61343832313066336662343766383164616433653336653862306261353232613336366534633462
30613232353830353163626134646332353839666566633233363232383730633138316634336465
32396161333639376362316139636663313132383761616237663262666537376562333833343636
35316530336565343535343134313062666436373236616563633335646165663232653763313838
32663663393365626335626635383037613166633338323865343362613537373464333464393531
37626661636539336436646336366434346563333163623662336161643437316638313033336434
34343161373964356436386435656631383862366530643930653339643565643538303032653135
30303161303561643439643165393932663462343737323963653332393234366237663830333561
32363230343734613734633534643265373032656461386231333739616132326632306539333364
30616562366234393932366433626633343932663930306564623233333864366334306333303663
66366661376161306466393139383031656563376432383330646338663138333630333636333131
30393062326431373864323737363935643866633533613766636661393739306235623361323930
31353564623437626662386431376530323163633939646262366632323932333263643463373938
64363231653834663738386436346164326239346565376665346365656636316161393962636566
39356238313065323834653566626664643662666238346461613563386636333635343131616435
64336563356464333762326336343863633433306566353663653139313466396366613737633239
38633734383031393339626336373738303832316339653061333361653965313362633235613465
63353466613130376330643330353135636634313339613934636633373739326661393838613534
38376563333836646361663433346233633634393430663236393336376361343565396663383139
35366439313866303330336337306236663834326439613832363439663162633130653365643066
37633030343039626563666366633533373334666265316437653365623233626632653466323239
37623936366564653762633534346134666463623232373666626230323531613139643031666639
66653539383834643663616565656533636263626136333661323137323061316134323838383161
30623336323935386133646432643538376131306138313264393866636339323862356139306665
31623636653764313430386437363863633336326330373837366261636330323864663561373161
62393664346637363938343434343937666462383339313331373963613462613061653863393132
36326538623339326431343430626162393365653164323831656537613664653264616566343937
37373362333339646537313266383731643237366362663261383837383230633666636364636339
66636564663263373638643262303738373033363262393039393464346131663134646538643131
30336236386131663761633432353565343130316132336234613463346533613863353435383439
62333339323137333265326361623562366431646165623264393338613263386462393437663763
39663132356232623634633261643036353733653064383563366165316237323766313138366135
37373130373731343461326233663834653239626464633864343965366535336562363464303961
37353235346661633232373734393335306436333166373861383138373835333666306135333836
38383463393238346562643437633164316331366662636130623532373061363464346263326534
39346435396330643235386362323330663564613363396265396633613437336663353838643566
31633432633464663234613438346634643132636139623862643731656539663631396236366361
32323131356661633238613963643166376538303563633636313164343832633937656233313134
30343761306161383535626164643631613833383731323166303431366631306338383261383764
32633330333731303164353532373034323633653130353062336266313265366637356635333965
66626464336161356563393631616461616630393865326666316532636263663164376436313436
35616466653030643237326439656539353235303130656138356539366364373530623164306561
31303431643034646666393963653862613639303936336366363832616430623962383462373733
65323530396533316233373339363530633761633132363161313132646638383062313630316663
61373466646236313062383564336266376366396132333532326137623134376337333864313533
31306237613634616437613266626566393135386663363062646636326230653461316232366164
32363962313039353463376631646236616637363832643634646531613262633334353135336566
35363538623735666466626565656430313333373532396662323865366133373962353838343732
31633064666566373932666535303039326337323362393236316237343939383033386237353336
39663164666265386539333234303661326136373962303966633566623238343361333837383133
66663436663366623262646433353765666335333164623238366437626232373338326164396465
38373636323966363633316662396162326261623533396132326338353130666265373332333138
39626537633337613836613766313730336233633337666539623364393739346139313030303238
33613463313038333237613739323835346664323033306631623562643166646435616636363037
34383637353865666530643538623865343139613637303238636139643162313761343831373066
35636364393466663334623838313461393234313462306633343132373439363937316266393862
30303938666238613937666165316662326532313531616231326234363034643563633735383461
34383137646464323434636531633737346365666132353064663563643330346337616161326431
32383364646137616265383064376235363435353636323762613232383037303534633133373535
62313839636535346161626663666438653235336334666631343764333163316639353366366334
63616463663337653732313432303463623034653865666136373432623164663534373239333632
61333535363463373632333231643136373634613537313438366461323434343935333432333537
62643336663765376131356634343562633238646162623565396661383738376339316533363461
64333265316331346137376664303962313661636635396130323035373335623135376133653431
6361656138636537373730643039363864366332383266323366
63626565393066343966323064646661383330623937613233616534313331363530613062643964
3831383231313564376432303465376532623531643539610a663134386361353330626637626162
64373334373639663762343362646636303837376138393338643533363438616535623064323061
6436343866336234350a313733383930366635646437383464353363643964346437323535333866
39636163666637326531336136653461636135363230663762613637666230353135616435393962
32383132313963623131313831326333656232656538336433633735633939636661383266396663
30653763333761623734383862326438626631643965376137663662643362663165306265633363
63636238336438643733633665613232306437396130663432366364613737653431653361653965
32373931633536656335396134313065666437666634343466653136343362343165366233383964
66663263316162626466646234623363616135663039393761373734663566623235343263323261
37646434373863303033386464343766323462643338396466363863356430616431343463326432
66376630663337386461663934393566393138353363376235343764363431323636653361343839
33353864653031633831383639633565616332373033333436636362393565306233326632373639
38316265303135366436643262653733663333383863386536343035366362643762646437306135
65663065366335656436633137316266643361643336613235613562633537313366343163376164
63663661383032343962666363393834626339333437313032303134643036646636333464353931
66356664623938333230616365316666653832393730616332376434336339363430366239656636
31323236666165623736376133393063323537326164386536633631313466653162663739376639
35376364653066396635396539316234313037356339363833396430353134356136666537363337
63343435363235386538636361343138363263663035653666656637333036666331343139373463
61666266636134366233633766623430633164636337653839663365343062616464323861363836
64613638626338353335633164613931363537356232373066323035393435373932633932663838
62303232643835303636323638653435343836383432313161306363303565356239663430376331
62323038616332663032366133656632663363623837333537366432643439353934346165623039
63306436653235646535333134643438656133323131333266656337396337353833313230653438
66313834656430323962653263643231396330313561613935336132646238366637633230323134
35346564383166636563366637643738353838636530303235616265306133336431393064646434
32363065633136326364336637656235316330323137633364383739633032366437373233376334
38663762643832373264383064333662376634633738383239343932353162343466393637343439
31353936366137623538393737316661666161633464343466306139323030653935343564396132
66653934326230326563643837333562333438303334623138623362323737313461373930666162
34656162313730663365373835366231383638623834653238326261616332333665393732383864
31646163346431373434323961633966623564363432306562663031626562353036613632666130
31656466333934663265656336313161643135346235663838383563333535623163396636613738
34376534386635393062306363343137336666656330343863623439316131353066353337383734
35306137353434333435313033636565653537306264636332646464306633666635616435663034
38653635383861343237616339306662663634653937663730376232306161306435333432343235
38626232613939623166623465353837663064396264643966383634343736353161346232373135
66303338376338663431373131653462343766376235653762343564383965333131353431356565
66313163343537343931306131373738383965356433323139333262363331663438316364343539
32373362613433633638306235383638313334633130326637613734393965633164646539396465
30356135666464353531643061346635386663366438656638646237366431366237616632363330
38646661396561643039336631333037313638653334666361383132323264323037633132353464
61306261353765386136313331623264633532363833343336313465333332663837303934313332
63633330313434353666616533663939383431303334616434303037643763383935633061643737
37376139656565633466633638303838623238363030363734323739643339633130633030346431
39373863376137376430313532623662633738666539663566316366356536613963323437636236
36396461646439326164623230303362636664303131326561383536653436316239643161313932
36393638666630383761303965666461326433393635306230333136343064633161373034656635
35386362316465366134386566656366616236326133366665366437616630346565353261613464
31633338623163626138663034346137356131333335333536386365373237333737653163333533
39373430633534636632356432313161636433393931303361366565353665633662313832646565
35633237663161313832613065326638356130306439643437613735643264373331653331373232
33383966363833376439333431303664323465383664383566656531663366383735383364663461
66623161623738343365356365303730656337373636333361376534356363366134333338366464
34366139636162613031313265306635663435396533633031316139356163613532363737313031
37393438653465323963343139383766373062666632343939316166646265393730343331386630
64616231386330386339656434346236376432376432383639363431666233336437623263663763
31363964313766386535646561656261633938656238303762633465373565633962626663336266
66313965613730643631376264343461633038616430326637633330313861363233363162623232
66363861383530373933326436373165383930316138633665663336663266626362386365653264
33376230376336393962313036393134316233316539393037323065643265633964306530656462
30383562653333323263613661393861643332656330633635333135616463336566353630666562
31646139326630343738653539373337356139653338306663353932623535626232636634393334
66323230393633646165633835653834373261353031356365643933303737313534383533663762
32643739646639656430663562393166626539353533656563393862353562336432373234656136
35343266356330306432346435363035336432636135663464393033353733393732356364613132
65353464616231653137373734323761396430363664643464353430646134656665633933623666
62363535303265353533333335653061616230613163373361363336373337623131383563323938
66643830363863616134343564343132346639323030396166383965336265396138636431666462
62306333363136653462386633643637663262623638373833663030316539623566323461393536
36656465353436336363623536376164373264643863666631353865643462663636636130376266
32623435643631303836653262643031353630396261343666663237663436366664356639366532
34353839373863646366366236623265346631343561666263346136326534353634613638336339
36356131633464343565626539653738396334653564303563306131316539343438636265663736
30306134333431366530666131616265336637396237626436326462363062313861633565346264
34613432343938636232316466396565323038613931616361643561613862333638636163623532
65393137636636303830376535396238336433626266313136616135323937303033396230303265
34666461356339373061626434613366303664636337373362326237633834366263393938663963
35363565643330313839653935393336663338316635636333353963333334616661393065373935
36366265653835343363636237356433366164636664346633393239316539383565663561316136
39623162363961623239346132623933303864373664343333393466343564393762646365346562
65646563343865323261366335663765373364336266376431373536656366343539656466363939
33303732383034346465633838623864623130653334666436623837636234356361663562306666
31316166656638613137636435383733363365346230626130633564386433623931396264383265
62396435376634383863663136343731386536326461643932303263656636656139316661613134
33663666636664306539313537616261363933653037616364643637396234646431356262653566
34336534306632373034623534363765376538323333386137626638363430633538353030343137
66353235353731646333623562363065333533323734373765383562633337323962306430353635
37333664643636643037393638316537386164613136393732653061616134316534383365303839
33383731616365613031646534343733363037366235383131643564366239626563633132306163
31306335323664303634333432666230626462393261393761646434616233666436326432373466
32306164373936363937316530313564313262343164366539396135353639666138616364636239
34306432653335653837383134623665663062663339633263366131633836326137333932313730
38336638626262636535306235383437316333646362383265623931616235363034666231656239
39396337633932356335386365313066363863376166303335396364376638303430336436323038
63666361636630393562316465346334393963356130353564633437663731656234643264386137
37386237646261656364643031326166313539663938363532643131633332306331623538353036
35356136356234616330613636356137393665303065653763386563303938373162656438373333
65393262613338363661646532306435343334343035363034636131366264373436633436333366
33303531326433643866653961643839336464613036623961353661313534396334313533633963
30386337653237386466383531623936306666326633393239353533396663393032626331323365
33353433663663303331353633353634333164393065336231633930656335666538663464353837
35353262623637303731303932356432313337643139383264336230383331323966393261376539
3133