From d378ae29ddfe9ed77c2002be683b07c74b45daf0 Mon Sep 17 00:00:00 2001 From: vados-dev Date: Wed, 1 Jul 2026 01:20:03 +0300 Subject: [PATCH] Backup for MikroNUC created successfully at Jul 01 01:20:03. --- .../20260701/20260701004003-Config.rsc | 3692 ++++++++++++ .../20260701/20260701010002-Config.rsc | 3693 ++++++++++++ MikroMaster/tmp/Diff-Config.rsc | 12 +- .../20260701/20260701012001-Binary.backup | Bin 0 -> 383478 bytes MikroNUC/20260701/20260701012001-Config.rsc | 5362 +++++++++++++++++ .../20260701/20260701012001-Diff-Config.rsc | 365 ++ 6 files changed, 13120 insertions(+), 4 deletions(-) create mode 100644 MikroMaster/20260701/20260701004003-Config.rsc create mode 100644 MikroMaster/20260701/20260701010002-Config.rsc create mode 100644 MikroNUC/20260701/20260701012001-Binary.backup create mode 100644 MikroNUC/20260701/20260701012001-Config.rsc create mode 100644 MikroNUC/history/20260701/20260701012001-Diff-Config.rsc diff --git a/MikroMaster/20260701/20260701004003-Config.rsc b/MikroMaster/20260701/20260701004003-Config.rsc new file mode 100644 index 0000000..b6d1ef8 --- /dev/null +++ b/MikroMaster/20260701/20260701004003-Config.rsc @@ -0,0 +1,3692 @@ +# 2026-07-01 00:40:10 by RouterOS 7.23.1 +# software id = A8L5-07YF +# +# model = RB952Ui-5ac2nD +# serial number = D3D50CEDCD38 +/interface bridge +add admin-mac=48:8F:5A:8E:1A:BF auto-mac=no dhcpv6-agent-circuit-id=\ + "\$(INTERFACE):\$(VID)" dhcpv6-agent-remote-id="\$(BRIDGEMAC)" name=\ + Bridge-LAN port-cost-mode=short +/interface ethernet +set [ find default-name=ether1 ] comment="WAN - Unet" loop-protect=off name=\ + "ether1 - Unet" rx-flow-control=auto tx-flow-control=auto +set [ find default-name=ether2 ] comment=LAN-2 +set [ find default-name=ether3 ] advertise="10M-baseT-half,10M-baseT-full,100M\ + -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-3 +set [ find default-name=ether4 ] comment=LAN-4 +set [ find default-name=ether5 ] advertise="10M-baseT-half,10M-baseT-full,100M\ + -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-5 \ + loop-protect=on poe-out=off rx-flow-control=auto tx-flow-control=auto +/interface wireless +# managed by CAPsMAN +# channel: 2442/20-Ce/gn(18dBm), SSID: vados, local forwarding +set [ find default-name=wlan1 ] country=belarus disabled=no mode=ap-bridge \ + ssid=vados wireless-protocol=802.11 +# managed by CAPsMAN +# channel: 5260/20-Ceee/ac/DP(18dBm), SSID: vados5g, local forwarding +set [ find default-name=wlan2 ] country=belarus disabled=no mode=ap-bridge \ + ssid=vados5g wireless-protocol=802.11 +/interface wireguard +add comment=WG listen-port=13231 mtu=1320 name=WG +/interface list +add include=static name=LAN +add name=Internet +add include=Internet name=WAN +/interface wireless security-profiles +set [ find default=yes ] authentication-types=wpa-psk,wpa2-psk mode=\ + dynamic-keys supplicant-identity=MikroTik +/iot wiliot servers +set *1 address=mqtt.us-east-2.prod.wiliot.cloud name="Wiliot US East" +/ip dhcp-server option +add code=12 name=HostName +add code=119 force=yes name=domain-search-list value="0x03'WORKGROUP'0x00" +/ip dhcp-server option sets +add name=HP1505n options=HostName +add name=StartLife1 options=HostName +add name=amsterDev options=HostName +add name=MiTV options=HostName +add name=miller options=HostName +add name=amster options=HostName +add name=garage options=HostName +add name=domain-search-set options=domain-search-list +add name=VADOS-LEN options=HostName +add name=VADOS-NUC options=HostName +add name=MikroNUC options=HostName +add name=master options=HostName +add name=MikroYellow options=HostName +add name="=\"Client ID\"" options=HostName +add name=iVados options=HostName +/ip dns forwarders +add dns-servers=1.0.0.1,1.1.1.1 name=blsp.at verify-doh-cert=no +add comment=Kra dns-servers=1.0.0.1,1.1.1.1 name=slon2.to verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +/ip ipsec proposal +set [ find default=yes ] disabled=yes +/ip pool +add name=dhcp ranges=10.30.30.83-10.30.30.254 +/ip dhcp-server +add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ + dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ + name=masterDHCP server-address=10.30.30.81 +/ip smb users +set [ find default=yes ] disabled=yes +add disabled=yes name=vados +/ipv6 dhcp-client option +add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +add code=12 name=HostName value="\$(HOSTNAME)" +add code=61 name=DUID value=0x00030001488f5a8e1abc +add code=61 name=clientid +/ipv6 dhcp-server option +add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +add code=12 name=HostName value="\$(HOSTNAME)" +add code=61 name=CLIENT_DUID +add code=61 name=CLIENT_MAC +#error exporting "/ppp/profile" (timeout) +/routing bgp template +set default disabled=no output.network=bgp-networks +/routing table +add disabled=no fib name=To-VPN +/system logging action +add email-start-tls=yes email-to=vados@vados.ru name=email target=email +/system script +add dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n\r\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.86.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.86.pub\";\ + \n\r\ + \n#:local Script AM-setup\ + \n;\r\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\r\ + \n\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n\r\ + \n#\ + \n\r\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ + \n\r\ + \n#\r\ + \n\ + \n#root.mnuc.backuper\ + \n\ + \n\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@10\ + .30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\r\ + \n\ + \n#:local Script AM-GlobalConfig;\ + \n\r\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\r\ + \n\ + \n#/usb1/mikro_bak_rsa.pub\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n\r\ + \n\r\ + \n#\ + \n:global MkDir;\ + \n\r\ + \n\ + \n#:local FetchFile Binary.backup\ + \n:local localDir \"\";\ + \n\ + \n\r\ + \n#\$MkDir \$localDir;\r\ + \n\ + \n#\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);\r\ + \n" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix (a);\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n#:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\";\r\ + \n#:global EmailGeneralCc \"\";\r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass (a); #{\r\ + \n# \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass (a); # {\r\ + \n# \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ + owner=AM-GlobalFunc policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GglobalFunc\r\ + \n# Script comment: Global functions\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n:local ExitOK false;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n#:global checkRunJob \$SriptName;\r\ + \n#:global fixCRLF;\r\ + \n#:if (\$fixCRLF != false) do={\r\ + \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ + ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ + }\r\ + \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ + et \$fixScript source ] ] \$fixScript};};\r\ + \n#}\r\ + \n:global GlobalFuncReady false;\r\ + \n\r\ + \n# Git commit id & info, expected configuration version\r\ + \n:global CommitId \"main/727/203f86a6\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 13:30:05 29.06.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 140;\r\ + \n\r\ + \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ + \n\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global IdentityShort [:pick \$Identity 0 18];\r\ + \n\r\ + \n:global devBoardName [/system/resource/get board-name];\r\ + \n:global devMode [/system/device-mode/get mode];\r\ + \n:global devCurArch [/system/resource/get architecture-name];\r\ + \n:global devCurVersion [/system/resource/get version];\r\ + \n\r\ + \n# Variables defined in AM-GlobalConfig.rsc\r\ + \n:global TerminalColorOutput;\r\ + \n:global CommentsInScripts;\r\ + \n:global DetectIpAddrDefault;\r\ + \n:global DetectIpAddrFallback;\r\ + \n:global updateChannel;\r\ + \n:global Domain;\r\ + \n:global EmailGeneralTo;\r\ + \n:global BackupAndUpdateMode;\r\ + \n\r\ + \n# Single functions, without nested functions.\r\ + \n:global MiniDateTimeStamp;\r\ + \n:global MicroDateTimeStamp;\r\ + \n\r\ + \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ + \n:global LogPrint;\r\ + \n\r\ + \n# DeviceInfo and Updates\r\ + \n:global IsCheckUpdates;\r\ + \n:global WaitCheckUpdates;\r\ + \n:global GetPubIp;\r\ + \n\r\ + \n:global GetArrDeviceInfo;\r\ + \n:global WaitArrDeviceInfo;\r\ + \n\r\ + \n:global devModel;\r\ + \n:global devRunningMode;\r\ + \n\r\ + \n:global devRbRevision;\r\ + \n:global devRbSerialNumber;\r\ + \n:global devRbVerAvail;\r\ + \n\r\ + \n:global runningChannelVersion;\r\ + \n:global runningChannel;\r\ + \n:global runningVersion;\r\ + \n\r\ + \n:global devBuildTime;\r\ + \n:global ROsVerAvail;\r\ + \n:global PkgUpdStatus;\r\ + \n:global currentUpdateChannel;\r\ + \n\r\ + \n:global ScriptInstallUpdate;\r\ + \n\r\ + \n:global DeviceInfo;\r\ + \n\r\ + \n:global OldMode;\r\ + \n\r\ + \n:global ParseKeyValueStore;\r\ + \n:global RandomDelay;\r\ + \n:global GetRandomNumber;\r\ + \n:global EscapeForRegEx;\r\ + \n:global CharacterMultiply;\r\ + \n:global CharacterReplace;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n\r\ + \n:global CommitBrief;\r\ + \n\r\ + \n:global EitherOr;\r\ + \n:global FormatLine;\r\ + \n:global GetRandom20CharAlNum;\r\ + \n:global GetRandom20CharHex;\r\ + \n:global GetRandomNumber;\r\ + \n:global Grep;\r\ + \n:global IfThenElse;\r\ + \n:global MAX;\r\ + \n:global MIN;\r\ + \n:global HumanReadableNum;\r\ + \n\r\ + \n:global IsFullyConnected;\r\ + \n:global IsDNSResolving;\r\ + \n:global IsTimeSync;\r\ + \n:global IsTimeSyncCached;\r\ + \n:global IsTimeSyncResetNtp;\r\ + \n\r\ + \n:global MkDir;\r\ + \n:global RmDir;\r\ + \n:global RmFile;\r\ + \n:global FileGet;\r\ + \n:global Unix2Dos;\r\ + \n:global UrlEncode;\r\ + \n:global WaitForFile;\r\ + \n:global ScriptLock;\r\ + \n:global SendTelegram;\r\ + \n:global NotificationFunctions;\r\ + \n:global SendNotification;\r\ + \n:global SendNotification2;\r\ + \n:global SymbolForNotification;\r\ + \n:global SymbolByUnicodeName;\r\ + \n:global ValidateSyntax;\r\ + \n:global CheckSumsVerify;\r\ + \n:global GlobalConfChanges;\r\ + \n:global GlobalConfMigration;\r\ + \n:global VersionToNum;\r\ + \n:global RequiredRouterOS;\r\ + \n:global ExitError;\r\ + \n:global ExitOnError;\r\ + \n\r\ + \n:global FetchHugeFiles;\r\ + \n:global FetchUserAgentStr;\r\ + \n:global FileExists;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n\r\ + \n:global InspectVar;\r\ + \n:global InspectVarRet;\r\ + \n:global ParseCustom;\r\ + \n\r\ + \n:set IsCheckUpdates do={\r\ + \n :local isInfo [:tobool \$1];\r\ + \n :global updateChannel;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :log info (\$0 . \" \\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ + el) do={\r\ + \n :retry command={/system/package/update set channel=\$updateChannel} \ + \_delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" Set updates channel to: \$updateChannel\");\r\ + \n }\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set currentUpdateChannel \$Channel;\r\ + \n :log info (\$0 . \" Update Channel: \" . \$Channel . \".\");\r\ + \n :local StatusPkg \"undefined\";\r\ + \n :log info (\$0 . \" Checking for updates...\");\r\ + \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ + dates without-paging as-value]->\"status\")} \\\r\ + \n delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" \\\$StatusPkg = \" . \$StatusPkg);\r\ + \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ + s true; } else={ :set PkgUpdStatus false; }\r\ + \n :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ + ] ];\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ + kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ + \n :return true;\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitCheckUpdates do={\r\ + \n :global IsCheckUpdates;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :local Status \"\";\r\ + \n :local Update;\r\ + \n :local WaitCount 0;\r\ + \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ + \") && \$WaitCount < 60) do={\r\ + \n :delay 1s;\r\ + \n :set WaitCount (\$WaitCount + 1);\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n }\r\ + \n :set Update [ /system/package/update/get ];\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ + \n :set PkgUpdStatus true;\r\ + \n } else={\r\ + \n :set PkgUpdStatus false;\r\ + \n }\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ + \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ + do={\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set WaitArrDeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ + \n :delay 1s;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetArrDeviceInfo do={\r\ + \n :global LogPrint;\r\ + \n :global arrDeviceInfo;\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devBuildTime;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :local DeviceInfo;\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ + \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ + \n :local RouterBoard;\r\ + \n :local IsRouterBoard false;\r\ + \n :local RunningMode \"\";\r\ + \n\r\ + \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ + \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ + \n :set runningChannelVersion \$VersionString;\r\ + \n :set runningVersion \$VersionString;\r\ + \n :set runningChannel \"\";\r\ + \n\r\ + \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ + {\r\ + \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ + \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ + len \$VersionString ] ];\r\ + \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ + \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ + \r\ + \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :do {\r\ + \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ + \n# :set RouterBoard [ /system/routerboard/get ];\r\ + \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ + \n :set IsRouterBoard true;\r\ + \n }\r\ + \n } on-error={}\r\ + \n }\r\ + \n\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get mode ];\r\ + \n } on-error={\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get running ];\r\ + \n } on-error={\r\ + \n :set RunningMode \"\";\r\ + \n }\r\ + \n }\r\ + \n :set devRunning \$RunningMode;\r\ + \n\r\ + \n :if (\$IsRouterBoard = true) do={\r\ + \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ + \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ + \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ + ];\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n :set devRbRevision \"\";\r\ + \n :set devRbSerialNumber \"\";\r\ + \n }\r\ + \n\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n\r\ + \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ + \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ + \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ + \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ + \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ + \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ + \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ + \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ + ion;\r\ + \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ + \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ + \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ + \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ + current-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ + upgrade-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ + \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ + alled-version\") ];\r\ + \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ + \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ + ) ];\r\ + \n\r\ + \n :set arrDeviceInfo \$DeviceInfo;\r\ + \n :return \$DeviceInfo;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :global CommitBrief;\r\ + \n\r\ + \n :local License [/system/license/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Info [ \$GetArrDeviceInfo ];\r\ + \n\r\ + \n :if ([ :typeof \$Info ] != \"array\") do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :return ( \\\r\ + \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Location\" (\$Snmp->\"location\") ] . \"\\n\") ]\ + \_. \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Contact\" (\$Snmp->\"contact\") ] . \"\\n\") ] .\ + \_\\\r\ + \n \"Hardware:\\n\" . \\\r\ + \n [ \$FormatLine \" Board\" (\$Info->\"board-name\") ] . \"\\n\" . \ + \\\r\ + \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ + n\" . \\\r\ + \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ + \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ + \\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ + \")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ + \\n\" . \\\r\ + \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ + \_\"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ + \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ + \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ + \"\\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ + \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ + \_\"\\n\") ] . \\\r\ + \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ + \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ + ) \\\r\ + \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ + \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS-Scripts:\\n\" . \\\r\ + \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ + \n}\r\ + \n\r\ + \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ + tionFunctions ({})}\r\ + \n\r\ + \n:set GetRandom20CharAlNum do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ + FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ + \n}\r\ + \n\r\ + \n:set GetRandom20CharHex do={:global EitherOr; :return [ :rndstr length=[\ + \_\$EitherOr [ :tonum \$1 ] 20 ] from=\"0123456789abcdef\" ]; }\r\ + \n:set GetRandomNumber do={:global EitherOr; :return [ :rndnum from=0 to=[\ + \_\$EitherOr [ :tonum \$1 ] 4294967295 ] ]; }\r\ + \n\r\ + \n:global checkRunJob;\r\ + \n:set checkRunJob do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLock; \r\ + \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ + \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ + :set Job [ /system/script/job/get \$Job ];\r\ + \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ + stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ + \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ + lse; \r\ + \n}\r\ + \n\r\ + \n:set InspectVar do={\r\ + \n :global InspectVarRet;\r\ + \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ + \n}\r\ + \n\r\ + \n:set CommitBrief do={\r\ + \n :global CommitId;\r\ + \n :global CommitInfo;\r\ + \n :if (\$CommitId = \"unknown\") do={\r\ + \n :return \"unknown\";\r\ + \n }\r\ + \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\r\ + \n}\r\ + \n\r\ + \n:set InspectVarRet do={\r\ + \n :local Input \$1;\r\ + \n :local Level (0 + [ :tonum \$2 ]);\r\ + \n :global CharacterReplace;\r\ + \n :global IfThenElse;\r\ + \n :global InspectVarRet;\r\ + \n :local IndentReturn do={\r\ + \n :local Prefix [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Level [ :tonum \$3 ];\r\ + \n :global CharacterMultiply;\r\ + \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ + fix . \"-> \" . \$Value);\r\ + \n }\r\ + \n :local TypeOf [ :typeof \$Input ];\r\ + \n :local Len [ :len \$Input ];\r\ + \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ + \n :if (\$TypeOf = \"array\") do={\r\ + \n :foreach Key,Value in=\$Input do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ + \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ + \n }\r\ + \n } else={\r\ + \n :if (\$TypeOf = \"str\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ + \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ + \n }\r\ + \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ + \n }\r\ + \n }\r\ + \n :if (\$TypeOf != \"nothing\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ + \_\\\r\ + \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ + \n }\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set GetPubIp do={\r\ + \n :global DetectIpAddrDefault;\r\ + \n :global DetectIpAddrFallback;\r\ + \n\r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n :local JobName [ :jobname ];\r\ + \n\r\ + \n :do {\r\ + \n :log debug (\$0 . \" Trying to detect public IP using default serv\ + ice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=50ms max=5 on-error={:log error (\$JobName . \" Failed to \ + detect public IP using default service: \" . \$Url . \".\")}\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed to detect public IP using default serv\ + ice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ + vice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=200ms max=5 on-error={:log error (\$JobName . \" Failed to\ + \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ + \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ + {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\r\ + \n :return \$PubIpAddr;\r\ + \n}\r\ + \n\r\ + \n:set FormatLine do={\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Indent [ :tonum \$3 ];\r\ + \n :local Spaces;\r\ + \n :local Return \"\";\r\ + \n :global CharacterMultiply;\r\ + \n :global EitherOr;\r\ + \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ + \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ + \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ + \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ + n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ + \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ + \$Return ]) ] . \$Value)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ParseCustom do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ + \n :local End [ :tostr \$3 ];\r\ + \n :local Num [ :tonum \$4 ];\r\ + \n :local Return;\r\ + \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ + \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ + \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ + lse={\r\ + \n :set End [:find \$rest \$End];\r\ + \n :set Return [:pick \$rest 0 \$End];\r\ + \n }\r\ + \n:return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set LogPrint do={\r\ + \n :local Severity [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Message [ :tostr \$3 ];\r\ + \n :global PrintDebug;\r\ + \n :global PrintDebugOverride;\r\ + \n :global EitherOr;\r\ + \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ + ];\r\ + \n :local PrintSeverity do={\r\ + \n :global TerminalColorOutput;\r\ + \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ + \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ + \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ + \n}\r\ + \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ + \r\ + \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ + \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ + \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ + \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ + \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ + \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ + erity \$Severity ] . \": \" . \$Message)}\r\ + \n}\r\ + \n\r\ + \n:set CertificateAvailable do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :local UseFor [ :tostr \$2 ];\r\ + \n\r\ + \n :global CertificateDownload;\r\ + \n :global ParseKeyValueStore;\r\ + \n\r\ + \n :if ([ :len \$UseFor ] = 0) do={\r\ + \n :log warning (\$0 . \"The intended use is undefined!\");\r\ + \n :set UseFor \"undefined\";\r\ + \n }\r\ + \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ + \n [ /certificate/settings/get crl-download ] = true && \\\r\ + \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ + \n :log warning (\$0 . \"This system has low free flash space but \" . \ + \\\r\ + \n \"is configured to download certificate CRLs to system!\");\r\ + \n }\r\ + \n :if ([ :len \$CommonName ] = 0) do={\r\ + \n :log warning (\$0 . \"No CommonName given!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ + \r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ + \_] ] > 0) do={\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ + \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n :log info (\$0 . \"There are \" . \$CertCount . \" Certificates with\ + \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ + e ] ];\r\ + \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ + ertVal->\"skid\")) do={\r\ + \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ + \_= 0) do={\r\ + \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ + >\"CN\");\r\ + \n :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ + is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ + \") ] ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateDownload do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :global ScriptUpdatesBaseUrl;\r\ + \n :global ScriptUpdatesUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ + \r\ + \n \"CommonName '\" . \$CommonName . \"'.\");\r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ + -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ + sUrlSuffix) \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0 && \\\r\ + \n !(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" \ + || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \ + \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ + \r\ + \n [ :len [ /certificate/builtin/find where common-name=\"ISRG\ + \_Root X1\" ] ] > 0)) do={\r\ + \n :log error (\$0 . \" Required certificate is not available.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ + er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ + n ({ \$CommonName }) ] \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n :if ([ /file/get \$FileName size ] = 0) do={\r\ + \n \$RmFile \$FileName;\r\ + \n :error false;\r\ + \n }\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ + e . \"' still unavailable!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ + \"_[0-9]+\\\$\") ] do={\r\ + \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateNameByCN do={\r\ + \n :local Match [ :tostr \$1 ];\r\ + \n :global CleanName;\r\ + \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ + rint=\$Match or name=\$Match) ]->0);\r\ + \n :if ([ :len \$Cert ] = 0) do={\r\ + \n :log warning (\$0 .\" No matching certificate found.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ + \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FileExists do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local Type [ :tostr \$2 ];\r\ + \n :global FileGet;\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={ :return false; }\r\ + \n :if ([ :len (\$FileVal->\"size\") ] = 0) do={ :return false; }\r\ + \n :if ([ :len \$Type ] = 0 || \$FileVal->\"type\" = \$Type) do={ :return\ + \_true; }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set Grep do={\r\ + \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ + \n :local Pattern [ :tostr \$2 ];\r\ + \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ + }\r\ + \n :do {\r\ + \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ + \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ + \$Line}\r\ + \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ + Input ] ];\r\ + \n } while=([ :len \$Input ] > 0);\r\ + \n :return [];\r\ + \n}\r\ + \n\r\ + \n:set HumanReadableNum do={\r\ + \n :local Input [ :tonum \$1 ];\r\ + \n :local Base [ :tonum \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global IfThenElse;\r\ + \n :local Prefix \"kMGTPE\";\r\ + \n :local Pow 1;\r\ + \n :set Base [ \$EitherOr \$Base 1024 ];\r\ + \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ + \n :if (\$Input < \$Base) do={:return \$Input}\r\ + \n :for I from=0 to=[ :len \$Prefix ] do={\r\ + \n :set Pow (\$Pow * \$Base);\r\ + \n :if (\$Input / \$Base < \$Pow) do={\r\ + \n :set Prefix [ :pick \$Prefix \$I ];\r\ + \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ + \n :local Tmp2 (\$Tmp1 / 100);\r\ + \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ + \n :return (\$Tmp2 . \".\" . \\\r\ + \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ + 2 ] + 1) ] . \\\r\ + \n \$Prefix . \$Bin);\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set CleanFilePath do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CharacterReplace;\r\ + \n :while (\$Path ~ \"//\") do={ :set \$Path [ \$CharacterReplace \$Path \ + \"//\" \"/\" ]; }\r\ + \n :if ([ :pick \$Path 0 ] = \"/\") do={ :set Path [ :pick \$Path 1 [ :le\ + n \$Path ] ]; }\r\ + \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={ :set Path [ \ + :pick \$Path 0 ([ :len \$Path ] - 1) ]; }\r\ + \n :return \$Path;\r\ + \n}\r\ + \n\r\ + \n:set CleanName do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Return \"\";\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ + stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ + \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ + \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ + ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ + \n };\r\ + \n :set Return (\$Return . \$Char)};\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set RandomDelay do={\r\ + \n :local Time [ :tonum \$1 ];\r\ + \n :local Unit [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global GetRandomNumber;\r\ + \n :global MAX;\r\ + \n :if (\$Time = 0) do={:return false}\r\ + \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ + [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ + \n}\r\ + \n\r\ + \n:set EscapeForRegEx do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ExitError do={\r\ + \n :local ExitOK [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Error [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :if (\$ExitOK = \"false\") do={\r\ + \n :log error (\$Name [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\$\") \ + \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ + ror\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ + \$Error) \".\" ]);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set ExitOnError do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :local Error [ :tostr \$2 ];\r\ + \n :global IfThenElse;\r\ + \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ + \\\$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ + r\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ + rror) \".\" ]);\r\ + \n}\r\ + \n\r\ + \n:set MiniDateTimeStamp do={\r\ + \n :local mikro [ :tobool \$1 ];\r\ + \n /system/clock;\r\ + \n :local vdate [get date];\r\ + \n :local vtime [get time];\r\ + \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ + \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ + \n :local M [:tonum \$MM];\r\ + \n :if (\$vdate ~ \".../../....\") do={\r\ + \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ + \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ + PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ + \n :if (\$M>12) do={:set M (\$M - 12)}\r\ + \n :set MM [:pick (100 + \$M) 1 3];\r\ + \n }\r\ + \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ + \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ + \n :local HH [:pick \$vtime 0 2];\r\ + \n :local mm [:pick \$vtime 3 5];\r\ + \n :local ss [:pick \$vtime 6 8];\r\ + \n :local Return;\r\ + \n :if (\$mikro = true) do={\r\ + \n :set Return ([:pick \$yyyy 2 4] . [:pick \$dd 0 1] . [:pick \$HH 0\ + \_1] . [:pick \$mm 3 4] . [:pick \$ss 6 7]);\r\ + \n } else={\r\ + \n :set Return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ + \r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set WaitForFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local WaitTime [ :totime \$2 ];\r\ + \n :global CleanFilePath;\r\ + \n :global EitherOr;\r\ + \n :global MAX;\r\ + \n :set FileName [ \$CleanFilePath \$FileName ];\r\ + \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } delay=\$Delay max=10;\r\ + \n } on-error={ }\r\ + \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ + \n :do {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } on-error={ }\r\ + \n :delay \$Delay;\r\ + \n :set Delay (\$Delay * 3 / 2);\r\ + \n }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set FileGet do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global WaitForFile;\r\ + \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileVal false;\r\ + \n :do {\r\ + \n :set FileVal [ /file/get \$FileName ];\r\ + \n } on-error={ }\r\ + \n :return \$FileVal;\r\ + \n}\r\ + \n\r\ + \n:set RmDir do={\r\ + \n :local DirName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n };\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ + \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ + ory.\");\r\ + \n :return false;\r\ + \n };\r\ + \n :onerror Err {\r\ + \n /file/remove \$DirName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n };\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set RmFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ + \_. \$Err); :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MkDir do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CleanFilePath;\r\ + \n :global FileGet;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :local MkTmpfs do={\r\ + \n :global WaitForFile;\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ + \n \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ + /get total-memory ] / 3);\r\ + \n \$WaitForFile \"tmpfs\";\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Creating disk of type tmpfs failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :set Path [ \$CleanFilePath \$Path ];\r\ + \n :if (\$Path = \"\") do={\r\ + \n :return true;\r\ + \n }\r\ + \n :log debug (\$0 . \" Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n :log debug (\$0 . \" ... which already exists.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=\$Path;\r\ + \n \$WaitForFile \$Path;\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Making directory '\" . \$Path . \"' failed: \ + \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set CharacterReplace do={\r\ + \n :local String [ :tostr \$1 ];\r\ + \n :local ReplaceFrom [ :tostr \$2 ];\r\ + \n :local ReplaceWith [ :tostr \$3 ];\r\ + \n :local Return \"\";\r\ + \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ + \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ + \r\ + \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ + \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ + \r\ + \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ + \_\$String ] ];\r\ + \n }\r\ + \n :return (\$Return . \$String);\r\ + \n}\r\ + \n\r\ + \n:set IfThenElse do={\r\ + \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ + \$2};\r\ + \n :return \$3;\r\ + \n}\r\ + \n\r\ + \n:set EitherOr do={\r\ + \n :global IfThenElse;\r\ + \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ + \$1 \$2 ]}\r\ + \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ + \_\$1 \$2 ]}\r\ + \n# this works for boolean values, literal ones with parentheses\r\ + \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ + \n}\r\ + \n\r\ + \n:set ParseKeyValueStore do={\r\ + \n :local Source \$1;\r\ + \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ + \n :do {\r\ + \n :return [ :deserialize from=json \$Source ];\r\ + \n } on-error={ }\r\ + \n } \r\ + \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ + }\r\ + \n :local Result ({});\r\ + \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ + \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ + \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ + \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ + \_:len \$KeyValue ] ];\r\ + \n :if (\$Value=\"true\") do={:set Value true}\r\ + \n :if (\$Value=\"false\") do={:set Value false}\r\ + \n :set (\$Result->\$Key) \$Value;\r\ + \n } else={:set (\$Result->\$KeyValue) true}\r\ + \n }\r\ + \n :return \$Result;\r\ + \n}\r\ + \n:set RequiredRouterOS do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :local Required [ :tostr \$2 ];\r\ + \n :local Warn [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ + e/update/get installed-version ] ]) do={\r\ + \n :if (\$Warn = \"true\") do={\r\ + \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ + 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ + \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ + es RouterOS \" . \$Required . \". Please update!\");\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :global LogPrint;\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set VersionToNum do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Multi 0x1000000;\r\ + \n :local Return 0;\r\ + \n :global CharacterReplace;\r\ + \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ + \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ + \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ + \r\ + \n }\r\ + \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ + \n :local Num [ :tonum \$Value ];\r\ + \n :if (\$Multi = 0x100) do={\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={\r\ + \n :set Return (\$Return + 0xff00);\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n } else={\r\ + \n :if (\$Value = \"zero\") do={ }\r\ + \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ + }\r\ + \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ + \r\ + \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ + \n }\r\ + \n }\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ + lue * \$Multi)); }\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ScriptLock do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local WaitMax [ :totime \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global ScriptLockOrder;\r\ + \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ + \n :set ScriptLockOrder ({});\r\ + \n }\r\ + \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :local JobCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ + \r\ + \n }\r\ + \n :local TicketCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :local Count 0;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ + + 1)}\r\ + \n }\r\ + \n :return \$Count;\r\ + \n }\r\ + \n :local IsFirstTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Check [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if (\$Ticket = \$Check) do={:return true}\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ + o={:return false}\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :local AddTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Add [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :while (true) do={\r\ + \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ + \n :delay 10ms;\r\ + \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ + e}\r\ + \n }\r\ + \n }\r\ + \n :local RemoveTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Remove [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ + \n :delay 10ms;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :local CleanupTickets do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ + \n }\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ + \n :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ + ist!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$JobCount \$Script ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ + \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ + t . \"', resetting!\");\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n /system/script/job/remove [ find where script=\$Script ];\r\ + \n }\r\ + \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ + \n \$AddTicket \$Script \$MyTicket;\r\ + \n :local WaitInterval (\$WaitMax / 20);\r\ + \n :local WaitTime \$WaitMax;\r\ + \n :while (\$WaitTime > 0 && \\\r\ + \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ + \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ + \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ + \n :delay \$WaitInterval;\r\ + \n }\r\ + \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ + \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$CleanupTickets \$Script;\r\ + \n :return true;\r\ + \n }\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ + once\" . \\\r\ + \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ + \_lock\" \"\" ] . \"...\");\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set SendNotification do={ :onerror Err {\r\ + \n :global SendNotification2;\r\ + \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ + \_silent=\$4 });\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n\r\ + \n:set SendNotification2 do={\r\ + \n :local Notification \$1;\r\ + \n :global NotificationFunctions;\r\ + \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ + \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ + ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\r\ + \n :global SymbolsExtra;\r\ + \n :local Symbols ({\r\ + \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ + \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ + \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ + \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ + \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ + \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ + \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ + \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ + \n \"cloud\"=\"\\E2\\98\\81\";\r\ + \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ + \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ + \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ + \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ + \n \"gear\"=\"\\E2\\9A\\99\";\r\ + \n \"heart\"=\"\\E2\\99\\A5\";\r\ + \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ + \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ + \n \"information\"=\"\\E2\\84\\B9\";\r\ + \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ + \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ + \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ + \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ + \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ + \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ + \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ + \n \"scissors\"=\"\\E2\\9C\\82\";\r\ + \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ + \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ + \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ + \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ + \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ + \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ + \n \"star\"=\"\\E2\\AD\\90\";\r\ + \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ + \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ + \n }, \$SymbolsExtra);\r\ + \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ + \n :local Special {\r\ + \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ + \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ + \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ + \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ + \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ + \n :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ + '!\");\r\ + \n :return \"\";\r\ + \n }\r\ + \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ + me) ] . \"\\EF\\B8\\8F\");\r\ + \n}\r\ + \n\r\ + \n:set SymbolForNotification do={\r\ + \n :global NotificationsWithSymbols;\r\ + \n :global SymbolByUnicodeName;\r\ + \n :global IfThenElse;\r\ + \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ + \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ + \n :local Return \"\";\r\ + \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ + mbolByUnicodeName \$Symbol ])}\r\ + \n :return (\$Return . \" \");\r\ + \n}\r\ + \n\r\ + \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ + \n:set UrlEncode do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ + \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ + %24\"; \"%25\"; \"%26\"; \"%27\";\r\ + \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ + \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ + \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ + \"%7C\"; \"%7D\"; \"%7E\" };\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :local Replace [ :find \$Chars \$Char ];\r\ + \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ + ce)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set IsDNSResolving do={\r\ + \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsFullyConnected do={\r\ + \n :global IsDNSResolving;\r\ + \n :global IsTimeSync;\r\ + \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ + \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsTimeSync do={\r\ + \n :global IsTimeSyncCached;\r\ + \n :global IsTimeSyncResetNtp;\r\ + \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ + \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ + \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :local Uptime [ /system/resource/get uptime ];\r\ + \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n }\r\ + \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ + \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ + ;\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n /system/ntp/client/set enabled=no;\r\ + \n :delay 20ms;\r\ + \n /system/ntp/client/set enabled=yes;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ + \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ + \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ + ee license and x86.\";\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ + \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set FetchHugeFiles do={\r\ + \n :local ScriptName [ :tostr \$1 ];\r\ + \n :local Url [ :tostr \$2 ];\r\ + \n :local CheckCert [ :tostr \$3 ];\r\ + \n\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ + ithout-crl\" ];\r\ + \n\r\ + \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ + \n :if ([ \$MkDir \$DirName ] = false) do={\r\ + \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ + \$GetRandom20CharAlNum ]);\r\ + \n :onerror Err {\r\ + \n /tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName \ + \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ + lue;\r\ + \n } do={\r\ + \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ + \n \$RmFile \$FileName;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$Url . \" - \"\ + \_. \$Err);\r\ + \n \$RmDir \$DirName;\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ + \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$Url . \" did\ + \_not show up.\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileSize [ /file/get \$FileName size ];\r\ + \n :local Return \"\";\r\ + \n :local VarSize 0;\r\ + \n :while (\$VarSize != \$FileSize) do={\r\ + \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ + 768 file=\$FileName as-value ]->\"data\"));\r\ + \n :set FileSize [ /file/get \$FileName size ];\r\ + \n :set VarSize [ :len \$Return ];\r\ + \n :if (\$VarSize > \$FileSize) do={\r\ + \n :delay 100ms;\r\ + \n }\r\ + \n }\r\ + \n \$RmDir \$DirName;\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global CommitBrief;\r\ + \n :global IfThenElse;\r\ + \n :local Resource [ /system/resource/get ];\r\ + \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ + \_\$Resource->\"architecture-name\" . \\\r\ + \n \" \" . \$Caller . \"/Fetch (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ + CommitBrief ] . \")\");\r\ + \n}\r\ + \n\r\ + \n:set ScriptInstallUpdate do={ :onerror Err {\r\ + \n :local Scripts [ :toarray \$1 ];\r\ + \n :local NewComment [ :tostr \$2 ];\r\ + \n :global InitSetup;\r\ + \n\r\ + \n :global CommitId;\r\ + \n :global ScriptUpdatesCRLF;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global CertificateAvailable;\r\ + \n :global CheckSumsVerify;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SumsDirAndFileName;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global EitherOr;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global Grep;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global RequiredRouterOS;\r\ + \n :global SendNotification2;\r\ + \n :global SymbolForNotification;\r\ + \n :global ValidateSyntax;\r\ + \n :global CommentsInScripts;\r\ + \n\r\ + \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ + hout.\");\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ + \r\ + \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ + \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ + Vados\\n\" comment=\$NewComment;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local CommitIdBefore \$CommitId;\r\ + \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ + \n :local ReloadGlobal false;\r\ + \n :local DeviceMode [ /system/device-mode/get ];\r\ + \n\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSums ({});\r\ + \n :do {\r\ + \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ + iptsUrlSuffix);\r\ + \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ + \r\ + \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ + ficate=yes-without-crl \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ + =user as-value ]->\"data\") ];\r\ + \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ + s\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ + ];\r\ + \n :local SourceNew;\r\ + \n\r\ + \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ + \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ + \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ + \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ + \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ + iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ + \"'!\");\r\ + \n }\r\ + \n }\r\ + \n :do {\r\ + \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ + \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ + e\" . \"', as requested.\");\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ + ptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ + rce\") ] ] = \$CheckSum) do={\r\ + \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ + >\"name\" . \"' matches, ignoring.\");\r\ + \n :error true;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ + \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ + fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ + ng without.\");\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ + lScriptsUrl ];\r\ + \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ + lobalScriptsUrlSuffix ];\r\ + \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ + Suffix);\r\ + \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ + name\") . \"' from url: \" . \$Url);\r\ + \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ + \r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ + ut=user as-value ];\r\ + \n :if (\$Result->\"status\" = \"finished\") do={\r\ + \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ + \n } \r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ + al->\"name\" . \"': \" . \$Err);\r\ + \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ + \?\");\r\ + \n /system/script/remove \$Script;\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ + riptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :len \$CheckSum ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ + pdates with 'ignore=true' in comment.\");\r\ + \n }\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$SourceNew ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ + >\"name\") . \"'.\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ + \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ + lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ + \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ + \$ScriptVal->\"source\")) do={\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ + . \"' source did not change. End of lines set to CRLF.\");\r\ + \n if (\$ScriptUpdatesCRLF = false) do={\r\ + \n :put [ :tolf \$SourceNew ];\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ + ) . \"' source update end of lines to LF.\");\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ + l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if (\$CommentsInScripts = true) do={\r\ + \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ + \_\") ];\r\ + \n :if ([ :len \$CommentLine ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ + iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ + noring!\");\r\ + \n :error false;\r\ + \n } else={\r\ + \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ + ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ + ] + 2) [ :len \$CommentLine] ]) do={\r\ + \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ + \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ + ;\r\ + \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ + ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ + \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ + omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ + ded!\");\r\ + \n } else={\r\ + \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ + al->\"name\") . \"' did not change.\");\r\ + \n :error false;\r\ + \n }\r\ + \n } \r\ + \n }\r\ + \n\r\ + \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ + \"\\23 requires RouterOS, \") ] ]->version);\r\ + \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ + \_false ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires RouterOS \" . \\\r\ + \n \$RequiredROS . \", which is not met by your installation. I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ + \\23 requires device-mode, \") ] ];\r\ + \n :local MissingDM ({});\r\ + \n :foreach Feature,Value in=\$RequiredDM do={\r\ + \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ + ceMode->\$Feature) = false) do={\r\ + \n :set MissingDM (\$MissingDM, \$Feature);\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len \$MissingDM ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires disabled \" . \\\r\ + \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ + ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n \r\ + \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ + ript comment: \" . (\$ScriptVal->\"comment\"));\r\ + \n\r\ + \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ + Val->\"comment\") \\\r\ + \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ + F \$SourceNew ] \$Script;\r\ + \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ + \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ + \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ + o={\r\ + \n :set ReloadGlobal true;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n :if (\$ReloadGlobal = true) do={\r\ + \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ + \");\r\ + \n :onerror Err {\r\ + \n :global InitSetup (a);\r\ + \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ + \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ + ctions failed! \" . \$Err)}\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ + \n \$LogPrint warning \$0 (\"The configuration version decreased from \ + \" . \\\r\ + \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ + \n \". Installed an older version\?\");\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ + \n :global GlobalConfChanges;\r\ + \n :global GlobalConfMigration;\r\ + \n :local ChangeLogCode;\r\ + \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ + \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ + \n :onerror Err {\r\ + \n [ :parse \$ChangeLogCode ];\r\ + \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ + . \$Err)}\r\ + \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ + dation!\")}\r\ + \n }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ + \n :do {\r\ + \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ + \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ + \_\" is not available.\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ + \_. \" failed syntax validation!\");\r\ + \n :error false}\r\ + \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ + . \": \" . \$Migration);\r\ + \n :onerror Err {\r\ + \n [ :parse \$Migration ];\r\ + \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ + \_\$I . \" failed to run: \" . \$Err)}\r\ + \n } on-error={ }\r\ + \n }\r\ + \n }\r\ + \n :local NotificationMessage (\"The configuration version on \" . \$Id\ + entity . \" increased \" . \\\r\ + \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ + d modification. \" . \\\r\ + \n \"Please review and update global-config-overlay, then re-run glo\ + bal-config.\");\r\ + \n \$LogPrint info \$0 (\$NotificationMessage);\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ + \");\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ + \r\ + \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ + \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ + \n }\r\ + \n } else={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nNews and\ + \_changes are not available.\");\r\ + \n\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={ :set GlobalConfChanges; \ + } else={ :global GlobalConfChanges (a); }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={ :set GlobalConfMigrati\ + on; } else={ :global GlobalConfMigration (a); }\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n\r\ + \n# load modules\r\ + \n:foreach Script in=[ /system/script/find where name ~ \"^(global-functio\ + ns\\\\.d|mod)/.\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :if ([ \$ValidateSyntax (\$ScriptVal->\"source\") ] = true) do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' f\ + ailed to run: \" . \$Err);\r\ + \n }\r\ + \n } else={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' fai\ + led syntax validation, skipping.\");\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# Add and fix global scheduler\r\ + \n:put \"Add or/and fix Global scheduler...\";\r\ + \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ + ; }\";\r\ + \n:local Comment \"Every Day Set Global Environment Variables\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ + = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ + ent=\$OnEvent start-time=startup;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ + \_do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ + ) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n}\r\ + \n# Add Update Script scheduler\r\ + \n:put \"Add or/and fix Update Script scheduler\";\r\ + \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ + \r\ + \n:set Comment \"Every Day Check For Update Scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ + \" ] ] = 0) do={\r\ + \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ + start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n}\r\ + \n\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ + \_not ready.\"); }; } delay=100ms max=5;\r\ + \n\r\ + \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ + \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ + \") ] . \\\r\ + \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ + \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ + \n # signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n:set ExitOK true;\r\ + \n\r\ + \n:log info (\$0 . \"Global configs ready!\");\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n}\r\ + \n" +add comment=\ + "Lookup IP addresses for RKN list and add them to firewall address-list" \ + dont-require-permissions=no name=AM-RKN-dnsLookup owner=AM-RKN-dnsLookup \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-RKN-dnsLookup\r\ + \n# Script comment: Lookup IP addresses for RKN list and add them to firew\ + all address-list\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# Script description: This script is intended to be run periodically, e.\ + g. once a day, to update the IP addresses in the firewall address-list bas\ + ed on the RKN list.\r\ + \n# It resolves the domain names in the RKN list and a\ + dds the corresponding IP addresses to the specified firewall address-list.\ + \r\ + \n# The script also handles CNAME records by following\ + \_them until it finds A records.\r\ + \n# Usage:\r\ + \n# /system/script { run AM-RKN-dnsLookup; }\r\ + \n:local ScriptName [ :jobname ];\r\ + \n\r\ + \n:global dnsLookupReady false;\r\ + \n:if ([:typeof \$dnsLookupReady] != \"boolean\") do={ :set dnsLookupReady\ + \_true; }\r\ + \nwhile (!\$dnsLookupReady) do={ :nothing; }\r\ + \n:set dnsLookupReady false;\r\ + \n\r\ + \n:local arrRKN {\r\ + \n \"telegra.ph\"\r\ + \n \"grani.ru\"\r\ + \n \"xhamster.com\"\r\ + \n \"lostfilm.tv\"\r\ + \n \"rutracker.org\"\r\ + \n \"lurkmore.to\"\r\ + \n \"dou.ua\"\r\ + \n \"youporn.com\"\r\ + \n \"pornolab.net\"\r\ + \n \"crimerussia.com\"\r\ + \n \"telegram.org\"\r\ + \n \"api.telegram.org\"\r\ + \n \"facebook.com\"\r\ + \n \"instagram.com\"\r\ + \n \"x.com\"\r\ + \n \"twitter.com\"\r\ + \n \"youtube.com\"\r\ + \n \"googleapis.com\"\r\ + \n \"youtu.be\"\r\ + \n \"googlevideo.com\"\r\ + \n \"gstatic.com\"\r\ + \n \"googleusercontent.com\"\r\ + \n \"nhacmp3youtube.com\"\r\ + \n \"telegram.me\"\r\ + \n \"t.me\";}\r\ + \n\r\ + \n:local ListRKN \"RKN-dnsLookup\";\r\ + \n:local ListComment (\"ListRKN managed by \" . \$ScriptName);\r\ + \n:foreach aListItem in=[/ip/firewall/address-list find list=\$ListRKN] do\ + ={\r\ + \n /ip firewall address-list remove \$aListItem;\r\ + \n}\r\ + \n:foreach aItem in=\$arrRKN do={\r\ + \n# :do {\r\ + \n :retry delay=500ms max=5 on-error={:log error \"dns resolve fail\ + ure [ \$aItem - resolve ip ]\"} command={:resolve \$aItem}\r\ + \n# } on-error={\r\ + \n# :log error \"dns resolve failure [ \$arItem - resolve ip ]\";\r\ + \n# }\r\ + \n :foreach dnsRecord in=[/ip dns cache all find where (name=\$aItem)] \ + do={\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"A\") do={\r\ + \n :local newAddress [/ip dns cache all get \$dnsRecord data];\ + \r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address=\$newA\ + ddress comment=\$aItem;\r\ + \n :log warning \"Successfully adding ip to list A record: \ + \$dnsRecord, address: \$newAddress domain: \$aItem\";\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list A record: \$dn\ + sRecord, address: \$newAddress domain: \$aItem\";\r\ + \n }\r\ + \n }\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"CNAME\") do={\r\ + \n :local cname;\r\ + \n :local nextCname;\r\ + \n :local cnameAddress;\r\ + \n :set cname [/ip dns cache all find where (name=\$aItem && ty\ + pe=\"CNAME\")];\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip dns \ + cache all get \$cname data] && type=\"CNAME\")];\r\ + \n :while (\$nextCname != \"\") do={\r\ + \n :set cname \$nextCname;\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip \ + dns cache all get \$cname data] && type=\"CNAME\")];\r\ + \n }\r\ + \n :foreach aRecord in=[/ip dns cache all find where (name=[/ip\ + \_dns cache all get \$cname data] && type=\"A\")] do={\r\ + \n :do {\r\ + \n :set cnameAddress [/ip dns cache all get \$aRecord d\ + ata];\r\ + \n /ip firewall address-list add list=\$ListRKN address\ + =\$cnameAddress comment=\$aItem;\r\ + \n :log warning \"Succesfully adding ip to list CNAME r\ + ecord: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \ + \$aItem.\";\r\ + \n# /ip firewall raw add action=add-dst-to-address-list\ + \_address-list=\$ListRKN address-list-timeout=none-dynamic chain=preroutin\ + g comment=\$aItem content=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list CNAME reco\ + rd: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \$aI\ + tem.\";\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:if ([ :len [ /system/scheduler/find where name=\$ScriptName ] ] = 0) do\ + ={\r\ + \n :log error (\$ScriptName . \"System Scheduler for script: \" . \$Scri\ + ptName . \" is NOT SET! Fix It Now!\");\r\ + \n /system/scheduler/add name=\$ScriptName on-event=\"/system/script { \ + run \$ScriptName; }\" comment=\"Update RKN DNS Looup\" interval=00:30:00 p\ + olicy=\"ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon\"\ + \_start-time=startup;\r\ + \n }\r\ + \n:set dnsLookupReady true;\r\ + \ndelay 2s; \r\ + \n:global dnsLookupReady (a);\r\ + \n" +add dont-require-permissions=no name="renameLists " owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + local oldName \"Test\";\ + \n:local newName \"Test-IP\";\ + \n/ip firewall address-list\ + \n:foreach i in=[find list=\$oldName] do={\ + \nset \$i list=\$newName;\ + \n}\ + \n" +add dont-require-permissions=no name=IPv6-Settings owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + #############Script Settings##################\ + \n\ + \n:local \"IF-TUN\" \"6to4-tun\"\ + \n:local \"IF-LOC\" \"Bridge-LAN\"\ + \n:local \"POOL-6TO4\" \"poolV6-local\"\ + \n:local \"force-update\" false\ + \n############ use then static ip #######################\ + \n:local \"lease-address\" [/ip address get [find interface=\$\"IF-LOC\"] \ + address]\ + \n#:local \"interface\" \"ext\"\ + \n:local bound 0\ + \n\ + \n###############################################\ + \n\ + \n:local 6to4prefix do={\ + \n :global dec2hex\ + \n :local ipv4 \$1\ + \n :local ipv6 \"2002:\"\ + \n :for i from=0 to=2 step=1 do={ \ + \n :if ( \$i = 2) do={\ + \n :set ipv6 (\$ipv6.\":\")\ + \n }\ + \n :local fp [:find \$ipv4 \".\"]\ + \n :if ( \$fp > 0 ) do={\ + \n :set ipv6 (\$ipv6.[\$dec2hex [:pick \$ipv4 0 \$fp]])\ + \n :set ipv4 [:pick \$ipv4 (\$fp + 1 ) [:len \$ipv4]]\ + \n }\ + \n }\ + \n :return (\$ipv6.[\$dec2hex \$ipv4])\ + \n}\ + \n:local \"str_replace\" do={\ + \n :local \"str-pos\" [:find \$1 \$2]\ + \n :local \"str-len\" [:len \$2]\ + \n :local str \"\"\ + \n :local rest \$1\ + \n :while (\$\"str-pos\" >= 0) do={\ + \n :local t [:pick \$rest 0 \$\"str-pos\"]\ + \n :if ( \$4 > 0 ) do={\ + \n :for i from=1 to=(\$4 - [:len \$t]) step=1 do={\ + \n :set str (\$str.\$5)\ + \n }\ + \n }\ + \n :set str (\$str.\$t.\$3)\ + \n :set rest [:pick \$rest (\$\"str-pos\"+\$\"str-len\") [:len \$re\ + st]]\ + \n :set \"str-pos\" [:find \$rest \$2]\ + \n }\ + \n :return (\$str.\$rest)\ + \n}\ + \n\ + \n:if (\$bound=1) do={\ + \n :local t [:find \$\"lease-address\" \"/\"]\ + \n\ + \n :if ( \$t >= 0 ) do={\ + \n :set \"lease-address\" [:pick \$\"lease-address\" 0 \$t]\ + \n }\ + \n\ + \n :if ( [/interface 6to4 print count-only where name=\$\"IF-TUN\"] = 0\ + ) do={\ + \n /interface 6to4 add !keepalive local-address=\$\"lease-address\"\ + \_mtu=1280 name=\$\"IF-TUN\" remote-address=10.30.30.0\ + \n :set \"force-update\" true\ + \n }\ + \n\ + \n :local \"IPv4-TUN\" [/interface 6to4 get [find name=\$\"IF-TUN\"] lo\ + cal-address];\ + \n\ + \n :if ( \$\"lease-address\" != \$\"IPv4-TUN\" || \$\"force-update\" = \ + true) do={\ + \n /interface 6to4 set [find name=\$\"IF-TUN\"] local-address=\$\"l\ + ease-address\"\ + \n /ipv6 address remove [find interface=\$\"IF-TUN\"]\ + \n /ipv6 address remove [find interface=\$\"IF-LOC\"]\ + \n /ipv6 route remove [find gateway ~ \$\"IF-TUN\" and dst-address=\ + \"::/0\"]\ + \n :local \"pool-prefix\" [\$6to4prefix \$\"lease-address\"]\ + \n :if ( [/ipv6 pool print count-only where name=\$\"POOL-6TO4\"] =\ + \_0) do={ \ + \n /ipv6 pool add name=\$\"POOL-6TO4\" prefix=(\$\"pool-prefix\ + \".\":1::/64\") prefix-length=64\ + \n } else={\ + \n /ipv6 pool set [/ipv6 pool find where name=\$\"POOL-6TO4\"] \ + prefix=(\$\"pool-prefix\".\":1::/64\")\ + \n }\ + \n /ipv6 address add address=(\$\"pool-prefix\".\"::\".[\$MAC2EUI64\ + \_[/interface get [find name=\$\"interface\"] mac-address]].\"/3\") interf\ + ace=\$\"IF-TUN\" advertise=no\ + \n /ipv6 address add eui-64=yes from-pool=\$\"POOL-6TO4\" interface\ + =\$\"IF-LOC\" advertise=yes\ + \n /ipv6 route add dst-address=::/0 gateway=(\"::10.30.30.81%\".\$\ + \"IF-TUN\")\ + \n :local t [/ipv6 address get [find interface=\$\"IF-LOC\"] addres\ + s]\ + \n :set t [:pick \$t 0 [:find \$t \"/\"]]\ + \n :if ( [/ipv6 dhcp-server option print count-only where name=DNS]\ + \_= 0) do={\ + \n /ipv6 dhcp-server option add code=23 name=DNS value=(\"0x\".\ + [\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ + \n } else={\ + \n /ipv6 dhcp-server option set [/ipv6 dhcp-server option find \ + where name=DNS] value=(\"0x\".[\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ + \n }\ + \n :if ( [/ipv6 dhcp-server print count-only where interface=\$\"IF\ + -LOC\"] = 0) do={\ + \n /ipv6 dhcp-server add address-pool=\$\"POOL-6TO4\" dhcp-opti\ + on=DNS interface=\$\"IF-LOC\" lease-time=1d name=\$\"IF-LOC\"\ + \n }\ + \n :if ( [ipv6 nd print count-only where interface=\$\"IF-LOC\"] = \ + 0) do={\ + \n /ipv6 nd add advertise-dns=no interface=\$\"IF-LOC\" other-c\ + onfiguration=yes\ + \n }\ + \n }\ + \n}" +add dont-require-permissions=no name=IPv6-GlobalFunc owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + global MAC2EUI64 do={\ + \n :local EUI64 \"\"\ + \n :local MAC \$1\ + \n :local HEX2DEC \"0123456789ABCDEF\"\ + \n :for i from=0 to=5 step=1 do={\ + \n :if ( \$i = 0 ) do={\ + \n :set EUI64 [:pick \$MAC 0]\ + \n :set EUI64 (\$EUI64.[:tostr [:pick \$\"HEX2DEC\" ([:find \$\ + \"HEX2DEC\" [:pick \$MAC 1]] ^ 2)]])\ + \n }\ + \n :if ( \$i = 1 || \$i = 3) do={\ + \n :set EUI64 (\$EUI64.\":\")\ + \n }\ + \n :if ( \$i = 2 ) do={\ + \n :set EUI64 (\$EUI64.\"FF:FE\")\ + \n }\ + \n :if ( [:find \$MAC \":\"] = 2 ) do={\ + \n :set MAC [:pick \$MAC 3 [:len \$MAC]]\ + \n :set EUI64 (\$EUI64.[:pick \$MAC 0 2])\ + \n }\ + \n }\ + \n :return (\$EUI64)\ + \n}\ + \n\ + \n:global dec2hex do={\ + \n :local hex \"\"\ + \n :local dec [:tonum \$1]\ + \n :for i from=0 to=4 step=4 do={\ + \n :set hex ([:pick \"0123456789ABCDEF\" ((\$dec>>\$i)&0xf) (((\$de\ + c>>\$i)&0xf)+1)].\$hex)\ + \n }\ + \n :return ([:tostr \$hex])\ + \n}" +/user group +add name=backup policy="ssh,read,write,policy,test,web,sniff,sensitive,api,res\ + t-api,!local,!telnet,!ftp,!reboot,!winbox,!password,!romon" +/ip smb +set enabled=no interfaces=lo +/interface bridge port +add bridge=Bridge-LAN interface=ether5 +add bridge=Bridge-LAN interface=ether2 +add bridge=Bridge-LAN interface=ether4 trusted=yes +add bridge=Bridge-LAN interface=ether3 +add bridge=Bridge-LAN interface=wlan2 +add bridge=Bridge-LAN interface=wlan1 +/interface bridge settings +set use-ip-firewall=yes +/ip firewall connection tracking +set udp-timeout=10s +/ip neighbor discovery-settings +set discover-interface-list=LAN lldp-med=no lldp-poe-power=no +/ip settings +set accept-redirects=yes ipv4-multipath-hash-policy=l4 max-neighbor-entries=\ + 8192 +/ipv6 settings +set disable-ipv6=yes disable-link-local-address=yes forward=no \ + max-neighbor-entries=8192 multipath-hash-policy=l4 +/interface detect-internet +set detect-interface-list=WAN internet-interface-list=Internet \ + lan-interface-list=LAN request-interval=1m wan-interface-list=WAN +/interface l2tp-server server +set authentication=mschap2 use-ipsec=yes +/interface list member +add interface=ether4 list=WAN +add interface="ether1 - Unet" list=Internet +add disabled=yes interface=WG list=WAN +add interface=Bridge-LAN list=LAN +/interface wireguard peers +add allowed-address=0.0.0.0/0 client-allowed-address=::/0 endpoint-address=\ + 109.107.177.79 endpoint-port=29185 interface=WG name=VDSina \ + persistent-keepalive=10s public-key=\ + "zuRsO+dL/j6awaBWZ/NgnHR+bCNUjRWbaHFpdzkNnw4=" +/interface wireless cap +# +set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ + CAP-488F5A8E1ABC discovery-interfaces=Bridge-LAN enabled=yes interfaces=\ + wlan2,wlan1 lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +add address=10.8.0.2/24 interface=WG network=10.8.0.0 +/ip cloud +set update-time=no +/ip dhcp-client +add add-default-route=special-classless default-route-distance=2 \ + default-route-tables=main:2 dhcp-options=clientid,clientid_duid \ + interface="ether1 - Unet" name=client1 use-peer-dns=no use-peer-ntp=no +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ + dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ + dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ + dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ + mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ + dhcp-option-set=iVados mac-address=DE:4D:72:F3:1A:9F server=masterDHCP +add address=10.30.30.10 allow-dual-stack-queue=yes client-id=\ + ff:0:0:0:df:0:3:0:1:f0:75:5d:1e:5f:85 dhcp-option=HostName \ + dhcp-option-set=MikroNUC mac-address=F0:75:5D:1E:5F:85 server=masterDHCP \ + use-src-mac=yes +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.33,109.107.177.79 domain=WORKGROUP gateway=10.30.30.81 netmask=\ + 24 ntp-server=10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ + doh-max-server-connections=20 servers=10.30.30.33,109.107.177.79 \ + verify-doh-cert=yes +/ip dns static +add address=109.107.177.79 comment="VDSina Server DNS" name=ns1.vados.ru \ + type=A +add address=109.107.177.79 name=vds.vados.ru type=A +add comment="Local DNS server for vados.ru" disabled=yes ns=10.30.30.81 \ + regexp=*.vados.ru type=NS +add comment="*.vados.ru Regexp" disabled=yes forward-to=10.30.30.81 regexp=\ + "\".*\\\\.vados\\\\.ru\"" type=FWD +add comment="*.30.30.10.in-addr.arpa Regexp" disabled=yes forward-to=\ + 10.30.30.81 regexp="\".*\\\\.30\\\\.30\\\\.10\\\\.in-addr\\\\.arpa" type=\ + FWD +add address=10.30.30.81 comment=NS.vados.ru.local disabled=yes name=\ + ns.vados.ru.local type=A +add comment="DNS ns.vados.ru.local" disabled=yes match-subdomain=yes name=\ + vados.ru ns=ns.vados.ru.local type=NS +add address=10.30.30.33 comment=reg.vados.ru name=reg.vados.ru type=A +add address=8.8.8.8 comment="Google-dns IPv4 1" match-subdomain=yes name=\ + dns.google type=A +add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +add address=10.30.30.33 name=ros.vados.ru type=A +add address=10.30.30.95 name=vados-nuc type=A +add address=10.30.30.33 name=amster-nuc type=A +add address=10.30.30.33 name=amster type=A +add address=10.30.30.33 name=amster-reg type=A +add address=10.30.30.33 disabled=yes name=mng.vados.ru type=A +add address=10.30.30.33 name=mgr.vados.ru type=A +add address=10.30.30.33 name=prt.vados.ru type=A +add address=10.30.30.33 disabled=yes match-subdomain=yes name=\ + mikrots.vados.ru type=A +add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +add address=10.30.30.30 name=MILLER-LEN type=A +add address=10.30.30.30 name=miller type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ + dns.quad9.net type=A +add address=195.133.25.16 comment="DNS Comss" disabled=yes name=dns.comss.one \ + type=A +add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +add address=10.30.30.10 name=MikroNUC type=A +add address=10.30.30.86 disabled=yes name=MikroYellow type=A +add address=10.30.30.85 disabled=yes name=MikroMic type=A +add address=10.30.30.95 name=VADOS-NUC type=A +add address=10.30.30.98 name=VADOS-LEN type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=10.30.30.20 disabled=yes name=garage type=A +/ip firewall address-list +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=8.8.4.0/24 list=YouTube +add address=8.8.8.0/24 list=YouTube +add address=8.34.208.0/20 list=YouTube +add address=8.35.192.0/20 list=YouTube +add address=23.236.48.0/20 list=YouTube +add address=23.251.128.0/19 list=YouTube +add address=34.0.0.0/15 list=YouTube +add address=34.2.0.0/16 list=YouTube +add address=34.3.0.0/23 list=YouTube +add address=34.3.3.0/24 list=YouTube +add address=34.3.4.0/24 list=YouTube +add address=34.3.8.0/21 list=YouTube +add address=34.3.16.0/20 list=YouTube +add address=34.3.32.0/19 list=YouTube +add address=34.3.64.0/18 list=YouTube +add address=34.4.0.0/14 list=YouTube +add address=34.8.0.0/13 list=YouTube +add address=34.16.0.0/12 list=YouTube +add address=34.32.0.0/11 list=YouTube +add address=34.64.0.0/10 list=YouTube +add address=34.128.0.0/10 list=YouTube +add address=35.184.0.0/13 list=YouTube +add address=35.192.0.0/14 list=YouTube +add address=35.196.0.0/15 list=YouTube +add address=35.198.0.0/16 list=YouTube +add address=35.199.0.0/17 list=YouTube +add address=35.199.128.0/18 list=YouTube +add address=35.200.0.0/13 list=YouTube +add address=35.208.0.0/12 list=YouTube +add address=35.224.0.0/12 list=YouTube +add address=35.240.0.0/13 list=YouTube +add address=57.140.192.0/18 list=YouTube +add address=64.15.112.0/20 list=YouTube +add address=64.233.160.0/19 list=YouTube +add address=66.22.228.0/23 list=YouTube +add address=66.102.0.0/20 list=YouTube +add address=66.249.64.0/19 list=YouTube +add address=70.32.128.0/19 list=YouTube +add address=72.14.192.0/18 list=YouTube +add address=74.125.0.0/16 list=YouTube +add address=104.154.0.0/15 list=YouTube +add address=104.196.0.0/14 list=YouTube +add address=104.237.160.0/19 list=YouTube +add address=107.167.160.0/19 list=YouTube +add address=107.178.192.0/18 list=YouTube +add address=108.59.80.0/20 list=YouTube +add address=108.170.192.0/18 list=YouTube +add address=108.177.0.0/17 list=YouTube +add address=130.211.0.0/16 list=YouTube +add address=136.22.160.0/20 list=YouTube +add address=136.22.176.0/21 list=YouTube +add address=136.22.184.0/23 list=YouTube +add address=136.22.186.0/24 list=YouTube +add address=142.250.0.0/15 list=YouTube +add address=146.148.0.0/17 list=YouTube +add address=152.65.208.0/22 list=YouTube +add address=152.65.214.0/23 list=YouTube +add address=152.65.218.0/23 list=YouTube +add address=152.65.222.0/23 list=YouTube +add address=152.65.224.0/19 list=YouTube +add address=162.120.128.0/17 list=YouTube +add address=162.216.148.0/22 list=YouTube +add address=162.222.176.0/21 list=YouTube +add address=172.110.32.0/21 list=YouTube +add address=172.217.0.0/16 list=YouTube +add address=172.253.0.0/16 list=YouTube +add address=173.194.0.0/16 list=YouTube +add address=173.255.112.0/20 list=YouTube +add address=192.158.28.0/22 list=YouTube +add address=192.178.0.0/15 list=YouTube +add address=193.186.4.0/24 list=YouTube +add address=199.36.154.0/23 list=YouTube +add address=199.36.156.0/24 list=YouTube +add address=199.192.112.0/22 list=YouTube +add address=199.223.232.0/21 list=YouTube +add address=207.223.160.0/20 list=YouTube +add address=208.65.152.0/22 list=YouTube +add address=208.68.108.0/22 list=YouTube +add address=208.81.188.0/22 list=YouTube +add address=208.117.224.0/19 list=YouTube +add address=209.85.128.0/17 list=YouTube +add address=216.58.192.0/19 list=YouTube +add address=216.73.80.0/20 list=YouTube +add address=216.239.32.0/19 list=YouTube +add address=2ip.ru list=Test-IP +add address=wg.vados.ru comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" disabled=yes list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com list=NoVdsina +add address=vdsina.ru list=NoVdsina +add address=youla.ru list=NoVdsina +add address=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test-IP +add address=geoip.co list=NoVdsina +add address=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=amster disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC disabled=yes list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! disabled=yes list=NoWG +add address=wg.vados.ru comment=VDSina-vpn list=VDSina +add address=80.85.244.9 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=89.110.101.17 comment="!!!VDSina Server!!!" list=NoVdsina +add address=dns.quad9.net comment=Quad9-dns disabled=yes list=Trusted-DNS +add address=dns.google comment=Google-dns list=Trusted-DNS +add address=security.cloudflare-dns.com comment=CloudFlare-dns list=\ + Trusted-DNS +add address=time.google.com comment=Google-time list=Trusted-NTP +add address=0.ru.pool.ntp.org comment=ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=1.ru.pool.ntp.org disabled=yes list=Trusted-NTP +add address=2.ru.pool.ntp.org comment=2.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=3.ru.pool.ntp.org comment=3.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=cp.vdsina.com comment=VDSina-vpn list=VDSina +add address=vdsina.ru comment=VDSina-vpn list=VDSina +add address=ns.vados.ru comment=VDSina-vpn list=VDSina +add address=vdsina.com comment=VDSina-vpn list=VDSina +add address=cp.vdsina.ru comment=VDSina-vpn list=VDSina +add address=ns1.vdsina.ru comment=VDSina-vpn list=VDSina +add address=10.30.30.0/24 comment="Local Network" list=Local-Net +add address=10.8.0.0/24 comment="WireGuard Network" list=Local-Net +add address=146.120.64.208/29 comment="External Net" list=Unet +add address=esia.gosuslugi.ru comment=esia.gosuslugi.ru list=NoVdsina +add address=lk.gosuslugi.ru comment=lk.gosuslugi.ru list=NoVdsina +add address=trudvsem.ru comment=trudvsem.ru list=NoVdsina +add address=10.30.30.30 comment=miller disabled=yes list=NoWG +add address=10.30.30.33 comment="Direct connet to DNS servers" list=\ + Direct-DNS +add address=109.107.177.79 list=VPN-Server +add address=10.30.30.10 list=AWG-Proxy +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS" \ + connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ + udp src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input connection-state=new dst-port=53 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=22,8291 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface="ether1 - Unet" protocol=\ + udp +add action=fasttrack-connection chain=forward comment=\ + "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ + connection-state=established,related,new disabled=yes +add action=accept chain=input disabled=yes dst-port=29185 in-interface=\ + "ether1 - Unet" protocol=tcp +add action=accept chain=input disabled=yes dst-port=29185 in-interface=\ + "ether1 - Unet" protocol=udp +add action=accept chain=input comment="tcp Accept input DNS queries from LAN" \ + dst-port=53 protocol=tcp src-address=10.30.30.0/24 +add action=accept chain=input comment="udp Accept input DNS queries" \ + dst-port=53 protocol=udp src-address=10.30.30.0/24 +add action=accept chain=output comment="accept WireGuard" disabled=yes \ + dst-address-list=VPN-Server out-interface="ether1 - Unet" protocol=udp \ + src-port=13231 +add action=accept chain=output disabled=yes dst-address-list=VPN-Server \ + dst-port=29185 out-interface="ether1 - Unet" protocol=udp +add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ + connection-state=established,related,new disabled=yes routing-mark=\ + !To-VPN +add action=accept chain=output disabled=yes protocol=tcp src-port=443 +add action=accept chain=output disabled=yes src-address=127.0.0.1 +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + disabled=yes ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + disabled=yes ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid in-interface="ether1 - Unet" src-address=\ + !10.30.30.0/24 +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + connection-state=new in-interface="ether1 - Unet" src-address-list=\ + !VDSina +add action=drop chain=forward comment=\ + "Filter Rule to block FB address LIST : )" disabled=yes dst-address-list=\ + facebook +add action=drop chain=forward comment=\ + "Filter Rule to block YOUTUBE address LIST : )" disabled=yes \ + dst-address-list=YouTube +add action=accept chain=input in-interface="ether1 - Unet" protocol=icmp \ + src-address-list=VDSina +add action=accept chain=input connection-state=established disabled=yes +add action=accept chain=input connection-state=related disabled=yes +/ip firewall mangle +add action=mark-routing chain=prerouting comment="Mark Routing main for NoWG" \ + disabled=yes new-routing-mark=main src-address-list=NoWG +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for NoVdsina" dst-address-list=NoVdsina \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for VDSina" dst-address-list=VPN-Server \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for MikroNuc" disabled=yes dst-address-list=AWG-Proxy \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "!!!ERROR Mark Routing main for Unet!!!" disabled=yes dst-address-list=\ + Unet new-routing-mark=main passthrough=no +add action=mark-routing chain=prerouting comment="Test-IP sites" disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=Test-IP new-routing-mark=\ + To-VPN src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=FuckRKN disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=RKN-dnsLookup \ + new-routing-mark=To-VPN passthrough=no src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment="AWG for All sites" \ + disabled=yes dst-address=!10.30.30.0/24 dst-address-list=!NoVdsina \ + new-routing-mark=*401 routing-mark=!main src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment="VDSIna for All sites" \ + dst-address=!10.30.30.0/24 dst-address-list=!NoVdsina new-routing-mark=\ + To-VPN routing-mark=!main src-address=10.30.30.0/24 +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" new-connection-mark=\ + VPN_No_FastTrack routing-mark=To-VPN +add action=change-mss chain=forward comment="MSS on WG" new-mss=1380 \ + out-interface=WG protocol=tcp routing-mark=To-VPN tcp-flags=syn tcp-mss=\ + 1381-65535 +add action=mark-routing chain=prerouting comment="VPN Network" dst-address=\ + 10.8.0.0/24 new-routing-mark=To-VPN src-address=10.30.30.0/24 +/ip firewall nat +add action=redirect chain=dstnat comment="udp Redirect DNS in NAT" disabled=\ + yes dst-port=53 protocol=udp src-address=10.30.30.0/24 src-address-list=\ + !NoWG to-addresses=10.30.30.33 to-ports=53 +add action=redirect chain=dstnat comment="tcp Redirect DNS in NAT" disabled=\ + yes dst-port=53 protocol=tcp src-address=10.30.30.0/24 src-address-list=\ + !NoWG to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat comment=\ + "53/tcp dst-nat to amster.loc. From VDSina Server" dst-port=53 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=VPN-Server \ + to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat comment=\ + "53/udp dst-nat to amster.loc. From VDSina Server" dst-port=53 protocol=\ + udp src-address-list=VPN-Server to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat disabled=yes dst-port=44333 in-interface=\ + "ether1 - Unet" protocol=udp src-address=!10.30.30.0/24 to-addresses=\ + 10.30.30.33 to-ports=44333 +add action=masquerade chain=srcnat comment="Default NAT" out-interface=\ + "ether1 - Unet" routing-mark=!To-VPN src-address=10.30.30.0/24 +add action=dst-nat chain=dstnat comment=amster.vados.ruhttps dst-port=443 \ + fragment=no in-interface="ether1 - Unet" protocol=tcp routing-mark=main \ + to-addresses=10.30.30.33 to-ports=443 +add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ + dst-port=80 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat comment="amster.vados.ru 3x-ui" disabled=yes \ + dst-port=2904 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=2904 +add action=dst-nat chain=dstnat comment=reg.vados.ru disabled=yes dst-port=\ + 5000 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=5000 +add action=dst-nat chain=dstnat comment="Docker swarm" disabled=yes dst-port=\ + 2377 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=2377 +add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=To-VPN to-addresses=10.30.30.33 \ + to-ports=81 +add action=dst-nat chain=dstnat comment=SSH dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp src-address-list=TRUSTED to-addresses=\ + 10.30.30.33 to-ports=22 +add action=dst-nat chain=dstnat comment="portainer agent" disabled=yes \ + dst-port=2377 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=2377 +add action=dst-nat chain=dstnat disabled=yes dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=22 +add action=masquerade chain=srcnat comment=WG dst-address-list=!NoVdsina \ + out-interface=WG routing-mark=To-VPN src-address-list=!NoWG +add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ + dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ + time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ + Bridge-LAN protocol=tcp src-address-list=KIDS time=\ + 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +/ip firewall raw +add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ + in-interface="ether1 - Unet" src-address-list="Honeypot Hacker" +add action=accept chain=prerouting comment="Trusted DNS" disabled=yes \ + in-interface-list=WAN src-address-list=Trusted-DNS +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ + content=linux.duke.edu disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=youtube.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googleapis.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=ggpht.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=youtu.be \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=ytimg.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googlevideo.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=gstatic.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googleusercontent.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + nhacmp3youtube.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ + content=rutube.ru disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment="me.com raw" \ + content=me.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "icloud.com raw" content=icloud.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "smtp.mail.me.com raw" content=smtp.mail.me.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "smtp.mail.me.com.akadns.net raw" content=smtp.mail.me.com.akadns.net \ + disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "api.db-ip.com raw" content=api.db-ip.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + esia.gosuslugi.ru content=esia.gosuslugi.ru disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=gosuslugi.ru \ + content=gosuslugi.ru disabled=yes +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +#error exporting "/ip/ipsec/key/psk" (timeout) +/ip ipsec settings +set accounting=no +/ip ipsec policy +set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +/ip ipsec profile +set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +/ip proxy +set cache-administrator="" max-cache-size=none port=80,443 src-address=\ + 0.0.0.0 +/ip route +add check-gateway=none disabled=no distance=1 dst-address=0.0.0.0/0 gateway=\ + WG routing-table=To-VPN scope=30 target-scope=10 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set reverse-proxy disabled=yes +set ssh address=10.30.30.0/24 port=2222 +set winbox address=10.30.30.0/24 +set api address=10.30.30.0/24 disabled=yes +set api-ssl address=10.30.30.0/24 disabled=yes +set www-ssl certificate=Root-YE port=18443 +set www address=10.30.30.0/24 disabled=yes port=18880 +/ip service webserver +set acme-plain=no crl-plain=no graphs-plain=no graphs-secure=no index-plain=\ + no index-secure=no rest-plain=no rest-secure=no scep-plain=no \ + webfig-plain=no webfig-secure=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface=Bridge-LAN type=internal +add forced-ip=146.120.64.211 interface="ether1 - Unet" type=external +add forced-ip=109.107.177.79 interface=*E type=external +add interface=lo type=internal +add interface=wlan2 type=internal +add interface=wlan1 type=internal +/ipv6 dhcp-client +add add-default-route=yes disabled=yes interface=*F rapid-commit=no request=\ + info use-interface-duid=yes validate-server-duid=no +/ipv6 dhcp-server option sets +add name=domain-search-set options=domain-search-list +add name="=\"Client ID\"" options=HostName +/ipv6 firewall address-list +add address=::/128 comment="defconf: unspecified address" list=bad_ipv6 +add address=::1/128 comment="defconf: lo" list=bad_ipv6 +add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6 +add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6 +add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6 +add address=100::/64 comment="defconf: discard only " list=bad_ipv6 +add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6 +add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6 +add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6 +/ipv6 firewall filter +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\ + icmpv6 +add action=accept chain=input comment="defconf: accept UDP traceroute" \ + dst-port=33434-33534 protocol=udp +add action=accept chain=input comment=\ + "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\ + udp src-address=fe80::/10 +add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \ + protocol=udp +add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\ + ipsec-ah +add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\ + ipsec-esp +add action=accept chain=input comment=\ + "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +add action=drop chain=input comment=\ + "defconf: drop everything else not coming from LAN" in-interface-list=\ + !LAN +add action=accept chain=forward comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6 +add action=drop chain=forward comment=\ + "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6 +add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \ + hop-limit=equal:1 protocol=icmpv6 +add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\ + icmpv6 +add action=accept chain=forward comment="defconf: accept HIP" protocol=139 +add action=accept chain=forward comment="defconf: accept IKE" dst-port=\ + 500,4500 protocol=udp +add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\ + ipsec-ah +add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\ + ipsec-esp +add action=accept chain=forward comment=\ + "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +add action=drop chain=forward comment=\ + "defconf: drop everything else not coming from LAN" in-interface-list=\ + !LAN +/ipv6 nd +set [ find default=yes ] advertise-dns=yes disabled=yes interface=Bridge-LAN \ + managed-address-configuration=yes other-configuration=yes pref64=::/64 +/ipv6 nd prefix +add autonomous=no disabled=yes interface=Bridge-LAN on-link=no prefix=none +/ipv6 nd prefix default +set dhcp6-pd-preferred=yes +/ipv6 nd proxy +add disabled=yes interface=lo +/ipv6 nd settings +set router-advertisement-route-distance=100 +/routing settings +set single-process=no +/system clock +set time-zone-name=Europe/Moscow +/system clock manual +set time-zone=+03:00 +/system identity +set name=MikroMaster +/system logging +add action=email disabled=yes regex="* added|changed|removed *" topics=\ + system,info +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=0.ru.pool.ntp.org +add address=1.ru.pool.ntp.org +add address=2.ru.pool.ntp.org +add address=3.ru.pool.ntp.org +add address=time.google.com disabled=yes +/system package update +set check-certificate=yes-without-crl ip-version=ipv4 +/system scheduler +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Update RKN DNS Looup" disabled=yes interval=20m name=\ + AM-RKN-dnsLookup on-event="/system/script { run AM-RKN-dnsLookup; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add certificate=DigiCert-Global-Root-CA check-certificate=no comment="doh, doh\ + -url=https://security.cloudflare-dns.com/dns-query, notify, name=CloudFlar\ + e-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 http-codes="" \ + interval=10s name="CloudFlare-doh IPv4 1" port=443 test-script="" type=\ + https-get up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + name="CloudFlare-doh IPv4" port=443 test-script="" type=https-get \ + up-script="" +add comment="dns, notify, name=Google-DNS IPv4" disabled=yes dns-server=\ + 8.8.8.8 down-script="" host=dns.google http-codes="" name=\ + "Google-DNS IPv4" test-script="" type=dns up-script="" +add certificate=GTS-Root-R4 check-certificate=yes comment="doh-fallback, doh-u\ + rl=https://dns.google/dns-query, doh-cert=GTS Root R1, notify, name=Google\ + -DOH IPv4" disabled=yes dns-server=8.8.4.4 down-script="" host=dns.google \ + http-codes="" name="Google-DOH IPv4" port=443 record-type=NS src-address=\ + "" test-script="" type=dns up-script="" +add comment="dns-fallback, notify, name=Cuad9-DOH IPv4" disabled=yes \ + dns-server=9.9.9.9 down-script="" host=dns9.quad9.net http-codes="" \ + interval=10s name="Cuad9-DOH IPv4" src-address=146.120.64.211 \ + test-script="" timeout=800ms type=dns up-script="" +add certificate=DigiCert-Assured-ID-Root-CA comment="doh-fallback, doh-url=htt\ + ps://dns.quad9.net/dns-query, name=Cuad9-DOH IPv4" disabled=yes \ + down-script="" host=149.112.112.112 http-codes="" interval=10s name=\ + "Cuad9-DOH IPv4" port=443 test-script="" type=https-get up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" interval=10s name=\ + ns1.unet.ws test-script="" type=simple up-script="" +add check-certificate=yes comment=\ + "doh, doh-url=https://vds.vados.ru/vds-query, name=vds.vados.ru" \ + disabled=yes down-script="" host=109.107.177.79 http-codes="" name=\ + vds.vados.ru port=443 test-script="" type=https-get up-script="" +/user aaa +set accounting=no diff --git a/MikroMaster/20260701/20260701010002-Config.rsc b/MikroMaster/20260701/20260701010002-Config.rsc new file mode 100644 index 0000000..e573e80 --- /dev/null +++ b/MikroMaster/20260701/20260701010002-Config.rsc @@ -0,0 +1,3693 @@ +# 2026-07-01 01:00:08 by RouterOS 7.23.1 +# software id = A8L5-07YF +# +# model = RB952Ui-5ac2nD +# serial number = D3D50CEDCD38 +/interface bridge +add admin-mac=48:8F:5A:8E:1A:BF auto-mac=no dhcpv6-agent-circuit-id=\ + "\$(INTERFACE):\$(VID)" dhcpv6-agent-remote-id="\$(BRIDGEMAC)" name=\ + Bridge-LAN port-cost-mode=short +/interface ethernet +set [ find default-name=ether1 ] comment="WAN - Unet" loop-protect=off name=\ + "ether1 - Unet" rx-flow-control=auto tx-flow-control=auto +set [ find default-name=ether2 ] comment=LAN-2 +set [ find default-name=ether3 ] advertise="10M-baseT-half,10M-baseT-full,100M\ + -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-3 +set [ find default-name=ether4 ] comment=LAN-4 +set [ find default-name=ether5 ] advertise="10M-baseT-half,10M-baseT-full,100M\ + -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-5 \ + loop-protect=on poe-out=off rx-flow-control=auto tx-flow-control=auto +/interface wireless +# managed by CAPsMAN +# channel: 2442/20-Ce/gn(18dBm), SSID: vados, local forwarding +set [ find default-name=wlan1 ] country=belarus disabled=no mode=ap-bridge \ + ssid=vados wireless-protocol=802.11 +# managed by CAPsMAN +# channel: 5260/20-Ceee/ac/DP(18dBm), SSID: vados5g, local forwarding +set [ find default-name=wlan2 ] country=belarus disabled=no mode=ap-bridge \ + ssid=vados5g wireless-protocol=802.11 +/interface wireguard +add comment=WG listen-port=13231 mtu=1320 name=WG +/interface list +add include=static name=LAN +add name=Internet +add include=Internet name=WAN +/interface wireless security-profiles +set [ find default=yes ] authentication-types=wpa-psk,wpa2-psk mode=\ + dynamic-keys supplicant-identity=MikroTik +/iot wiliot servers +set *1 address=mqtt.us-east-2.prod.wiliot.cloud name="Wiliot US East" +/ip dhcp-server option +add code=12 name=HostName +add code=119 force=yes name=domain-search-list value="0x03'WORKGROUP'0x00" +/ip dhcp-server option sets +add name=HP1505n options=HostName +add name=StartLife1 options=HostName +add name=amsterDev options=HostName +add name=MiTV options=HostName +add name=miller options=HostName +add name=amster options=HostName +add name=garage options=HostName +add name=domain-search-set options=domain-search-list +add name=VADOS-LEN options=HostName +add name=VADOS-NUC options=HostName +add name=MikroNUC options=HostName +add name=master options=HostName +add name=MikroYellow options=HostName +add name="=\"Client ID\"" options=HostName +add name=iVados options=HostName +/ip dns forwarders +add dns-servers=1.0.0.1,1.1.1.1 name=blsp.at verify-doh-cert=no +add comment=Kra dns-servers=1.0.0.1,1.1.1.1 name=slon2.to verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +/ip ipsec proposal +set [ find default=yes ] disabled=yes +/ip pool +add name=dhcp ranges=10.30.30.83-10.30.30.254 +/ip dhcp-server +add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ + dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ + name=masterDHCP server-address=10.30.30.81 +/ip smb users +set [ find default=yes ] disabled=yes +add disabled=yes name=vados +/ipv6 dhcp-client option +add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +add code=12 name=HostName value="\$(HOSTNAME)" +add code=61 name=DUID value=0x00030001488f5a8e1abc +add code=61 name=clientid +/ipv6 dhcp-server option +add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +add code=12 name=HostName value="\$(HOSTNAME)" +add code=61 name=CLIENT_DUID +add code=61 name=CLIENT_MAC +/ppp profile +set *FFFFFFFE use-upnp=no +#error exporting "/queue/interface" (timeout) +/routing bgp template +set default disabled=no output.network=bgp-networks +/routing table +add disabled=no fib name=To-VPN +/system logging action +add email-start-tls=yes email-to=vados@vados.ru name=email target=email +/system script +add dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n\r\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.86.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.86.pub\";\ + \n\r\ + \n#:local Script AM-setup\ + \n;\r\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\r\ + \n\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n\r\ + \n#\ + \n\r\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ + \n\r\ + \n#\r\ + \n\ + \n#root.mnuc.backuper\ + \n\ + \n\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@10\ + .30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\r\ + \n\ + \n#:local Script AM-GlobalConfig;\ + \n\r\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\r\ + \n\ + \n#/usb1/mikro_bak_rsa.pub\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n\r\ + \n\r\ + \n#\ + \n:global MkDir;\ + \n\r\ + \n\ + \n#:local FetchFile Binary.backup\ + \n:local localDir \"\";\ + \n\ + \n\r\ + \n#\$MkDir \$localDir;\r\ + \n\ + \n#\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);\r\ + \n" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix (a);\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n#:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\";\r\ + \n#:global EmailGeneralCc \"\";\r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass (a); #{\r\ + \n# \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass (a); # {\r\ + \n# \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ + owner=AM-GlobalFunc policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GglobalFunc\r\ + \n# Script comment: Global functions\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n:local ExitOK false;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n#:global checkRunJob \$SriptName;\r\ + \n#:global fixCRLF;\r\ + \n#:if (\$fixCRLF != false) do={\r\ + \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ + ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ + }\r\ + \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ + et \$fixScript source ] ] \$fixScript};};\r\ + \n#}\r\ + \n:global GlobalFuncReady false;\r\ + \n\r\ + \n# Git commit id & info, expected configuration version\r\ + \n:global CommitId \"main/727/203f86a6\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 13:30:05 29.06.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 140;\r\ + \n\r\ + \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ + \n\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global IdentityShort [:pick \$Identity 0 18];\r\ + \n\r\ + \n:global devBoardName [/system/resource/get board-name];\r\ + \n:global devMode [/system/device-mode/get mode];\r\ + \n:global devCurArch [/system/resource/get architecture-name];\r\ + \n:global devCurVersion [/system/resource/get version];\r\ + \n\r\ + \n# Variables defined in AM-GlobalConfig.rsc\r\ + \n:global TerminalColorOutput;\r\ + \n:global CommentsInScripts;\r\ + \n:global DetectIpAddrDefault;\r\ + \n:global DetectIpAddrFallback;\r\ + \n:global updateChannel;\r\ + \n:global Domain;\r\ + \n:global EmailGeneralTo;\r\ + \n:global BackupAndUpdateMode;\r\ + \n\r\ + \n# Single functions, without nested functions.\r\ + \n:global MiniDateTimeStamp;\r\ + \n:global MicroDateTimeStamp;\r\ + \n\r\ + \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ + \n:global LogPrint;\r\ + \n\r\ + \n# DeviceInfo and Updates\r\ + \n:global IsCheckUpdates;\r\ + \n:global WaitCheckUpdates;\r\ + \n:global GetPubIp;\r\ + \n\r\ + \n:global GetArrDeviceInfo;\r\ + \n:global WaitArrDeviceInfo;\r\ + \n\r\ + \n:global devModel;\r\ + \n:global devRunningMode;\r\ + \n\r\ + \n:global devRbRevision;\r\ + \n:global devRbSerialNumber;\r\ + \n:global devRbVerAvail;\r\ + \n\r\ + \n:global runningChannelVersion;\r\ + \n:global runningChannel;\r\ + \n:global runningVersion;\r\ + \n\r\ + \n:global devBuildTime;\r\ + \n:global ROsVerAvail;\r\ + \n:global PkgUpdStatus;\r\ + \n:global currentUpdateChannel;\r\ + \n\r\ + \n:global ScriptInstallUpdate;\r\ + \n\r\ + \n:global DeviceInfo;\r\ + \n\r\ + \n:global OldMode;\r\ + \n\r\ + \n:global ParseKeyValueStore;\r\ + \n:global RandomDelay;\r\ + \n:global GetRandomNumber;\r\ + \n:global EscapeForRegEx;\r\ + \n:global CharacterMultiply;\r\ + \n:global CharacterReplace;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n\r\ + \n:global CommitBrief;\r\ + \n\r\ + \n:global EitherOr;\r\ + \n:global FormatLine;\r\ + \n:global GetRandom20CharAlNum;\r\ + \n:global GetRandom20CharHex;\r\ + \n:global GetRandomNumber;\r\ + \n:global Grep;\r\ + \n:global IfThenElse;\r\ + \n:global MAX;\r\ + \n:global MIN;\r\ + \n:global HumanReadableNum;\r\ + \n\r\ + \n:global IsFullyConnected;\r\ + \n:global IsDNSResolving;\r\ + \n:global IsTimeSync;\r\ + \n:global IsTimeSyncCached;\r\ + \n:global IsTimeSyncResetNtp;\r\ + \n\r\ + \n:global MkDir;\r\ + \n:global RmDir;\r\ + \n:global RmFile;\r\ + \n:global FileGet;\r\ + \n:global Unix2Dos;\r\ + \n:global UrlEncode;\r\ + \n:global WaitForFile;\r\ + \n:global ScriptLock;\r\ + \n:global SendTelegram;\r\ + \n:global NotificationFunctions;\r\ + \n:global SendNotification;\r\ + \n:global SendNotification2;\r\ + \n:global SymbolForNotification;\r\ + \n:global SymbolByUnicodeName;\r\ + \n:global ValidateSyntax;\r\ + \n:global CheckSumsVerify;\r\ + \n:global GlobalConfChanges;\r\ + \n:global GlobalConfMigration;\r\ + \n:global VersionToNum;\r\ + \n:global RequiredRouterOS;\r\ + \n:global ExitError;\r\ + \n:global ExitOnError;\r\ + \n\r\ + \n:global FetchHugeFiles;\r\ + \n:global FetchUserAgentStr;\r\ + \n:global FileExists;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n\r\ + \n:global InspectVar;\r\ + \n:global InspectVarRet;\r\ + \n:global ParseCustom;\r\ + \n\r\ + \n:set IsCheckUpdates do={\r\ + \n :local isInfo [:tobool \$1];\r\ + \n :global updateChannel;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :log info (\$0 . \" \\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ + el) do={\r\ + \n :retry command={/system/package/update set channel=\$updateChannel} \ + \_delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" Set updates channel to: \$updateChannel\");\r\ + \n }\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set currentUpdateChannel \$Channel;\r\ + \n :log info (\$0 . \" Update Channel: \" . \$Channel . \".\");\r\ + \n :local StatusPkg \"undefined\";\r\ + \n :log info (\$0 . \" Checking for updates...\");\r\ + \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ + dates without-paging as-value]->\"status\")} \\\r\ + \n delay=300ms max=5 on-error={};\r\ + \n :log info (\$0 . \" \\\$StatusPkg = \" . \$StatusPkg);\r\ + \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ + s true; } else={ :set PkgUpdStatus false; }\r\ + \n :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ + ] ];\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ + \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ + kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ + \n :return true;\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitCheckUpdates do={\r\ + \n :global IsCheckUpdates;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n :local Status \"\";\r\ + \n :local Update;\r\ + \n :local WaitCount 0;\r\ + \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ + \") && \$WaitCount < 60) do={\r\ + \n :delay 1s;\r\ + \n :set WaitCount (\$WaitCount + 1);\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n }\r\ + \n :set Update [ /system/package/update/get ];\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ + \n :set PkgUpdStatus true;\r\ + \n } else={\r\ + \n :set PkgUpdStatus false;\r\ + \n }\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ + \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ + do={\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set WaitArrDeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ + \n :delay 1s;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetArrDeviceInfo do={\r\ + \n :global LogPrint;\r\ + \n :global arrDeviceInfo;\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devBuildTime;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :local DeviceInfo;\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ + \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ + \n :local RouterBoard;\r\ + \n :local IsRouterBoard false;\r\ + \n :local RunningMode \"\";\r\ + \n\r\ + \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ + \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ + \n :set runningChannelVersion \$VersionString;\r\ + \n :set runningVersion \$VersionString;\r\ + \n :set runningChannel \"\";\r\ + \n\r\ + \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ + {\r\ + \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ + \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ + len \$VersionString ] ];\r\ + \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ + \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ + \r\ + \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :do {\r\ + \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ + \n# :set RouterBoard [ /system/routerboard/get ];\r\ + \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ + \n :set IsRouterBoard true;\r\ + \n }\r\ + \n } on-error={}\r\ + \n }\r\ + \n\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get mode ];\r\ + \n } on-error={\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get running ];\r\ + \n } on-error={\r\ + \n :set RunningMode \"\";\r\ + \n }\r\ + \n }\r\ + \n :set devRunning \$RunningMode;\r\ + \n\r\ + \n :if (\$IsRouterBoard = true) do={\r\ + \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ + \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ + \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ + ];\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n :set devRbRevision \"\";\r\ + \n :set devRbSerialNumber \"\";\r\ + \n }\r\ + \n\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n\r\ + \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ + \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ + \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ + \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ + \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ + \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ + \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ + \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ + ion;\r\ + \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ + \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ + \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ + \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ + current-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ + upgrade-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ + \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ + alled-version\") ];\r\ + \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ + \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ + ) ];\r\ + \n\r\ + \n :set arrDeviceInfo \$DeviceInfo;\r\ + \n :return \$DeviceInfo;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :global CommitBrief;\r\ + \n\r\ + \n :local License [/system/license/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Info [ \$GetArrDeviceInfo ];\r\ + \n\r\ + \n :if ([ :typeof \$Info ] != \"array\") do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :return ( \\\r\ + \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Location\" (\$Snmp->\"location\") ] . \"\\n\") ]\ + \_. \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Contact\" (\$Snmp->\"contact\") ] . \"\\n\") ] .\ + \_\\\r\ + \n \"Hardware:\\n\" . \\\r\ + \n [ \$FormatLine \" Board\" (\$Info->\"board-name\") ] . \"\\n\" . \ + \\\r\ + \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ + n\" . \\\r\ + \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ + \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ + \\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ + \")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ + \\n\" . \\\r\ + \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ + \_\"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ + \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ + \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ + \"\\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ + \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ + \_\"\\n\") ] . \\\r\ + \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ + \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ + ) \\\r\ + \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ + \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS-Scripts:\\n\" . \\\r\ + \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ + \n}\r\ + \n\r\ + \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ + tionFunctions ({})}\r\ + \n\r\ + \n:set GetRandom20CharAlNum do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ + FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ + \n}\r\ + \n\r\ + \n:set GetRandom20CharHex do={:global EitherOr; :return [ :rndstr length=[\ + \_\$EitherOr [ :tonum \$1 ] 20 ] from=\"0123456789abcdef\" ]; }\r\ + \n:set GetRandomNumber do={:global EitherOr; :return [ :rndnum from=0 to=[\ + \_\$EitherOr [ :tonum \$1 ] 4294967295 ] ]; }\r\ + \n\r\ + \n:global checkRunJob;\r\ + \n:set checkRunJob do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLock; \r\ + \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ + \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ + :set Job [ /system/script/job/get \$Job ];\r\ + \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ + stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ + \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ + lse; \r\ + \n}\r\ + \n\r\ + \n:set InspectVar do={\r\ + \n :global InspectVarRet;\r\ + \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ + \n}\r\ + \n\r\ + \n:set CommitBrief do={\r\ + \n :global CommitId;\r\ + \n :global CommitInfo;\r\ + \n :if (\$CommitId = \"unknown\") do={\r\ + \n :return \"unknown\";\r\ + \n }\r\ + \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\r\ + \n}\r\ + \n\r\ + \n:set InspectVarRet do={\r\ + \n :local Input \$1;\r\ + \n :local Level (0 + [ :tonum \$2 ]);\r\ + \n :global CharacterReplace;\r\ + \n :global IfThenElse;\r\ + \n :global InspectVarRet;\r\ + \n :local IndentReturn do={\r\ + \n :local Prefix [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Level [ :tonum \$3 ];\r\ + \n :global CharacterMultiply;\r\ + \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ + fix . \"-> \" . \$Value);\r\ + \n }\r\ + \n :local TypeOf [ :typeof \$Input ];\r\ + \n :local Len [ :len \$Input ];\r\ + \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ + \n :if (\$TypeOf = \"array\") do={\r\ + \n :foreach Key,Value in=\$Input do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ + \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ + \n }\r\ + \n } else={\r\ + \n :if (\$TypeOf = \"str\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ + \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ + \n }\r\ + \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ + \n }\r\ + \n }\r\ + \n :if (\$TypeOf != \"nothing\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ + \_\\\r\ + \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ + \n }\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set GetPubIp do={\r\ + \n :global DetectIpAddrDefault;\r\ + \n :global DetectIpAddrFallback;\r\ + \n\r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n :local JobName [ :jobname ];\r\ + \n\r\ + \n :do {\r\ + \n :log debug (\$0 . \" Trying to detect public IP using default serv\ + ice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=50ms max=5 on-error={:log error (\$JobName . \" Failed to \ + detect public IP using default service: \" . \$Url . \".\")}\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed to detect public IP using default serv\ + ice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ + vice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=200ms max=5 on-error={:log error (\$JobName . \" Failed to\ + \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ + \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ + {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\r\ + \n :return \$PubIpAddr;\r\ + \n}\r\ + \n\r\ + \n:set FormatLine do={\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Indent [ :tonum \$3 ];\r\ + \n :local Spaces;\r\ + \n :local Return \"\";\r\ + \n :global CharacterMultiply;\r\ + \n :global EitherOr;\r\ + \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ + \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ + \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ + \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ + n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ + \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ + \$Return ]) ] . \$Value)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ParseCustom do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ + \n :local End [ :tostr \$3 ];\r\ + \n :local Num [ :tonum \$4 ];\r\ + \n :local Return;\r\ + \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ + \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ + \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ + lse={\r\ + \n :set End [:find \$rest \$End];\r\ + \n :set Return [:pick \$rest 0 \$End];\r\ + \n }\r\ + \n:return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set LogPrint do={\r\ + \n :local Severity [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Message [ :tostr \$3 ];\r\ + \n :global PrintDebug;\r\ + \n :global PrintDebugOverride;\r\ + \n :global EitherOr;\r\ + \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ + ];\r\ + \n :local PrintSeverity do={\r\ + \n :global TerminalColorOutput;\r\ + \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ + \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ + \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ + \n}\r\ + \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ + \r\ + \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ + \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ + \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ + \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ + \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ + \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ + erity \$Severity ] . \": \" . \$Message)}\r\ + \n}\r\ + \n\r\ + \n:set CertificateAvailable do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :local UseFor [ :tostr \$2 ];\r\ + \n\r\ + \n :global CertificateDownload;\r\ + \n :global ParseKeyValueStore;\r\ + \n\r\ + \n :if ([ :len \$UseFor ] = 0) do={\r\ + \n :log warning (\$0 . \"The intended use is undefined!\");\r\ + \n :set UseFor \"undefined\";\r\ + \n }\r\ + \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ + \n [ /certificate/settings/get crl-download ] = true && \\\r\ + \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ + \n :log warning (\$0 . \"This system has low free flash space but \" . \ + \\\r\ + \n \"is configured to download certificate CRLs to system!\");\r\ + \n }\r\ + \n :if ([ :len \$CommonName ] = 0) do={\r\ + \n :log warning (\$0 . \"No CommonName given!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ + \r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ + \_] ] > 0) do={\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ + \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n :log info (\$0 . \"There are \" . \$CertCount . \" Certificates with\ + \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ + e ] ];\r\ + \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ + ertVal->\"skid\")) do={\r\ + \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ + \_= 0) do={\r\ + \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ + >\"CN\");\r\ + \n :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ + is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ + \") ] ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateDownload do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :global ScriptUpdatesBaseUrl;\r\ + \n :global ScriptUpdatesUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ + \r\ + \n \"CommonName '\" . \$CommonName . \"'.\");\r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ + -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ + sUrlSuffix) \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0 && \\\r\ + \n !(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" \ + || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \ + \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ + \r\ + \n [ :len [ /certificate/builtin/find where common-name=\"ISRG\ + \_Root X1\" ] ] > 0)) do={\r\ + \n :log error (\$0 . \" Required certificate is not available.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ + er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ + n ({ \$CommonName }) ] \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n :if ([ /file/get \$FileName size ] = 0) do={\r\ + \n \$RmFile \$FileName;\r\ + \n :error false;\r\ + \n }\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ + e . \"' still unavailable!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ + \"_[0-9]+\\\$\") ] do={\r\ + \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateNameByCN do={\r\ + \n :local Match [ :tostr \$1 ];\r\ + \n :global CleanName;\r\ + \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ + rint=\$Match or name=\$Match) ]->0);\r\ + \n :if ([ :len \$Cert ] = 0) do={\r\ + \n :log warning (\$0 .\" No matching certificate found.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ + \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FileExists do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local Type [ :tostr \$2 ];\r\ + \n :global FileGet;\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={ :return false; }\r\ + \n :if ([ :len (\$FileVal->\"size\") ] = 0) do={ :return false; }\r\ + \n :if ([ :len \$Type ] = 0 || \$FileVal->\"type\" = \$Type) do={ :return\ + \_true; }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set Grep do={\r\ + \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ + \n :local Pattern [ :tostr \$2 ];\r\ + \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ + }\r\ + \n :do {\r\ + \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ + \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ + \$Line}\r\ + \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ + Input ] ];\r\ + \n } while=([ :len \$Input ] > 0);\r\ + \n :return [];\r\ + \n}\r\ + \n\r\ + \n:set HumanReadableNum do={\r\ + \n :local Input [ :tonum \$1 ];\r\ + \n :local Base [ :tonum \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global IfThenElse;\r\ + \n :local Prefix \"kMGTPE\";\r\ + \n :local Pow 1;\r\ + \n :set Base [ \$EitherOr \$Base 1024 ];\r\ + \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ + \n :if (\$Input < \$Base) do={:return \$Input}\r\ + \n :for I from=0 to=[ :len \$Prefix ] do={\r\ + \n :set Pow (\$Pow * \$Base);\r\ + \n :if (\$Input / \$Base < \$Pow) do={\r\ + \n :set Prefix [ :pick \$Prefix \$I ];\r\ + \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ + \n :local Tmp2 (\$Tmp1 / 100);\r\ + \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ + \n :return (\$Tmp2 . \".\" . \\\r\ + \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ + 2 ] + 1) ] . \\\r\ + \n \$Prefix . \$Bin);\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set CleanFilePath do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CharacterReplace;\r\ + \n :while (\$Path ~ \"//\") do={ :set \$Path [ \$CharacterReplace \$Path \ + \"//\" \"/\" ]; }\r\ + \n :if ([ :pick \$Path 0 ] = \"/\") do={ :set Path [ :pick \$Path 1 [ :le\ + n \$Path ] ]; }\r\ + \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={ :set Path [ \ + :pick \$Path 0 ([ :len \$Path ] - 1) ]; }\r\ + \n :return \$Path;\r\ + \n}\r\ + \n\r\ + \n:set CleanName do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Return \"\";\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ + stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ + \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ + \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ + ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ + \n };\r\ + \n :set Return (\$Return . \$Char)};\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set RandomDelay do={\r\ + \n :local Time [ :tonum \$1 ];\r\ + \n :local Unit [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global GetRandomNumber;\r\ + \n :global MAX;\r\ + \n :if (\$Time = 0) do={:return false}\r\ + \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ + [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ + \n}\r\ + \n\r\ + \n:set EscapeForRegEx do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ExitError do={\r\ + \n :local ExitOK [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Error [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :if (\$ExitOK = \"false\") do={\r\ + \n :log error (\$Name [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\$\") \ + \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ + ror\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ + \$Error) \".\" ]);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set ExitOnError do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :local Error [ :tostr \$2 ];\r\ + \n :global IfThenElse;\r\ + \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ + \\\$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ + r\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ + rror) \".\" ]);\r\ + \n}\r\ + \n\r\ + \n:set MiniDateTimeStamp do={\r\ + \n :local mikro [ :tobool \$1 ];\r\ + \n /system/clock;\r\ + \n :local vdate [get date];\r\ + \n :local vtime [get time];\r\ + \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ + \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ + \n :local M [:tonum \$MM];\r\ + \n :if (\$vdate ~ \".../../....\") do={\r\ + \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ + \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ + PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ + \n :if (\$M>12) do={:set M (\$M - 12)}\r\ + \n :set MM [:pick (100 + \$M) 1 3];\r\ + \n }\r\ + \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ + \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ + \n :local HH [:pick \$vtime 0 2];\r\ + \n :local mm [:pick \$vtime 3 5];\r\ + \n :local ss [:pick \$vtime 6 8];\r\ + \n :local Return;\r\ + \n :if (\$mikro = true) do={\r\ + \n :set Return ([:pick \$yyyy 2 4] . [:pick \$dd 0 1] . [:pick \$HH 0\ + \_1] . [:pick \$mm 3 4] . [:pick \$ss 6 7]);\r\ + \n } else={\r\ + \n :set Return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ + \r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set WaitForFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local WaitTime [ :totime \$2 ];\r\ + \n :global CleanFilePath;\r\ + \n :global EitherOr;\r\ + \n :global MAX;\r\ + \n :set FileName [ \$CleanFilePath \$FileName ];\r\ + \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } delay=\$Delay max=10;\r\ + \n } on-error={ }\r\ + \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ + \n :do {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } on-error={ }\r\ + \n :delay \$Delay;\r\ + \n :set Delay (\$Delay * 3 / 2);\r\ + \n }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set FileGet do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global WaitForFile;\r\ + \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileVal false;\r\ + \n :do {\r\ + \n :set FileVal [ /file/get \$FileName ];\r\ + \n } on-error={ }\r\ + \n :return \$FileVal;\r\ + \n}\r\ + \n\r\ + \n:set RmDir do={\r\ + \n :local DirName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n };\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ + \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ + ory.\");\r\ + \n :return false;\r\ + \n };\r\ + \n :onerror Err {\r\ + \n /file/remove \$DirName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n };\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set RmFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :log debug (\$0 . \" Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ + \_. \$Err); :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MkDir do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CleanFilePath;\r\ + \n :global FileGet;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :local MkTmpfs do={\r\ + \n :global WaitForFile;\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ + \n \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ + /get total-memory ] / 3);\r\ + \n \$WaitForFile \"tmpfs\";\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Creating disk of type tmpfs failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :set Path [ \$CleanFilePath \$Path ];\r\ + \n :if (\$Path = \"\") do={\r\ + \n :return true;\r\ + \n }\r\ + \n :log debug (\$0 . \" Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n :log debug (\$0 . \" ... which already exists.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=\$Path;\r\ + \n \$WaitForFile \$Path;\r\ + \n } do={\r\ + \n :log warning (\$0 . \" Making directory '\" . \$Path . \"' failed: \ + \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set CharacterReplace do={\r\ + \n :local String [ :tostr \$1 ];\r\ + \n :local ReplaceFrom [ :tostr \$2 ];\r\ + \n :local ReplaceWith [ :tostr \$3 ];\r\ + \n :local Return \"\";\r\ + \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ + \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ + \r\ + \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ + \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ + \r\ + \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ + \_\$String ] ];\r\ + \n }\r\ + \n :return (\$Return . \$String);\r\ + \n}\r\ + \n\r\ + \n:set IfThenElse do={\r\ + \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ + \$2};\r\ + \n :return \$3;\r\ + \n}\r\ + \n\r\ + \n:set EitherOr do={\r\ + \n :global IfThenElse;\r\ + \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ + \$1 \$2 ]}\r\ + \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ + \_\$1 \$2 ]}\r\ + \n# this works for boolean values, literal ones with parentheses\r\ + \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ + \n}\r\ + \n\r\ + \n:set ParseKeyValueStore do={\r\ + \n :local Source \$1;\r\ + \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ + \n :do {\r\ + \n :return [ :deserialize from=json \$Source ];\r\ + \n } on-error={ }\r\ + \n } \r\ + \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ + }\r\ + \n :local Result ({});\r\ + \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ + \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ + \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ + \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ + \_:len \$KeyValue ] ];\r\ + \n :if (\$Value=\"true\") do={:set Value true}\r\ + \n :if (\$Value=\"false\") do={:set Value false}\r\ + \n :set (\$Result->\$Key) \$Value;\r\ + \n } else={:set (\$Result->\$KeyValue) true}\r\ + \n }\r\ + \n :return \$Result;\r\ + \n}\r\ + \n:set RequiredRouterOS do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :local Required [ :tostr \$2 ];\r\ + \n :local Warn [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ + e/update/get installed-version ] ]) do={\r\ + \n :if (\$Warn = \"true\") do={\r\ + \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ + 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ + \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ + es RouterOS \" . \$Required . \". Please update!\");\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :global LogPrint;\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set VersionToNum do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Multi 0x1000000;\r\ + \n :local Return 0;\r\ + \n :global CharacterReplace;\r\ + \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ + \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ + \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ + \r\ + \n }\r\ + \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ + \n :local Num [ :tonum \$Value ];\r\ + \n :if (\$Multi = 0x100) do={\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={\r\ + \n :set Return (\$Return + 0xff00);\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n } else={\r\ + \n :if (\$Value = \"zero\") do={ }\r\ + \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ + }\r\ + \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ + \r\ + \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ + \n }\r\ + \n }\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ + lue * \$Multi)); }\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ScriptLock do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local WaitMax [ :totime \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global ScriptLockOrder;\r\ + \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ + \n :set ScriptLockOrder ({});\r\ + \n }\r\ + \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :local JobCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ + \r\ + \n }\r\ + \n :local TicketCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :local Count 0;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ + + 1)}\r\ + \n }\r\ + \n :return \$Count;\r\ + \n }\r\ + \n :local IsFirstTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Check [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if (\$Ticket = \$Check) do={:return true}\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ + o={:return false}\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :local AddTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Add [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :while (true) do={\r\ + \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ + \n :delay 10ms;\r\ + \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ + e}\r\ + \n }\r\ + \n }\r\ + \n :local RemoveTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Remove [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ + \n :delay 10ms;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :local CleanupTickets do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ + \n }\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ + \n :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ + ist!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$JobCount \$Script ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ + \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ + t . \"', resetting!\");\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n /system/script/job/remove [ find where script=\$Script ];\r\ + \n }\r\ + \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ + \n \$AddTicket \$Script \$MyTicket;\r\ + \n :local WaitInterval (\$WaitMax / 20);\r\ + \n :local WaitTime \$WaitMax;\r\ + \n :while (\$WaitTime > 0 && \\\r\ + \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ + \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ + \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ + \n :delay \$WaitInterval;\r\ + \n }\r\ + \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ + \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$CleanupTickets \$Script;\r\ + \n :return true;\r\ + \n }\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ + once\" . \\\r\ + \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ + \_lock\" \"\" ] . \"...\");\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set SendNotification do={ :onerror Err {\r\ + \n :global SendNotification2;\r\ + \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ + \_silent=\$4 });\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n\r\ + \n:set SendNotification2 do={\r\ + \n :local Notification \$1;\r\ + \n :global NotificationFunctions;\r\ + \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ + \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ + ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\r\ + \n :global SymbolsExtra;\r\ + \n :local Symbols ({\r\ + \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ + \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ + \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ + \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ + \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ + \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ + \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ + \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ + \n \"cloud\"=\"\\E2\\98\\81\";\r\ + \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ + \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ + \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ + \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ + \n \"gear\"=\"\\E2\\9A\\99\";\r\ + \n \"heart\"=\"\\E2\\99\\A5\";\r\ + \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ + \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ + \n \"information\"=\"\\E2\\84\\B9\";\r\ + \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ + \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ + \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ + \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ + \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ + \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ + \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ + \n \"scissors\"=\"\\E2\\9C\\82\";\r\ + \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ + \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ + \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ + \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ + \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ + \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ + \n \"star\"=\"\\E2\\AD\\90\";\r\ + \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ + \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ + \n }, \$SymbolsExtra);\r\ + \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ + \n :local Special {\r\ + \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ + \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ + \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ + \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ + \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ + \n :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ + '!\");\r\ + \n :return \"\";\r\ + \n }\r\ + \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ + me) ] . \"\\EF\\B8\\8F\");\r\ + \n}\r\ + \n\r\ + \n:set SymbolForNotification do={\r\ + \n :global NotificationsWithSymbols;\r\ + \n :global SymbolByUnicodeName;\r\ + \n :global IfThenElse;\r\ + \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ + \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ + \n :local Return \"\";\r\ + \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ + mbolByUnicodeName \$Symbol ])}\r\ + \n :return (\$Return . \" \");\r\ + \n}\r\ + \n\r\ + \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ + \n:set UrlEncode do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ + \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ + %24\"; \"%25\"; \"%26\"; \"%27\";\r\ + \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ + \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ + \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ + \"%7C\"; \"%7D\"; \"%7E\" };\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :local Replace [ :find \$Chars \$Char ];\r\ + \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ + ce)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set IsDNSResolving do={\r\ + \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsFullyConnected do={\r\ + \n :global IsDNSResolving;\r\ + \n :global IsTimeSync;\r\ + \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ + \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set IsTimeSync do={\r\ + \n :global IsTimeSyncCached;\r\ + \n :global IsTimeSyncResetNtp;\r\ + \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ + \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ + \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :local Uptime [ /system/resource/get uptime ];\r\ + \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n }\r\ + \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ + \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ + ;\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n /system/ntp/client/set enabled=no;\r\ + \n :delay 20ms;\r\ + \n /system/ntp/client/set enabled=yes;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ + \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ + \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ + ee license and x86.\";\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ + \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set FetchHugeFiles do={\r\ + \n :local ScriptName [ :tostr \$1 ];\r\ + \n :local Url [ :tostr \$2 ];\r\ + \n :local CheckCert [ :tostr \$3 ];\r\ + \n\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ + ithout-crl\" ];\r\ + \n\r\ + \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ + \n :if ([ \$MkDir \$DirName ] = false) do={\r\ + \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ + \$GetRandom20CharAlNum ]);\r\ + \n :onerror Err {\r\ + \n /tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName \ + \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ + lue;\r\ + \n } do={\r\ + \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ + \n \$RmFile \$FileName;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$Url . \" - \"\ + \_. \$Err);\r\ + \n \$RmDir \$DirName;\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ + \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$Url . \" did\ + \_not show up.\");\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :local FileSize [ /file/get \$FileName size ];\r\ + \n :local Return \"\";\r\ + \n :local VarSize 0;\r\ + \n :while (\$VarSize != \$FileSize) do={\r\ + \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ + 768 file=\$FileName as-value ]->\"data\"));\r\ + \n :set FileSize [ /file/get \$FileName size ];\r\ + \n :set VarSize [ :len \$Return ];\r\ + \n :if (\$VarSize > \$FileSize) do={\r\ + \n :delay 100ms;\r\ + \n }\r\ + \n }\r\ + \n \$RmDir \$DirName;\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global CommitBrief;\r\ + \n :global IfThenElse;\r\ + \n :local Resource [ /system/resource/get ];\r\ + \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ + \_\$Resource->\"architecture-name\" . \\\r\ + \n \" \" . \$Caller . \"/Fetch (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ + CommitBrief ] . \")\");\r\ + \n}\r\ + \n\r\ + \n:set ScriptInstallUpdate do={ :onerror Err {\r\ + \n :local Scripts [ :toarray \$1 ];\r\ + \n :local NewComment [ :tostr \$2 ];\r\ + \n :global InitSetup;\r\ + \n\r\ + \n :global CommitId;\r\ + \n :global ScriptUpdatesCRLF;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global CertificateAvailable;\r\ + \n :global CheckSumsVerify;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SumsDirAndFileName;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global EitherOr;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global Grep;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global RequiredRouterOS;\r\ + \n :global SendNotification2;\r\ + \n :global SymbolForNotification;\r\ + \n :global ValidateSyntax;\r\ + \n :global CommentsInScripts;\r\ + \n\r\ + \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ + hout.\");\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ + \r\ + \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ + \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ + Vados\\n\" comment=\$NewComment;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local CommitIdBefore \$CommitId;\r\ + \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ + \n :local ReloadGlobal false;\r\ + \n :local DeviceMode [ /system/device-mode/get ];\r\ + \n\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSums ({});\r\ + \n :do {\r\ + \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ + iptsUrlSuffix);\r\ + \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ + \r\ + \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ + ficate=yes-without-crl \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ + =user as-value ]->\"data\") ];\r\ + \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ + s\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ + ];\r\ + \n :local SourceNew;\r\ + \n\r\ + \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ + \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ + \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ + \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ + \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ + iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ + \"'!\");\r\ + \n }\r\ + \n }\r\ + \n :do {\r\ + \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ + \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ + e\" . \"', as requested.\");\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ + ptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ + rce\") ] ] = \$CheckSum) do={\r\ + \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ + >\"name\" . \"' matches, ignoring.\");\r\ + \n :error true;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ + \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ + fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ + ng without.\");\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ + lScriptsUrl ];\r\ + \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ + lobalScriptsUrlSuffix ];\r\ + \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ + Suffix);\r\ + \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ + name\") . \"' from url: \" . \$Url);\r\ + \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ + \r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ + ut=user as-value ];\r\ + \n :if (\$Result->\"status\" = \"finished\") do={\r\ + \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ + \n } \r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ + al->\"name\" . \"': \" . \$Err);\r\ + \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ + \?\");\r\ + \n /system/script/remove \$Script;\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ + riptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :len \$CheckSum ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ + pdates with 'ignore=true' in comment.\");\r\ + \n }\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$SourceNew ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ + >\"name\") . \"'.\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ + \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ + lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ + \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ + \$ScriptVal->\"source\")) do={\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ + . \"' source did not change. End of lines set to CRLF.\");\r\ + \n if (\$ScriptUpdatesCRLF = false) do={\r\ + \n :put [ :tolf \$SourceNew ];\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ + ) . \"' source update end of lines to LF.\");\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ + l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if (\$CommentsInScripts = true) do={\r\ + \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ + \_\") ];\r\ + \n :if ([ :len \$CommentLine ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ + iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ + noring!\");\r\ + \n :error false;\r\ + \n } else={\r\ + \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ + ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ + ] + 2) [ :len \$CommentLine] ]) do={\r\ + \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ + \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ + ;\r\ + \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ + ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ + \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ + omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ + ded!\");\r\ + \n } else={\r\ + \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ + al->\"name\") . \"' did not change.\");\r\ + \n :error false;\r\ + \n }\r\ + \n } \r\ + \n }\r\ + \n\r\ + \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ + \"\\23 requires RouterOS, \") ] ]->version);\r\ + \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ + \_false ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires RouterOS \" . \\\r\ + \n \$RequiredROS . \", which is not met by your installation. I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ + \\23 requires device-mode, \") ] ];\r\ + \n :local MissingDM ({});\r\ + \n :foreach Feature,Value in=\$RequiredDM do={\r\ + \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ + ceMode->\$Feature) = false) do={\r\ + \n :set MissingDM (\$MissingDM, \$Feature);\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len \$MissingDM ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires disabled \" . \\\r\ + \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ + ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n \r\ + \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ + ript comment: \" . (\$ScriptVal->\"comment\"));\r\ + \n\r\ + \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ + Val->\"comment\") \\\r\ + \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ + F \$SourceNew ] \$Script;\r\ + \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ + \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ + \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ + o={\r\ + \n :set ReloadGlobal true;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n :if (\$ReloadGlobal = true) do={\r\ + \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ + \");\r\ + \n :onerror Err {\r\ + \n :global InitSetup (a);\r\ + \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ + \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ + ctions failed! \" . \$Err)}\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ + \n \$LogPrint warning \$0 (\"The configuration version decreased from \ + \" . \\\r\ + \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ + \n \". Installed an older version\?\");\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ + \n :global GlobalConfChanges;\r\ + \n :global GlobalConfMigration;\r\ + \n :local ChangeLogCode;\r\ + \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ + \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ + \n :onerror Err {\r\ + \n [ :parse \$ChangeLogCode ];\r\ + \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ + . \$Err)}\r\ + \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ + dation!\")}\r\ + \n }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ + \n :do {\r\ + \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ + \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ + \_\" is not available.\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ + \_. \" failed syntax validation!\");\r\ + \n :error false}\r\ + \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ + . \": \" . \$Migration);\r\ + \n :onerror Err {\r\ + \n [ :parse \$Migration ];\r\ + \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ + \_\$I . \" failed to run: \" . \$Err)}\r\ + \n } on-error={ }\r\ + \n }\r\ + \n }\r\ + \n :local NotificationMessage (\"The configuration version on \" . \$Id\ + entity . \" increased \" . \\\r\ + \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ + d modification. \" . \\\r\ + \n \"Please review and update global-config-overlay, then re-run glo\ + bal-config.\");\r\ + \n \$LogPrint info \$0 (\$NotificationMessage);\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ + \");\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ + \r\ + \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ + \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ + \n }\r\ + \n } else={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nNews and\ + \_changes are not available.\");\r\ + \n\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={ :set GlobalConfChanges; \ + } else={ :global GlobalConfChanges (a); }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={ :set GlobalConfMigrati\ + on; } else={ :global GlobalConfMigration (a); }\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n\r\ + \n# load modules\r\ + \n:foreach Script in=[ /system/script/find where name ~ \"^(global-functio\ + ns\\\\.d|mod)/.\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :if ([ \$ValidateSyntax (\$ScriptVal->\"source\") ] = true) do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' f\ + ailed to run: \" . \$Err);\r\ + \n }\r\ + \n } else={\r\ + \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' fai\ + led syntax validation, skipping.\");\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# Add and fix global scheduler\r\ + \n:put \"Add or/and fix Global scheduler...\";\r\ + \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ + ; }\";\r\ + \n:local Comment \"Every Day Set Global Environment Variables\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ + = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ + ent=\$OnEvent start-time=startup;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ + \_do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ + ) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n}\r\ + \n# Add Update Script scheduler\r\ + \n:put \"Add or/and fix Update Script scheduler\";\r\ + \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ + \r\ + \n:set Comment \"Every Day Check For Update Scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ + \" ] ] = 0) do={\r\ + \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ + start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n}\r\ + \n\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ + \_not ready.\"); }; } delay=100ms max=5;\r\ + \n\r\ + \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ + \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ + \") ] . \\\r\ + \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ + \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ + \n # signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n:set ExitOK true;\r\ + \n\r\ + \n:log info (\$0 . \"Global configs ready!\");\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n}\r\ + \n" +add comment=\ + "Lookup IP addresses for RKN list and add them to firewall address-list" \ + dont-require-permissions=no name=AM-RKN-dnsLookup owner=AM-RKN-dnsLookup \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-RKN-dnsLookup\r\ + \n# Script comment: Lookup IP addresses for RKN list and add them to firew\ + all address-list\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n#\r\ + \n# Script description: This script is intended to be run periodically, e.\ + g. once a day, to update the IP addresses in the firewall address-list bas\ + ed on the RKN list.\r\ + \n# It resolves the domain names in the RKN list and a\ + dds the corresponding IP addresses to the specified firewall address-list.\ + \r\ + \n# The script also handles CNAME records by following\ + \_them until it finds A records.\r\ + \n# Usage:\r\ + \n# /system/script { run AM-RKN-dnsLookup; }\r\ + \n:local ScriptName [ :jobname ];\r\ + \n\r\ + \n:global dnsLookupReady false;\r\ + \n:if ([:typeof \$dnsLookupReady] != \"boolean\") do={ :set dnsLookupReady\ + \_true; }\r\ + \nwhile (!\$dnsLookupReady) do={ :nothing; }\r\ + \n:set dnsLookupReady false;\r\ + \n\r\ + \n:local arrRKN {\r\ + \n \"telegra.ph\"\r\ + \n \"grani.ru\"\r\ + \n \"xhamster.com\"\r\ + \n \"lostfilm.tv\"\r\ + \n \"rutracker.org\"\r\ + \n \"lurkmore.to\"\r\ + \n \"dou.ua\"\r\ + \n \"youporn.com\"\r\ + \n \"pornolab.net\"\r\ + \n \"crimerussia.com\"\r\ + \n \"telegram.org\"\r\ + \n \"api.telegram.org\"\r\ + \n \"facebook.com\"\r\ + \n \"instagram.com\"\r\ + \n \"x.com\"\r\ + \n \"twitter.com\"\r\ + \n \"youtube.com\"\r\ + \n \"googleapis.com\"\r\ + \n \"youtu.be\"\r\ + \n \"googlevideo.com\"\r\ + \n \"gstatic.com\"\r\ + \n \"googleusercontent.com\"\r\ + \n \"nhacmp3youtube.com\"\r\ + \n \"telegram.me\"\r\ + \n \"t.me\";}\r\ + \n\r\ + \n:local ListRKN \"RKN-dnsLookup\";\r\ + \n:local ListComment (\"ListRKN managed by \" . \$ScriptName);\r\ + \n:foreach aListItem in=[/ip/firewall/address-list find list=\$ListRKN] do\ + ={\r\ + \n /ip firewall address-list remove \$aListItem;\r\ + \n}\r\ + \n:foreach aItem in=\$arrRKN do={\r\ + \n# :do {\r\ + \n :retry delay=500ms max=5 on-error={:log error \"dns resolve fail\ + ure [ \$aItem - resolve ip ]\"} command={:resolve \$aItem}\r\ + \n# } on-error={\r\ + \n# :log error \"dns resolve failure [ \$arItem - resolve ip ]\";\r\ + \n# }\r\ + \n :foreach dnsRecord in=[/ip dns cache all find where (name=\$aItem)] \ + do={\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"A\") do={\r\ + \n :local newAddress [/ip dns cache all get \$dnsRecord data];\ + \r\ + \n :do {\r\ + \n /ip firewall address-list add list=\$ListRKN address=\$newA\ + ddress comment=\$aItem;\r\ + \n :log warning \"Successfully adding ip to list A record: \ + \$dnsRecord, address: \$newAddress domain: \$aItem\";\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list A record: \$dn\ + sRecord, address: \$newAddress domain: \$aItem\";\r\ + \n }\r\ + \n }\r\ + \n :if ([/ip dns cache all get \$dnsRecord type]=\"CNAME\") do={\r\ + \n :local cname;\r\ + \n :local nextCname;\r\ + \n :local cnameAddress;\r\ + \n :set cname [/ip dns cache all find where (name=\$aItem && ty\ + pe=\"CNAME\")];\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip dns \ + cache all get \$cname data] && type=\"CNAME\")];\r\ + \n :while (\$nextCname != \"\") do={\r\ + \n :set cname \$nextCname;\r\ + \n :set nextCname [/ip dns cache all find where (name=[/ip \ + dns cache all get \$cname data] && type=\"CNAME\")];\r\ + \n }\r\ + \n :foreach aRecord in=[/ip dns cache all find where (name=[/ip\ + \_dns cache all get \$cname data] && type=\"A\")] do={\r\ + \n :do {\r\ + \n :set cnameAddress [/ip dns cache all get \$aRecord d\ + ata];\r\ + \n /ip firewall address-list add list=\$ListRKN address\ + =\$cnameAddress comment=\$aItem;\r\ + \n :log warning \"Succesfully adding ip to list CNAME r\ + ecord: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \ + \$aItem.\";\r\ + \n# /ip firewall raw add action=add-dst-to-address-list\ + \_address-list=\$ListRKN address-list-timeout=none-dynamic chain=preroutin\ + g comment=\$aItem content=\$aItem;\r\ + \n } on-error={\r\ + \n :log error \"error when adding ip to list CNAME reco\ + rd: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \$aI\ + tem.\";\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:if ([ :len [ /system/scheduler/find where name=\$ScriptName ] ] = 0) do\ + ={\r\ + \n :log error (\$ScriptName . \"System Scheduler for script: \" . \$Scri\ + ptName . \" is NOT SET! Fix It Now!\");\r\ + \n /system/scheduler/add name=\$ScriptName on-event=\"/system/script { \ + run \$ScriptName; }\" comment=\"Update RKN DNS Looup\" interval=00:30:00 p\ + olicy=\"ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon\"\ + \_start-time=startup;\r\ + \n }\r\ + \n:set dnsLookupReady true;\r\ + \ndelay 2s; \r\ + \n:global dnsLookupReady (a);\r\ + \n" +add dont-require-permissions=no name="renameLists " owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + local oldName \"Test\";\ + \n:local newName \"Test-IP\";\ + \n/ip firewall address-list\ + \n:foreach i in=[find list=\$oldName] do={\ + \nset \$i list=\$newName;\ + \n}\ + \n" +add dont-require-permissions=no name=IPv6-Settings owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + #############Script Settings##################\ + \n\ + \n:local \"IF-TUN\" \"6to4-tun\"\ + \n:local \"IF-LOC\" \"Bridge-LAN\"\ + \n:local \"POOL-6TO4\" \"poolV6-local\"\ + \n:local \"force-update\" false\ + \n############ use then static ip #######################\ + \n:local \"lease-address\" [/ip address get [find interface=\$\"IF-LOC\"] \ + address]\ + \n#:local \"interface\" \"ext\"\ + \n:local bound 0\ + \n\ + \n###############################################\ + \n\ + \n:local 6to4prefix do={\ + \n :global dec2hex\ + \n :local ipv4 \$1\ + \n :local ipv6 \"2002:\"\ + \n :for i from=0 to=2 step=1 do={ \ + \n :if ( \$i = 2) do={\ + \n :set ipv6 (\$ipv6.\":\")\ + \n }\ + \n :local fp [:find \$ipv4 \".\"]\ + \n :if ( \$fp > 0 ) do={\ + \n :set ipv6 (\$ipv6.[\$dec2hex [:pick \$ipv4 0 \$fp]])\ + \n :set ipv4 [:pick \$ipv4 (\$fp + 1 ) [:len \$ipv4]]\ + \n }\ + \n }\ + \n :return (\$ipv6.[\$dec2hex \$ipv4])\ + \n}\ + \n:local \"str_replace\" do={\ + \n :local \"str-pos\" [:find \$1 \$2]\ + \n :local \"str-len\" [:len \$2]\ + \n :local str \"\"\ + \n :local rest \$1\ + \n :while (\$\"str-pos\" >= 0) do={\ + \n :local t [:pick \$rest 0 \$\"str-pos\"]\ + \n :if ( \$4 > 0 ) do={\ + \n :for i from=1 to=(\$4 - [:len \$t]) step=1 do={\ + \n :set str (\$str.\$5)\ + \n }\ + \n }\ + \n :set str (\$str.\$t.\$3)\ + \n :set rest [:pick \$rest (\$\"str-pos\"+\$\"str-len\") [:len \$re\ + st]]\ + \n :set \"str-pos\" [:find \$rest \$2]\ + \n }\ + \n :return (\$str.\$rest)\ + \n}\ + \n\ + \n:if (\$bound=1) do={\ + \n :local t [:find \$\"lease-address\" \"/\"]\ + \n\ + \n :if ( \$t >= 0 ) do={\ + \n :set \"lease-address\" [:pick \$\"lease-address\" 0 \$t]\ + \n }\ + \n\ + \n :if ( [/interface 6to4 print count-only where name=\$\"IF-TUN\"] = 0\ + ) do={\ + \n /interface 6to4 add !keepalive local-address=\$\"lease-address\"\ + \_mtu=1280 name=\$\"IF-TUN\" remote-address=10.30.30.0\ + \n :set \"force-update\" true\ + \n }\ + \n\ + \n :local \"IPv4-TUN\" [/interface 6to4 get [find name=\$\"IF-TUN\"] lo\ + cal-address];\ + \n\ + \n :if ( \$\"lease-address\" != \$\"IPv4-TUN\" || \$\"force-update\" = \ + true) do={\ + \n /interface 6to4 set [find name=\$\"IF-TUN\"] local-address=\$\"l\ + ease-address\"\ + \n /ipv6 address remove [find interface=\$\"IF-TUN\"]\ + \n /ipv6 address remove [find interface=\$\"IF-LOC\"]\ + \n /ipv6 route remove [find gateway ~ \$\"IF-TUN\" and dst-address=\ + \"::/0\"]\ + \n :local \"pool-prefix\" [\$6to4prefix \$\"lease-address\"]\ + \n :if ( [/ipv6 pool print count-only where name=\$\"POOL-6TO4\"] =\ + \_0) do={ \ + \n /ipv6 pool add name=\$\"POOL-6TO4\" prefix=(\$\"pool-prefix\ + \".\":1::/64\") prefix-length=64\ + \n } else={\ + \n /ipv6 pool set [/ipv6 pool find where name=\$\"POOL-6TO4\"] \ + prefix=(\$\"pool-prefix\".\":1::/64\")\ + \n }\ + \n /ipv6 address add address=(\$\"pool-prefix\".\"::\".[\$MAC2EUI64\ + \_[/interface get [find name=\$\"interface\"] mac-address]].\"/3\") interf\ + ace=\$\"IF-TUN\" advertise=no\ + \n /ipv6 address add eui-64=yes from-pool=\$\"POOL-6TO4\" interface\ + =\$\"IF-LOC\" advertise=yes\ + \n /ipv6 route add dst-address=::/0 gateway=(\"::10.30.30.81%\".\$\ + \"IF-TUN\")\ + \n :local t [/ipv6 address get [find interface=\$\"IF-LOC\"] addres\ + s]\ + \n :set t [:pick \$t 0 [:find \$t \"/\"]]\ + \n :if ( [/ipv6 dhcp-server option print count-only where name=DNS]\ + \_= 0) do={\ + \n /ipv6 dhcp-server option add code=23 name=DNS value=(\"0x\".\ + [\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ + \n } else={\ + \n /ipv6 dhcp-server option set [/ipv6 dhcp-server option find \ + where name=DNS] value=(\"0x\".[\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ + \n }\ + \n :if ( [/ipv6 dhcp-server print count-only where interface=\$\"IF\ + -LOC\"] = 0) do={\ + \n /ipv6 dhcp-server add address-pool=\$\"POOL-6TO4\" dhcp-opti\ + on=DNS interface=\$\"IF-LOC\" lease-time=1d name=\$\"IF-LOC\"\ + \n }\ + \n :if ( [ipv6 nd print count-only where interface=\$\"IF-LOC\"] = \ + 0) do={\ + \n /ipv6 nd add advertise-dns=no interface=\$\"IF-LOC\" other-c\ + onfiguration=yes\ + \n }\ + \n }\ + \n}" +add dont-require-permissions=no name=IPv6-GlobalFunc owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + global MAC2EUI64 do={\ + \n :local EUI64 \"\"\ + \n :local MAC \$1\ + \n :local HEX2DEC \"0123456789ABCDEF\"\ + \n :for i from=0 to=5 step=1 do={\ + \n :if ( \$i = 0 ) do={\ + \n :set EUI64 [:pick \$MAC 0]\ + \n :set EUI64 (\$EUI64.[:tostr [:pick \$\"HEX2DEC\" ([:find \$\ + \"HEX2DEC\" [:pick \$MAC 1]] ^ 2)]])\ + \n }\ + \n :if ( \$i = 1 || \$i = 3) do={\ + \n :set EUI64 (\$EUI64.\":\")\ + \n }\ + \n :if ( \$i = 2 ) do={\ + \n :set EUI64 (\$EUI64.\"FF:FE\")\ + \n }\ + \n :if ( [:find \$MAC \":\"] = 2 ) do={\ + \n :set MAC [:pick \$MAC 3 [:len \$MAC]]\ + \n :set EUI64 (\$EUI64.[:pick \$MAC 0 2])\ + \n }\ + \n }\ + \n :return (\$EUI64)\ + \n}\ + \n\ + \n:global dec2hex do={\ + \n :local hex \"\"\ + \n :local dec [:tonum \$1]\ + \n :for i from=0 to=4 step=4 do={\ + \n :set hex ([:pick \"0123456789ABCDEF\" ((\$dec>>\$i)&0xf) (((\$de\ + c>>\$i)&0xf)+1)].\$hex)\ + \n }\ + \n :return ([:tostr \$hex])\ + \n}" +/user group +add name=backup policy="ssh,read,write,policy,test,web,sniff,sensitive,api,res\ + t-api,!local,!telnet,!ftp,!reboot,!winbox,!password,!romon" +/ip smb +set enabled=no interfaces=lo +/interface bridge port +add bridge=Bridge-LAN interface=ether5 +add bridge=Bridge-LAN interface=ether2 +add bridge=Bridge-LAN interface=ether4 trusted=yes +add bridge=Bridge-LAN interface=ether3 +add bridge=Bridge-LAN interface=wlan2 +add bridge=Bridge-LAN interface=wlan1 +/interface bridge settings +set use-ip-firewall=yes +/ip firewall connection tracking +set udp-timeout=10s +/ip neighbor discovery-settings +set discover-interface-list=LAN lldp-med=no lldp-poe-power=no +/ip settings +set accept-redirects=yes ipv4-multipath-hash-policy=l4 max-neighbor-entries=\ + 8192 +/ipv6 settings +set disable-ipv6=yes disable-link-local-address=yes forward=no \ + max-neighbor-entries=8192 multipath-hash-policy=l4 +/interface detect-internet +set detect-interface-list=WAN internet-interface-list=Internet \ + lan-interface-list=LAN request-interval=1m wan-interface-list=WAN +/interface l2tp-server server +set authentication=mschap2 use-ipsec=yes +/interface list member +add interface=ether4 list=WAN +add interface="ether1 - Unet" list=Internet +add disabled=yes interface=WG list=WAN +add interface=Bridge-LAN list=LAN +/interface wireguard peers +add allowed-address=0.0.0.0/0 client-allowed-address=::/0 endpoint-address=\ + 109.107.177.79 endpoint-port=29185 interface=WG name=VDSina \ + persistent-keepalive=10s public-key=\ + "zuRsO+dL/j6awaBWZ/NgnHR+bCNUjRWbaHFpdzkNnw4=" +/interface wireless cap +# +set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ + CAP-488F5A8E1ABC discovery-interfaces=Bridge-LAN enabled=yes interfaces=\ + wlan2,wlan1 lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +add address=10.8.0.2/24 interface=WG network=10.8.0.0 +/ip cloud +set update-time=no +/ip dhcp-client +add add-default-route=special-classless default-route-distance=2 \ + default-route-tables=main:2 dhcp-options=clientid,clientid_duid \ + interface="ether1 - Unet" name=client1 use-peer-dns=no use-peer-ntp=no +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ + dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ + dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ + dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ + mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ + dhcp-option-set=iVados mac-address=DE:4D:72:F3:1A:9F server=masterDHCP +add address=10.30.30.10 allow-dual-stack-queue=yes client-id=\ + ff:0:0:0:df:0:3:0:1:f0:75:5d:1e:5f:85 dhcp-option=HostName \ + dhcp-option-set=MikroNUC mac-address=F0:75:5D:1E:5F:85 server=masterDHCP \ + use-src-mac=yes +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.33,109.107.177.79 domain=WORKGROUP gateway=10.30.30.81 netmask=\ + 24 ntp-server=10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ + doh-max-server-connections=20 servers=10.30.30.33,109.107.177.79 \ + verify-doh-cert=yes +/ip dns static +add address=109.107.177.79 comment="VDSina Server DNS" name=ns1.vados.ru \ + type=A +add address=109.107.177.79 name=vds.vados.ru type=A +add comment="Local DNS server for vados.ru" disabled=yes ns=10.30.30.81 \ + regexp=*.vados.ru type=NS +add comment="*.vados.ru Regexp" disabled=yes forward-to=10.30.30.81 regexp=\ + "\".*\\\\.vados\\\\.ru\"" type=FWD +add comment="*.30.30.10.in-addr.arpa Regexp" disabled=yes forward-to=\ + 10.30.30.81 regexp="\".*\\\\.30\\\\.30\\\\.10\\\\.in-addr\\\\.arpa" type=\ + FWD +add address=10.30.30.81 comment=NS.vados.ru.local disabled=yes name=\ + ns.vados.ru.local type=A +add comment="DNS ns.vados.ru.local" disabled=yes match-subdomain=yes name=\ + vados.ru ns=ns.vados.ru.local type=NS +add address=10.30.30.33 comment=reg.vados.ru name=reg.vados.ru type=A +add address=8.8.8.8 comment="Google-dns IPv4 1" match-subdomain=yes name=\ + dns.google type=A +add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +add address=10.30.30.33 name=ros.vados.ru type=A +add address=10.30.30.95 name=vados-nuc type=A +add address=10.30.30.33 name=amster-nuc type=A +add address=10.30.30.33 name=amster type=A +add address=10.30.30.33 name=amster-reg type=A +add address=10.30.30.33 disabled=yes name=mng.vados.ru type=A +add address=10.30.30.33 name=mgr.vados.ru type=A +add address=10.30.30.33 name=prt.vados.ru type=A +add address=10.30.30.33 disabled=yes match-subdomain=yes name=\ + mikrots.vados.ru type=A +add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +add address=10.30.30.30 name=MILLER-LEN type=A +add address=10.30.30.30 name=miller type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ + dns.quad9.net type=A +add address=195.133.25.16 comment="DNS Comss" disabled=yes name=dns.comss.one \ + type=A +add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +add address=10.30.30.10 name=MikroNUC type=A +add address=10.30.30.86 disabled=yes name=MikroYellow type=A +add address=10.30.30.85 disabled=yes name=MikroMic type=A +add address=10.30.30.95 name=VADOS-NUC type=A +add address=10.30.30.98 name=VADOS-LEN type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=10.30.30.20 disabled=yes name=garage type=A +/ip firewall address-list +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=8.8.4.0/24 list=YouTube +add address=8.8.8.0/24 list=YouTube +add address=8.34.208.0/20 list=YouTube +add address=8.35.192.0/20 list=YouTube +add address=23.236.48.0/20 list=YouTube +add address=23.251.128.0/19 list=YouTube +add address=34.0.0.0/15 list=YouTube +add address=34.2.0.0/16 list=YouTube +add address=34.3.0.0/23 list=YouTube +add address=34.3.3.0/24 list=YouTube +add address=34.3.4.0/24 list=YouTube +add address=34.3.8.0/21 list=YouTube +add address=34.3.16.0/20 list=YouTube +add address=34.3.32.0/19 list=YouTube +add address=34.3.64.0/18 list=YouTube +add address=34.4.0.0/14 list=YouTube +add address=34.8.0.0/13 list=YouTube +add address=34.16.0.0/12 list=YouTube +add address=34.32.0.0/11 list=YouTube +add address=34.64.0.0/10 list=YouTube +add address=34.128.0.0/10 list=YouTube +add address=35.184.0.0/13 list=YouTube +add address=35.192.0.0/14 list=YouTube +add address=35.196.0.0/15 list=YouTube +add address=35.198.0.0/16 list=YouTube +add address=35.199.0.0/17 list=YouTube +add address=35.199.128.0/18 list=YouTube +add address=35.200.0.0/13 list=YouTube +add address=35.208.0.0/12 list=YouTube +add address=35.224.0.0/12 list=YouTube +add address=35.240.0.0/13 list=YouTube +add address=57.140.192.0/18 list=YouTube +add address=64.15.112.0/20 list=YouTube +add address=64.233.160.0/19 list=YouTube +add address=66.22.228.0/23 list=YouTube +add address=66.102.0.0/20 list=YouTube +add address=66.249.64.0/19 list=YouTube +add address=70.32.128.0/19 list=YouTube +add address=72.14.192.0/18 list=YouTube +add address=74.125.0.0/16 list=YouTube +add address=104.154.0.0/15 list=YouTube +add address=104.196.0.0/14 list=YouTube +add address=104.237.160.0/19 list=YouTube +add address=107.167.160.0/19 list=YouTube +add address=107.178.192.0/18 list=YouTube +add address=108.59.80.0/20 list=YouTube +add address=108.170.192.0/18 list=YouTube +add address=108.177.0.0/17 list=YouTube +add address=130.211.0.0/16 list=YouTube +add address=136.22.160.0/20 list=YouTube +add address=136.22.176.0/21 list=YouTube +add address=136.22.184.0/23 list=YouTube +add address=136.22.186.0/24 list=YouTube +add address=142.250.0.0/15 list=YouTube +add address=146.148.0.0/17 list=YouTube +add address=152.65.208.0/22 list=YouTube +add address=152.65.214.0/23 list=YouTube +add address=152.65.218.0/23 list=YouTube +add address=152.65.222.0/23 list=YouTube +add address=152.65.224.0/19 list=YouTube +add address=162.120.128.0/17 list=YouTube +add address=162.216.148.0/22 list=YouTube +add address=162.222.176.0/21 list=YouTube +add address=172.110.32.0/21 list=YouTube +add address=172.217.0.0/16 list=YouTube +add address=172.253.0.0/16 list=YouTube +add address=173.194.0.0/16 list=YouTube +add address=173.255.112.0/20 list=YouTube +add address=192.158.28.0/22 list=YouTube +add address=192.178.0.0/15 list=YouTube +add address=193.186.4.0/24 list=YouTube +add address=199.36.154.0/23 list=YouTube +add address=199.36.156.0/24 list=YouTube +add address=199.192.112.0/22 list=YouTube +add address=199.223.232.0/21 list=YouTube +add address=207.223.160.0/20 list=YouTube +add address=208.65.152.0/22 list=YouTube +add address=208.68.108.0/22 list=YouTube +add address=208.81.188.0/22 list=YouTube +add address=208.117.224.0/19 list=YouTube +add address=209.85.128.0/17 list=YouTube +add address=216.58.192.0/19 list=YouTube +add address=216.73.80.0/20 list=YouTube +add address=216.239.32.0/19 list=YouTube +add address=2ip.ru list=Test-IP +add address=wg.vados.ru comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" disabled=yes list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com list=NoVdsina +add address=vdsina.ru list=NoVdsina +add address=youla.ru list=NoVdsina +add address=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test-IP +add address=geoip.co list=NoVdsina +add address=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=amster disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC disabled=yes list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! disabled=yes list=NoWG +add address=wg.vados.ru comment=VDSina-vpn list=VDSina +add address=80.85.244.9 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=89.110.101.17 comment="!!!VDSina Server!!!" list=NoVdsina +add address=dns.quad9.net comment=Quad9-dns disabled=yes list=Trusted-DNS +add address=dns.google comment=Google-dns list=Trusted-DNS +add address=security.cloudflare-dns.com comment=CloudFlare-dns list=\ + Trusted-DNS +add address=time.google.com comment=Google-time list=Trusted-NTP +add address=0.ru.pool.ntp.org comment=ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=1.ru.pool.ntp.org disabled=yes list=Trusted-NTP +add address=2.ru.pool.ntp.org comment=2.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=3.ru.pool.ntp.org comment=3.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=cp.vdsina.com comment=VDSina-vpn list=VDSina +add address=vdsina.ru comment=VDSina-vpn list=VDSina +add address=ns.vados.ru comment=VDSina-vpn list=VDSina +add address=vdsina.com comment=VDSina-vpn list=VDSina +add address=cp.vdsina.ru comment=VDSina-vpn list=VDSina +add address=ns1.vdsina.ru comment=VDSina-vpn list=VDSina +add address=10.30.30.0/24 comment="Local Network" list=Local-Net +add address=10.8.0.0/24 comment="WireGuard Network" list=Local-Net +add address=146.120.64.208/29 comment="External Net" list=Unet +add address=esia.gosuslugi.ru comment=esia.gosuslugi.ru list=NoVdsina +add address=lk.gosuslugi.ru comment=lk.gosuslugi.ru list=NoVdsina +add address=trudvsem.ru comment=trudvsem.ru list=NoVdsina +add address=10.30.30.30 comment=miller disabled=yes list=NoWG +add address=10.30.30.33 comment="Direct connet to DNS servers" list=\ + Direct-DNS +add address=109.107.177.79 list=VPN-Server +add address=10.30.30.10 list=AWG-Proxy +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS" \ + connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ + udp src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input connection-state=new dst-port=53 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=!Trusted-DNS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=22,8291 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=!TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface="ether1 - Unet" protocol=\ + udp +add action=fasttrack-connection chain=forward comment=\ + "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ + connection-state=established,related,new disabled=yes +add action=accept chain=input disabled=yes dst-port=29185 in-interface=\ + "ether1 - Unet" protocol=tcp +add action=accept chain=input disabled=yes dst-port=29185 in-interface=\ + "ether1 - Unet" protocol=udp +add action=accept chain=input comment="tcp Accept input DNS queries from LAN" \ + dst-port=53 protocol=tcp src-address=10.30.30.0/24 +add action=accept chain=input comment="udp Accept input DNS queries" \ + dst-port=53 protocol=udp src-address=10.30.30.0/24 +add action=accept chain=output comment="accept WireGuard" disabled=yes \ + dst-address-list=VPN-Server out-interface="ether1 - Unet" protocol=udp \ + src-port=13231 +add action=accept chain=output disabled=yes dst-address-list=VPN-Server \ + dst-port=29185 out-interface="ether1 - Unet" protocol=udp +add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ + connection-state=established,related,new disabled=yes routing-mark=\ + !To-VPN +add action=accept chain=output disabled=yes protocol=tcp src-port=443 +add action=accept chain=output disabled=yes src-address=127.0.0.1 +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + disabled=yes ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + disabled=yes ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid in-interface="ether1 - Unet" src-address=\ + !10.30.30.0/24 +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + connection-state=new in-interface="ether1 - Unet" src-address-list=\ + !VDSina +add action=drop chain=forward comment=\ + "Filter Rule to block FB address LIST : )" disabled=yes dst-address-list=\ + facebook +add action=drop chain=forward comment=\ + "Filter Rule to block YOUTUBE address LIST : )" disabled=yes \ + dst-address-list=YouTube +add action=accept chain=input in-interface="ether1 - Unet" protocol=icmp \ + src-address-list=VDSina +add action=accept chain=input connection-state=established disabled=yes +add action=accept chain=input connection-state=related disabled=yes +/ip firewall mangle +add action=mark-routing chain=prerouting comment="Mark Routing main for NoWG" \ + disabled=yes new-routing-mark=main src-address-list=NoWG +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for NoVdsina" dst-address-list=NoVdsina \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for VDSina" dst-address-list=VPN-Server \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "Mark Routing main for MikroNuc" disabled=yes dst-address-list=AWG-Proxy \ + new-routing-mark=main src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=\ + "!!!ERROR Mark Routing main for Unet!!!" disabled=yes dst-address-list=\ + Unet new-routing-mark=main passthrough=no +add action=mark-routing chain=prerouting comment="Test-IP sites" disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=Test-IP new-routing-mark=\ + To-VPN src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=FuckRKN disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=RKN-dnsLookup \ + new-routing-mark=To-VPN passthrough=no src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment="AWG for All sites" \ + disabled=yes dst-address=!10.30.30.0/24 dst-address-list=!NoVdsina \ + new-routing-mark=*401 routing-mark=!main src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=mark-routing chain=prerouting comment="VDSIna for All sites" \ + dst-address=!10.30.30.0/24 dst-address-list=!NoVdsina new-routing-mark=\ + To-VPN routing-mark=!main src-address=10.30.30.0/24 +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" new-connection-mark=\ + VPN_No_FastTrack routing-mark=To-VPN +add action=change-mss chain=forward comment="MSS on WG" new-mss=1380 \ + out-interface=WG protocol=tcp routing-mark=To-VPN tcp-flags=syn tcp-mss=\ + 1381-65535 +add action=mark-routing chain=prerouting comment="VPN Network" dst-address=\ + 10.8.0.0/24 new-routing-mark=To-VPN src-address=10.30.30.0/24 +/ip firewall nat +add action=redirect chain=dstnat comment="udp Redirect DNS in NAT" disabled=\ + yes dst-port=53 protocol=udp src-address=10.30.30.0/24 src-address-list=\ + !NoWG to-addresses=10.30.30.33 to-ports=53 +add action=redirect chain=dstnat comment="tcp Redirect DNS in NAT" disabled=\ + yes dst-port=53 protocol=tcp src-address=10.30.30.0/24 src-address-list=\ + !NoWG to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat comment=\ + "53/tcp dst-nat to amster.loc. From VDSina Server" dst-port=53 \ + in-interface="ether1 - Unet" protocol=tcp src-address-list=VPN-Server \ + to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat comment=\ + "53/udp dst-nat to amster.loc. From VDSina Server" dst-port=53 protocol=\ + udp src-address-list=VPN-Server to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat disabled=yes dst-port=44333 in-interface=\ + "ether1 - Unet" protocol=udp src-address=!10.30.30.0/24 to-addresses=\ + 10.30.30.33 to-ports=44333 +add action=masquerade chain=srcnat comment="Default NAT" out-interface=\ + "ether1 - Unet" routing-mark=!To-VPN src-address=10.30.30.0/24 +add action=dst-nat chain=dstnat comment=amster.vados.ruhttps dst-port=443 \ + fragment=no in-interface="ether1 - Unet" protocol=tcp routing-mark=main \ + to-addresses=10.30.30.33 to-ports=443 +add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ + dst-port=80 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat comment="amster.vados.ru 3x-ui" disabled=yes \ + dst-port=2904 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=2904 +add action=dst-nat chain=dstnat comment=reg.vados.ru disabled=yes dst-port=\ + 5000 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=5000 +add action=dst-nat chain=dstnat comment="Docker swarm" disabled=yes dst-port=\ + 2377 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=2377 +add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=To-VPN to-addresses=10.30.30.33 \ + to-ports=81 +add action=dst-nat chain=dstnat comment=SSH dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp src-address-list=TRUSTED to-addresses=\ + 10.30.30.33 to-ports=22 +add action=dst-nat chain=dstnat comment="portainer agent" disabled=yes \ + dst-port=2377 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=2377 +add action=dst-nat chain=dstnat disabled=yes dst-port=22 in-interface=\ + "ether1 - Unet" protocol=tcp routing-mark=!To-VPN to-addresses=\ + 10.30.30.33 to-ports=22 +add action=masquerade chain=srcnat comment=WG dst-address-list=!NoVdsina \ + out-interface=WG routing-mark=To-VPN src-address-list=!NoWG +add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ + dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ + time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ + Bridge-LAN protocol=tcp src-address-list=KIDS time=\ + 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +/ip firewall raw +add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ + in-interface="ether1 - Unet" src-address-list="Honeypot Hacker" +add action=accept chain=prerouting comment="Trusted DNS" disabled=yes \ + in-interface-list=WAN src-address-list=Trusted-DNS +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ + content=linux.duke.edu disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=youtube.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googleapis.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=ggpht.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=youtu.be \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=ytimg.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googlevideo.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=gstatic.com \ + disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + googleusercontent.com disabled=yes +add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ + none-dynamic chain=prerouting comment="YouTube raw" content=\ + nhacmp3youtube.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ + content=rutube.ru disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment="me.com raw" \ + content=me.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "icloud.com raw" content=icloud.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "smtp.mail.me.com raw" content=smtp.mail.me.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "smtp.mail.me.com.akadns.net raw" content=smtp.mail.me.com.akadns.net \ + disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + "api.db-ip.com raw" content=api.db-ip.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + esia.gosuslugi.ru content=esia.gosuslugi.ru disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=gosuslugi.ru \ + content=gosuslugi.ru disabled=yes +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +/ip ipsec settings +set accounting=no +/ip ipsec policy +set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +/ip ipsec profile +set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +/ip proxy +set cache-administrator="" max-cache-size=none port=80,443 src-address=\ + 0.0.0.0 +/ip route +add check-gateway=none disabled=no distance=1 dst-address=0.0.0.0/0 gateway=\ + WG routing-table=To-VPN scope=30 target-scope=10 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set reverse-proxy disabled=yes +set ssh address=10.30.30.0/24 port=2222 +set winbox address=10.30.30.0/24 +set api address=10.30.30.0/24 disabled=yes +set api-ssl address=10.30.30.0/24 disabled=yes +set www-ssl certificate=Root-YE port=18443 +set www address=10.30.30.0/24 disabled=yes port=18880 +/ip service webserver +set acme-plain=no crl-plain=no graphs-plain=no graphs-secure=no index-plain=\ + no index-secure=no rest-plain=no rest-secure=no scep-plain=no \ + webfig-plain=no webfig-secure=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface=Bridge-LAN type=internal +add forced-ip=146.120.64.211 interface="ether1 - Unet" type=external +add forced-ip=109.107.177.79 interface=*E type=external +add interface=lo type=internal +add interface=wlan2 type=internal +add interface=wlan1 type=internal +/ipv6 dhcp-client +add add-default-route=yes disabled=yes interface=*F rapid-commit=no request=\ + info use-interface-duid=yes validate-server-duid=no +/ipv6 dhcp-server option sets +add name=domain-search-set options=domain-search-list +add name="=\"Client ID\"" options=HostName +/ipv6 firewall address-list +add address=::/128 comment="defconf: unspecified address" list=bad_ipv6 +add address=::1/128 comment="defconf: lo" list=bad_ipv6 +add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6 +add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6 +add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6 +add address=100::/64 comment="defconf: discard only " list=bad_ipv6 +add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6 +add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6 +add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6 +/ipv6 firewall filter +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\ + icmpv6 +add action=accept chain=input comment="defconf: accept UDP traceroute" \ + dst-port=33434-33534 protocol=udp +add action=accept chain=input comment=\ + "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\ + udp src-address=fe80::/10 +add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \ + protocol=udp +add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\ + ipsec-ah +add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\ + ipsec-esp +add action=accept chain=input comment=\ + "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +add action=drop chain=input comment=\ + "defconf: drop everything else not coming from LAN" in-interface-list=\ + !LAN +add action=accept chain=forward comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6 +add action=drop chain=forward comment=\ + "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6 +add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \ + hop-limit=equal:1 protocol=icmpv6 +add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\ + icmpv6 +add action=accept chain=forward comment="defconf: accept HIP" protocol=139 +add action=accept chain=forward comment="defconf: accept IKE" dst-port=\ + 500,4500 protocol=udp +add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\ + ipsec-ah +add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\ + ipsec-esp +add action=accept chain=forward comment=\ + "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +add action=drop chain=forward comment=\ + "defconf: drop everything else not coming from LAN" in-interface-list=\ + !LAN +/ipv6 nd +set [ find default=yes ] advertise-dns=yes disabled=yes interface=Bridge-LAN \ + managed-address-configuration=yes other-configuration=yes pref64=::/64 +/ipv6 nd prefix +add autonomous=no disabled=yes interface=Bridge-LAN on-link=no prefix=none +/ipv6 nd prefix default +set dhcp6-pd-preferred=yes +/ipv6 nd proxy +add disabled=yes interface=lo +/ipv6 nd settings +set router-advertisement-route-distance=100 +/routing settings +set single-process=no +/system clock +set time-zone-name=Europe/Moscow +/system clock manual +set time-zone=+03:00 +/system identity +set name=MikroMaster +/system logging +add action=email disabled=yes regex="* added|changed|removed *" topics=\ + system,info +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=0.ru.pool.ntp.org +add address=1.ru.pool.ntp.org +add address=2.ru.pool.ntp.org +add address=3.ru.pool.ntp.org +add address=time.google.com disabled=yes +/system package update +set check-certificate=yes-without-crl ip-version=ipv4 +/system scheduler +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Update RKN DNS Looup" disabled=yes interval=20m name=\ + AM-RKN-dnsLookup on-event="/system/script { run AM-RKN-dnsLookup; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add certificate=DigiCert-Global-Root-CA check-certificate=no comment="doh, doh\ + -url=https://security.cloudflare-dns.com/dns-query, notify, name=CloudFlar\ + e-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 http-codes="" \ + interval=10s name="CloudFlare-doh IPv4 1" port=443 test-script="" type=\ + https-get up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + name="CloudFlare-doh IPv4" port=443 test-script="" type=https-get \ + up-script="" +add comment="dns, notify, name=Google-DNS IPv4" disabled=yes dns-server=\ + 8.8.8.8 down-script="" host=dns.google http-codes="" name=\ + "Google-DNS IPv4" test-script="" type=dns up-script="" +add certificate=GTS-Root-R4 check-certificate=yes comment="doh-fallback, doh-u\ + rl=https://dns.google/dns-query, doh-cert=GTS Root R1, notify, name=Google\ + -DOH IPv4" disabled=yes dns-server=8.8.4.4 down-script="" host=dns.google \ + http-codes="" name="Google-DOH IPv4" port=443 record-type=NS src-address=\ + "" test-script="" type=dns up-script="" +add comment="dns-fallback, notify, name=Cuad9-DOH IPv4" disabled=yes \ + dns-server=9.9.9.9 down-script="" host=dns9.quad9.net http-codes="" \ + interval=10s name="Cuad9-DOH IPv4" src-address=146.120.64.211 \ + test-script="" timeout=800ms type=dns up-script="" +add certificate=DigiCert-Assured-ID-Root-CA comment="doh-fallback, doh-url=htt\ + ps://dns.quad9.net/dns-query, name=Cuad9-DOH IPv4" disabled=yes \ + down-script="" host=149.112.112.112 http-codes="" interval=10s name=\ + "Cuad9-DOH IPv4" port=443 test-script="" type=https-get up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" interval=10s name=\ + ns1.unet.ws test-script="" type=simple up-script="" +add check-certificate=yes comment=\ + "doh, doh-url=https://vds.vados.ru/vds-query, name=vds.vados.ru" \ + disabled=yes down-script="" host=109.107.177.79 http-codes="" name=\ + vds.vados.ru port=443 test-script="" type=https-get up-script="" +/user aaa +set accounting=no diff --git a/MikroMaster/tmp/Diff-Config.rsc b/MikroMaster/tmp/Diff-Config.rsc index d101469..dcf6829 100644 --- a/MikroMaster/tmp/Diff-Config.rsc +++ b/MikroMaster/tmp/Diff-Config.rsc @@ -1,4 +1,8 @@ -3613d3612 -< #error exporting "/snmp/community" (timeout) -3635d3633 -< #error exporting "/system/routerboard/settings" (timeout) +88,90c88 +< /ppp profile +< set *FFFFFFFE use-upnp=no +< #error exporting "/queue/interface" (timeout) +--- +> #error exporting "/ppp/profile" (timeout) +3497a3496 +> #error exporting "/ip/ipsec/key/psk" (timeout) diff --git a/MikroNUC/20260701/20260701012001-Binary.backup b/MikroNUC/20260701/20260701012001-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..f544e3460c7812be48819c2685d3ff46be2845ec GIT binary patch literal 383478 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%0A$qkcQG0~p`|0m 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

-6r|McQHtV;&n(1zmaXM0S6m{a2e}i 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Ð)jYl%bxHMH{u)We;oZSiX$XViQ)vV(GD~{z2MUorA{d4 z)dFZ{)BsWGTdeaar9!^4FZx*f*{lCkZz5|g+F!Qk&tnXLxBMt+Q_}auJNf6w)4a&^ z<1)H_Xw%*cH>SzgUvG{4zZdj&Nk(UWGOHslb!#$6I`%|b(7Z_H7+FLWtDtPz43|hB8|y)wkN&6 zu1#sg*jmtiuX<@@IP{2qhm;9ojoqHzb8;Sxi_f@G1zJ^e@z&4FkHO4!|KANM0V1(8 zLSes{iLQMfS|Cr!aI(F2FZVj)V+&T^m0cdVU5{r1|69`-4yDem#5fgEP)ywpxo~_# z*wcjdbF1WWufl#`L%qPQQX%kHWzz-s#*c0domA3@rCL=^a66kET5Pa4*cUwk(uAOFN!>AhmTaHA^jDnKLFAa*XZv2IYKf%k$ozPm!+5mRA9&L<$ zJUf^w6={qnMV=qdE3^yNuiw6n{D?bd9x90I=`oYX!S55jrKY@)onSokhadtDFx!6c z*kJjm2`Rj`ExT;KT&p}&{bGWkk}coSf%{yj+9dmS7bH`B_OpQA7#55Ap3TR}11Mj= zo3$92c)fvwOCq}f!1WS6XJ|bG`n4h;SUc1n%H*I!&EiOJa;(^%+JgpmNRoAb4Qq0$ zc*qX`H8h{>69cz9^bWZZ%i0?3onP1u61>SC0=N5}9n$%$*2XwA`bCi|{#jvDAr(B2JCL_66fM4=irWLuhR4wb*0b3eA?rqx40u-t z1=sdaT#VS?Tuv9-$ASbGz9oCAU5i5+Nl3bo;i_J6YvyPDrvXsiH^Y@vM38aC^^B~h z&pofO$XQ|Xb8#^)?+}4bAzhK; zR4`&c#yLcb(yDY8oF*1lc23wZbCF}za2Y4y%p|sTKH!dmG4Izei>S<@L*You#SD;# zhFHVfR3~!Ct!eQ&o4&}xc|r?%gSOI)IHs=BHy{z!wBHI{q0IE?k;z8Rx!RljCE_3t z*^rO{dQDJwiuH|?U*qaE`crmtP(xXlt+k^pKOvd4fU}NRfh0u_MW| zu#@}5WmF`MfbzABqv8n!BJ$NZcWu{%@qgty!;6cGN$b<{o)>T*`fbi?F0begt9}a- zOY>Z0p#d=BoDZBv4R19|yZCkIz84k473L~3$&Nmj zU($g@``W#ZreFr@k`{^vdbri5EN$tPP4Cmj__7XOdNP0Q#>b3D6O=kEfL$79Yf~v; z5xr9a3z zUbSNO3eK{TbB(~qxLgKk_{4lXcxa92Wj~`&z=Njl(h?Reyv*o^icN+ds3g_?u3fHA z1>Ysj--eI`NIp-+t5RlB{@B0i>>6<}fhGM>_j7KY>A z`gZQtV1%L;YiY!pp4g3B3qM1f9l3J*S*QeN@mwLO=N;%k| z=?`VOxa%$TV#qyC)p=;CxKdYWX}X?ii;$vWRPm7h#?g1UIZIPywv17A&N@?)_`6h($-|kl@zz zVEU@={(-|fT;7eH^;nIvUyJZF&MnWOMe`&#J46B-zw zcHuYQJ6Nc%PT;Ha>34#!fQf^6Xyy>gljzPmwAj9@Et~$g0)7N z?xg;tXb2y)1m)mfg*lQhs|L%Rc&2A2ZJ+odrQkwTGur72egRj+A5v0{Nk+v^O6mq0 zK#EKJZ;m58Q$hmF6KI(d8VQ=2$4b2u->~K$Ar?RV6Y7 zW!K;}qUMdbIoV%HR~dlX$f7#{x#`}KC&SU4pO&rtw;$U03f@r@`AkE4%idB~t2bNF z>?NEpMM_JFuR*NS?jAy~hKWMkJT`deh@Ya)^v3IFshiZLMZNVjtZ$BQ0@O>gm5o5M ze)H$>3kQuA zr?q>@_Do>{R_4hjbI{y=AaypCaGrR!NhFVW_z#}j0%K$0g)D%hZ@JL(PySgh-%#p< zePo;vGCiQcY3EH)Q~T&nA0GBjbPWus+1<1<`ktJnl&LZ%I#pqQW`z>-S_5XVacsZ~HjKShBqbpR z?eO+Sqg8u7uZ&3IpXMAs=YGEEF6C0=NTbq&o$wsA(UITxGiK@xTJzGK5t0v|Q>bY4hL3x7f-r#DGDR>RlDg5QJcPbT@?_EaW7l!dQlBeWl)5Mw_!vM z`3nrx-{7crP?I{l;p)9$dh&a-0gC&jFNjUcl(aes6qBow{<+<$$|mw^t80dDQbu>C zbDnq!l{7BCKZve%ex%Ey))lEqFd($YAQHJhaWNP5^;;Dwc7yWk+*Zh&1Olzc!CMj!*!~+a@{%NLJ3UBg?8g50<7%& zvA0AusxK*RN9Nw~cFueUy0@p3yhPs8P8#qcC=)34nIkg6c9stG0FxV!@r;~>wAGt8 z5raq-TNH-Zd;UU7S&H67OrV-?N@9aer48jV5g@!Z~hdPv%+`F9lgkM zpbsXCn4_4;MtV0Mzt1y+p@~qh3Et1=oIPj-z}QR&z9wH=f3cm2`v7-@uA0 zMB$K1s$xu=>*6~$*l@o{yApU&kmrmY8V}n%<1YdGPa(=*f;dLE0Hi2eFG(b6r#uf! zNpO3_2F@G<3@<8R+@?)foy2P3E0>Jp)S7#yHC+#-@y<$_g>3v$(AcQekIu1_dl-iZ zwW57c7#nfBM{JUo*!Bd_Fp6r99dxar1pk8`mZxbmdpyWS@mMcAjw7|w;O))OoV}Ws zuF?`{cIT9dZcK%kIhg;Ao%oRlJ#E{v;H2_N8Z9{r9VrLC=l9ty!DAstS4o(h@Y&2@ z=yh(3KWX4hz2v|1^lK}+KQkp6d@?wb1uIn$F$bqB?KUpdn_UPjYs?PH_$%ytoK?D* zGODRd9d0*>e#~@UV0m_{%dK>v4(oT3iRZHmeYjc^ff6u>Ox<)R<&3g>_8r8&6l4hf z+3|bVIecBJ@QtM3z`6FR#xe)H;S0Vw`+Q7>Jdoi9ue_>tX{Q)H5%--;XYbfsy|Z1} z2cl+%QXYU#3(FJ3G3Bub<7~+yi+yD@j^_HAp^46Bt^!}-vQx?g{$sTil=li(tGAM& z5L?gO>JLNteqfufvW)_$KFsh1qtrWQywa=x5>gv!naNS)pyyIl!4#L9ZziPFo+%Cw zs0yrP3KqfqKx*Q>GiI}b3eQPNpDA2+$~Mr?-&Y-O(CLf1*IQm=4z{*zVit ziojE~4AK5{;%Ub4KZ$q}&?2UbD9@cvJ-J~v7!Mq_jbhJ_jp8N5SQaZ_VoCO4vx=EI zwq@_Vh;d()%ldIHz;Z|Gu>BF4mm7QXGO~a*RB)C!n9u%BkscJCT)z2Osl;#{kUJG=>;k(_I%_j6x4(SOg2rT zNJqSTo|}0Vv3i#5OMMQL7|Cja^mkgv00mpSFrSqnO5c!0f6x^sU~xr)NG?H=$$8YoZj#dWa;RgAwPPgI+&Fo83rEFLQB9&Z5F1hEf>j|?I4b6 z4YRtXjet^|LXGlI2<) z5^PMOFhRWl&<+##8WvTgqtjjCuU7$Y4`3(>8T_MoM}f_a76qBaYSQ_1$X_%(Nk>}B z8@ZFlhQk$@G(U;3H3&8EY$^G5Svzh*qZ2WA;;sLx>>c?zj2`ux@|iEaW@9&=TX zt;8YSB|64K5%8gX+^_yKMqavaz5)tSqnfl$O`A!(ooe>5s^Sd5k+L1C|3+gdBcXq(InWT}glvJTcj)D_y*{$&9g!oV>JLhTA=@~Sem>{bKv^W^ zlX`S_7NHYD=DaYE$M(0D_f7KDp(y!2b+p&aAz6!gw>#7=`VXb!ttl^{(M$x7@U(6y zwQDqIi@qReW3>hWw}CmoJ=j(y!p^100vEz2^eL^M@H!aG@~x35`Q`=z1M+!M8`Gpm5x+yR_M*!>~H^mQyb# z)oGJ9enEAA`bk1o_gK9A^0Mn_&wZR<^HsV5?;iu7MtWW^r&-cK3dCIg(x6qo`vL9s zV>>!DU6?STTc9QRMIjo9w zDXj|TfSt>rD#EQGWvzb+7=Gt&zo=%|sJ$Z{s&ac#<|09jY3{w2wkh%9x-3ME*8xy& zah&a0nt~8FvMo@%psOpVnQv=&Zvr}3i&Gd<;+paE#{Ow0(T7B`pr2vn*w6=P;}{t> zi&v83#~9j`d*{QzENdlyqD8NzXQ*C-6(l&8TvRnR5wy?VC{PVta&jlplz@;sD<6kA z5z(Ne&Akso{q@72Zn;oaAx8rUJ9EeG> z<06#R$hD&=!5yjiYD;q?>yP?%N?^o}N(jnjCWMfrBjNSl5VG%|UszP1VzjWC6bOF_ zRV(ycdIz>;CD8=ie|ZZuIo&Kp!O7g;yQ>aT)uZ$Km9+RV>LWG)o@(k$8$A3KvKh;& zANpp;c=^czS$rObl@?$;Vp%5?GH0c*;*YsQqIAPByCO869%4n0qj$w>D@H z@Nexeru7{})aPpX@sUF1$G-}T;-ovL@Z<)lx&&{=jmY62AR=X&zFHG>8QNuRt4$RR zQ^*+k(^DW4`I5tJ{{eaOtM@HhSOne%r0K_f+y7!$5gFM3kqj%QWCo(F|MY68DJIvE z~HUBW9tyyLcL}pXl~GBB5@pC&k4?U<#ea|I+V}d~&9{xfVy2&ms9z%R3W) zbhJq2;f`SQMy}%1rQ!vEZHw8VGoF_ri=89Sa|eg#$pB(lUJ#=^b{FNljR)K`QFM_> z3YJr62f~;iL8zY1uW~=-U;ZrSO#)I$mitb`j!yjB4V5E=iIRcDq9AD@K}oC((eAz$h4L@xMhj;+c1Mrw@fg(w|@&&pP=pm;rw5^gzrA?l(yGa+ITdSrf>3fS|q zkF1wUU#GS+i$*K zzqKAP0e&NX3bwci0vcjxM!9nxqq#2!D&WQQB=Xsjw1Xcgr^t^}xQ=#V^>#Rau6Ub) z86zUQ#d37s?6dZ|8(Sx~fZmO3zwF$Om<4ArfN%Y;MD>|e!XS&K*j?+HHe^M@M=M!( zVmKVpwl<;Gb_PY)e!y7+7P7umJM#L1spTH`Z0V%IzXc4hmOMAFgjD#>%ns(SoOnE3 zXxkiYH`DFVS+&=c5`Zk%VH9=%{h9dE%C;Am`sB(T6%x)d!xk=;3e&SGwIHw+bK?>L@8o9Q$50&M!oQu4tSYJe+R++l@kk2g> z4{|6uE&+Y23;fh-x+0P&x1HqJ(MchJmgTB)Qs85&Cw)o`Wj81`bmKayrTqPQoyrrc zWl|J*Yq;=Z_EAb4LCce3B0RnlS5TDC5jme6-n>s=P~v;o0`CiNQSN&Bn&QO_2>)utw-b*UaD5|9{`F2BG3t?{9A*d#c-N(YxiE08Tm|HOa|iu zs##9ahyb$MW?}wolxl>-FRdruCB`D*k`{XB3%jL*@`Bu9K8YPpt^ z#5br}7J@|V@H`*Jw`?(k5Wp$&(Mf>$0|{gmKy^L>B9i<7tupbNVt_%n0UnaAYI4%% z95ZSJ?QV^`k^FK$R(%=*2(f81Mow<2xM{n%(0fmnj1?v(h-`INrje58ncm&7h#&g;jozcXKIU-*Q6Zn2!w2 zf7H(imatl+0*~G)`|MG?1^hXSN35u(A>G=U*lLjU_Y8mpC`+nkViuM^Tp_JLTe zBX)_alpcp@7I-oqh|k2vX$-4n3x^RH9arJYi8J+Qor< zCvY~FFuTW1vy5(vnrR91x?NLsqSx1*{NM?ie{b%J^i8R~C%P^53DVh%jkJ+7_2)Xb z(g^FCFm55T0=lIVtl7owe~d~A#eTo!Z{daw;!QyU2LB?8TGD76{KF@3 z>Ire!N!5e}KHJQiLu80gmaoJ0^BrdBLB;1RPy6h&o8v>i4~9*sWbwAF^;yBoLp@;6 z5#S_xdvR>S+Y9NP#oJW|z49?&J-MuVTy;KoUq zq)BnjfQ0R#vKe(|O}^bF zFiayaJ!TINY|>yR#oZX%*04NkDvi%#%FxmUVUOmnpzfW7|MLcoOO~Drrh3V&>&z|& zJr!WC`GrC?WGtdnGAzek177;d=3HsFcUhRwm>ug%GV068_%ftWtOC8#az5w{Z7<(Y zfs6?%Ggk!MK1=l+&uY;}tdr0Ug-K3(Pm+H0wc@y=H3{%hJFSIb4{IxTLU>zo?SP<8 zh*5ITWPVl$1R#0sB=av0-*I{Wq6zXf6cd%)E#2WR2Om$B+18?^M~2KTViU( zh>@Q|KtvcCSma%qM($NcJ%f46C3M?1*Y#!0Dh{0 zh$Bu7LjHIAE6(i(kuITy^%)l#f9*!&WIU1`-<^N9b9C^loxt-QzWZK|zzT?3-t|?L z06Q#i(EJEzJ{`XbG9KZ)Jhgt;4y05hlsTwIeB*= zoY z3FMw)I=@_=t=NwKB!*PLhGEIan(M&Vot7Iz1^;MOojyNeLr?5<=Si_Fvo{J^p}6gL zjP~I`kfe&<=_55#74Oa2Q2OPG@_MQwM)+bfG*Fa7Foq*s=$mqnBfkfHYs~?fuktc&jk=~-tb9y_x)TlJtutV!b;luMIzkJDC6MnFZEmT zMF;RWyt4+S9xj&(&I^D5F&cPN6(w;w8!Qo3pcqomk#5fLdRYfC__p=zZOB#0y=rKtC32&SFvT{KZHp=piU~@WKTZju zHt1*PX%?QAJv@H=qB2`ZNuuY?=4y6Eg z`2i#mDt37VKZy&KPCllw(m~<^axHQJ#Mz*>irY=&mnLM3qkz=;5epK`uQ0czYS36K zUN6$4+B1LGP*_G-72f0>utkcR{i2gHVsksXo{y@vZ6@SU_9WoK5Nd}gju7YT<7f{0Q7TU$??@`PDQ0qd3#O!HPB z(BPDDhZK3SsikB{N-vRi1Gj>W(7FGCm5wQVEWEbT%K?F_vyI(8w@^<3lHI{pi|(}- zW;5O|=B2!*wI_6Osx=@68uP7~HscgpFO8$AE;4@Kk@N{$T1p@T+1|}bq(?Qpi-D+v z&+UrwKhgOn2*x|0(PA!-8X!4MW9wr;nz6V)fMT(vUl%r;IvHZ%e0+?=w{kW%UY(yP zlKs^rpTSraIx{ASqvQ;e=!dHN8C3BuRFIsh8^dY&Kacqs> zZZnjbr#3s{XJJ5uvw}#A^pnUf=TkTLS5`rdufO>Xz?kbZ8lsS+YE8OPNpaZx)VvWyOWTla0Dj#hZ*xm~aizNmMcLB+ z0FbVu4nHlwaoIVCY3H0!+*}b#FFp4Jh+rDXiD&S-fw+jQwf}p%=ymOU9)op351+%E z$6~6%next2yBWTy^E2XhHn^VK`x!LSMG1Hu)DXi?WYcmD@;x2H5S}!50bbkvW^1Vv zL9Qhk*8Ed@<$E8kqJd0BS9EE&7>syFY<}qVJxQvB_!*O|*-N9_vh+umv2_736|L9L zJqUseq9rA=2<&XH%~#pl=-3bxejcfq=oKK?kHl-^EI!qoPzFR(cxWo38Jx1j8XaCm zcK1S+-TxXb)CcPi7>J<(td~m<9ql=5Ig>MCqNE8Y0gmL%NwzP{?e*sygulpyrg}ph z`Vj+M_jaN|`ynp`IzI_O>7rD#&AOvPkjsfAK($%M+kNXG;(cvmGA}264y;jXMBQO^ zbh8x*a4dcYTBO)J5wjOq01U^t5nDFO8ZL!;?_toU2YXs+!Pm=W(^W5pL2Dug`n6Or z_aTSv?6D6T^ZKvZ%3v2ttb*?^dUZKO=Q?edJ^2FzX!UxiMD}Y4Ul@ZP)mR_Hjn4JZ zln)$j`t91zVoU9>CS7}}R5t9@Yl$=0h^?SSb;_1Cf@*u7C(2wz z`mXBjBd6PFV+Cph1y1GfwO#N4pt1M#cx4&k|J}w1!7Klo4tm!QDTaSb2*ArQfZDLO zU=LkaU6# z8?wL)c~HH9`Yuk*p~N!g=Uufl#1Il>D4#GCB&mn_6g!IkN5bA!Ju`BY=iijvA8a;- zIf0*wx3C}^LBfJ&AGMe{gO1C;9GN0cs^4v3e`9*Wa~^U^475C}Wr)k!+d_1^G>ya5 z>)n46AOv&Ns6^GppP%>>8;)E53k#R)5u3)jiK(=pC^(0~UWLk@U6TjWFodtj{^u*b zt&y?2+mPN7tDl@T@!Qe%MUY+r1E3zM@+|N^=t=I>YBo6Ge1}%&J5J>lJxq^JYcI{# zt$uCJJ9U)w`g)H3YyyRS4kuvdnefoxc?Hq%Ph9N+Q5#*w6o~OqyJ4}XeV%vV-Kb84 z@T6h}J%)s9p%{spg8`s~;Ud)O2UoxwOyV6s*$4zXanVLF=aiDSnTe80fZn&x-&a=v zHFq_o_%rTiXELl<;D=Z(2gz|PN#p=*=G|tlnRY3iOUoZ9LSo9>1Ca$YX97s}$bC6X zoUBB2)vHr5McnLs3AV{VWH|AkEtUxz7KyM%rYU@*cSG+gN~Vu^r5rAzKKs^cB}DH( z++bO#2V=7c^A|@(;u7w(EO}=aZn`Td5kW0|(-I0^5v!719zUYtwM)y0nuL9{$xo3! ztKl>p2ZCvYEn9S?33!g;e7l0GQLSH4qej=M7ptdFY#kZC*0C3Q-kTn5bv8&jH0z!M zP}$N~CL48a%H&#zofUwMi9h=&IVz6oM6W|S<2B*CJxn8?>Uq?H@kp}UWi}sA_&3s+ zOeK1_tO&uCnKU?}nTlLY8(!`!A``*l#Mj$T2j(?`Sh0FU#n8NfDJM*5TfAT#%z)<=jzp(ibK3XuAl@_@X)RXo_ja7K{JakRX%}$B_K4eKXx~! zZt1b2W#k;@wTCxzhCX6-|CifnqH4T!nsVcDADgkE);y!#+x4i*#5Cq19b!(gg}Mgb zJDJ4t6m2k+*Fu$SU8Xu)iLpH1DWL*zOFBbZFxFCq?20#BVnt$9wI%JtGGA1A))BPA z=wgQ_3X2dpGYJ#N=f|-WZf?Kwxz_}OubvRWu5AOZIE7t;YM_!?Eh6(CE(Lu`6-dn= zpnmkqLX0D<(R?*hP;0^s_8`t)nFSchxmWOJ#$Ac=qjsh);5J5`mz6Em(>`&nTFgUV zApkaLX-5!h(?|~8PaCXdb~t%&<4nWn)9e6oO|!lxp%R^xC_vHGtsCAMhfru)lU?J?Rw-ZXx8Q$IX^^ya{1*@ zfSBI7o2HfkB>zX9E{#E~P6^L5b<|k|#OfFQ&si|i;8CRPM4!~>0Uz30gz#gAl|mh|eA8LXVCo9ES-}af`TfSg z*v51`m}Dw-fZREnSzI?7bC!Mvvf3>`o~NBccDEu?kheLz?YuMCm)3$isNZ!$ALniE zPZ5SAaRUFir&I_1*T0n%s9oww`3Z{$6;ErvvoV|!8{dbArUSh>Ynd&pe>4#IARKsa zhrbR$k_m3!FtwN!J`o0irG{rv)ujSpYMzq=!b%<=`J&I)-k<)u&QWE|kSm|zln;!Q z%5n{6uN1I2NDweMvxe6lK4jkNBay&WBK{4M=O8w36|CXtdMF{S75*-U7~kADXjY`j zKH~w5WA9!I3ax2s>|x0(vRuwDDzKY*e+ug=38h8`z`j;*bdmBUj!K%vOd(Ss z1(P;VKv9LqiCgO<0gS4HdVvL*N5$5Rs7d3JYqSZ9BCC11Y_&Rz#^&3`dZFQYBU-c| ziZrustfRvEld95b57JNtm0#dt9$b!%VXJ5BpyJ_to4k)FHYGIXUcXqi>*@PbhfeFQ zYt0YNXYLf)n{8I#_?uf!>ygS3L&)1{%r%;!uDvIP7%`mF=F*A`3crz4n?TWqo*LoY zgxN&HjN-v&lwdXybVTpim(ik_%lQo;IOYjdG%+>g-*0lHkI|Og+%Z`{%+O=aFXSOK zAwo>6R||$8@##Y8*cB9#R#0q>qo{T=`ldQ&^$Y0>50vlzRSd3SWtQd&^ z-iP!pTJ4jydHqjO#NR+GLZJpW)c`o2G@BnRo~|!DZ8DQTT590SB^@pPyQj3G$!CvN zXNa{El<{C&y)8|Wh9J^0Ak^9rv`1CcErv5LNrJru?md&aByqW`yRzBRuP~g`_Sx$roFcbTK2bdY}5)~H|<7ZMhf(#@EF=tXY8RrDmWngCDegVsX*07fyd2#c zr*O2wxiC*KU07~+wqf5bB$xq!VINt6emi-ZApw80^XLLeV0JfVDpanq&$SRHXsGdA z%vOS^g8`~voVo)yp{j`{=k(q~dDhP8296dmb1)`)eNk$_F zjo&gqXg0JpMiv$nVtaXhe0O7=)^O6*DPwf|DRO)J$UE(5&N>T90moC#|4>VQ;gzexJ>0_SBkw)|R6RRg%*hgV8!E_JII-F=k4k;M z@lOlX(XTh*3w%2mXM@DKx1^hI9~o!}ZaFZKO&>AbJ$_!hNNh7#(b?B^+g`%3SCKqS z5h$PbNc{B<8C_z-H^S0WN@)Tf4cO-<-TiaP*VCG1V_7GlnW?yDfi9GbC7SP*i3$fU zReuCjO0@RBaMY*iqrbRI-kP0BtNkt`7lAyr9^hniH1s#Z;(ozb-c-7m{8{=r@U$SJ ze(*qDEAep%xAYop+Vgxt_qlV(P;Le0p*D%l1kfp;hGdo0>F7tDQ_umQ0XTM6vR=!w z0AK7w^tkfTQ`l_ZQ|9|^sIz3=ax-hVHe!0><2tA0gIvG=@UH=mi8p)(hdt_s*=J~Z zW;5euIJ@Ia9tlH?yI~B0u66jbTS;#_R2+q}#!YPWv`ovcX`~Z|t94_l1-3sNzc(T# zB=J1+84|#Y$SRQUULR86A$ItXc$@WIcwS4OkY)qTr-V0P5fOCZUk=RDAic7njQyK3 zPdVAV|5lDSd-B&siqJ2B)w;JxK~I+S7Cp*sP;MLX!9MTL%ML_>p5|sNQW$UU`C?1+ z6+(^e(!8+Yh(;>Xow-b6(Bo}@f}tKkuPVr4{mlBE>Hx+Tg(}7&VS#7ZxN}#J!jcKR zp5cgl9TTj^b)3b!pDGC|v-X@AQU<$`+!#i7wmp&@5-W2l<~~00-*|uPjGn99AikPk zy=m>xfpFJ`yzxt@1iE*C5sZsCmh);1%-qaM3rLxOf*#G{6-}8ut-Tet(C4dxEEAp0 zbak{B7Gro2LjmtVc8CVFinTq6<$(ME*0ryg=V@ULozIsmYIL}#0q8@{E*$AYy1_?X zVWE5tmL@Lt5P?6sofr_eh)9E=D_;80z~RGblw6XN-j`b0>cHP)DhW{Y$h$|Q%|jnY zqdbvanAESOC-HlB&G85B>%PYS*;?%}5=2r4 zwaiRX2$( z^F~lGCw;tp0(Z!nDNcY%X4;rip_1+5tV&!Z3Aaz7&Y)7nI>wTausEr}gqPllr@(W& zHLK(J!`9i#!xs6R`x;+8SUx{}L_4Kj$7D}{J^Iv8#{a?u9Lg6;6f}-{*GX=|+!rTm zkQqX;_Zz+^ym1vVvnKI;Yfbl-t`IQE3eAZ&wFFLJ^A)??Cr`KOSCkW@yhcco7j;K$ zgX3K6vcbk;THW2;@Osp!6J|AYa9!-tpl;3;dn5R!8vGvRNn{FXy45j37S2tSGPc9x zYgo;}B>>(cyA2%vv1{0T2xrckXzZiM6t6;(pV@9}I!Ytqy9cmRu1mX+!R_lfvIVef z@`h@b>wL<($Fh^_&@AL;d>n^nCk>)-KdY_u;;!KcYvAP}Tjzhey7?OCky2C*inG!bLX>69 zyYqJOca3b9z+*ysx53M$d z8L44k6(8VI$hr>I1z)xjGp!wA1mW-gkM=F(F!@x#zp)7cKBc+adVi13(gasv`I&tg zzN@kl#TvuI+5L2L6izi^&8}o7)+q66_j4fI09)>)>LWK?O5-Xa@#RO<-`Sj4IGy7m8@GyLwc}Zw;U9an$KNpD8o8Ny)deZdqF&}xe)gIQ+ z%bO9o#F$FGfNB#C)KGz|;XqtTB z6emUedlihIUwm0-KP-IY11pN>eAKRj6 zd2_5OoWPnMlpFv3f83MT5i!DPJdvveW=%x*pEpymY5!>|BXH*%Ll$ey@ulk?x3c0+ zn*f$3OP##H8HW@Ke6H7<81d&~B4u4ff-)mS*<*8e zYw_+ahe4nUd@D< zI0#sLs}t~Ta4nt%ET|A+DV$}#PF2Hoz7OHVG4k25jOXd$>{e1rJ+UELw8x|`f>P~5 z9({+_v1CfHF8D?+^qT8~Le6~GT)+)2E!5oQ3<%k*WEgKv&(&70iCFbx5i8K(vxg}7 zLeE3|HgDhO9Fd-@+hZjuD!Py6kA{Wu?Ar5Nsv2Ju#a+q_<%y&~@9K`HX6xHq;t1h$ zSAVesazk~=a!ZFo1=h-7^UNBV{;*->Cg9mpfzCC8Yo8FY_vgV2%mJ6)|vz~}h;XBAh z&W1Gt3xQz2NzgVLH3~{#9>))2Bc}v{hF-`1+PtgAOI}b20A3LjCyMPoUu6EC%|_Tp zuX;AB+>gnha|63AP~cEnZGp8Xw=bNMvN%aLHrY zGWmiVINew5!eGXv43^WaQ_ul5L~g;PF0VQlYavzBL^smENvLqO>!bcPBOI`c4$e_R z$Qr@4Mvfik+)vC&oQZhm|C=k&=NUL7Z3nuc(WD%nQqai;l?JAinxd9;yOILym>ux9 zn4px55;AJEi0-URtz44IyI}RKZr85(OME9dSN<6Jx#Tpn^bIaZ&QuB@y%`5K8(2s=<|tZbL!RWN$%^e+k*;3pGsGN2ilehR z$d{K-kF6=o(MNA0vGpLkMD$82E|zl=)+8R&%+ydf%$25(+^9_1XMPk!sU1a-xhSDo zx1z~5`zEt_CaE}+RAm#|w0GL}?+jNGS(6eDsE}9_S&t4q5I20!#>xB9{e8Z7txQ|i zsJ;l7%eNa97|rK5V<5Y4q$BQUyXo)`#oqOAQ$ZYm7ES+0i;nc-F^ft2q*wf8^OTj> zLz17ig$wv*{iG#l78kw@Elnf-DAS{vc)+LA&Byuc5o$Oq}Sy7?E}YwD?~s z=yKKp8F~qX?!FQpg|uQ)mp`Q4gTU+65}9KboB|HZ@9MD}D|hfayMFM{tZ9C`8m%~%Efq)sv$3^-u<)~{gNg!>IpCY>7IYPdhGxYJ44!sPJ zRsC*grhz(ch#@t#&r-3yzD}Qa?PnnovlmQTjdi3?6AfSo_l3Eg+%?JgAbgMfygc1|NIK{D{ZbRnBg(Oo$C~%OTFb9-9c89i49WmY(kv zw&+(RCj1HRhLAGG?IMLvCRiTbp{|+4^R6#WjO~%hll%&xZU$?V65FYI_+asQ8wkg} z3#n$VRJ(24<&pw#>ZwTQFeBh$qb7U?p?bC24>)IGyNf(*-t+Fm8-7LJN|Kj>$O~*t zM1Yu&g7fYYa7hDHG!)7T<035>72*?N9TjY}1}WyJm;~fM&#Ty(>T+~P7k_8Nf9L%m zdC7Wx&R`0hr8B=fOGIS`E$${h5$a1QnbpRd0V=2Ym*AG7z6U*k+;ZOUNoe=8d-Qc? zv^X4Fh5+>3B^fxzX&(il??d_UyINWImcwuK&@Wu-JS`AofqLS%g<9uCc*#QU=aEz= zqy$u_hfyD~;}4~>9$ZKiDYhMK7GDu&y%*1MHA!WvI}&b5l?!K^NFb>FY+d`h%oUW@ z?;e2WoI4A%yVg)s6OEq{s`fA!*(y8718X+CAo z8&!l(O&rdJM~1nP6U)z)jM^RM6py2ck^b+~?91d2Ue(B_U&2iJtI3z08SIqIVqp?{ z%rPV|rq@*+ugzTbry<;;`7jE(kNT7*C8st!rN?7*?-MAaDnm**wp&0q{DqKDEv1kr zONIiUiG;q9TSDFt)zQ1GYsp(JN(gvf=?90@);u!|rOZxFS78qekj)LP>)!J<3o@Hn z2CVrM0KkY1ET5~ImRqdiuqCf3#Zc;<0Rwa$fW=aqe`T5a;-i=X;ALOD3&mXy zuIaWLE1OGp6%phHw>|H=IYny;6EHb@#)To$>|++SIes7B@zT&QeDo&THK2XF9`q*& z(%t4iMlE9G)2;}(rS9V~bR93M`6ph>riGqzfp>%6i(xp^1@XA~vybVbnEh|+qiLsD z$le?}OTv>5n{n7cW8xq5?_qG3RQw&wNV;s5h_GVRe^5qIis`wWkqTegeZD1hGe`um zxaeW?p7sA>8oU}M=r(4ySkPZd|Ap!QJ;I={qwVMHVR=nLzoWt?L5%);sc5X62oM=q z{tp>1e`5dW&BGLJboU$QJK1by%@%t?j=shN=n3(1RYQx&Y^Eg_R45EgG>gpuLi!;+ zZ=8lXVsj_>#FXfMTOzIp?DfLIPK*5GL4euCT+3dQe?lH1-$Y;fl;OGBQqDl^2bcvvbd*LkY`0}Nk2AclAYB+%`2Ip3C z`zFUdS*7q4^mUx{x66RlBUpgOR9SFqBHk#R1U;uh-%&i?sV0MfqjT@34K$FwtF zw2uY^+1m=sLcY4lBQTzjd#9*2yNGzWj+5Nm<-1I=Yy?)BNhw3^)B z7>vSqY^Wa`5c=dSAEKh!(_FnZtd)>P3r6-rwwbZywEU26Bb(Htf4o|QhzhhNm?|`s%O8RD`$>XH8NdE|_!;)7q3%e&E7oYyEYc0ZL|Mffm(eWLwZ| zyZ9SLZNm9U8nVHup{~Zm*>R@y2HEoPQ6^*u9*646n(%Wt@5{xmQPKjG&+o4!0znai z>}zt4=P&oT0#y}`u8XLrWkruxKFh^2_@4?T(r;jj)EDZ&vkQH`-dA8`Qe_mzM9FKy z2TavQpbsWTNpQSlY)tL7KAq1sfN+ct$}JmWU+4MO!5#8cR>CS(Pjeu_ktX>?jU(pg z>;prOMno8fPIC6z!<}B=`&)W_i%G||x;P%?Q~)@7{?M)`82!~27bw6j^FS$e6a0Xz zyt-YSy~>21zsG9QRw0vKLI>QO=Q-JWS{7YfOl%T~jboWC5db-!W2uYgi7S&Z0WrGYuFb>Dw5VVRbMRC6>9vz z0I-etHwWvFAJN4v*pmLc2DZImW6iYZUAFh|96+2CT@5IxesI)yu~)vbq|@O0?I4Gu zHkdyiiX|mwGfPS?+Pd8(#i_KbV;XbOTPE#c>^y4u!cI(Gn|wkxb~QU*BwQs>r&kU) zTLYQj5jS#kt4#~edfGlYr$RsLMKkAcnK9Ez zkz;09%Q($EO_AJ(35aE$e{oU8xZ308N22YBb&%9ng@_zMI_~Z`ZFDhQ7AD0hLj9!0 zeXEf_1-8~YqNR)I0N?|C5J4x2gZW9>b)#%>GUiQvY`Um5vy@n3KB@0#nA%1hyo~tO zC~CpO$Bc7dh7L=q7M=5B^{J7?@Fue+Z>hVPUY7Ye{Dab+nX%$c_!umwPU)@~EeQP6 zLZ$Ll9H|oaShi9b61T_^SM#!UEX+5uf4cOQ#gm}r55lHiaD7r~A{Z=6zcV(*HgZc< z0h&Y;x?zPG(`5eQi`n|^TZv@tm#%2YWkXfGlIdvq#U~uZz;P~MG+%qhSh$K}80%1T zACNIeSBx>Uk-I9odRV5q5{^ZJLm}=NzFDH*Ijja|?(Vf;iBx$w6#pnRJIBku_`82bW%?43Hg9f?SJ z7=tAD(-=8kl}}ks2=%Eu4xGS?*ubIJuO=Z6RHTf5VmH45*IscDZ!gBup4`%%t1DoC zeP9M#3Z*wBlj&R1-;6=rp}&kWN5v6{8z*oZlg2w5%Sj-vsifZuE}rd?J{iqA<@g=z zW{}Q5wpsu0V9^2Vid?%AlR%=tM6|||;$|s`5&mg|sF71WxQn()B(rwwR~%!0{QRA( z{EEufE_w!L#iM*)kZ!|RXB_42$CdU^4+c#ip%PSMRmQ(&!s~7m$#Qj|7jL!%YLM2&uK#n4?5&aX^#_qdX{t2l8Yc*n1=gr1lc~9&y)4jM(V?qYI|qnI zCJaE`-qQYX`MRSjGDEcENYBQTp8)poH1Lff3^Tm9t)2QJ>i$uI^UaGh;#J zV&0dwGqw4p_N;c;v;75fM+s`Ib4j~Fl2sEA`(8!vE_Nj(mw;Z^ zM{X?xWC_I7wr~?eK8yd_7h2ww*#q1IQi)H;GapaP@|I=7om-X;Xqk89La_`qa7O8fzdaA2FFvsE_c2<=2aw2(X z+xEhGjIskY8FC$L?E2`TS-OdgRFw2G5Hrn!j7cXghC$q~Fh6&0&W#c#RpHIw2yd$# zA)*~-y#T^{O7^d+aQ>t8;dIfQ%R)y9tQ*k#8ugYlgV^6w7?WBHK2It&5@NrZ$qNSQ zk2H^!;d8p@VLU~LULw*13=T6*5HBUU^PFKWl{9Zk7il!NHQb#{Qm*#F=LMtr2!aa? zQ=j{mg~EAFv!jlUfd}_3lrA{3IelN0yZ!F^I^PsXh9Sy}Jp-eL)X6?yo8EuKxat|Q zrkLvqYZrA^h@L5ZNUb;u=DFi?m3+?e`Gl?PLDrt$UsHOYK{liZBTQu=QvVq{7d*0E z5o#_ucPY#?Z_;`Z=h~p*!ZlE9PFWtn%Y;k(tl72Bty4)R%x1}&wc++jlDf9&l6$JU zMN5ZJ){QSJd8_8`j%m2?qP`cW%P<3K7y@U|U{0PPdrH~ChOp9+4OD z6yjRx=SJOb&`-j_s}3ejzAPg(3V}J9{Y3QV@H;>%XI&fN^Dsm}JF1F@57-h^&=~`6 z+mv}&SYmSvOo?S4ES}d6J2R5BAvi~LB`2gz(2hO<9d6PmkVADjZ|M? zvf}$r)1C|2{?%6K&k%`>v6xfPTHtVni>g%ltMY|MB-I#!cT7i8-Ch zK?CqN@u{aHPJi@PBh2U@q9^Dvx_Cw2fcEfoESfGMG6ci8v}Uout*&Kzici22;}`)m~Chf|F>-HNHm9Sp{?-V zfsYCn^j``RH@SG5?vIQ){-=6hG*D`z0n7NY0wS0r+W#kM1nLA~)tZSlm>#pcXCfGr zQcTlE5J#DX>^w*ueh0tEb+T?KRgRago)M|0M=Es_oJU{e!!k*Y(&fFqKG;wnlB~$o zBP~~3HMLSL<$%F>!0ka)Up9pmX^v-zI`;GMF{u1Ravt#x9Ud*6MK%v%`1;$zQ&|?y=ci2_a6$Yuc z^@&?CDab+h<+)&rxmahaexv(DiJ@9Vd`465$ISdpd$@5`zIBJ+G|*PBo( zSu9r+vn7*wP*kn=H}OLwu|}6%hCfvl)rZ>TiNl8u9y~P1r^oJ0guCJ`=}LY+ng+=% z6=`=LPoftdK9@NcHw8WJmP6p|Rk(-#WI5a1EgIuf;*372!#bK97lo%+lsksml#%9| zjqWc8?7LNQ{&N7358VFoVH!+nVM<;sHBV8%+oOahyWqZ~t8|*s9R78?)fHML3*`G) zA)oeUYEc?nn;C<4r$zl+4ylzL%l+D*?M=_GBbf8v_}vhke7rorDwWEFS%Vk3hQx2f zEEz};=R0v>&92j+I>h@IUV!J*iGbpq%iP^P&NL|8cCA4)V{3-2?yc=z?)Y9?5w$>? z8>YHEZ=rCEJbfg{5T_ej%LMY3G9>un=FQJ@D~A#LaNYTXQ6Lz1gR0)kSK&M(J0+m0 zZQ*TtpR>XBxWl3=`jRrQuH-dyxb%YgB-el${pX$xYb;sKm+(Jr?Hr)=_;zJzB+j}<3!#`P+4cbki zWF=@%Ojnkm`cp~<(TGj{fzbr>)NK)FFfLG}k~B$P72Vdp{%q}P{$L<#P2z8C%J@iF zC4H9&C5R{46bOoej3At3S*O^6H}J!P07G>(<9mG?0|5;Tf3RvuP6QnRAK+gJ7+Qc7 z-JX~$s=K9TM<{U=ko}_KD%KK3W}n||QJUDA2^E1xu3T76xE;c4TJoI5+6 zw2%fs89JM-VZdIt+|?BVC5$qe48C`9`^y({PpPFd2`%E(pLx$rjD?wMj&oL@1S%@j zE~%B7Lhp}kQN$p>iyN{?j?ofu3!M1~#gF8KKW_tTTBz)tzD=h_ZTp{;Z-aAuFNQ?Mn}E?kzL#YZBLxwN$^$_66a zVL976R+_%3Piw#XzQoh|C{|kp*(>UR;|<&V_NwZp?jm|&PsK{6+YH@#O#;7NeK{8a z@) z(SG92MJ&DXi*@EE$D^exGMlOS$}D7(Pz1@Zw=bK72c6SQTVb2H?2{2J zPok;YM|o?Swxh@|JQFD>5<(zfhGZqEOy~ZcocLzcX3N*{-0A=on#4u7HWE!fXX(Vo zh}jb%6O3HM1in0>P-`GFzQ9Qg&1ts;3ziaiq?@diBC`27)U?j7>SDV2Xih!sf6vC zHsc3tLU)*?Q=2C-qmJ<812i{DCa6?1lJCwwFsA4oayWq{>ju7rn=!}3bV|k0>caYqFF)2vHY%TbpMMwkUX}m`b zDy#=(+YYhTU1Xa#udlfG1Sv$EXC0%t07~G5~ax{M?B&x~fV(-fZsH7V} z6(nn3-!xry0LT%T04y>!dJ1_*Igd`7BLuO(u_=PSO8&vztI{cj_jqE{TF_Yo8VpbS zNznp`b$D5E$n+>&eU_DKc%7Y)evmwP$DW(2YWmi*Liq6}w9P|I-wfppZCX?|dy|XQ zwHPgg^0-vVhv_#*!0Zyh1XEaib<+^~4l?jiX_K|0Dw}}G^AUbkGp+>`)YoKk@ML#0 zfS2eOUBhw|qdGaIPB1E^CRpk4`Ys7pH~__qW*dib)pcRc4fko&QM+fuGvG(@62CJ^ z9;57ihH#KD-HKx;eS}Cdg1Ii+R_HJBe7Q3pPn`+mp?Yu?r8s@=!6QzTP5qWHk+_55j}q7h&9qlY`am7-(Cb zauiqXJ~E%}JgTFXvd_lK5FBCKX9SMqqONT38nx?QH#@0ABj#*kabyBy4oe)n@dEEl z@D5P|CkH=WM)xKfry^pz)v(>~xT|o_lGWl9H}6MCppEClGJrKl#2J&M-yrC2)6zJ- z{oR2tvv`QXruv2J0yRGix7hMV`rkyDbXF={5%o<}Dd+`amNkilB@k*l30W^Ajm%Sz z+pzAj$?F^7RrMXQ%g_~jgtflIz*&+6ne(1aIcB^8XI#50p@qNb0>TO>14LVIcYK*B zj+9(H)N-MK$I9kS1%bIJ7);`Hl#OnHNQch0ItiiuXWOyT>UhTt(Nk$t+7Mj)F}~F! z9|hMJy5U`{-^8pT4dclP4?<%7)2Ip(x914O|88#`VrMtuB{R9Au4Mmt_QK$gY38GJ z;<@Vs!o<rq)n!2R!Oc1=LzkNr&2M<^dW9MMNq{} zV0PXjM*Az?-7&5Ve4~fX6g_dlCv88CIkk(6bhGH{n5+y{l^80e)yIFWyGMC74bO7% zO7Y-LGSKht7r8veSgOz=L$C3NJ&1M;B`ysE#>%K_`G~Q#XRA)0y7b75AUawb*1fz@ z2sv|%58g9ud4h!j>0wzlIds7=;|!aEeT5(#jWK4_Du|iedm1HcUYWfJETwY20LIA(Jf#&5gZcZi6-PF`9$$s}gV>YaVv~;PLVszF{ zj8&xHi`ApAuNz+AcyA(IZ_#?hlNE_%5d89r*hP7dZacFa2Hp z4KC)BL&3Yig1#SMOg*^`I6bFD;{2egRTNw$0LtuPCDJo%+-&!z{+I_m>Vx3*qKbGE zgc&w6*9G1Hp8;gg>{JDOman5vW`Y{Hjs#0ho;z=-H^)`u6Dbp_yOzt1P+FssE{=h& zK4+H3&>2deT^%u^OuPR!l4O-f4lAsTMRJlmHNwrfg%a$DfT_l#sSxEYuVFiGp|3`9 z(t0oJE0?pNJufkT@5K2lJfR?K>wDUawyzW;IN<3q7c`!lNH;r*$wSqb=)&O{CnIK3 zx)rwDc*TtS>al?gj@Q96wIa-+Y};}%eYoA_bU&T1xt=ZMf}HGn5#!JEba6aKgTM^v zZSDy4d}e6j1Aldtp7E`f7XbXrmn*pwCI$_`90t{g7!IKYjc3(K|7UvcJ1`SFmk2(X zR=}eKlC=Yk!3S7v_<0^~@8$UJ()0cZ1V2xM8lcb*$}cWw=W%9-$x7qZp9yplIoxsD zyU2nxlmSA3?SvUmC_FKGNC`UG4%Fl9+0P&1j4@|rVzf2l%TcWN%%byTua!Ep3P7-S zIv?dJ-~3`>uLNKaaf-uEZ=bs+)biicz0NhXo*^>JF5(ozGtuT_5EosQ>J-b^#%|Bn zCURX9XfuJmnocU=NXCG(4)RHC9#jJpt1h;)hG>yzRV%;gw{f+uK$A|8xAf;lf64r@ zqGWs|H&$37%v*+&C-yMi_=^PL5#IT||HK%d^s39ECJKG_{|~1qKL{1ZY#QeJP)n_V zGty(QP>CP*S&(W{;#LHy%@dhGjY8I!AUxJOkdKYqB)WZ{gPBYIh{SNG*xrQ$Kp3WG zbWd;BpNvqHdQnPAy5Ff9`hgb_t7}1PwHn}lM*-TrPD4oX+7fUIJ=`j)g&wK6K?x78 z`NIw70v?Ch8p6mf=;mpMW&GMN$Z6)cuoGj2Be&;wgJ~}1&L@9$#gfY;P|Z^Edk#0R zeNRF+e_>0XM{;qYK0n)j{|548^;S)|bDDynw1=&Bt>#lKUwDm5)-ocafdSK@B>qCz z10U$HLqr{E%2rTL4J++Tl^Dpf=V`?>c&k?4&R6Q6KiAW*+sj0~vr zXu30snI9~Q0PzU^nTw{CHO0Y;mb8Rw%7AxZXlRzB^CQfNUx{5)&n+bG&-_|V!+`&H z+AJczeS~|*#z5`xh?Bu_|5|@|eoxqj9IxBiC}+V$ z@XV%z>5?mdAbB>8WG~K-Y`y8NgK4hxTNb106P?2hKuZt)_7O8i4deY%Dik1JZdL!= zW`gKT8lp}8m2B&3=#RWzOOI% z_*|o`Vrv&ru~~XQ@VxZousvZac{!xAFp|^BEyFj3NAh(mqUM`1b)$OFXG_49mYs-4 zwVuwE8k}Mb3jEMHz7FHLqJTaf6oq9qej|l&17(>roC;>J^!A~Nu_}VF7Tvcn#yX~` zKK{GUUR4IS_&a;tBoP&e2-T-&{Bg!?lT)QZ z!gV&Peoomkuhxp_SUi@WGofscl$X}PrGC7zYg{utB_t3S6=|EJ9zhm~QU`?vUV=3k zm7)7*P}-isvox{agAZV8)Yn&`{THn)^=~g5N6a^q(m%fddLDm5={ETe=jY3aZwGhL_bsBdm*{>2xApv{ zi*bNWt-s_n?A|TpvY6`u>ShwL?{AEd2sOFQU>E_OOgW>UDBW7Lxy52Cu=VrAc!9k% zntcy$pr7B5-g3V~9@K{aQ%aKqtn{8th$_@fn4&}_alD(`chQq6OAbRaLFPTtof7i) zJ+!P6-rUS2h!i6j6|o7-d+>CxX}r+~3BX%TGGKGN?l)~|jO{2nMn;^%XODpmxG#RA znZZOeS||&Yfel^6-?Fp7{N8=&Bes2SMSk~PkttMu-)5G4iNgq59G0wJmU%&xll;C; zk>E-Gc~*5j@$c68XR5_-ShM)6nK`;Vji`)t11 zOnPD!__0n#Rwbby)sD~+a%5igr4SEqIiYdVhFLkSCVyiH1PWAOA6Fa?UGJX*hX7od z`Q%@J7H||l)Q~j`k%#U)d4cdwrx36tYH@}C_*=a+QbsNfc;#c*9rKD%@Cq+hV6~~f z453Ql=9+txhg!8aKoq`X%(aQX_=Q(r!#Ry__&+b?^T9AnqyXHF!i`%XgW*~VspLSy zYDjAo!zHZj8peoTdW$cjhmi_E-LeXYG-uK!5v?htB&mpJdQnWtPO1J0gjQ&pHJqAi zBTug+hv?IIUUGR}n{0%VU5B$TQpIUIRI23?ho>-3aDau|G!LRkZEDYB-b}P+Vbr~6 z%+B6k%G6WJnHE^_={Tpt3fhIfSlrbM9;E2$g1<3w3$osIqR;d@3>`VOv*7HYGW1pc zyHX3e8>F426}`J5G^Q;y0^{>L)mcGf8pNI?JFV6$rwQ<#nyjUbEB}f_b3v{YF>RDav}5 z&umuQW1Mef3!!V%zc+SPSAqA=w46;t(9**L!=0|6`pkW1WRTVuchx%lW$w&r1m*a0 zka|p~F=KXo_0!2EmUr{bUt5~y?qv>-*5Uo;_+PayC_8zE_g3VFZLe(5grV>|&0?b| zRDH(nfm6itSzO<7G95ADq!~HSZt#eu!TOpECk=^sl(J(P@D6xqtkG(;oOXA?b!!LO zl_ne5!E%_7BR|ZFaPTZ$exU}btYYX#JKGc*Px44o#P@LsWb3&>s8-`LFpO}U82Kgd z=^{L#*`L|}n-^*aCv#zRJH`oxby;+V@>$7)%YqeZQ4ABvj>NfMm@b94w&XxM0DN`} znF=*p!Ez;*QZMgn(*qoXHd7@+2E2Aa;7X--H^)~4&_KfVV4f8XCFDJ{*G?`U{%ss0 zjBx(l0;b}a$je(~S4YvUA6^IS*eE-fWg^|+k}km6UI0joNCZD-6XYcLYNWlVf4}Gu zNGJQ&WMVhCEs;jF3#7)TlqgpEwi-%{YrXI?Qlp~m>%jRo3_nMLD-RCJ;k%VX?4Qi5 z2JL6aea6;sI%K*vW_>W+0@Jt#999bAGfqGFFQ5qZrp*7TDXX;RfKo)#ml#{7b*2>@ zgpa{uSJ(-Q>Y1I3H8E4H8*EeNs6N7l6dkGY-s#AGjsH^L1Qia92e-Go!O1*>AvFt%FF@MD&6rw^LNUsiw-bjjyWzy_3kyCg5LVu2dVE% z>XRu>_q(Q^Q|!^+*3oA}zMpem>UQ|)^-|T_v%|T+Y1XiQEN{Wol|YxoYr<>eL)vV; z2~6-CGxk5irpX!SZx^7Rh=?nteK0HVxQ6&!1O`Xi6mZtO*ieRz00n+W?)%Pe`d zvFHRg!|^d<{o0VY-xW8IAF4Tg+%I3T3XKM>Oh$xJc-;r{C+G^BzLHLfO+{toccn4T4&21Jp=YvePE7CHm;G|Ke zj&VYfQ*hDwb?>*uD>?FtyKCig4XBI^NA&V=xGog2A?? z?a3<+?hnwU%b_?|sn*?sF=%LW$Ado>KVDJ^fZb4aFEzZd)j)3!8%VHa29(uo4%QoK zJydd~%We>g>tdtM3J&2y^5c;k^>AmCF1JvvYK^Itgt_}$m4ysYY z{R~opETUT{IReiIgJ@HvbM6k+HvCmpKg{0i+vieO4qon|%YDIcxAkYt80r2ReL#Q0 zvhKfi{2uM{{V>4|>)VkYWVj-0@#k)hVdgpD16GRQs7WuibNv|*MQ-0<gDmPiHA_Gl72C{D8p^^dc@i_Ly{wNdqQ0-nNMD8MWhk4K^XhzNs_)23g7 zhbsRXP>LB8E7lERn(nCY4_PDZ+G^bL`l8r?$FM~vH5<-=j!PJa{#BVQ(BZ4^f@&ix zU^;Njyy}#eC>KL=w=NQ#?;bzyPcDeS{?VBXh?f|1>PP*HVg<%&@4Z{(pmhx(em8*gDx zY8Rl=hQhVCwwzG><|2RguQiRo`94@EJWT6y`r^cnLK_{y*IHs)V#E;wTFq+ENqYdt zJHheWfJyRyp>X2bF;Qrs8`Tf1@<$I>% zD&ZJL3H^Qz$R2;gnZWGHpggrXj zpRgp4%1yc)r~a{D6JNVFmv5&ng;>%T;%ydqs!qJjfADTr53|0WN}#c%PETI*1N%_@ z)*X+J>Yz-%aXeEqC^TnuLE5DY@9WjFL==J%KfCU3 z9rf-43LEZSloO+JU4ti;lhX#L>ok{lama}wpC1^KPy=|zyN4>M$ab7R$vW644orfg z6f=~i%45-uj6n?v(YFAcxjm5Flz|nppi492NUU5gxw;0o!~Dr-!z-C26%SKByMceG zE7hqBG~ua=3TYi`rN;E9i;&bTOorZQ&vkvST4oj5;Crrjj9R$x z+bs)905~EcDO}qa@4pBKdr5-Hi*}#HUU@Xy0k5?O{AYFNK|&zN!2f^sNW@2`ap1=7 zdQw=b;Ky$BpXpY;ey4H5>}sc`_uXvBE%CFBWvVDo z{OIHt&GbF|YCqpwh*ob3Qu6qPqBJ~ah4uJwO$gInI*fQ{u@|9j#nK-eip)f zeH3fN1)_`fv%7Ku59oCASfMV)$#h7EsD$l=VYg9vV94CZMH8S=0T^05-4)qT)r;=d zXpcTCL6i1HXr(zO9(LQ|^+Lc`Ug-=*_XZqOVAPE7F}Z01UPdxWG=-R2I;WrdSxVV& zTi6>}%>o7*u3zWId^bWlox*KgvsOWrV5N@L18>4S&iDR_O{)!oHptV6&alu|?r~h~ zeDUyC6WS1$$mqD5D)4`U-^dV%G7n*Bp#~oCy<1|@B?)cCB$fHjoB-gTtB~W9waCtN z{KO$*IxwA}$8Xt8U(mVWWL(c9-XO2X)|r-TB`HQFfRnDR%;YT~zST3pEuQuP>b#F` zufLvtr+~D?kyjS;1gM8{VJ{(v3-juut@M zkzF2C1^*8rS93p8Wu$VTkVMPE)fOTy6A8psr^r{XwzU?_G07#)wowu>PXjw}`g)dj zH_+-#h^lRkRY;rF*Bd-xZ48K9x=Eb=qv%o2kpy}F{(h?UQ5lvF8DbKOsNc&PrWde} zm--bTPWQbXVAQFxco3Pugejg8_n`9@TPLuXHL>Ox%-v1Ns2+`}R@nhruO65{Rr^LFbV$q3IsA%7O|AY>NCbK5NF zvX&8G4R9JQ^%qKWrb(HLGE(nWv&QN_0{=Y4_SQ%E1g?}vowz+q)}Hr$-gvO1sO_i# z2f-AI;^v#PR~q=O$bi*n#?Qu8fH*^ezlgG0=lat+|Ch*Fhc>^`Hryc8(xtXc%LJwA z<$D#u!X^8eq>;PBOVKD!{r}DcfS7-0g9!+*z;;RxXd<8s!F}1KW&hXO#eP&A2Bkkx zM-CyUZKMT&wuxoll@}rnqG2z})sXcg>ww`|K~=Z~0!-JjZ6f$MVvZ(+2NW{z*@;z# zm!AMoNuNdersinVZL7qB{Tp|6BW2>b)_Ycvv|mF>+N?#-#&jy4%vh&OZ>(3wDj*Gf zh8&BNX6x?0Dz!k%l&Kd{d9ogV-Xk;To%=6cA`))49P%|4;s~&yf&Nd-ZTNhDqaAT7 z8^MBYW_4T0DW~YI=D5gCxRqxdGOzE0JiJJ8vI_)3`#7`XYzF zMLverimFGu`N1CkIyOqW_(5WqCik@SthiEc zlVunS5qL~O%_s9jodWyP53Wbmyr?wKn#N5KZ-8$TKKNmHSfBO--%wQ_$8)$QO@LaP zs4NH&NqZR~*q)7fsV}n4cq{6-4DabSOMmOqf#@vW?pCct!gV%J)@qz!+N;(yvail> z2@tcT*H<+`aMudo0XeQe;HgY{9-ji6A!g)&zOeNX^w2(oTdX@XFdeG$5dA6e$ww<; z_<(9}0c12lFN}2mPI1nObb3GqAZkhp3z$%B?Cjz@pl`CI*GwW~s7$wI%^}x#(cXKJ z&9N+O?#b^#*%X9y7H}hY%11An#}^uCxl)VUvn0X8Z4VmK#@Z{Dlm)_oFEDF!)8k4* zvSbNqXV#L!P*o^=h^LkXjYc0i*c{zMQZuNZ)@V?_Ul~|#3sS;{D+tCFh-Rpm9mP#Q1-(w zK?z0Fhn^s8i(+Wt7JlyLibss`Uig^s^QYH;5`Z5L0A*ol3UBDn{45;c2w~6U(FO*o zKWR~Py74yWz>9MD##g>Uiw$0=Grj&7mb{W2tWE@*=|)rw-Od40ruW7kElG*aj>Fu2 zT{qejJu0SOk8pytV(o?-(E2n`4<05)A#T&oLG_hUR2wtih+m2Cfj|vMhPxD`sAy8z= zKxgK(sQ)z3$B4tfbNmb-hnlEDyiMbX7OJ-ct#@VrL+~>%e;(wAn>;xAS}S6G*<^Z<6q5h!o!SWp{>$31qkbUx zqdx34TmsC>yta-olb5Hnd8b;LYF7hwgJ7l(GKAO`g8{o=$#571rNlPmq*_ z`ez$Z8awKJ28DAC?XsJiKMlusJjLzs`U~PXS6*fO<9Mg~^2}lU)E!1R#xhdLnpnR8 ziDpIBkV2FIAmY|H(othdPE731pYBMZgb3!=K>>Ip!W?^nQ)2(I{Fsb*_J*$|!abeu z#$Mex7VLYg9rJJoFXk7yF?P~8JK+Kw~s#IgsnTsWjNak4X1Cc=c zAf5bCSGOWW*nM6833eb^rk{9&SCb&x5CaK0!?cx6V@Ryyn6sdy-(+hpI>lSbTW(aK zrxQ4Pj-(bM(!$`z?vryCWvo!hYio8)jl=e3;;h({QT>WZ&nndAe1{o3ItR<50$aMj zS*unM7#}=$a^JZTZn1Q)yh@5KFN_6GZWkYU7j^|x@s{^;WSEY6JWZzuK&y@XO23i{2&psGye|g$3|iX1s;$$vmsV%l_ml5E z42Ja*ofZ?B87ZG1rf@iH9Id&br3CB1 z6N-wd2l*gcZkh=;5uA}aHRvw8*qEwM77!rg!v2pnVSTUVJGFw(bk~Kwxo-Iy2X*Uvxg}uGq`|bo zm|d6Suki7Bi_aCBAtfiw|9<3@{!lNGh zrISvVA`)so43UNNf_q-db{tMBPwY&8#Bq+m!+*ZMv;E#(szsJ-atc65xX^V9ztb5| zzM)taaa3S#h=EvOqfMc@2Mt^K$h)dc9=A|9I8D5L+DqY0L14X9R+YbJMMYP|n)Wi; zuiY}M8uzxA4rXe;8-+ z$J|ttEfU!Ga67UYw1e9>|C97miq&AjnHu)El8aLasOx&UPcI(Gm=4^gih7b7P9asU zl`?k_g`GezU$Hb05FiiP(oob#$#Lw`S$)IL^!^5l8!HyQn8{Pyh>QIQ9fzKl9-y7DksU#;cr z@!NW8T#iK?ZD)YeBNdP?DJ0gMdT#Wzr_RmNXL$yeJA@NIW4XOz+OMrCr-nh9 zX7eqMV)}@1brUGizOp}K1OtmsNx2x>>jXlrp2R(Z{;P$Z7g;P2$FQ$W!z@i>kpd=< zbg&!XJWg$&r3{Zp4IzZOXj*1JD=&I>Wx%oYhQ#wufX8>Y*NS_n&Twz^>WuzT94S(h)HOJXe z5n=Ulg!Tx|ah0&FVN~sz#c)F&A>KcTNiv!AABbE{BsO&CSuhARKa^*xnQ8@TRfhYv zGfA4{&PC{tEqJl^WvW4is{uQ&IhY}e;gHCEuVk|yUd-RL*CJF++1TLN9aeLAOA>wy z6OXL$S!)W#*l#)as7dBqlE^N6${c)si_Ce@;#)L*kOSj#U#j#%EN`)r!l!SK|6%eC zKk|U5+s4zwZdzl5C;=XnG);P8VOA;@in_=r{A3SJqfVG+lWG913;>6>9h3ZHPz-F? zYbkjtsH5^teE3iZ?d3~PKvNHRB_S`+^4dFiKovs9J>03OnV!#KWjChNw_c97^(>xD z*s=2SmHjt3ttchloFGw<+KyDG%ZS71x~cyyeL3xgrgPg-Jg47dcKeJ?o`V0MpHJ&2 z0(C|5o>|FrR-2#^O_$~7@%YSLUa6uHrmI|T_P)u+2z=JE9sQ@>Y!UR$EB|_a&(jpg zW(z;D#<4-{J(S;+FNvbRuGcg``%C1FkYzLR-!l%UB4i=X70_uG9ng3ka|yA)`m5~{ zz_vPcwONtq_5gCUX7#xeaiN0m# z9qsBHN(5Pbg<_c&8=q2CBpJX1#HY(C?^eMgTkaCkjr0^hU{0{`qX zR9vH8kHC|)R2IpK@7wz~*hFcwgbyZqFN$O;efaYUVtYpNUyxbpsBZf!JFO|o-%>JX4{07)g@RJqJmfYVpopP#iCb*7y30N zK`ASExKahGibN)~4fc=BEMlG4GNjtAo5F4D91=2p=vlps+I+ZqAF0Gs_{s*Vcgb#*$jb&gTzn_z>Ml<0t3{LY z(Y6leaMn~e{o1nYt&0ukag3t|l9$unNO1N1p-%?+?og;CP0wMzmMUK0YKF1|EgyVkV1Nn49Xu<=@o z8zJbf%wsFoN%78BFoWA~U`LFi9zDc?S51QCUko+$(yUwH?RD0K zq%`RH2qj?QYhR^2e}$@6*nF@#bU^`57LvCy{|(l?vc6GQnAF8-UB3mNr+gwy*r>5- z^|-rGZ*wINSQR3829ogZ-b|FQRPeDnt6nGV$}|3HLw70EzH3>x41Gw7+{&zG!=9ih zp7<%x+0EHmU3;~mQKGe@;5z@CS|@-4eMX)^+JdQ2WQ(3y@Jnh~h$gtD(ADZ8+An zDJI3v%x%yT7cMh3nBI>x*wp=y;fGdbc<*v1-lQH+J#qr7)ISbO|<~V%9rD}Ai>SZ_rBpj z2#M=&08D?uks$i28a)+*Vv_-iOP+26v2s^EVoOZSa@3Zsez?Sx?m?Og5nCbk0C_75 zUoyNo8`oNXF4i?sNgEKJoIlHcvGf)&uMX(^& zaH!=UVnS}md9c`hUr~s5UYYw1y}9Est1=fe8JjCro$*-)mz((t zSP(3WDyN1`k4Mbv3ileUgi+>eyVBQE*EP^jsU2=Nfm2%rYVC5CZ}o5pJ@JVq2$j;* z*aG{Qa4N_TOP4p1)KdPB2^M5-6q!dNLcsSZF``Gp`C~gPFR^l{FomkUz&4bx_e2_njTfi!;wY7PGSy05v~FKZHBa`W zI~8d-dw+M_mIdaByC!#F!~hWp_|2{4X#~S)uC;$X*FoS!#$<_kABkGQ!D7UgrC(ol z*Z4W@iIaLr?e%2%$V%1;BFI^$y+GKMGi0O5hA{8s(-KK-n$?0mw6K6Ms?qE!<8}NT zTRq@hN&%L6oovhH11)F;vo8Hs0%Sw?yT#L#I{4WA##v-v34DVLR?3G19_qU2#qC7gxX&-RJwcF3Jt{4pZv(WDZ9nJzS2fbZ)Jnu4tuj% zW#>=vFkB7(B==eaa;kB~{N&Oo0NWM9GDQvf*gjIPr+!z^{+#6`5EFM!KHh0%7*N$w z7h=+e&aWk`@|L31LzoGkyJD==0|TjCrPG%i95YAgiOI%OHT?1|xRvygzj#x(H-m42 zM2~IE7D34iCEoc9QWfMGm@!fCWX$vcUO@#gf~M%D9Wf=HW%H|B>Vk~OV$TjF#u) zqey^x74HLQbgZO}7k&=0y|9p6J#{Su^h07vlY5$sQT-WkBw>KtrLa}w=Vd(Axw0qx zyzL0epr@&!hJzG5OwDoi(f@CT#*y+*xox#Wxa=q|Bz9(lrAa6WHmI2?*=aV`it)q6u-4*v z7o$b=pXyerq-2BvA<9#WuJR;7*n3rW5`JFfjo@Nld{*H0r#o&}t=>tH?nOktf^W8hm}onkc|cuS_dTa6^C@ zXlnBri@C=wi);+#iOGCn$IPsSttE;VV`B?WaH2o{K{>+ho-8SZ^`tY{fM;@9KJMF9!h>;+{_radXwO~{HFc4^(m2?zB(j>-J zGhoHfs~eBOk;{+|z`@b!xq}zRf`W-Ni5pv1q70^gBU<`=DR1#8H*vfpr0ZF5RJ|_U zmP?H(Obk*XUq6vzXbG)>JYN~`=|P%3kTO6<|!92Du8@%_zg ziUL77xH_kIGw+32TeY)t(9Wx#1bb86C{gE(P{ML1->g??;T{RZDa_@%U8Z_oCFE@a zk_3osWgxdEsh9R~n@)|&+Xh)>I@S3`O>>3@#Y>7QiEEn~su|?VWqQKyK%VA+{$O!w zbP211QTXyJAAI4`*8Z2f7BG*(xIuJtrk~RloGq17h195yM$i5eH-Wv4pzQz3RAWb1 zvZ<=gQK?hpyH-b8k7apID;gTl2NI{V%H0=JiGpx?zZIBH9PbS-Ln$-j-+o|&=X1gqTk6UC+wL7>Z4*K2zLh>YI=90(il&N-xgz=P zjCoVOWrc|V5wX$1I8~0h%(SVzCRcqs%QA1NmTbzOjEOq3KFq65yais{BM7Op z$5G_dMEo`3RrN+yj*{0sT{1YjWhEu5eV(Bc@lHoIm#V| zzH5Z(h%)4IYnW(Hx9;V9!+>)Yc~=%uuO>7Z zi6L_P>_&Wa!>N-=FjR&H&)M`}%poI%e!&@_putbRHWmjXJQ$#TW80++hF z!WP`9S(Rff)NJdFZl~LHE0p|7$+-qx{wm3wkQ{mI7jav_RRX0+noH-boL#(}RL#?TXy{lLQ*5LllMB6v8Lq2lY<8F4(|`V4>hM;PCt<&EiG~6ID?; z^ZU^*ynodN0LI?b)pEl0Xr|FVG3q{#6ifIC#;rLw(7=Gj^SK*-;SvmMciP6OCV23q znby*u$6yg$_FW_(r*wLdXkNmSO)~_H*yq8;E(^xFRec4uKObtJegc_)D#9!V=M^5a zzg8S3Y5+loE{e6c!Zo;k_xgvx0l$iV>V4mt1b5exLuT%1d8nh-G)>?HIdM(1NeE>W z$W?es@j23OU+xrE#93cc=gBH_2x1g7G zt_4Zq8@j=@{%MkHuiIkRry$gS)`%(>`bXOS#K{^kCd*{OLp0Ple=OJ@S`rXVh%0Bm z1Vx7sd&+Zc`glw4Q-)2RxOgk>E+B>Ux$X!dC!pwt?0+eITd28*;K8gU#Pn zVEvwjDT>z}OAR(^B%HH4Q`@$~Y9<)6W~ae~te4}avE!XB)Pq$u^TC|v&q4NOy7T z!_Bk^ei@`17ZjMuZFi|6jtw#6nlO0=JA@OK0hlf_3oU^##>tm&4DdjtCPwB!l!+iw zh|nBKDj^H7x(rfhwV$ZY2dWn!o-nq9R;RZ2yi7icSi{OL<=`8V`l8~aSsny7>OI)n zUy&@T(+0E(U*k>Ddrw}iht%DBT9_BZ7AF=;u~fe(No07tPP8Fp)+z?ts-&t5jv0)X zzCsU;T;9+oc2fZVKLEgV6IK;v9fQoW5drAcp3_Lir)D8XFM!=fKF1>5a75j_t)z0t zh|;_Y$X;6T0!DCSVgr3FpibQ^np}iYX{0yj=trfW_?zYHu6!QZEE|ZghDsJs4Ov)0 zeGf9|JNk&4JAIWG{4-CI@Au%k9WK8587nz~#4<$c`V;s-5P`uGAKO)8uwJMSxu2>g*4r0^t!I)zG& zyV8NcGIdHYM)F6#Y$k6Tl3I<}~!+{E}IkJp5f;BrzAG6z$NDRY= zpdgomh10c2=!p>8^l&_xP3eW`XBzxZ=JYn;gD=nyFJ-v_O&v}jvkSuoTw;C*9QfRt ziL)aXyn)2J4P2cC%U%c8Z0GL7Sgegr>~b~epkUDv0cbLw5(p#nc^%Qe4c3N(7M<2R z%5;gF^jUPoP6S%UH!W_Jv%S$RP&&mV(Kgt&>_7%rq8zg{7j9=6hWLl2SYxEzirS_r zwbDc9DKHcD9}%CgYhK5}kwv*$dRp(h_CAeRJSoWFM$emNiZ~bMl$}$d89FX3R%#>C zKQ%{3(x*s z`J;NV%=6FkTQ`u&4QN3LI-kg+IEYu^KZ<}p_5L@X`d<)55o}J43i0W+>VgdVeVCLf z1D>VNcUgbB7xpn4l37>L^sTiKnZ9hjNJ|%T8NC_c9FZ19*km;pAAu=% z{!coHjD=IM2>)apM(o$=D>vtce9ZD8i^6x4-E&9r>LK zf*7N`aY(6z1>B_bngTIodmz;4!|PT6?i2g$1t5Okc8l~yE1Mt^OT_+`CX{3*aiGb9 zD?XEXJ{kP&iq*>cNO%-T-*M5+X8_v4@D|FBoT_qFSOqn(fuN2C#FF{oTV$=TS**8| zfu{SsWwCy0_4Y?$-KK@GBL6F$2Lr-=GL9?HDBUh<$y+nG%xXyOzK$Q0gTStHetLiZ zPN>Cc%c=)C6-ya;k7mX}QdC9z=lbPeArFoRtB*VSs*Uu1NWty5f>-B_74YZw&T6Ni z=l>*h<(P%^5tI#IB$5%Z{Cbq|^7jN9EQv?)9(Q4dQ3ca=nWC2pY4f>#<%aBuBRl-* z__7s>StIV~W*uuF5MNL;|g>R2nXSpL;Kl3+M84GG8H=E?aht1)%ykMhmSmun2(9e z>2#0dGmf%*w84f2&Tymld%Rkvn3KJfHR?*C#HucTD|I76Q9AG%%cP#43d-dd%r&xo zBl)cY4ulXQ2B7{5Un{ERt|qnL|4TGE%TX@V^DB-F^`l&G~NSn=;i zT+FVxHPnACg3U~J4!2&d{E(iJJPFap2}dNoF{5JbXK6BJKc;3haBQ*SEOoWU)Y&1h z&*#H$soqRl{bXm~S>sT4fLG!C#}!R8H%5*9kbtJF%)B#^(3Gy&V(6jR-t0`$(d(k; zr*6MAj9}Hk=gs#0AzRDdHcibYvT$$0D>NIrA!NC&Ph4swLJ)mwU#`Z_l$(x;N+V0pPkdu~tQU(H(Fd81aNZ-b0Ur-P%^5g_Nt6Mx!4 z)1zpik8|f0Da=n3!3xS98HC)XoAQ#2J+CwuVH2ZRQ~6-0eL^*M|Mh5%0)OED?eN{` zO-{T`hp-^RSthCz%FkbqF^YIZ7{3DEeE3W(6#kNqi-vLb_c}t?+UYGHZkh40)zl=y z-*}@k0P!v$+eqO7Tx#I@&#evQRX@jl2SzV=r{z~L4Ne`qK@n7UMDMwGKEK76kK^A$ z%hRK(F^6ePvpg80sl6Cg_$S6s=14N6`f)?v<#;0_fk@9#0c|C$}NNaZRUwO{I)Nb^{qZtpV}E(wZlIQ5VMEc;I7eS;nMC z+Q_XajeSATsOWGFsVNv=JWV$6s{ zv`%Wyj1YC(#SINPB|~!m33EXk&r3E`I7cV7x7{piw#go#(Xf5l(nv9-IF6xpsXbKLh)jZ6acMW1AgAzSXoq>;0^|u7F1w6t$1wJ z{CC;_RdI@RJ9&7hPN{!TF3pN~+EQfE%FNmaQ3~C$8W2Gpo2y@?8gb^j!ct@$OhZ(! zTkK(XOgO}s!?PEviV>GyQMmD2Ra$Zms9q+V)df02&XOCUKz6q8Z56#50zfTzB#K^~ zb{&KqRy`*(M?M>o&HSIT04qk^rTiS)iJk#gDFEF;3SXD$_OZid?jzT!V%KK`8wEx4 z{9N^Azf8p%5D(*1rQv{aqo8?d#t!qia?%91l_EB~Q89##_6zc?!AeR9L~_gK z5tghPCJ!mWuUl)pMRFUPX#Dy|Ib^4xqY`@`R1Z$hXUn5aqU1Iw8Lq~Fo(S+;nTDsP z^b5!xPt;7$P4ZWP8($?@WYw2yslT|${xjq0Mz^!!CTZ-$jFHFrpe>OB?L zg?=gzkUrp)jZk3?cg8i{{c*qg;j$0#`##L0X=N`8&PKC`iCtu3 z(aR%LCQ|~ihZlPZ#PckR{h)AI&-^66wBbZ&8iFHoYkLdBZlNRaP{onZ3_DmY!YvzS z3_mYy@?+Civc)Xw2UW~H^WPz|a5*Y_rR$o|6w(oa0r+j^!Prrwe{`;ox`=!G(gjF3 zsg5$$G`}o~@CN5Q<1s}6SdLD%?(iSce&-T5@ho1=z>A>2A-SL}H}>mi%|!sY@4-M4UKPd9r6Co%N6(v+c@OU1WFh z=8<()5OA4P^Iay>#4zdKNcIo*l8n8Db=3|9?1)KyTd$VM!2Y4xk3PfbC;VD^42|yT z`kP6r2n>sepnTpfl&u2r9J(UtJK+tzo~#kA7}AXrK~BgWHBrFO*X6S=h>?_RfZ<3MdXmI!(|jRY*R@ zva#}OInIVo2QwXa$~Ng>lhq(Xf10bAb5N%!-|WSQ8nVwre6)6lsp8RQ#dhYCwm;co zGl{zx5PYeI@l`k$G0eG1!XWUqRi#Z#(E4XH3VmR+kX%EV%?#FV$1{velHoRP*ha)= z(uD|tGVM$o(Y2+O+uXb!o;3Ds&GVKR)Nj-F043iFj_5cG^EQ}1q`M{vtx$~uUPUzc+NAEwq{bWU-lsVg*>)NfExY6L+; zcE%<;WPH#m8l9$K?Is+-5H1c06e{RufN77UNPPGJ+M)jo*H(E`o#)&OAy%SX86xF*?Nle8R#C)S1F^0EL3IeYZcg8F#SEv@acS7kaz zWtu+w9)pXgpX%u$YzxnMfAux#Wsjr4`;|Z@Q!od4a$S^LC$mS#UZp<=MkO^fw57kY zk#X5Oh<|@giSI$|LYL(Q)K25s7sMci*Svinvzf+;Lt;Q`47vc9CTLY~$H-Ay$4O(T zcPCq1O1&@aIz}R`1wNhM@;(_C3mzl19E*Z}xNx4^?{QPhU%IV70ZbJrW|5xV#WTQV z+&coJ1kYvLUzhqE>!qAZpOTmYPU9#;b8*I)?$~;Vm;ErlMSLM|Z}$s3+^BDiQZ3F~ zk;vE4sG0h$LEq`@N?`YmrTOJtzBQ8xo7JKwJcR>3C$RW_-KK?pfN43X0bOd1l_Ila zvq6jhEt5$LK?Ou$bKM?~Q^taBrUguNz;2C+{UJ$(00jQYH<)qK{IXdYt}5n>9IrfW=u=ALCUtEW1ELO*LOPM?(R!SG z6Yp%vbx7DO1CcCn3PCY}-1L@eM0|xy=>lZ$<(pgeE*NjOo(blB34WAFpu-Abtz}l4k!*cI-c~XiKJn`eoj2goR%? z;C4_(ceB~6N59{AjzivZTLXBS2);3+t9s?h;F55y(~8gDAB&2a_Iq@;QA`s5a5NBZ z)yuYr{VmYd^I3h!dGR!Syx%~?`yf0PnzqB7=zQ?aFR5#VB4LX`)@9lz8pm*!h2n;~ zOmkq?S%SW3K*^wql{|ROSo;60Y{AU5`rAz6K`T>Q6`H0%a;YHW)7=R&$-#Q|JG`DA zgBxPbE7&B#VEs0cL<({^SaA*Deh9hhE8=Xg(r(`EJDuxL;fLZ$#1m*`0*DTxcbWC; z&D~M(Z`+xyu+3U}aNVh!zW^8lRxi8n4|~qq3M;pa_`tM$>{PTHb1CoFZPy&6Q$d*7 zfD+D-WR{1uMoK2Obe9;EX#vh#cQTdF4{bz2dFTI*b|!DiP`jHzoxP<8J^)YSdltfo zYbHtWYrW5aa@70<8a>>ff$mVIpxv-KL6PSud&&=KIr**xqC$6tqQMJDl?;_Bl*QLV zu*4Iuwt>ELgMoIF1b*sFrmf&BNpL?Qg)*Va6esH~`=u zY_-bdnz%C8$4s9qixvg^TpF5*DtICdGMyz*d%!*+8AGT}xwn=Cum%@_`gdFGq{ z81d5%G=0_Or-Va*NNT6D5{S-Jug(21KSt5y?Uc4tGAd)q_tm7=Od*R)YUXt(2e%DV zaRS{h>StSoUq}M0p1e@~Fpv|3PwG+Z<0bEvm2AjVilJ(oDZIhT_J>!WB;}^VhY z@I?C?YU>sf4{IbZ)t8a{j$2NN9~tNKQ?OV+kmKIE>b($h=EgX`Asl21_?=g90us{O zOc`R7IOVUqG+xyk*qP-V8#WZiTUKoi%WLo{_6^;)8jUbVS6gZUQ+BW6jt}FW(ht@d8f3HqZM^J7XyZ~b%1vflcfgWhU6O6J+3WvKPu%S)lD-}cLbDo0Q z7>P<5f>UUq33Tzbftw=5?i`Ll`g17&VWgPX6z`y}aINBySF_7<&iZsxm`qP12V2Ms zB*rP7L-@w*P#3m_D;5)S4co7FF2fFV9FmU4iM>GS1TI&|>DuUxcAfu(>%;DxvJ$$l zg4PjsONwbKR0pu{);-$EdfpPg@Ol6JK}K&j0&EZmV85d}oig6rtwxZ}Xm*;(waTZ~ z9`-rD#T_cZu3IGrBZZ*NPs9F7-BtJraP{a?N-A-sn5h^Nvy_>8aCcigthVVR_^Om! znmaOJSoIiH9+VfsT!7NscrSa%6;~w5D;?z(=(%6|lI3*-tXsC|gOuF^Yzg?8v_Rtq z*N$lm_gw*p_9k0&3TY0=28Y6ta5uZT>djz!VVQk|wkbvnf{jq%o{!s9pvBU2IxYPs zUHw!8NaE2pr=0OL#sfxf`{6_jB%IrOsh_s(nQ>fQh!(Uj?^6d3SFiizni22%u}Dbh z<}||jzxw<3kEU`*k0)EK&YW$(a({mba6P+om+?>DobqYb9_?a=eX^V$FU7CAE0Unq zd`8dxII(DM?>%mOI*~BzwTVNh9HyTSm45^>3xC`kY(+9*@?g9>JM*7^LDq`CqWh@` z!mbVcP#VSJ4w^A5fQ-2!8NFCwzIWt~qQi=?N%_lw+%n~qLZ43gUjJzd9FMg&)qaeo zQ=Oig7Q8sqHt1Fx+$Qjh82>e-cuAKdrj)c$<7yDQ^_r$fnJUuG2AB4~Eq7#g%g)z*ItUSLEopET38 zbLsgPo@8e*dzlN$EFT5-?lb5*==77qFnr&q(9A?#xb+Ne!G|Vh+Hw``_vCRnlf&|^ zbM+9jxc^*$C{mdo-Y(XU^3wUu<{;=|m z_)wetn6(&uULZR$7ga48c0-W660O#uGb!r6T%fJGIbU8rCfo;jP)4oDy3! z*2duoxgdS}L_B@fx6+|Ad~}WnHn>{^x)0;~V|F9gFzDL;aYyQ!?RJu@9d1%QkfZBv1yv@%3Nwb9Fz{Xyc629)NaTw; z=@8iOf1#UGh5FCDM4U_(R_czBI!={CM>e-7wwy}-c$Tz~hhQJU6$>0}Q0biqq9%ST z4GDfZ?j|~@Bp!+=-QQ5~_=!g@-ECasswpNe$R|OKKPKtw@y+}g9FB&y|88< zT)~7UkdCy`{bsNBN%3S$>Y|-q+!l0NUDK`-(K-g%VA1qCW)nE5_PX8wP>a=+b5V&fH`cU!0W$kJfQOieW(M``!txCk$&mT!!-{IIK9SI4k=c z%G2|O1n^SVKfu2v3oq~Hozjwu5=vK!z*g8kFHeKkU0u17gr!RlIm)cQ9H=bjnr1kv4|!x_K8WqlS+P1>FXgDNLqu7A~1fT9XN zhg*(rk?cS@n7fceZbxxB^H&V~3nC-xKqP`sFXDk#eqt6AZ%ew&C%RPK)cvN>KHFU2 z)VfwU5`+Jbx^{F3FdKUR!HN;|CNbtQbL}Voh*gx*<2T&|(96sE1qN{ljz*?GVqUvw zgJ#YV3?!>&rYW8;XaYow;Wi*p)@hU8;+=4SQ#6EDM6^t1XKpLdb68vSQFIkZ0sA>9 z4hKS~b0UBB8X>gN5jgRy`r<*cGAmz4H1X4{{0;2YuKe^e5<|FX4N#=D?>hOk9)rp6 zrE3P#JLYe~`H1r>v+t{qW{nduxCD{6?FJGLJFM=}CFbAlG8x5d%rhno@?J<&j|Xsj zyQkg1izu83T}Lr;akR2iFZ`wo59)(c_Nr(v>oCB$NmX{n5-nIq8dU|#Y{i{dnA_AJ48`Uo)PHmqR5t8)X$7v2+D$oe7 zJdG^!R1F<6$q#Fv$r|oBA1J`CwMaIoV<7#&T>ml}D5ZOx%i6bnB7rQIXbTQW6Uho9 zeghMfn~c4dKCDBBei|i-=GH7Q8W-dlVA#4{AGI0`dQ8n2+jJxT;i3Z!f?f)^LE~dm zs3D?vWR{>G1WSo$GRo-JcHj*LFE4MMlU-inn~qG8mgyX3 z1{8`Geq2P3#beRLVo0JSKsYP1|0-&r1$Mh-oJuZMRZ+~CP1STel8a=KTRC;iJ;pt& zkWIPs(+Wn|Ai0&xriX&s@9!AFRy|i67AUGmlnYPzOnU35a|J|${zmt?@$AH9?Vr`^ zLz8DjPvZ~k)ppHYhev$`K*D$h6?8V&>f?JrRZufYq+pfov5!yPb|tz}izrc~Vh=#Fxmtoj^=b4Onp~^jnZg{uzK4$K`e_e~Tj@X}p@oX| z7v3hRA4>(^X!=*)9O5pZ*r`lPX)|3KD~Q^bewn!_uC{n7kSE5QA$ zNwJkKb%Zt^Q(D~O=}=_q*F8$vx-G_#-{JV5X(HH}Up^4$0{?()D!%;*f>(~2sj2%y zLh7-G^^(w&{oh?7V{OgXXLGx+6;2k^Y>`!u?t*@Y_^zh6q(PyMF`{ zPsN<*jOXD zY>$B9xf7?_TI!Ui^=R0&-0>H(aa4DR_yROi#YtW={P!Vt?)dealU#QmE%f$Kg5nSD_bq_nXJSPLG zenX;r)pK~db|46dK-tw6>W@?;xRa7$6B4999WL>JUGUdCEUUb_p%qjRo zqQj@SU8YNCvM0i@h6$U`%;z&{r;+t38>jgy9tp_GC)j(P|8fGv=y9H52CDerO=b?w zR(TrbUYXYopX$*_$a%@IU{_CrWMq<|gcAJ z&lL{mE{&gZJBFqq^uz3j*p;;AS@`Fco)?|iB8D&24q|u9(Hx(R)Vhy>g4U3c#+`{xN7ew5AtdqxqGHm(#xB=SkehPpF zPrxNc9u!BXSh93wsS8p5%;bm;&eF=dlR6@*_B=o}2-;|{oW|Z~3Qb=aH5`@RYe>aj z(DovLvxs0~!MrAbs3XON8*l6y{CYRlTHUyRI{DO;MJ*8m&d=IUOH9*lmKepLmKA)% z<=@E`36W{?j3;2%k=s4wpWn9EN8`1mrYYunX`w$8cC{WOqOe;0`2Y0KD4REonvI%& zBa@NrV@!aVM=+k|B{9{EVI_XUY(nDA3hy5!`mwGULmvk%^5Kp0O{m>Yfzq-1(-V0+ zcOG%r9>KAuf>W~bq+`(prhLZdw(H!9kwn75#n5U{O-Edl*D)RRQ^An>5leA_Hp+#- zQ>99_9tqIG=-qd@sU5uk&mWvl23|d9pT@_^6cGUI4L0(k6-z+7dH|>)JtgD4CDvpr z?V#njvM9msOS+b@MV{!8n_2nKP_<3W^5MjZ`5bB)opz(deCi}@3&QgK*UzIP0~exI z5z1eidfGcoi5J$T>Kx8Ttu&9(48$D?2%OIErkk?cAuDjxy2)wz!Y=M@KmgAmp-*3r zm0^Tx`+oY-bbR6-f35fuJww|ecqur_+HeS%XS>B^HK#(P) zr>H7&={^ZTPD_Z47T$HhK=8E*j-7v&%n+CA6wX-ac|V;TCHeCiC-`iQo%3VoB)9pM zUXn3>sh}s)_ik0JT6;ez&&{x4)inQun6v{uN7CI08uDyE*d9-%wmTvEK-fwyOXf$c zu|9szV)n)YkMp=-Pz*C`b42pcp+RYQbd-or$S4^wQl>dxvd(1`ShXg^K;+gKQ_gFA zIR&! zj0(-h;ax$-fMI3%MdaWNAXVUG>-f7`VK^*@@%hzHzI$vkKks5Hzm0UoTgoGhO0t>t zP>ywncbbx_OhMAttMdlNcFyOWfU+2wx#B2W_*Kv3f`n*C=9f}l<4u^jo#OrRpVrp3 zLchV<1#7Q`bz-h5dc>|~Pe>;1A}vIrG3FH7OSJ1tLQ5GmigUGjmbWaoE?=CNTQlL;1gIfTdP26@LUMXO}9ge2*l?7_DvPWp+M zYmB=%g3G_x1Un!yQQU&SRy6opBrY$$?rpQ)WMq*e)R<^7dx|{GJ95?I#Sx=Oc!Djt zn1_OxbC6LV5o#&@mZhr}?H5p%a2@XUpZ&L1ElI7DS2Ik``GW@dX`vZ>5UwPn9ndIh zZerld+#+os(fe-kL;zy#5%jEX0GfgQoLTGrbS0snR<*SaZ23qi?xqI-xX+U&*xOhehY!QF7u0=m3DAS2qzIaER?ZCt!OVMz8Y5?jsp-Ud1GwjBAEe}tWM@!4+7Qb(8HgCvE zTH?*N1EBHX2QPzq`D}k-+w|nY( zW=A3pfCb(zrMGp%pzm}^e=o80Xblfd)hDo)UhOtp*6eE#RME4-l!Px*!SrID{QyBt zBl5CIn^L{zh%-+V%b;{R=Xv@}c+USNHg*WyTRW>&04xgz-aCd12*;z;KMR@tSw+4F z3IVW+!&L`tWP%Gac!}MgV~Y|XkEBwtq2U~xBKc;ApF_P8A32}Va6fO zDRw#C|Ci&|0y7Fj1SV)Thln zoC$?8)o4D|;cs(V(AfC>caC|aB$7AVA@jp{_c7DcQlGb+vuBl-D$)U&F3D{=H3t^4)@61fn`Y=iim2>y;u z><+gIXi#EOHxS)AxT>s%(pi5yNN_6R~?9W^m#{c9yl5FK~bkO76t)C5fkd6 z3q%#VZvw*`k%O)8bQ8?-$#9lfM6bAUywG~*`1=cOnjwXFiE~v0;F4;UlYH^H1Z+)i z5wjK|uR8N3-UTm7i(2AK+gC@G8M>Ot_qrkWU=}nU6~YY|Idglkn-;rE9g@5*vucP{rt z&J)@|D^dI_3w4iUjG5j`f7WRAW5k_mUMn)nIW(*YI+g~_%>SR-2v5~cJ4R?(19oj6 z?u@#7I7$q^6JzwlJw%S&^>mN1T00uUX{zVQy^hL>h+X3xF;YdF)E-V`bH^(3jD>>N z3@Pb(d5;zAlYOktZ2%Z^%wLeFAyRhx|76Q}?foE*1IIdo; z+U7ZCZ06fU{7~%-gJxMYvvWZF*DJ^@%B*vD;ZO1>S-A_{2H5x|vv%(}o^`##b&@Sy zZ1TmqZinN?+qJ^pWB15KC&$Le3yKdgukgRnLnO+hqHp6V;L!bh7gw+f@sQa38R${z ze}*jMz^s%wONV{x8Qa1d9)kpG$nMNj;L{Vq$PxVYu5+m&sH>aWVrCK{QMakPOdV|W zbpmxvXIa;eex*nCa|%xpgg`RZBDOd@ndXTh?-t!7y899p@$>Hg5CtXUm|^J1@AgKc z6;{Kjp|E^P0vVdZTD*y*(swMCI*=m|3!}eSfeHvQEB}WtDF{O1QpT-u>n^jlqJ4m; zhw4cJ?8-zCTm(4q1SL!oo&t2c?elyraoNnQE7QHKNM|&^b7#fy#{<=5L`YwWKPu-r zA_0q^H@jH_HLppr0VYp%3o$filE*VI; zfZG*5r|fUrz+HtuU4D??^&I}j%KI*%7Z@#q%h=*LuPvH~LFR6}UbFzB&X`D03&)$c zpn20$OQ))T|E}3t0$!@+@th>A=~~eCLPcZM!0`+6(YV^TCmH=JbB=0~}Um*i|sWkF#IuX|PT}c=jXljivmG-K}#>TYnY> z1wkZD=d(|9AHk@m?Yl9T37f=&EMAZ^oIJWfJnf$TDGLd0M8O~RN6~s2MUg`8*?0k-(sMf}{XIZFnJUWjaMC4=-|g99!=69w z^c>vp787a{b~lu8K@PZ%i_tMR5#A~+TcLjzg~D`!AO!B$pzDl*A~zdhgvc+VSE@hR9W8ixg|S;c)aqOrnMLPnm>ZqXy7*~?loA+nt6E-3x2)>f z2IL>`QenZq<~O63kZ`>==0YPr-%|_op`r7MD6MA--)5N0Zqhw&p+EPKB&dCGjgr3H zwY-~c=rA+W22o_Hxb`FW9Rn;3C@riT=2_*-4#J^H?fJJtXp~E>z6%=15TAyjOT%SA>u+9ECs(VF>jvFAi$mk zJmbGdg7(!<%fWi-C9Z=zfK*~mE9m|p2WG6^Hli;{V(_6|X2943?G>Q)xqbH};w#Qw zYdV1dN8#W9jl~*?_stPLTz{7wl6ndf=9=-PYh2=0b}p>bJ_QpVRI}INx#&G5=q7#v zN<<$0;>D@+401pdWA0=O5E*!TXDN-)js-i>Z;?{ z5+&^Fx4#wVjUQaVpFIGCvW+4o8gP|`MSucCeoVK9`Zw+Pbdmyzx*)-4+Jcl@)yRs; zW!;8OpwOE@Qv7{neqqft-YdLAZ(TLVg=&g4tyY9XYu$M1Y6;3O zf8{}l76GWFOJ`AJqxfw4FRSx9frP2e6F)QV1!R^$xr*j>zpVkxMuIOXY0v)35%mSF zz4f%dnRSk`D4pO!O>~t%_-nB2{(9^OAtY)Xcf5O)ttr|AALw9IEo!RdxcIa>i1i%u ziMjRXZvwHABGZZ8jkE1g^k&C7_N>X1(+gxlY3d3EF8hMLxU%W0UC)YIF=!!CG`u)e zQ0qAZ%-at~R+Z2&DO=i2Bqf?Zxju1K@@wClQCqJLEC>71*p&}@EeV)FhCp?<>Gu&;;Nmv6@s54}~955h5~ zLjFAuA~#mkyXmQ4%}KytZtZU4tvGbA4F1`BDHlSiUbT25m8k>P2mlfxoo;c?2KYB> zLg_{^I~rix34I_~+CXKz?!qG4hS5|phhUj@y#oC5Z86&G@8>3KCyuOGWY?lPt@}Q) zj>^7|Pe#i(-;(kT{s}+Az6L*j>xQkU|Cb_sN}+o5bJ<1WsGeL#ip+zJaeOZMFD(!i zn^xQTS^}-ED-i)lBehrKveLBJ|Gokfnr1cE8Uv8wwj^}d^(N9w?iRu;TZ{d|fhQ(n zic*sR`<;3Xo`97?fmBQ~EmIfum97s6b79RAYNQbwMwi_?v4b6nBq^lqx9r&_elr}p z{+j~`2h|1~zB4hXK1#+nn~+=aec(a^3gj<@G+Biir<}bzxi&o@@QIQv=<9vYDa(r) zUzLN#aE$zh+~w4^!prY}yoBC_2l1G?-lwDJc(h?Eq*M6y>{7fhs|>+i0F<^sVb-^* zick?T;B1W@L6qQ*JuDj-$!1GRVh0_UDR`|;X2GN?|BoPBlBY(5kyCWO^RfT+`22fH zA3m7E0+c^XBv^D4UZP+fmBH`HBERcE3>~Uu_X50=lH3+keLwk^+!(ptX8VN8Hb@!T zxxcHH>aXoyV}wTxTR(ByF@%De&b+_I)s+!mM9N_$RA`jFjV**yGBabUWt6KM1U2HO z)j|2O(S}y==4H865m&f<9mKJrjl#V(dB-Huh-*%8r|5_15)MjUwn8n9X+??!wer*l ziC>-!_zc&V@oaH;zq?0GTD7Lo&5!Cw^Id-c>Msj!!ZMR|@g{?Zw6T)IXEjLenio)` zr<^PMNQl8LrN5K0s;GjL)=wFV>9{78)D_b!VJP!Ea#K5d&&RyV8^Iwf{9?yg{~}@O zGxYak-cs!GZe)(f;9`>rfb&J0x{6|M*R6Q`7{l>dik$x3vTPAQor^)27Z3=EE~Ea| z@o$)K-BUsIgU$`w=9+anxbG{U=1Y7G`-cN0X}w&mUS*|vQSufqU|Wl$;2lcau26;O zs!hvz2G#)&N(_c_?%~<%iF#g7&cYyyWITe#1_k;bgY4|Cj}9;4HVD=L+7Tut_SjDj z;>emS+2t|t=yhnQ)K-v@cLdE2Pi2M{MuZE!Q2k#7@chhteRSldd=Brjw-9_Z&Ed-Qw0>~W9_xG z28h`mk4ak@HUy+@LoyZV zCr0rVl}M#f+MzgN^sG1pQOhfFV02bg4a?7p+MN~mCqj8upJ6pvLSy*?WRcVF@i{LF z^ypbCnB*Sur)~p7G;Va*{p7)KY-@UxYF^w(ZLHK`@TaGfaTaV1?x)i@3BjI3`cevq8F-G7o%-m5We$CGtyr`$8p;1% zk|*%n5Ff|DQ}PNREnL_DCkgybh8Q#%bd!*>;McF{(Zh9_7CRl1e+f!j%fzH{s?qgu zDpQ?E7`@&Y4e{%i%O3Ag&;#PIYk-pI-AX`Nc^;S-NUNvq_iZ|WPQyhaM!VA^3q2ut zWht0+B>c)-c(0WPh>!JFkaOkC{PP4(m3-N)CroL`O|+-T(ECF2xXr-t-wM=}7B}4i4m^!w5bY zs;YUJLR?!bC@iW=6cCOPLI=)@ZQ=;5iGd9{XxNj?jD!9q#l3dehnlvX!9eMENXwO9 z+32+m^C^_do$GDNS4TKUxGWTAd?iHha?V4T)d8bfECUH7&mfT^N-D)X zAPy=F2R*3pZvM-P=vP%R@5j*Z_e& z%_vq_?1P38{77;!d$u<&T&Vi1W=6-D){Ase^sAR@8bEq~l-dlkQ(7bm+is>Z{{vd) z)kX(1KRop=2fPzVlK!?i4HTH(GWPgJp_S92WIUpBgNn9U?f&Rhj;jY_-mzSjt0!+c zw`0yTpfF)bG&|AJPjOFIli@jMOQatY87^%-tOG{zPc!udoPq1h4muVUFgv!mQ`p$H ziHSzKaJbq2-UaKwH&|Q2G)h}oO7T&Eq8Eq+G`6L*ge5=LU1We~&qCx&i`zRBD5n%Ue}t^bo<SW<`QFlW!V zzN66QPs4*Qr{BKSh1m!`WlFU8E{qgt9J`MVo8#-lZop}_apK3%#zMQ*J3DOuV*LnO z45|yaFY$!aOo$x#Mp{5w%9wXQpWGHw|CY)dm+L;M<$vZ`xvVNQ`0fps9zfyVDm08o z&k3t*IHl`6v_+!~l9{-oEmYGeAVguQq!m3Qs)zX?@eB2<)23*b+ zH924v)R@7BTG<$ThkJ!Q7rpP3r+=~H(OROQ=JmNt3EqmC9|lF@I~)d`wx!{QfkNEF zD#d`I++kUkZO51+#G1d#yB)N1K?p@yLc6jf$)*8o<3 z`6;X2|5~?&upm~Ja85XX#JloG&EN@_JRh_|f;NtdZxhrAiKx`4>+4m&qTERL5gpjO zxy`S?f1&72q30;TW-lV(eKlWby5iu=GC1`&k~FT@*NN zVDO}^rx~#?>^4@x8kjRsJ@DN}4#FjNO3wG7x?t%8+uJnamNEj}wxT+YK>S;0Sud+E zFNCy3&ZBwodDu;vbdZk_w`G*oma`39E4h~g-n{UiQUcPUHA1D}h$5WF#=MvJDpOs6 z==XnybzRlY1zcZao?F%NSt~pI0Xo7jE|$_V0q1jCXDN<#0$KIk{#HZrqp6T&QQW)M zDKSvUI>e*b9#3|A16rNWQ@^|hU(D-8+>Ai4U&}ZI?l(c~WXtSmPeat?KyyPX*%IAv zSH)lj%&dj&p|Zh^b_+m-F*1R6Hpn1*VvzdG`D$UeZwZEROOn!g`smd4H_?>6AMBL` zy8!@J048YOU4NW7{0un{HPpnz2l2_=`Dpjd@#QJAK8B{Hor&aCetwgQ*CQ; z*EuaG|F42ZkYrW#08!N2&7%PSKLEh2GKCNQv8Gibq4q;VO$@CRi;&`KxN;a)`^PTo z6ZAe`hRj?;(R^{vMas&dL?M906S}%>4HK|}|DmFOL2$&`zwy(;S&HR*L8snF-QkqG zClK)Y^4ISeDLUX1 zk}ZD~A6e|GS^vc#A=fu@PWJ+}(b#8gchHY5$VU3E)Jie`fU2X(K&tjM2aO363r}KE zq>0eVy)|3%k8{3&lj)qT6k^qOj>=b`{BRRG2F`+krc8h!<|Q1)srk~{4Q_GpnRlcJ z(soF)m$Ljmk+&K?RO?QDu@7n?Dn0z@?#p_~fBm4!c!Z*@cJ!5pXLUPcNl}t%h%n5# zQJV0yEH?HSwPf$MB{cXmBF%Wt0HKftLQ5v&TX{<}k3$VzXZ2+^W?VswwUJ|kmgq3l zeK=reC8I9JVFslI;HHeeK=2^p6Z*2Tcz7Qu>SRl4{tMQF(@chd3?>=mZxXDd)?Ez54#@rTwBcE3Q|2CHL zqF$#oJ?kCyKOJ04_(b9+4Vgd*(GOKkU7S{!PCgwWZIR9m7#Tk=X32g&iNt>$pXM~=&ZR+^ofZ1!{KrUeF6wK4ZDJ@n!c@MXCux=DUFG+ zgw@0KOpep*7x5y-t3e5L0RI?`)$Y@b4RA1Ie9^uaAr3XNnw z_DNO8YE*xhkgmSirt)=sPfJYO)p4R6CWGE~ovHEM*{*lodkm*L7st-c4BC1HX;TQL zTC}7s4Hr*xwW}f36$5sG*d7C(Ic^k%f(Bqui&b8dq$4Q8^9B5myfwb;%6B5ouhwh%m`TTEO2P;pvV9WqytlK{na+s5C*} z7Xy1VVKKnu(rTZ2k-dBeWE!P8)4TEB32 z2CFzQnm1ffZ*g}B!kVDDafXZ9#NU#wKG@SMQQaWfs%m$*Y5n-)ZYinn=lD_8_xGGf zNpaR_782zA0QYlPzQWs@SoIu{@mD^=N(r2qara8$muYfYicDV(8p5Sb0wfByGz0;aZT zeDLTM*x_K=Z_8`Ke%w^R>IEB*51HOP4FOEGt2u@Qbvim&sllxp*$JP{ECYt12FT2d z+u~v8OQx4V{rn_5Caxh;Xo$F|>PyBFZmO^s{z$J+Vg8kg|cN zOI~Fh%#$LTvbZHF8>kp$qe%@QEwo6Mky*4ogNSbbs=duUY=Sd>O7 z)a`b(h0~(&d;gGuOSN&R)g`)=#qDe+vWuv~q)b=XX3u&a!zxAh1|?p?RiV1G2KK6f zEk`z{4g{X;eOhu3N2#D!sytwqOxv~1Z5_+vyEs(_0(<ZZ&s_b|-EMmeuA$hEyg~Q*w;D14G-e;N zoFp%w3Y#E&EL+zMk}h-XAI|2}EH=BKBiKEnuu>2(F^SjX6B2`HA=-Sc|UJ6%OhEq#z9) zc{fFKkGw^dL-1jH3)^2noSe)mJL8yIevA*CR@_5r{pax5lw9L8XGsK{0Fm5yEMK9O z&(5*k^H6(S=s|T$yeB(6{b>y+w_cy>TRe3$RzbW8G|Y2q6w6`MpgvbXU1`0dDOLT5Urt zc{jf%6LqUi;hA}*FV;{Q^mK^5msS*4$8-5ueMS*gPDcT(7)9iI7^guM0-x{PqSd@a z%1@7j8L!Y+f1S!dg;sNiS-3mHJwiIE;1;9U_Z+S|m{Ep|H^Y@nF;&$q% zpJrdf|Dq0z@GX?XFjYca6kR6}0keqn19-IRxS%Z&)ZYfR|HPdH6K|_>^$v@Y$fm9% zj`n_X-2{eKZsKqYUB0%_Qk;_-Pu?{$B8ks4>6cD}-iT{&#+ZbJBPI-QI6o+b(&;3z zgdzQ*|J>QS6@X*(Q4`j^F4wsl9{8Tfl!P)ZcuZnhlxf=SW!X#BrH2xrxIu-HPc}$(Sw* zL6ZxlJckVaLVvm>+NUhBgq6`{mC7rToxf%YH^|$=;);R=h3DTzSlOT70Kr}|)>6Qw zm*XCOUCxBA3$d6orWHwr=^KbrpEs*Wxy}|bM(*hxT#%{BU_k#z)B9`*YuGKUuKL3_xK1N?*jv)<1-Q)JXVG zDZc}`*`cl*eZ2iXGAs6v6|Z}*L$T<6)5!vGIL*zACLE((Qz?9LrlIPDU7j*7wxHws zV;__+D>)N#&p=0LyhRcaqRjFsWg5sYxS1c_={t7kxlKtQ!S1~#0N7AC6U{tc*H|u{ zL3!2n?O@+frRhnGeja-bT2DjC3kY!kJmUo0p_$qgDYqKHVHL2MXyP1U+KcuqNf(>C zI8#BgILr1{(Z@>mSNt0j`aWIk1W6+eS@VIQ*?l1dd(elLO^w>?&zMnrs9CH2hZ9XIOr3V`GXTL5k)x^4glgNpdR@G8X8|H zsBe(C_$?dpZw()Yj$M&fOF(<~AHs!>H50JVQZQt236!@B?haWzp`2Bav+Bc?-~K4< z;9AZc^s*t%Ib(K3?adosj``i!a;Iob(MBX#W{k!o4nQ4)r-r4n@*#IV-|qLgZ3~Vm zVV_B`fby~CdREF7(Zinzf+55M^PS1Ne`U|9!Rkk!j>Mh~?gPo1!WqmrK7ANz{uzA2 zu|VV)D1Sg-FXcl>rzOIlR|O@*p@BBXlw}0vBc1J+bZ8*5ze{C%2478k?=;4`27T7l zDUu2<^B8Bky7=#Xk;L@q87PAo&>QM7h?)(8<*FZ-N8eGSKaedMB!x?i7+MI6;#n zr;(i)1srjk_s|6NpM4Bi2p8F>KIqv|T&g>4TK7dqT$S^kYM6@(KlB`=O%vy`=TKD0 z;hcA+&md$281Ty9x7f@Xhd*jyEKxG!%K8d<+=B>K){lE^U2a=yM>YPZ{+*U1N`SNe zVaOtV^aErrs&Ms5@-WekMqqv}S+KO4koD}9JOT@>m55p2#MoR)bC-Zw1GX7+M0NeN z9)wPKjncnCiCL8)w*V@MIe2>$v9g2t)FRI+pEztBm5J^q<)SzpWiAr&coNun`uF5~ zQ9K@tF&6ax{mLaNChxQkreE7qWk7p2o09l5Tv{Iqy-ak>TqlFuk8c1byZORTTBvNh zK$lhaRmOS;zQ~GG7t4JvZ;92hI+I3JD16p<0&L$PC?t=YVAZC^aLe?caS_F5a|w~z zpff?k7%SH6(MAL%)w(J>%>dk9MAA_LAo^~tKk+()md!7|>js_NEM)CPXIFQ0!^VBc zAt}*O{?)P`FwaFm%)+af&nKeSJWq7?q8vt-fwoO_0v0TKDJ|_rERNw zf<~8FKn)_DZU?yqyTXr9Na_!o@485NhS`@DvJU2LoZc^=to!s6 zAbHhaKO4?ep*-HRZ)f_)Q5}G>pGHDbv&JsU?c-XbtyVIL+Mtv7R}RgOOs@j~UiCUM zeZ9WwnUAwv1>1$Yug4$G8nRyFq8FIUPEgdYXS&w84<*(#ask7@Hv4<;YJso(Ty;j z7i2NHF?)D9wh?{~xE0v%uyvbx?9HT?+GT@%O@8Nq2<$)e$dw<&KC-dQ|9<^zIS!U% ziIf_+%_Dot3tm$h@*Wwe4Qmds*dbcBfHr7ntB4_KgO79eY z+?8@nALEj1hHoODopgqqcMLvPai7FZ<(m0s;lAU+Q~6s1>hOIGZUgqqdT!-3l|LRchabqar|vZ zniNy8h3DRCHB;~(p8j(^W!4cBG9=^lcfK-9?i@5xFo0nT>#G=NJOHX7Zu6N6HJqk& zX9V}~(bUhb`nZGr%&Fa9fcpVm;}YVJDqZg&!2(qtmARRfpdvqZv8k?Ja5GXgbCMQM zx+{lw&Ak!%JGJE|-g>SlS8A+)?wj5ij=o@PhDnHiHYE8gW)7 zN(Y*gFz*Yv+`gbNz7(LA8Hh|Nmm?TRTGP^75q~$9B1LSU@tK0%3NUF{WI%^)Jf-{? z62kF3Y&$h#0k+@TM7Kb|=FZ)sQ=Iy(@kQAjsw|ePcqbvweZdErzm0VpsP?JRJ+>uv zD(c64E##w1eA4!;LJ>bcQYub6VGyU3xMj?@>)Uf$94@FA+5uczH?wSO_JVa(Q2A%j zNz)sf-+gF2Z4jnml(ey=hL!K%Rj-Rp$yO@`A{_O`ObeOnkq57 zs|wkA!Q{UQWEu5GvltlzMsbQsJ;E=3Lu` z+HQhi1OqRY;D17t;jqL={0M5pR4b0H*RX4=cVj+-#prvdLw+#{Jo9R(yv;`RN5pZZDEXr1o*OqH=Pae8 zSxb5q*t|AHl0^MATU7JNv$(u1rA7YzD)kJ^ub?I|vD!K%X63}TmQsf>ARiey*7#Tz zijD|&uEqBmabF>K*ccw0DJl{LGf?EmZR0mYxc^v*Svm_v^WiSranz@=UvO)PUWy|y zx_!esANKVZtN0Tyve*|-SL}A`#kW=+n<@xyAj%JzaOqi}iLd6(JJrZ?Wu1|9ccj}! zhUyE*gGBK^@R!~Jk%olq4=my70_w_#0768y8w%Q5s^bYDab+&31-T*FEo<(HnNrg= zYw>WZBQC2+9X+`^$2fB`c+NMh9tflS%mB4lxW*HAQRhOtJ5s_^JDA4jO^l!7psno? zcvT*qa}z~nM4XgiJqtDlC896sy~EN|(xqxa^%0f!i7qQ{=9p73Y;R+GOS~A6Vv5RW zcoR}H<_7hDRXOe+QM#rfukY@m6%x)|c%q+Qd5gf4qaa7o^z^Qx4K9sgl`Ia-4zt6O zG*rr+RXlL>IA4T28aR;T?{2J>m}K$MDtebp&3TtymKz$GeD~Y?F)1>MIRn@?FpmuP zjdUCykgkgo4Zwi4%kVqR*`6dR%U!Y`t%p4`PxZrG2s*EW!3i4ae4Xxk z^mz=tt-tH{Wn&>-y{Zp&^mUv^QWZEV7yQa1oDg>*eUPYvjM{*Eu+m!4V8zfdUXZf8x*@LG2S4K!rl zXKUqHq-$9e+d+|sw^o<*nv!-xGnLnP)^bRgc*Z$R3a6}?6+^JSS@a(q1gT)brFK3R-)uEMU^2tR`B@B$PD1lryoOaWxbi9(`~< z&HKv4{0^|4uTy!6?Rn|8da}UK>*^7+9msEG`%cu@?6i*~a4ud)c$t!sQY2+I6mQ@3 z6zspa{h;A<0N;^vx2%ZW2JKn!YnQ=Pi;6!Ao&;*3-w1g;dvOPedL^L9jYMOE7y~ z6oT2$cmz*RIcw5^1c;OH*tOia`4#?^>i73f7KhmaabAA67k}<%rFit=$Y&VU9-2IG z?LJ&vfZY>K5XU8zbwtBu&(DW~_Y^)5!OZ%}{SwB|I|f5eu|F3GC{q`?UC%s74J#=i z)J7NfKL^SRee>oNt`Av4`yfROQ7P}x$36cCACRSE433@6WPBhI7(-^!mdkC=6s)%rI?O6A;f|^B0igkm-e>MI#{Q?v#5|YYCR$cqB z3sXK@T$+TitPTd@i*;~rRKpGVBodEv~Q~JhBkOHV}ox4(Ix&K$CT_9d)U{NLv4!&Eth=^ZspB_-O{xpjsUqwGS zrRY^4}(QxC=VBf3@`DDB70ee=Znqd z?~eoSd3_<$w)Z(flmJtMjWLq{A66OXXw8}H;%45qnmw+k(c~jLO+Y#MK*~w`;DY~# zvJbIimQ;mY1e2O8uedICk(@465___^SczR*R2w#Oi;~=`dy^j1RJf#!W_$Va*OfJ5 zMHUgg1k2)6HrkW*#Hr9Aoh^{&H??t2^!krIv8G*O%+Q2h!aAm(!Imz@7JwV#TR)oq zPFE*>gHc|xO!P&amRt?>6hiD6NwsgXcc}vOWMZs=OyTH`nTT3kkF{%|6nO=vdz94s zW1e>#{vfQWcs^+QOCDPbUQ7ckO_jGSuZB0SJk}dTDNriW23mwC1Iv#Y(&HFnw_H?` zipZBSO&Wf}N~f}>;}sxeBU=Z3wxRwa1%*!RX9@)i2DFQ=(gdrC2tn>PV z8Eb<>t=SU&OJ6XnGMmPPC;(Yl&CKa{^E|U>o!SYOE+}9z0eXPWq2oJ->=|AlGrZZk zwS!S~`5&=vDTdD9=HDcb6F5Ks%Kpl_LN?o)K4|UcL&rULWnb|ZYYBrUgO?{tdkb_X zUx|d*;${6BvFjMW^j;I}9y&O?u6*U0@+<+Sq>p=(c+!b|h5s{2XkP@@drX7)L^i>;E% ztd1U}oc(VU_(f`1&UX+^UoB03f~9h8aN6-!#LRZ1F5uxnTz22kZ2a%U9MLJYrpOWa zfAwhRYC{(Y18Kc{y>x7c#DXQuCyE;}4L~ycS3v?%qNZg|cJy|tm8f!=HOo~|qQUXG_wP<`(?I6pGIG=SIeIjdTjpg#9VT~EWAnq9x(>n) zalh8$wS-WSuhAr3(xkjhe1ds5XKlDcO3I4z z5kdJ+U09ASRqxYYBeNCFYI{&rZD=oXZOdUapH6mi);z3(W7|B7$J!BsIbnmVpIsAE zCUbF*5iUom-g^KPO7zDE$6?cX+1^(8RXA^W?=M^#JVV2ANbehk88&rk!Q9`vuQ_T_ zZVjK9r5@~`EMJOM7ze-yfygEK^z!-{%XEu#86;J33TW{wI5HCG3s;-7p2}|NjO%`v2Vqb)=P4>F5plM>o zskvf_qMEMbY#$56JD;1cScd!)2VM8kq;2${Ph3J)T#dG*ZK`q3$p*2xG=qU}f#+BW zrP8f3*~WG*1%{x$OgslO8xYed4iJqe*|(CUFRSOHfw5+$)b4Kg2(kBr;B)Xh%Q4GQ z=ZoROYnj}6DB75y_ z0S-X(nX!KKmSNZul@r;I-2zi9Kw3r5@c3bI#5bPp?%&s%OegMhXrNYYa&IVE46L`N zW~Gy83gq}NRGPYk<7T<>rK2P!9DTPyjR<}enuvRof z70^@1hNdTCa1pk6)36K58YHkziDiJ?xq}s|aUdLMq|SxB5!52{S*rv)V=1gYe5FcB zi^4x&zvh21I!Gb?$!0D~RY=eqv_~V+d9Kkr3`Z_xzxy3hrHejR{{?|LBD~!1W%Gy= z$_Zzk1#t|>>jvf14U+$tm7WQbt~39GXS5s6kwVb|U3P|Cl_-_{UGhs1NCK8)-RQC) z9^IN>GvGewQQmgwMMd_5VYr>`c3AR>DbTEUh*Gtdri{p1Y3tN7OAFM+P=VUXkfW~E zr5n)fi?}b0y`$*PwGk+?Hf){wzVS)WcV>SB1qX^AO~vZeDV)!{Qn#uhT9>W6Q2 z-kXyctHmIhn3=SH53PS@?YkX0KnX&c%2^?VCIVrk(1s}yzB)jQJnzLma-NhmBDT|2 z@Mjj8PC8xo5Uzmt;$vLUX-HCR#meBiNj$KS6__ki2uTb3@#IuE)ah?=6h;P#WM;r| z(76s6Jo*t44`aA76*>u*I5?t+Ut8^cm*=K`1i#34eR#LtWW5zuUomilI)G_=iBQ+tgTflSERV@#bkkxuCDL)O_ z8Jo$FjVk4Jow$j#vUChP_H4*vGK8`%QR!U`@t#`SfQ=qPq);Mui*8!VSjl3Y88m+_ zjDn$!?BA~M3YjJtxjX*81-Y^F^k#p`jWkO6k+_UhA}`AX`e`hV$?R5ggvm_ESXmzn zB+uJ{&egVyY}lwE*`6PfP^XYs;b{(J42g>_|`O$uBLL^>=gVx(b16-ue`* zhJFB^rJ_!g!zOq7nwyaz47l6agP;~=v|p%Zr+z%GmHA~fXy!aw%A2HT^W)@X0#7mE zI|Ky@3o@L_&nxd1&6R}HK1m7MJA*;iqlNQ5E!Kwp8*i|12X@gM7-EA}hKI)ur>sW@ zrTM@z!+f<@`QBriuSST$jec-Fj0$DEZiv>mRTRg&bI!T9;(R!lk5KF?uui!0iSf#8 zF(t50`by|(RXZr1Hb5#D1s2_U^0p8O$LvPU@r(HtXPz(1w(^iE**gplU1nLjY#)~Zm>>tJT0ceGc1 z+EV1CTeIKei=Bk)*SOTZhO7$GSWi+QPaZj5#;8Ik6>YsA=$y^1X@oFML)T=Dx^xdaDNoW+ZVZm5L2fuUMLtVdrt z9>!0U`gep`h4Xr|pd4V6CwVliKyoDoNt6vgV*DX;Uk@R$zrw_A74nopdHn5adF6k( z7zdp$joNTf{oaX{%e1x7cjPfJ9q_m9un7~CE){Sf0|iW5W#NMCy({r!{_Tc(x zA&5iioS@(v%i$~pnVYE+1pqg*@eNzQ@NPTqRc^i}xW8znu|lZo;tYPtY|yVVX4qhP z&5W|oY&(KdiK=?9&L0*62cm_(FKS^0PT}Xeu3XEh&Hj$3JWud~)=c_A?+aJ{n{5K> zo=9pUW~nUp-INQej9o6Nc~Sw#q4I!02-#V!&Q&-3uLm~#Vb|v7Qw^?B@q0swI#oi5 zfsc0}cRE8so&i>BW(vMvA-}RxVX2YABGM1t#^xgc?Sii-=%Btu|U(7}Uxb;@cln+V|48aGw z+tQ-EoqrxR(0LvEIP^Kdj?JfMgVQcz3@T z^8{^ILRvw!XZWpt#r=ysRIkC=SKP+Py5aGNq{B(x?g}R|6JmJ4G6QZ(#_NNL77z+> zyQR#{4$HkF3}2ppV8?HJWA&=Q5yl3K9Y40KH$Ju?IbIEq^M|g18AeN zEK~t@V}d>Mm0jv01KH8_Sfa=lOlG~AjkdFQ@2?c13pn(=P#b&=bKo~Bzt1H^2Q$`B zB35v@qaCf6#dY_P`fwg}g3BwC>*xFC#0UJ|v27C6?puJ6_;rE$guZp>Y)OMG1hR#J z+7553r<-^~M~`K&b#TBt_xM+(a};c2N9xp+N5vui0bJH~Dngpw+7FfCncLnH2sHFAh9MEbwp-eTM8aoA z08SegmPT<&JKergqJbr;G3>n4eve~goB$Mk2qq4G^%X+7c3%oD_1ygiCMZarB#+uQ zTYXVJB${R=ESA?@^%x@hznpbg{RtCO7LYW|%=f%HTso(!CKQGvHvwes^-ATB?1>?t zn8#s}+&73)G8p7`^@vnx+Mtm{;)_jj$e!ml38bc0QvVoLouM$r<9UN5L|s$b5M!vB zIUbd;L|z?i+LWI2V^eoOK~edSg@Y^NID9f|2dIIK?M1$}@FX&V zY~^=NOlbCJF_r+nw6v3gNk!HPtq3t1_&khrJDC|9U-Ygg(!V~|;%^;xINQO59@+7? z>-%~!L`Dv_isGTzv3ORvW6-4zk4Y2I1+_7}wWw?)*I@`SIX*-+%bB(YXyk3sXhGwUw{wb~kdYDK#CFXk zrD;&MJ2}z_Iqe=l39KVr*%4hTbqNf+pqYGM4#lD*KRYgqn_r}^zXk~< z8TPwVX-1zX%T4SZwX=AxJ*`)F75c=QplS*c1_eavp2IA{q$ zZkebu2A$A>4ieg@xc&8}o&iIUNEd;5@r7DxdU!dPEfmbgyGIm8L<|W-=CA2KS;FpL zu@In!`-x`42T?p`%o{)q({j;mu^IIlUnYgKJS9+6 z{{pQ@Gk5h9(PQ1mR=vXz2RA-c%0?E%M~2waSea(S#|G?`1~JIavD~6TwdZ0V&<>Co z9>%4?d?@#p6->h2*6;k{zrs zQ&$~WYdN@^02`~`NwiUDi8-q{C~Rg!0-YDoT{@EFMB+Re&g~ErwLFp>JR574%Nmfl=c(&gdJsGyc{7)OB ztZNTGfPL0HCSL6wy&la&2}9(FAT(2a?b+N%0FZx)Ka^s)%GXLYRsdtHuw%Q#jR~r+ zPBA%43Ee6&MqOeUU9sZlNa$%rbrSMF2@JD>;lCA(%v0!r{BN%3!=AeJ-2y6rW`}+t z@QC-z!*g<6+R|vK_6~@}>r5QghP%?zeJM_?Z3m`ZqEIxWnSq=4sE8eUU&yp;Tfp|{3fNEOL{DEY& za{5`3gjOCVRhy9Tv-r3CP#QPA{|1mRRoDm~c|m@d44dHa{J*pVAnXd}pVn{Sm?4{r zZX7Ei<}hLTRVM;b@Br5~6E7abtyMTJI^p21u3{5H=|N#5om!(g83cF+b?kZN(GPsD zqm8WT@iUkIQ{`pMnyJ8?5|ZafaMQM=djl1~p#0YcNF)d$kIf>GTk5nwTt3dx7fnWz z!vf0U^vRK-s@~vP=bgGrM%VJB~$r+D)oz;0NflaIs zuCmDAcw5+wkj@t}fJ_{JFG7$#7bue$VcyrD5h_$ZBrqfMbKE=f1-BL+2=Gb zgbIJqBP%~dyNb|O4nFXkVPKC8l~Fu8USN$8Uwke{FVhzwL2Z<%G6+1(N9j!mXV81K z=V^_DcmYohira#j8gEtHB}65dVT~U>woT-DjE@E?qvISG^=D_59lqaWvw829 z-=4ftmJ~P>t&#Hk#%7m_m4052q0m)VH7g7&cUfAsEAC&@1=gEYxV#7zzzugn;_b{v zaF8JfAn;&(si~ACd40;JN5loU8)yg0W4hY4;9J&9<$;Qx_$G1^kbr$F$o_Q#ZpE<% z3yiExJ}z13Hs4rOA+Wwck!Z0WSn9594?=TJ)HMP3dXroEHNIF*Dnsm+mKL1aghoRO z>47Fz9cX3W`21>|9P>yDL5#@3HlWJZGS1TKA`vX|^X?0*=~VQu%UIV$(jq>U3<0z& z$j}*FMtz%HD9*HvcZ!;7IaPOA!{I5WvnjG?EQu*O?UxIg;!!L*&FVB(9kzLWYAcpV zG)m0gSzgvF_0QBU2~(IPGycSUBbL|Q555vN5QGN)9kCqTJ7q)$PSx&)?lzE^DqtxR z=HGOa8uWxZcUP~VNB3I>JZWP~G_FmHy7-A)aUQkJ$r#eGjrqMl$o>Ipw}Z=+YiKV1 z=^b$4(mNd;DC#%6;!&zqFyh4K{?e&jPI_qjVU+1Vv!pK%orSVuRq|0102W3A6SKP^6Z~8VT{d?X7rM zMvErYh|{-tx6#jp|0}c@z$G?g>2L!`dJ!x!FeRdeWduj3JWPoTr@-AvXklLyC}OQ> zFKW`f#E--lV5c7Q_&2P#c1-OFyM$Y6+xZ#~qS4I(ByVQ~%?E@J9ebZg;lEYZGfPHO z{MVjfWS9bHg)JiT64aOE>p(0OP(?^Dv`D6?+GlYsVkb#N~ki{Axgr-kuyZ0No5C+Hl2IS0IwAS=2W{o;Mqr2-t z0H^g|-O}Nm3<|_i`-7l}c8yy(aEUsI??Hg^gb<}Bj6wDd7<;^>LaFRsmAI2Kmt%RT zbFpOT$_D3OrF^)G6Obk{TEwr5k;`IPoORXWdZJ;)&B$8!M zn;b_X7Ko?4Y4f!bRBSx8df=Bwt31s_{DS$kIPJh>)#ydJTdBuy6v<@sOA(^20jUWd zawG`t>WOj1>#+;9Q@K3Nz?#=W+sq}i>o z4jfbGcVgf@b_dOpLt|Z!z-P}=P!CM6!|Vf={x(ilGCmm$vIOPgK{2R@da1>#OH|iU zC8R49@`~WOIbj{?@V5u6L3JhES&Gy6mJEG@SDGH&e`kL&W+At`$$7NEKriY2 z(4bbdO!@@9MFo=~=~B!&-S(iCufY#YUCG9YRg8vDFyuhrocg0lY6G^kd&CTaUG@<2%vB4;ht_-LT^!#e9|E z1a1e|?Vg#c{JiC1T3mK7|x?&)eb&aX}+S383_tVh!>tSXLy>- zsv4%Af&}$joj**+VzbMiISpauX)_fS2OZ5qiZ3EAGR_V(@Mf8dVEKChNlC6BlITvQ z){#oZbuA%UN%*g1BP64UH9o_l0Ds zoX1V%c>Rdu@FcBm$R{QU)WNAmkv1$BDt7i37g$Vw>~{3Fh(m zt(#tm3NWE5v@dkE2t)Z%_(tGXV>|JzcO`h6+X2=t&GWD@AWle#m{R4e{?$ z(hm6-*mUk?gEF7cmT4Xkcld)QSX#$rF$J2Ss)#q@L4_dn^byyS(6J91xeA6_m}F2 z+M!G&wT(*VB^~-SvAVq{B;RAY zek(=8cPQ)8ggX1W-n-Zi z#nv0ggO=XKqnVz46#2gUr)?(7q=OOs^=_?k|1mV>M=SiT?msfx>+~TGP{2IIdMd;2 zF)aJ+ptK2I1d)4EPfWqwHJJ6t%HdKo!OFK!GOF7DNU?PZN%L=USbeZXBLb!X8R}5_ zg{RmEPd=XtHdSM0?QSQ>YbhYs>e8Q&9`T{2?^0?cRlZ~+a09!RFwq)ZS{o7LI$cnr z4B-Oma8H@BN>QXUt-V>I*Ihn+Tzv1YUg%0R?yP^GwcfcWQRw$f1)Y&hMwh3D&G?yjJi~#^ zH)|B*)V}nFtOoWA)1#U2jBoyKcXqyBK9J*fjYdy_R?6?@P~Hol(PGg?Q{72lD{0F5 zyOnYlc>`bF@d3ILT_m{Da2#Oi;hpJ1i~9BU@A>FiAuT>i0b3nMlunC}Fk$;7j2S_~ z=k|=3uzLWZ@)WwEKL(&*+z7PCR?RDfH@mQDh?v{37j7fG&qyvo0eJGXZod$dgf9tM zMeY|T>_tXtl=zFV3#cznL4-&uzh00Hd#+OfI)Sk(oS_T!;bU+QW7+?!W62Njz2}(GJzVDnjJB=uFUW8jkon+bF@HbM zKtCDRssDlLaA1&#>P*4LJPuu2I}87oIK?Fe%Q&oH6W|}w;D>XX zrIaJcAeD1W#joIj1P2zo?t}c5%B@DK2zLM1=47kM*cU;0Nh;LJ{ruQM^_r_5!_{n_ zH{|A4@j7L^D2Ii6zuPpwLQ#x_K#+%NIjjDrbJ+CL$2q=R(U?h{0+nWs6JO35W-EJZ zVp7WKyh)_~Af7bnPJImpJ0&8wArhuz8VB>zYV50&f;NIzJZ1qN_*hkWc2&k*WVbkD zy|mjVz1vxE%@BLrmOkGxd>Sa>!kS_*6+VmMqr`=K=8DU|o=jyK&+g;-StqANxsjW- z8LT6bXJ+59r@Sxo%pgHy}rlfI-c+^ z56FD^5CFc2C`Gx=GJ;7r)p2`IT|()yJurTY#EO-a$Z6y$+YOGDl#sl@5Sva-G|D|( z$mpwLbq%KQ(?wu?yMDxMvu%3zR)s8^m|dj<^S^CT=WJnSDY z{WQk@?xdmDld41Y0utm!CY`!|&l`cmY!4|B|HRa^*rDyV=i_aJR|&K3Dy{K5nji-Q z>Z;P0Z%s5Idu@=vHz}!RRoRzBr<=Xn+QK^>L7jO5T?(%v2Q-B)vR*{j@|rt~7_j*R z;kltCWmC?q1_h(4u9jh75*2i_W%&gSSl6{2OjK|>G3aEAE?boTcJ6bNQo?0bh-lmA ze&6rbzo>k;SiQhJJ0+_JxOQA* zo=`srr&s&GPHag!NUn0G$ofB%78uhjTYu6DoQ9sJo5SW1_(EGZGX0?Oy#y{XN&%vU zeYh{NdK}Xu@j6Qlg;4$U1U$a1;V*($XSr2%lOW5vT`xVM(3)aKJqP*Xm`ALfl)u8K zCQfW-f(WQXvS{n*74DWGbriKP=3AD-sZtl%R4j}|1#bF5)PTU?E8}_F$g+ck4<;rq@@)WAwU@NaeeTjHVk#U!3H;|l55-7tpsxhxe;(gZt!l=4>Qz5a$PJU)4yyE(=-hCyH9jT z<)M!oh&FB{at7Mcx%=b#Taq00nlMp1wHb`Al(K)7o92A#(oC#gVNqVtzS?ju zLBO(Q;M&|c87w$FCEAglxHrpVKC=HqLSXFkIgvu>f8mgnMCXIX;0a(Js%6;v)-aM> z=Db@G;ypJ*%`!`S8j*e|=S()RWK?G+kBID4@}5eHlg8kY=#<=;I14n;B)|5nNtq22o`IY8LFT)i7i;%HmQu3M>AuSuf*bI@aVE}BBj zZegdNNQ2p&0nBWFdl8>Veyc7{%u2sGoL!9mWpQIwD+`R+yCy`EiThs(rM)ZgCA*(c zMlcA;@?voH5ON`_p*qP}wU~LMsbCX%!ox zB!F7h({35pxf{f*UH;}+HNpkm7DR8?b+C(z)M6SQ-CtjvhT*guC!IF^s$8OFG8JdI zMLBMP#~)DP;N=t1B*4WNJ-U4B)h^6it}^il&oR*{T(YgueA~fIBQ6cttqcFH39w%Q z9cjm>sM&ulVa#dYsxTkx0pkT8$pJMM0d|M9s2P84H;qGJEpo;MSI}3_I0!Q^Z*W;; z(#mqPG^q2-l14%@uGGld10rwO|4Pa{}0X%>18Jj0%6> zp2iI!lOO4UbtcjhC8(gcnM9U#(A)xJYleXpR?Boyep@i(6U?bIoa|H%%W~L1QkHDt zcmhZo5@nd>9{C8fR0lOv4bZ<7iJtlvLmo3dF31JU*?m~b?1yo?$pBnF9Ab>6lLrXd zb=|0&V(+itynE7gUG>G~i3da!Ef)j=>X(_k{)p;(HBDf5Z`h9au9e@`68Apb^8z&} z`F^S-_LkwMIai`J*)wsT0&B}L=ubn@k$Zyn>dvL^ikSo#I$sb;T=iYC!}qkH+whx9!R0!kIP+*z!It4y34g4}p_rYUbA0i3 znDD@(`xhM3%ST#Lrn9Uk7*0nn~NGl{b==HJ}?YGy2g5xn}Z)<$tXB;m~L-&kSjYA&sfHM z`=NTCy=RB#f4|dEvKT6Ja6&=q^-gv>`WYgN4n%}1%$1{Jx_-YID>xOs*<=2e z3jBkuN?ey)B*0@tTH(^4Ou`qyRjt>akf$^jA}b6sSjy5nka{tNI%rF zLi!_Ir|wzqzA}qPKm=KX@|M+3-;tDnv1?krg>3Db_n}q)~$;ll_zwN zuNvAWsBnVjn?z5khb3nglW+GE(i#*h85mQONa*fdoPM^CqS`C<5<=TD<sLHj}{I+M*5QmuBHp*G!H1A@WfYKO#DCB4R=EjYSimi>vjne6g!>nAwt=1YC&Ae zR#J}i1hjwK>B4TnPgMG{OMJUZOkn((r-g=z5it%h-?zx2_`!)Nv>HddG%=%U$SC7% z>6)preW_C!3BjL4_@E4!PR7A{W zij--qp8iP67#ZI)Kdkn(P|3UQFksrFFI%$!^S=L=8iQ%x1V4kAORsh}o!=X1K&VoY z&TY{9AXlj%FdPD(nMI$&2=$C)_KH%-> zM70S|5_0Q)oqA)(TDERIX=Ks}bC@UPS>88pf130tG}JmoeI{xQWP&OB$B$K3XXuxD zuhT>>Q=CGC@fSJI=m4Y!i(sm%07b!*1XQ{3P7@9&y4} z&!%uje|s#s^xjj|-s&O1aN(PKD*WrhIqnHi!R{CbNQ|WP`X%BAqjp~V6LFd&tE)n} z3}NZB)SL&-4I0^xmsU0kzE;?kWLIp$G|Tfg(ARe21R?yQgdx$Q(v?V!rb3$cZ zCIH(X;=w*>@g~drl}iJlkQSf5ceFP4{xREUvY511zOymhlO6!b>iC^>*v5?2KP3hgO}qU*KQx%L<845H zLW;#1`!1)6MSEn@XNO#_t9F2MrUS{~v1H-YAN}r;kGjLbo;+ymO2D|*%;Q6lXR&hg&@KbMS z{Cj1SHxMz~T4}daXElKe)!)EPmke8Y!uyspV(VnJ%Rc>aJzqGoF^ww6gN-HtJ)<01=b0^8zR39UV+eg8gf@Vr@=_LrDuPIkj z1o?C}1n_q{m4NfUZqVu`ZTOW*n45hbOYjyYpQq$mS*L4c4k;NX*P+#YRc`j({hHq! zJsE&77}mMu9E8=}e@IsbZ!ek_5XVn>=II|Mfi0!-e1ftm@5Se8vwt+GGg4wAg^i@0 z_v{5H^k5YxI{7?uT8QcDf|OyLcPzmHq86&uz@J___FvkfLuBpAcVRVk{)M_EM`AS& zmAsVSO8J|TFtszWG9D%6k-<#XoD77@yw>OOb4UzM!n3b}Cr7Miu<-uFgoUYSwb-R< zE!9|4YU@I^53MU=f|Z_x!$@r1Ktzxj_orS<@9&|Q(qH&Fxs=LsPVkmkI|$^3SI>9P z&^Rac`{$+b&?cB$#Z`*Kx|o}7VN-S;3WL{O%2R(Yy(-}MOE?=c7Ry?ov#Cns?NW@Bw^D>W`RAsUXpjacFCnNe|c9`hb<=*JkWdk8;{O@QnN}iA-UJqa6 z-?8$Jo;%HbjOr@ao%p6gO@=Zm^5FxMhm|i9d5!%O?q(cz1Z7L^(?j)adVN6S20Zwb z0r{zPc%U0>i?DmhLGT~x7^jeq*nOEwnrrkh9oP&dq2Y|s)W3<@?aoMfwfkCNm$eUF zvI1nt8XCBIJ9@oxoKR5P?WgpR%6$BdrRFBhh@ZPZle&#QDnottwX{Toi)PNPo{2-+abu7O3J4I&T&)uE*stl+p{C^B;iD@ z7@sn$k7dx=@~zo7vKn2j80i60mr2GR;fvEr?w_-rmh4vbO8#K>)S-qT{GVjY*v(se zo6&1HZp?kTat80JrMtZSfcNcIXOqR*tijf0z1L061jBbxuZs$x`ql~}MsCLH|E5>Z zWU@Q%X9MCQ1)HYyALo+jXTfAjmNXV;%drXijxx#)=|Rsuz^YYR&>XzDSsB9hS`1J764zUmkT(92t!P=%Iv)ftt z)~wrbLPG}|o6H;=`}xp=02<^qq6e`2d1M`pstjS6^5=tpLHh-hRhbYXqLgq5PVcuZ zoY5NbmtbYWgK|S&_RtQph$$R&p{x1hw_Z zRl9sB1Cnvs(%k&bUbN#CB1{^w`z->`N_+^-?5VvNLbK72~1d-Dl;vO77wR`Rqr8wwD2L-ifYTF$`+r(1u#z z_q*sm?f5LAGRnmYl9-Cmh$prdCYcx zIqIU4sxaEl3e>P9qGDm431f>X8hs)V-Y`8mAU1hk>EsedrsgQkYOk0mjU=er@PPk9 zcF7df{B7ZjIhs)J9@?PqHous~99wUBK88m|Hb9G?!0&Lc`1`ng4B3=kgBQAz!5Chh z%AEsYD2Dby2Wg%LrBuMUbS>FijkzdL3Av7pB0GB= zuOr@I2M`kYDVgQ0%77*zEK^G656m%;&}e4LF^2=CCEPij8VOHu1sjB4?rd{CE>&+6 z>?bi}2^QSzP_b+qLZY1h0(XHti6<}Rg2s5ZBplM>=gv^aCgPMs>{tUYMvyvzx_)y<0xfx z_?ETxXCORd@`dcmECc_IcOv^dxyQs;P!T^lXT4Cw#ou5GsCkC>j;Mb&V=8^D;L?g( zi_ptpedR$0#(B!|`E4r*iK$dF7SkWE=}6;K4c2~y7&>o80i3E#J|bpP9{@2q&x@}dt1>>@lf%YTJ+WT? zf6695N4>=9_*(o@@kKo?pT+D2`}6JTdC^Y%_#E2{wZ(iD;PEEoz% zX<4wuQWp$Z7U$6B$??C1HR*ls7PS!$kyR>4FmUz>tUlJh9jN$7)Ro`-*(3lIvTwp?bYCo)Hmt>N(%VB| z%EOI^1k=sWFnPADG^aPY2 z&)K7i!JDp34Sd@}z#BjLI-B${LgB)|d{I`R&dj?Wr)Qb~zrnItE1sIeJjtH?ZWEN1 zUzz9*O%#++zaGFmvjS6vm&<`rycRIwEYLljG-GR9HhH+nIfq2~3NT*;8r91212Hpr zpp8XcI~+&@U&pYHd5rmM z(Rn;3-PmbvP7=D0w2)c=f~u(8Glrh)_;q7g4g_n8;&M~95Wc$8Drw3>_-ua5l0>Ta zG!b&|((F083TkV;l_XaIiSyad#%Li(o*7n|Fa6aPOclp6l*F`F!rpJi-&UcuTBw{& zOJ!SrGnuwwMc#W9`o8iqKuwE$=*X@>N_9A!l7Ks&79hmd9${nW;c4V2VpPuJ5sZQK zW-d2YY2wvm38=OZD3@+yN5dBKd^)aL{$2dN0Iw7PvaeWpZdt7OeHW=p-aTo+id*g1 z>T>wxf^y6J2uxS|s3%UXKvJc^xg{&5EbIvk5G$ZWoVk!hfQAhcq{ss<=9D_+Ybecz zd4tDlaB-+1TNLX&a)7G(>%k0Qiam>JGJu)C=w6EU2SLAKypwJ3-BzatT3YsVvYJ;^ z-NR^1%_Po{{sKqIOo~cFw|+s;gxI&hQ=IQmE<%(C52#lFxa)hS#k%s`XlKw**GG!l zUMVBLqG@Q6v>!qV9x)6iqqso(*PdL}ovTMj%#;rRHT0UIjFS>@BTNUOHCsE!%p^VL zR1kynv>_1LoQDOpUO1F@hj5MPX4J>-ist{XHx%b`wAd`Vu!MrE9f?dVJ09nS>(6K- zJ1I=LzqkR~?$eP?737xj7T69j0g7IW?Qt6%-Z9p@!77x6iALw{=GP_w_G2ZM{K+tY zV4p^EXxDMkGHC&sqcf8d$asvK*qXjQ=H2FLsV7oprSU2bjcJ5M$_~%;?U7{r1-#fm z$JHTAmY1xsG6+4^kj~s9-gu#5mPcXo4V~^9Z8qZH2(_O!k32 zX@oj}%`JDY6=)lm&?Mw6QJ>X$s6f9TulcMw&JA^TlyiX^$r}PGdV!MRRokQBK~?8< z_?TpzUVHB#x6R5o=4lSq>zM0Nqw%Ze<{pSsasf>VUt|EqXilj3+Jb^eE7@EBQqp^Z z1sHX&4y*qp$ z(^+(*(?(^9KszWhYgz$4Pw~ao{9(bf53WnJN89|@5xaM2RIVZTY7|kEMU@=m%a^x)NI z#X;D%tSnh{7GL0D0d4`=D?h#8l3Hma%pK!t-{2jyo$H?UC|*H~K&sfX6@!UMUMxe& z)g>NH@*0b$&cAMXUhG?V@0g5muU5Dh4H)!pMV_{viF9(g(o;qsZOl+XL(DdN>9Paf z=sH^X>6&3op3pR_i^;@*0y6d&$jCD+>xUN!q1A%3OJcKJ7n$2?m2IexiC+x&3A5?V zyE6xF1~WU=lktPincuJ~*`=FE2t>)>CR>=2ul?R(b<6E-4kg5R|6u6pH~}F^C&S0q z+Jy>XBFXri;qYg|9nSzK(`$pt5!r;B3p4PKEU@3}@3KDj?c1GC90p-zr=*)Oy*Y$)d{q)}A~^D3JGoBF(4 z7H5(C_7&CE=Etm+hI4KWPsj_$!cZELz>%n7D*=4CYoqf?Vs<&%BQ9}H4U8@`+fbln zS`a1U9DJLpadonyz7q>8%s33zeA0v?atS@XxbWacg7i)|B65}rWUwtdiGqiTcIhhp*<#h z_@8`@COxEn(jK8`ITU}A-0a2vD7RWiXF_>{GjQOpNbv8kXFaaS!t2fl4f;nVjkU#{ z0+TUJ$7d(5-#oJirzcR{f3r*)BewtS<kFk;BbU1bM(e>uLizbr)t`vzbTp>GmOoONaf5he3i2Tq%^#t7S5!&B-0}4qZW78 zrF!%?03^u@_!tHz%*5!M-h-2YRI%A-F0Q_&%LF`f^J}l4 zlHeAb1AYYTa=SeX0~MS6zsdK&pxl>7=3w;8cdIq*VjOUvvxK~*T#WYW&KF}Yv>x!) zzXrbgtS8Q#8X<=leoUKxOum!YfFiD@M+X*TaE{1@1KhYlGOVH!jhzXcvpig2yn!J{ z6GD7l=X7=AF<$I+_PbmU<_$!R%bDtEJBkIBZ9ZW`5~T~lm&QdMB2(}GMCv9^h!FUi zoQ}$2gfHmroH#_#>++weGs?%XPEbr&=~-3r}{CEV9D`X8VKfB?+@GS`u3;vf=Mo;=sxTZBkF?pqWqM}m~E(H%OntjI7xaOHDdY}OQCBl z-$RK45tV46h&=YOg+`PAFg=JN;%;GOV)N`KT@h*LZ;N@7#%V7sD~rff-lB8;Xfc1B z7!DJZ)Cs0nbJA5#>=@C0$V*UPpwoJ2O%+bt zugOh*3Jm*H!lj5vvy_RFaSlefn2VZOX9o3d;0#``9Yr&TlAYJmzvx_X7L)jN=s42z zjS@np1b{s+cP8ej`JVeW7mulP_X)Dd94B)KnAV#^`ZriV7MlhJcao;dAa(1Il^#~a zY9`(d;R@kxwXrbHn&9~*)S5(CRr%W!q#>j>~(y)v3OR{^c7v!9y7XR{(NdpN=cR{H2-Xd?Oin zvV72@)Q%ShRjWy=VJB4gS^yIz&koOosP^AW+WMn0HE=WgXbL2@y~t4LSFFP44&hr7 z6fj#u{phyn7E4`!{3)KJ<)-HdEFP>chQ!+L>}29*XV!D`WK-=^vG2!(QL@>&#K?tQ<_PL3N?1J+gocRjYp74iv> zW5vtehj=ILq`Uf%2Z6@MLQM%d$E*powP;7&B+}qaqN+A!#`syU5`M(L(~ID0f?OC6 zcYnEBe$y3h3H?_>_ay;HDa>}_-==HlnIav_2R=>(0GtE4KQ4dzxH0^eRSQYzD+{Vz zd*R(s0UpSm0mr225lYuhcR?K^u1o2lu86RQyxzOu?4&TsjHWjmEFThVzM!Rw{p(!? z;mfYpYE2F_BgBO%N+(=vZCmwz$)oRODu%OxJia?qB_CPP^ugN{IY&^JOTvdkg^@Gq zq5WX75yeYk-x-EA%y#JV0s5r}g2=I6(4sm+R~PiF+H?I5jE~0FAnbzqT7(jt+Bx=l z>cO`voMLGh=h*C($y7##Un0P7vPTvz4c)<15K1`CT_3b(mSXycQeXEkN|QW&x*?oz zSnV9V*$E9kfQ$*99X1=R7rgT(M6C#}2dB)0uF)HI$km#j;9yr+@ixWr(F5}{IXxL^ zZRfK81&yRGs0EP#VpJ=w^ z%_&z+lX|I6j6y0{^k>}EfkKD05&QfKp}S#5ul~3Mm;f$8Y(tahhab3ye1C_2E-8wK z3uf)h=2KmFk_`b;Xi~5 zqHq32>mYs_3;MiUYz)($-M*c(spWRl@RSL>vyeaO>IID9*yCIN*vB2dnS!wwa@Fq9 z2{1QowY*&JTRoy3<27PXBq#Wul^yI64QeHT<$QbAehDrRwLqr((yJ)_Qc6QnYJ@#iNiAkIg!{zJclkFA2 zv8BKi8F57UdnISIUcNGWj-N=jt8w85VnB`Gntrre@Q5>7ldAOeRr!*Dp!`AdG+Js~ zysr_AXxdGEdL#rPy^j$nWThaM*pP+Eg`Nsomq^|Wc1=@4nzt6_eHO2Xgzh9l+fIAY zg%86JVXfRB=BMrftE1ahRG#G%^CHT+#u446L`sgjo;xSC+(pEbJjSL|jj#@gck~RC zXR{$D&KL8e{UI-icLVnouJ#nsK!_*Zc+#DIW9kRXi_uXKIoTK}>thHlZ^Hcnm)Qu( zRcVTw@klc5x5Igt#(s|tcqlK;dgRfF`YkE1cbka3-}HBj0sXLgqto(j**ENc*ZT8s zeqRKmIxapl!URrV>@A4*iY@$DikQ!*Y7G1@m zAsM_|JB`g|11G1Mc10y$X>A~SSuSSr#NuV2G{Hu=WjICEDhHvPvI9&p$n1U zJ7KNF$pd!V=FlVbVB~9$c(Kk!ywLVUu$K^Q4tY@sqy(Fv#6<(hu8};P{3xA@bHBCu zS2|HZ6amZfb_j6OtyTkJxlf|h@q^tljTZr@x0aFv{{scCgooQEb2udT55KyXfU)m> z<4JI(dVrrJLJFy!9-!Igf$wuIh8Ce>OIV1q^#mx)Ryl@(pAK5N_NWuCR0#OJj;h%)3gc6x-W894=+6B7SzB3iJ@hf|6-Ljy9090GlRNoLe5 zIsspp;5$f7mZRRgwAQ%;Baoz%&ZbdX5*BW9%8W+C>fbX+AXsmmiJ*jaH7+PYp~)?? zJoDcsZ4-7kEq9bzEHn}$Bef*LJV6l`4?VyJ@!S(v4(ET29zE6HT{u}M!|8q+Hx0m4 z#x=j);6lKjm#s}8QdJA+%0-tukGthAdB3!B$&7&Lz;XII7Oq%ydY7T`sYu_+x+uQk ze(b@bC3dC?N5d?3$yJN!_#5M30^F*l)0B4+lI0mwi0eq^qBU-NO ziOEFb;A3&o3fNjNA-Z!X60zf$*`;?Uyz<-F=3nY=tQiuYYS4y!-becvH1*)tMs%!V zN_|(NSu${a3El$N8UN89B(EAn+V()zyO<4e1PbHa*~j*E;0h%Cd$w*LjP2q90^i_63$sJV9J< zvzW>dG#m8)_H5>?vl9ydD;Q`23P8`yu3$i0b`4Ts&IIi-zvOfiRP7Kx-pF3x{94z0 zXC6XRsA-O3LSfskDUulE$}P?LY}uvQ))}{F?QJp4NoYe&AoMZBV+Po4 zfj~fOp>bL9h8B~#+1u5L{ZAhtn(IAk5WKfxUSt94NRwbPWOxc;GiQaKPMsuM0`4~3 z15zd>BY&`S<{Cx1 zjsB*J9^*V{PEG-d8_O>})~!_t{#8TZb@ha}1u{cHymV&`+nV#V`Q3aS71UHXczpEr zQxd)wTxutwhl23I5vu`%2k=z2QGPh?<#%Aaup^lz45Jh{c>$%TBw0=AW!sC{sVbbm zL8V@*g`|Ekbew2D#PB%yLEEL^*uw;k7Sr8N-oP|lF<3BKXTV9WKA!hFEv^F*jot|XJVJBeNT)1D;-r;tCb%bm{``AbbptwD&mji6;yBx zS!9C4eYahcf^`X(tYfJvxsarJEYQ&MWXY%^FLy*+;EcAKv7W%a5rJN?3t%RoDB1F2UxVmB;G$plm}c!M@SF=>MH7n0Q^Lx%aZ-LtF|MVOr1bdx(c zykgg6I-4_9na_4B8SNey7!_a?3=PRFb6K7W7xU?UH{JVLv!k3xY)yRx(ggLhOTjv_ z*9#v*8WT(Otz0d43uSI{Kw0Dt{|*{4<8WwpL4I}&1y*f$x)Fo&31By?>0zUAOKwa( z{K?>nU^?eYM9pzqbsG?C{4bph1w7cfc3;JcT2Yzrh?3sYMHN!qPR-0Py6+SShQUfRnVslfrc%{CV6y&%aRm&T>6zEk*87w_H!Zvh)-rcV2)5@T(X=M4IaE zz|3K=oV<0Soe~GTeW@Rcv8#=1@ruEH)zVlUXPNbfZYL+@<+qAW&hz=lRfI)%^;Mlm z(O;UOByVf~pU8-ZY~{)Rm@R<4l|AA@^$aoNK`9RODT<^&wy8uFRLS4;Zm1hYeFFZ-C}pJA+(3BQ?S+QC?_ey+NceHAK#v!vzqCe-%{{f2r=vswHjZpQ=tQ?7EIH#ZG}DUv=Q|FSzFt77CjXCAe5P3Q3^SBnNH)=<20WK zc3PA~LXHcYyD|Am$%OwnLbBM1k7qULA@k7+&8E0^F6fO_&m%1Eu65(bKf|rYIKZR@ zU$~)y(aV?q0O)_+`0`CgtI5{8LSQ3ivw-)ll5p&Qmz1-#`q7buO*TUzgag|an{UHE zc6P!hM2uwJ`~vreM`uH=WYe^KY&aC1P?T57%sb7fpI48>em8h`cuGDFmxdtK!2~Wz zXX)gJN3)`XNWzTSMq1pV;~{NVOo+w#F^kPoB)K{te_V>jIg{`kL7{`e!ErTJw9WKk z+TN&FV+mstNWT5OCr-D1NY%-)ZYJ%e>$ zU>9Y3os-{pswpS5M4JP^JEdAjxsop7>o-DPG4`t^3D|q(a{5$5m007sF%72je z{`z|Nmo7l-=59KNm|yAjvc~`||GHqK$n-%3#41h#S>wuM68*XNBdMz&ZBz%a6c#Lp zr_SalyERz409RbT3?P6X?)L5ZN|0r!OCOK!Oal;L63jX8hb|gi1jrAhGg&liS1A zJEH~WP-@aKxo7VB-?|;je=8>Ui#WSXJ+AJ~{pI$?QK>f{O-IfTjfq#t2pZZ@;NW~A zK3_7p(10n0(F4?sJ;F~iq3r9lFYLwgzO)BIwAI7>K$*Oa4>hF>q8lT?P21m>eq@>)1{I>#|?QQ>W=eBH5>5Lknf zLJzTSqq@Fzr%`?dBWT!@)&u)i&S*%2D(2;>1K8YS|L@{Wla6Ejr! zb9NE3mNchdv8dbR3j zl{G_YNh7y_&_wFvX%m>Up=% zeL$nYuYk_DJw9)kOlDleisBe9C2QEW0ww2Mgpb{e|&#cpPdBMJtp1>QE1egLbH3EdcJepV*G^L zI1Y(&qd^V|xt+O+amJkCgc>h$j)Yb%n~;$XR8#CP7xaIFPf35W&OQd>mClxD_^^XA z=)e06ow?vnot+;Opm{ZdA8KhyH5LgY+f08DQDz`42oWVcK^sJwS%yR6$5goc@c8xA z&rtCm=|mV}ub+q)_63M(A}JZRHMB>=IU*2w?7rX*E(F{)YC7J8CP_$2qDG8zV|5fV z8lCWflX`6)0(+`4T%p4BSuew~9DF5q9Ty zieeuoK7ja2RS|i)82j8AU#H_b{bRxaN^P&4`0d5`1Sy??DX0KvCTK#%64riW z@iCno4MIf~OkAG2w{j89@bstCx_~D(x#BU60spjo?-48OPU_t#o8|0W6qCfDE=T6wT!==0Y|WDsVoX@?k9^Jyn3T zR^T(=m9`FY*e!w%%QYan0|zi}*M>3X&PgJYZ`pGaykTBmT~^+?9om9>)}nj7-B&{l z^Al3P3oq5VKDGz3_1l=N++93EDdFCRGcb?K<1K*c&V3S_Ii!Q8@?x4aUtLqxGuAoo z{i-wtoxFDDjf=}3x^YwM9F`(KEgnsp(W;54|VR`7;Z4UYKG1VNg2ajbI1~X$vw=KBFBxMJ} z$?bYyvpU?+jK7#45o1I=LR7|(V^?m%r!h4EfcrXq? zJXqPEe>W)js;|K6dqSC#@p|w@z5C7H5p9KK;@*;|#q4+4;kvlTG>2_TC>nmd2L0dO06n77j_hNx2VF2JC*{q!xu~c6>9WDihONFfYEAb z(tAPEd|2kz_2ZWB8`o94=iry7k&yv{L8RphZ!^Roo*C3ypk!5v(Jy_V+`IT!2k;z1 z9%<(Y^4V$``Y~p;ck68n#+Xc`GBGNfs9k9A7pw2cJAnjM1gt*HE=HC7=rEL7d%Bx2 zRR(nkH9_{%`N9D*ijb3FUt7+vI?Xi!2%jzxcP}Gv-;C^9KGIdX7rvd+rXG+1jcybV z2&SV5G5y80|4R}S*Ih(!M?3~K6a)?3Ac6phYH??*mBzva%kE?ojgBI2QL zO^HC*jv?C2w#88pvni-RCGjb|aWl+c*RUw;x)e4QwB{T3oFKdwBEEw<%Or`U(tBFD z8Er_G2qzvOOrqN1U`S|WBW^+&-N$`~Yj8p5YxqZ5`NX@HZi-&cMb+tQBv`A2EhLzJ zwi&xGF|(2WwHn*nn*R`7TxkVX)5pOV_Xx1iS|=M3#t*za5sGv}Z@dg;M2f4vSWFd;t>WhRT{3GwUjz>C9h>+uNTq{MA?~K8 z5^b*jdF9S`KdPI5vi1OAE16znIm|ac@eES42Y!z)--6q>iqGA-MIrdm%k%d7oQ^?+r| z?sD6NJJA5|3yg7fQbgJr>w=TQ_@q!=>?cqvRJEGr5++3dT4tC>lxx7a(xIQkH#FS^ zK62hyZi(mkys>1rYP3P(#X)&4q6RPdR?nusO95lu|%2yx@<&ODEiF*nLwc`xLjFP5{R2kRuyD{=}GCD~?Kpf)$+VEZgk z4(PR0y1NW8r0&w}r7aX5uxx|yd{Ittj#Cwi$kT11PT!AHOsgIM6tTAo0uUZ^OU3pw zlBM>L@_1C_y2K9d7^`^@-qV}=`vAN-!bI;rwJ7M(saL-~Vy5LCu-K;&IiF{yqy8fX z+wG_T9ZecBVzT3x_wJ1RE8@GZ`J0N%FK;h8P#6Jy@MWc^o(nk@OuCV7GLQ5w;7q~b zv^|Fe9i7W^8{3I`rDo&z@&;sJ*B9raK2YaY{T(F2FB&|)M+?FzEPi6i=LngANVyf_Ty>CN}i#A4-fOxySfuz96Jn>1lg zVDU_H*J>%ylz<9^|9(DTfME)B)s)f7m)Nd>WJiTm{L_m~YNZl;Iw3BgC{(AU{jX=l zxI*l0Qhf^Cn*~XRUkxmaUZY^0 zrw&6smhH?c${_3y9jLf{GUI7_rYRC8qOWpAU2kQmP3L8NggVvm7&+X`z2cGTIIf6y zV80y4iuZ28O*|pVy*>?ot%;RZYk&4B*5`kBE=B0lJ1Ru2wCE2zo}85fsUB{_AiyD< z9C|$R=jzlJq&|BgTy^mCF$6%yXV*uf3y>Ju&Vz?S&iC*?QJ|#Ty7LM$>dtRhXNXed zqPnS=cJ9YX?$0a`6cf&=6*p?jZames9#hzpnLTkf2rnMIgg?N31!QuyIS|D~vgD(= zjZ>=d11LbHJEO`c<3zMl;|VZa;0;q<;~eUAMbOiVrAS8e6yU(Xb!@8(H8eu`i?+R7 zGM>lNWdwt%o|k5^`7x7qAW8{hp77pyZ;HUNnWuP3=eEHkw2LR5yde8YB|CDwdvW7M zZ}Wn@c`5rC@E>@Y%gvwBnkgWT6em=Mz;<>qO+}2=J{*g<>=XrkB60*Z{<)ytV-KQ3 zK{8dac&%*d(jhA?z7Zd9#gV+P`kzr6Tk&Y~Q@NJC5^Ik4N)VN()UkG2x1UCU$^$rY zew8FtB3`cD<>)ZSdlq_T7EDX2v`~e~WJ=R+#=O_%j5N=Lom;HlG$wX&<8wkS;CLh+ zsYPEHzD(~v-bpY?WKqJn^;I5Y1m}PyU$&aqZykEFiy7DO^>CIwuA%Uwbjp`OZOz)h zN5ZcEdzNG%(M$lThY9O=>Uu8@H5m5Ly012_NS&JkEu@s@^=n!r92vd;*=ii4@Ik?!8IA>{bfY@l?T$XULFLQ*nV3Q2zQ3*@k&tD<{7e+%?md!s2a0-A?kKZ1sOWPe*5uG z&p{X$I}-l$@(wX^1FU`Z?cJjsBOuFH^FbXj@)2Q@k8Tc(-ar%0q{Zc9i9(57RnX(_ zY^tKfN>ocm5U`E{AN)HR(ReIFhwC zc#r1Patj=hM2&eSxUfd|=zTEdGqE~+h0@i%+ioobV3U*Iw?v-M<45HJ7kI@s(H4UM z{n*{``DCHHU-$NDO`JIE{M#PV2%>xYQ3n7XuV}h2tg^0W420& zW^V>M*%LvmG!)6RdHSKbZp~ZXgUUF#dII73E0INl5RLDIUyYGp#^9WvP9WYq8M9`l z9al>G^8%dzl%XPHTLnW%y{!G=+di(?RSqVpCTN%EsRK?p6%j@7Ig?~d8EK3OEZGNM zy`akR{HTwT^j<2};QF7t{UAAW%Fd@yA=E<_*5vymzQ6d@V$~gHnQ%u}kJaXa%fUBj z^a93@`u}Zy$0}Q?T^=j9#*z|~#B9DGHLvuJ0@gTWW9%(;L=jSMyaH>LWZxfy1te|Wc?KJgdyg-6{=3b23auuvK zGCO)JiOUs4#a}(L^}r{y2F!X_a(`B(w&sjtCk!cNW>{S>j7%_{#{B4)`x9hxUa&VG z-qN>aG~)3bO}Sa^5FT#X_Qt1Pxi3SVMICZ(5RhzBB}ftEYk4zjvuB_Xh{`@+&4# z1;QWPl#VE=2^QImg^U<0PMpQo1F?{r56P#@@vve*cBITCOLX#ll?memA(?I3I7yse zLD41lMBHMr6LGHm*!fNs-|droXqJD!fxSNYPOxK&J70i{n5AtM)dwh%Vjl{hM=_GQ zep%ZA*^c8#uBtLRbhZuoSd^<>@+LFcuf4*G+&gs&I}w#X`}Z2<@;s(g);$9YiibfE zIvOgr>U2IqXrU~_Mm_~B7tW3~fiy%WeN@-ki%)x`;Y)bGmkM2ng@txqwoG*_c{cB$ zdC!jTpl{*;|4WS?>2Vy8WOj$hR-3KSi|aIn<9bTNsTi$+yIL)VRt>>N&<)}| zT=Cc@MDyPP9n{tCNbeZR_iv{b)9U19yNDc;lH-ed>(*8A})P@L-(UX&aZSnG)IWrOry8)3` z8Ui01(;EoaUv#FnC%hAumA1>lf}3I6e~`4Nrd;hN^QM(8%2mCBGE0 zsyK5^sMIsz{GY1n;V)tG#hMn+s_s6mZCT+<@0=!U!FQU<3uMkHZdGQX(x3=iLh3|e zsNBW8dfgIolI@uM<`lTJp;Xa7Fgb_0{H8hka5Oq8>j-SYx?l+erQ zeilsPWJDsJTzfk(iSBtbTt(ykVIjgy4ehBRs9TM+N~KXtfFEZh)&c}UjC;69yr zz8M#O6;g$zz+Z@T%b_&Ol+o61d5c!W3)pvKtxry%z1JH}xv(IW z1wp0?>`SDl@$rsBzmnFon9&NTewXGgg@_&v_K67;zLM9IsvqWmQm>{mGDzaYeIo^m zL4rAz{+O^#@pwar&qODSgz>eN`yJnHposl*cK6548u85Hr-m4#6T+#410~`5yE8VV zZ8n}1`Fj~2A)nlQysKJ|kUqm&%kKCCZ%1#-+A!eItA$kUPSdV9{^)`=K-mU&K6+Y_ zzzrnahx=Aj=Fa>D2fM0Gb>VYRR}XOR$=To$9EX<6)`xgpgz~1H{BKxXn7;^YfW4BHrD|R*9{!6jf3|3-`h|BJn_u(eXYqG zuOG{%%UdtzI4GP#p>@l1CVeN6VuuKBaL$fzdDt@F0uf8};dCX8LBo}ujXL4s;j)+s z(3PBm^fc6NlEy^~l?ub_!ISe6ju~^UE~5kwsjjz?F?`-c|Mzj>=pI2jaRGUD$uLgvE|zp<$Zp!)bl0Ovb4XL@LK0kr;~+XT1s z5DjBgo(#gZ5`8*`2XzmTte_LTRb;<4=B>y4o9igPYW5!P9BOSLMK^*t>U}R@0#0a$ z37P0E#p5b9X~f7!wNY%2b4*@(S1PF?g5RTJ9w%C_SnMa&xdjM>S!(7r>i4|@nx{JK zg4R@QKxpn7=7>YSR8jbrSRINepeHYTZvoGnqH@WnGMUg!NEj3M`8*K5SZyG(L*8#d z<<4F&*M(AylT-$LRruA4o65n)HzCh!_wNFA9&#G(RAk&<0jd^{b#OrN@q=}mmOEJC zmYYZyC8j<%`aADDE1^r*x!Yr>J#P#dQrC2g;l5RKg zZS;$&z*>CYoGbXjtyOew#*D+XDXd&v9+|2MZc$`EX=3CAL+0(7BkqM?0JDB|=5LfU z*cLofLfX=o7jU4O5AS;(#k+hjcuDV5$J=95>>m_?%}zp-IsOB5Q(^-|h!%NSvAymU zMH)Q`IT77QlmlBV)+WI-dXB~tn=aujiOd;|8FI!FM&54sEoSJ(@V2*mf};Oj=TjX`cz#2QH2fokLSd!AP8BfEwQ_1YeQ&IDM(TUS(b7kFkeE!2+VT0_-yw)1P~j@cnJ4Shjf}GNiv{z zP8qc1aLNuu%kdv*OWiH{u(@H|$tyT!H9nuUzXUfNcr(|H=Sy=q)E?HpC8hGbre7GH zuNP`4^U8nY$)v55TQcON86#QCpJ2Z$gV}PC&H379BYS@|oa^_bM9$V?M`~XBG%Taj zFKXrGhj(LD?twSBBWdN{qQqd*tvy>$kE9-|D>jJwyU-$6ejVJx`Y&GL@ucHN5nK9* z)-CARmEBY<(er4UJ#yDs7C!DN_oP$>ju5sf-;>nB;Nf!KBu$vYN&zf+gQfF6E=`!E z<%nhgK$M0VWVIH=2Mwy1*EnJj2C$3mQ;<}w?@HN8gK+k&-!l-`{1KT)-czKOyaRg# z;w%P;bTun#6h7Y)*{Fb_I$yHf$lg00HR7RnEL9H!P~5wjMu$5fY0LNsr%cGRhZyn& zO8{c!uRh=d{2H^0KLv{;P}{sDI}+7=D%h5(6*dIiK|BiLvHlO-dX>y3fxhZ$Jn=}p zb|>@!R^!~AN{bc7x+6E7MMxX5x6Ho~Q-!~omKsbCU(MTG6cEf{=bLwhm&OnSKc@0> zVg8S0;hyTU=d@oM6pJe1*1G2@p65~~hlbWpR>;DI5%5wk*r`sq)dzRBmt)cwOw);u zw}lwsU4#11i8!y5RFl-~^4~{1ox0nv?%js51bMwX$erGjnAMEh6{I-SGT51t;;iRW zsXB=Yy?&{@nmc}Ojeg1k(nAA6o^k99!Uii5aXe*LCy1A%M|0P5vzC`#1c(EQLB)yH5WXF7=} z*jVa6K74M+hpJ-%I9pZ~>(H5Y#FH%YqR&(g@}Dt9~?zX zSO-}P%b=W&?*}F&3gzjQpK?ej)`EOs#Z? zsf4Qs1Ss-VZy6JTFl=_?#lZ;*zzrF0MMsZJi7E-XfBo{e)jG@gMf>Y)mM;>Q)t$tL zOyFrhGozNl`9wyot8Vj&cQ#kxI?GO;MoW45X&B>6>50y7#3+-&)&R0~+)zH=&)nhe zH_ye}f|V6Tgd7BK+zJGIZz3qkOrg59_tf8Yc%bTddEvCGFD zR&rAASH3gFEc5ZY_{obtgWXlDAP4O}2EX>`dI*U&9ekntH@lr9Q#Pal%A9nzxW5XW zKYDL9**~H}+3bwCn$#4>QKS-Uz_9&PH78XWCO=&KH2mFKxtlS;>b4ANK`e>i7o5Py z0c13E>_h(ehsug0x?c84D=DlhiO3yE?yk9(yOnL|04gp90s$quaE2Q7 z$#{nYkpv^=2{%}9cmRWXEDt;hvzqV+iLB1;H*IX|xp26u6=IPyhlSM}LR2cR!e1UQ z_!eeAaB)#9UX3xRu^=DSG&ruhi*C>@N%E$>LlQcEDhw7Re6RNnVc-W*Sm$3pmZ?8D zfSmTN2$>r1W0P4|*1-5Gok5sB7rKyp-7H7KWN=@MoXy-|g0%Jma3|Hv0&VKYI zT1LV{Aj!1V-_7H*Ce|7^gWj>)FYhv;=pIjb8))|$L8^S#i6Lb=b~_1Gj04*`XGzBKJ07tyGL^Uswt+0il-h6W(mMB8+tPlC4m%j-NQ zV>yXw7m#a4l4)LGW{UL)d45X1?q|qal$t`6^VpfnXSmJVbkB`QYo%$@cga~lR+Uuw zLL6S{%CPeqzpxi;bUVcBsW#dEfnBOt$G9Z=}2?HhyZ94vG6-dHkDNrjOe?hZ&Erkjy4PyV=6DO!&OHIUSCYT~~ zRagb@({EGCTk#6Jpv;_*>?;aC!=|fKC1%1Jx6mv+tkpRH?{x_c9Bk0A{7Emo-q)q( zK3MPF^Se6+l{*Om!P>d||B8J`W~3`C-U}>UZJG^_YIfFW{C`SDg=wQkh8e%7@KWpS z_1a&hg7rzQZf-fs`q*=*w0yU708KY z7TFrW1zMG>LO0KCpU6*NIzdGZrB60LPm-E&xOMqh6_wexpUh#lC-Br6=#nS)N-Ax1 z@zj8(KHMcIhhS1J`bVvr=0RrPTGYNE7lUH)W(&3&)DDN<=VoYf|>M!$wP_WrR$G=PPMw@W*0@OZ4D}w!n1*L+Xq!R_#fR)PAQ>H$WvE{H8 zm7xh{FpFTANb3jhMmFB<+fux&c@RG;(rwsAp6xQ6{Xy)DLyR_~D zNuND9Fv&qWr6HQ6qCdf)9OjLTiEkNgGD}#LIHdEB^@x8)0M_ip$6gR^u#DM@5E+zV zbRu<}Jr)5yW#F7uS)ePOA+Y>s=5`8%^@v5v<9^(mZ8D0Mu}O5R&iL|7(y0TRdY`kU zSjM>a&XMGc>}JqXIH`t6G!O7g^{i822|5-HL7XR#YRc?CfiqoK79>M*#a=vR3?ptO-$K+F%`<}pQJ0#%# z5h3iou*kfm!nKA7h=mmLm4C1PTGECCqH!^#E;*IGg9B1Kdip+^!i{G{S^n`h`TLBQy=(EgkA2l>Ch`UT@NZASZFkeyR;lb%Q8?Iq)4jBt@4BLHCVeKe z#5VI)A}s_e{yuLhJsMK=+EzB8pU=8BVTm--FX57Lh+@a)? z1D@$KP;gvua6~N7SdBvM#Dvag6@k4Id9>N-Z;=3aY>GFrsvc)7+8#}P%|-va5DO{i zRl0SIsSMCH@#HJjYJ@1)R$v9Hi zS|Qu0(0IXgPAU32a!CrUCKQx-&f$b-kABPUom)q%c>U3!n!Gzp*aqP3Jy~zH`jrFO zvVpR)26Mz@p30I=@%(2MR@prtUTU917f^a~FI_iUA$I z^fd79wzng0Tb1skt>OCC}H$ZAZdVS?OgqlE{3=(OYlwc!SC9nvCENCj8-al?AYVNQ*%mXL+rG23{vKgN2E2HAdpA&Z%JSWmf%-$sZ4Ze__0M&# zLe>Vx>0S^*QR+2jNo5A-_R4zEKTXI0%u+u()4ARigp~?ho<1yn&eI}t>R z9^vp;yVu95IDCwko`MeaivuJW{S43h+_62#2kZ`LFo=j2hasCaJSd2^Pr z9L0Eo%2!!yQxX)1GS%4Rx`Ac`>cNFYe39YS~ZgI$J@ z=CAYjzT0$N~@7=FcvQ5vTH=cSX_jAERo%e|uEGl@XEUNTgALf3O|@O|Ms9wC^C_6@ z{!ythaae-DC?+Ccl1DZU|LK;Q3^> zrN`Q{_JDOiE;$8ODM`rJ!^wHS2Jvn-?W1F0X>i-P3e3?&M|6EfBqP0BDwvXHJTgk& z_CF-1fo>9i&)jn4U*mGGZ=aU`enm?DTh?5%6&rq^wl!VLBd@p?OIdB#R=5M)k0j@A zk$5C&7>@6a5sf8DmLiN6sJ1Lgi$$Ism|c<^*An3NF&m-A<4Ez+Odjba4&b zLa&SR;%MC}I^a&gx3$EfS-RfBBO0oHw27UdkNH0~yI%CeA$vb5|F*`RE_&S-uP6&F zfS8Kxrn}Ktj;OsjcNx3<3^P73QUyAmn>RH%9jLGmpDL<6q-t{XqY%Vp^}RQvLAl)` zM!Zsf?Gk8Y(2I{7YflSy_;ApX3XeW4AOdG`x$;rW@W~7Gd`xD&F3XCM(sC zuN?OA7^BWS5(d9l3OHS*OfiCmKrM7`xE={m==D`^c}?yu)&rJs*0y@XfJr{B3%iG1BGyJ!@OKsjGLmEfXa2~7#cA26)0)EU{DdI zoRm`Ga!7d8tU+Y_M4l2I1g zr^9YuSxJ1HqV6N8ILJx+YqX)Trb0->=$R-HuGsS!Hxmy~@A#17pNhJjLUT~7zoeP6 z$-1(LF(osrp@yhMO?pT{5OCL&@AkgHtpa(Mkn#7t1<_91AXwweHH#P3TK)YC<3C-lCvbH0@pDo5%xkkI% zZ05FfQRK4s2XkvN_bb{QS5h25MpO4^lPJ`c*U-KVQ?_6n{!)laUTf$5 z7=E)%d-6;d&84AY%tC5+991Esfe?U7iswzR2s#Yhz?h9R(^d(|-!@Yx8L05jCECdw z$tc_4oR=iI-6iD!kd&a`Siyy#_x1Mvrz*`LPC03Z(_(3V|TP-z(D3>g3{C2b4z=&_sIq&hIXmQ&iV z!>K1#26}NF6`_t%B82u74FPYES9U&FQxaCD=(0=P5jCKRm6`S(5gA+LC&&s*`8z=t z^CF{5Np`_C$B}=jcCe^@@J?04zEv+!q*D*zW%K2tT)bG4;WMPdX z_HPgTNV@}|RLi=o?poIGOa7H zbK};x(*bMOS}6RkWu-)9b9b1Q3rCsOg;2~pP4m{OQQD54+n_c6{9a%&kE=}vm5I9} z2sI@ z6`t?%N7G%3E5jAgeo78X5ypV&9U?QCllmWoj{*1?s;l42;HlPf7TjTIoAZ9PtktmP zpkBiaGfPll+(O36*$d)3ZM4_i@{O-=$EQ!^zmMRBxCqTKhn>%o;t+Sh06TnIG`GUh z#2%r$WHb-|`yu8m8Sr-HuTJu1%F(R6hx?Od&nyz{&319u=2V+_Z5(5v4)ew3K{Z4V z8|U4wPv?OeGa5X-yh~?xbTC|fio_bZVl`df^eJoOhRuv!gX#l-`VrY45N~W|sb;h9 z?W2;+WTap^It~zqTb-!_&rrzToThw$)FiLAH{=^;EyD|EIY4>#Hs9j?6nM_{w@r7N z83jyLRoBOK>iHY}oHuVaC!)8y=4dg-^btrDTu;lh>&XXCoh)&WM^Zqi)m07<*H{s{XVr0TM z42nl|<>c4us~bQ?Bt*@Gg?Ziv;3BP>b`hg_8WYQY$9i)0kQ@S#5NP%zIBFdW%= z*1cYe0tud#L_B9sMyWRFerGcWtSBcfnhw(pn$Pb0{=Iy7;#BM=G5)OF(x~zkTirWL zo*Ja_r7KoFeykhKx8w(8PvNyHzAVcBMvez>?1&6n0O|o zs`*?0G;ZeEVdq=I-r~)0cky;(_X240EAn)JwvDu_1XN>V?!pJO@Ph#uwTelrJ0e!{ z-vG^mylenX<0V@v6R!Gi5#Yp!-tU$h__b$*T8R(*KF#uW?~oDdu9D_(E^hDsKpo)( z7iJQk@dbp*E#-1O4JLc%u36^er$IA~+&n%HoYm}1M!J95O8}Qi6I8H5nyF@Uwt2$f zTpXNvqZ@tJodga%^KhF#1sh^`wOfgMCU+g z&`EmZkjK(KYaQbmof$?sx_o=<4V8gtRKG4bj<3E;y>|(zb`yrhsptO?xPb4d zTUGj+0U}iFae40?WC=!kZu}v2UdLke^6oAJPtOR4%iCXDRggT>3B2^hPfvU{$KaxW z*!Os=#?xT2VxAX3+h?V$)JTblHZGHw#Mpwmi%>_0$>zPHtfz;^w-T2D}=Uy zD`oag<#|Cs4ei)ty5c;q?f(KhF6)4fO@0WZYA!oJjoFMAX0WMQY3Qlb?lPci#Tckf z*S}igYpxrx{0A9s{a3#Tz4fiZ%^)foz#1#q!&w+U6fy5amL?QG2zn@DU|8V>$4PI+ zZ`|EBeNw%)t&UC$fOe|;|rS)tg7s(eL;$r`Lt!)ckLtzmA&9b=`yr8k+)u5Ldp&Tp5sn z`F9yXELmxppN<(p2ZoQc%VOB#P9+93u9je+R!c>VI|!*&1Ar6mvlPdVRc527rv5!8 z6%FmXxC;9OUspat^Jw#2PoGLQv)SLO@`)kCby4v2g9x@A#szEsSVt7x1Vn+#g$0xf zBDCg1PD#SWnoZ%bD-c6PQ>5Tty$10xPxYn%fucgM# zTXz?4jj{o^g6d{`41~m`Eg(a5Kv(VgwE%V12>Epsnp)9Ap7pfDMPQ5Bd6^THS77ph~3b ztF~y;xn_h2+Ps}eZ5`ET| zNqrhMu01>$nv-loTz1XyQ#_Ql%%Hs4)`hVnN9NfhBDf7g%)_=R;UX)YtJCmth zqB;1dXO`Sotr<^FZV<@%Ky6>4Ld?EPEP|H$6Y zq;d)A(Oi4HmYVR%JOaxz4v=^j)e7wj($?YGn^+qjAjBFVxAgpCr$5&z4al{wf^1|t(doDsz46HeTkNU#v* z#o?uhyToj_06q@1DF2W-X04X&_(o3dWZq}uF%0ebf9JpBNT-Yl5h(4&;&+_)KUQx+ z9AQv+k-OaH{k#8>1<%H)uaE3FDKt#9KxCgJaIC+I-d;xPHu)PFR=tUQGa1LYAV?{`YoCo+R-g@}QNSA4}I9Y*nJ zo(gj@@Hvh&G7S_-I|^eZd+J23){QtDzVsJuAETGc#WNt5gOO?_<@i~rk%%9%TOpoz zp;m?R7g3J%&$`j)^5hl@zYit_*@5FPYr-B@3Fp3A$AUwo|EfKZ#Al(#?MFOcfzI-O zO<&sdsn(zrq3;r-neHlNv8Me^PR#=~0029mDBEF+FMPMSu~r+ZCU&mEY0cZz1-T^%dEuBhEb4t;gbz*`>%AO1^E$jfo zJ9|csn3zrW^W#k{C~IWEeR3yjw7*^OS?m9UbGqu=Eu6vySknRjX0jDrI}$(z$@Gcx zK9$-Vi_-V$cxt+6{(WU1G}179_AQ<)pFvVGj918YZqu)@+7MiJI{9KrT!(ZH*PW2e zoqn8-Bxw6~_l6iKb^V13FE<)VJe_<3DiKCyY#f^AceehG!-RlTu-KP%xYaEuIgF}Z zSp24ZWg$xFzp2^+i;DGj38&W3oE3l@q_~DH;<-p_orxuzU5!L=K=82rz9{0*n2!)I zZZuwY<Z$PQQi8sK6%53U( zo%yN{scHiq2eLWot-)bMC1tzZsc1Sw3^a*FE?2?XwYpv`j{15>;9}+#Kcz?`cHHzM zrywd8Gx()2zX<2TFc}=|a>1zd#O&Rm_O)jq{97M{TP;0c(wQMUZ-I^ECOb*r7=BJ- zhD3I3YHEOkL}c!MfZ8duT*s;XbK%o0A$FoOHK0FjW~d%vm2o>mw#1h+R~2S`Eu*t_ z)yD<9TBV0T=l5wrN4#&A+qOf1Q+DPi+&)=oF?$kIY&|(XB{x=>GphnWy_8$)y*=ni zaiq10HH@lfq(Bvz!WT&d71_{gs}MXy4bzeET8YAMPkClZfgqV}8(1!?=P*N3aUIqTVJr zzd?ss7X~WQR^c0brPj zcDH?&0D^;`q0m2=s}R3rz~>q|qI>bNPZp#!k{>(QIw(uvx7Vt<12)8PD%x3dZ<~p> zCh2HF5^j;oDzGx!CpW?AA0zP^;^=rx)kCYbPc8k+r7He*%Oijh3&P4H^>w0bRD9Jk zvZUvNukotaqpYU08^b4R6Q5}P6(>=@HYwR2vxn7^3wb)(50yQ*;r2nP-Tt5%jsPw1+ZsK`Ci*v^e-N<>`5ZU8!56sstaV@6@5>c8vFC4@NAkrv z-z9-H)b<}LEi<0FP01P;v@o9_9QMapz9C%!Oxy-8m-g^vb5`zPKHrNjB6&^o)@@Se3Ya+- zJ_TRfa4kp*72)l#YSN*|kK36ya~hMXlgAs#a33BM9r};n31XEY1jT&^@Q_|tQpjuN z3~b1ElpRqN0w(jhH9!LbIL2BVT~{tgZTO=~ukYkE$!#UcM34C{Rwp^F&=1|$gZg}L59@4`e7*7ZCQpkMv)+zL$%RRlzF!5U&5M&nb z-Wn5Ub4`ZSKFX#ejMFY@7JG<8KUXo6hVr=0prAC#? zhUS%(f4!l^L8pbrxMYWaPKb@Ati|ZBND|ovR`FEskK#Niu;vw}%}^mT3WYo6Y#c&X zI~aEk$E#yd|9ivH9!{&1Hco1LQOO35V+dRHU?_X(>BIDc8_#+e3vD`KQQzVH7cEX| z2Mmir1&mWCBP=8dqfmUHOj2k@W>?#LQ}Es5cdHGiE18QPMV?{ho^1FZ24!PoUilMs z84o??Em~QKteSDv0ZoQjvep;xg;6Fep>|i7JgYJPcblhQlV2!zvgoG}&MeG;&=4T| z)1Oc}*C}Yg?lqHx*scs~7WEh{#wR&mOJkH#!;SgexR^KJTEF^IYy*AB7?f(25zo$L zDsRz^Fbv>2@WT&@sH>+#l4pdBu5-e8MwQ51U$5tgLz`W~{vruXxG!*3`fAw@Zxu$r zW?|@5*tR|&g!iZqWS~9uQ2ZVXdC@TE@wxF8*m^mnMzmlnF8k%CSNvNC2A7n^{JW2f zG=zvC2{MqdMH+BrRN7IQR>Now;aBIZ@RlA8Y_*D1Z$>T;4rhaT3s0Kd8g1DG|KvC( zN9VYCq^Z^)o~TKjt?Ey6Tf1!WM1jApO>1r?%%H`ee9|YMo~IO9A+xSNEMtpT9}%>0 zRv{uuvA;*{!3Hj)G<#HaI60v=!p5AV+>(0ayOgM#ZekLN2E{)$`arE5wVZkxNNl^# zOE3Z6uj#3VJRWhcj;{CdlUIU#>@=^fbV`S1+WPQxHOQirQO99b z!cZ!jv0_CdmWJ~vvNj>3>21)3btQ>z2St#u`}hLM~o?vzCq4hNn)Z9XI^)|-bu*( z4$|Vm%Nina1BBwsvx=e&ro@aB-UDZ_4f|bGz*7Sa>8^1i-|7AnM+67v$U@BrUGI90 zy*t%+_h>la=YBeM>YoZ$4bZ_*pi83Ppj|;Tmnd(6n^m-cgYH7dog*nD%MN{1j8>lZ zH!peiM(-XQ~_TJEZe`A^%IKmQJrEFMJk(dC&3tY1+`8SfNDcoPuI9}7Q z4DRAwHc&=)R)Oa{1lWiE-x_AUBokU*Hswt8FH>`TA;F(bmRX-msld`Z<)#huK$Wyc z9EafnB9!4BB;_M&#cz=;crj4{wXCl}iI~E97ICo~spNqQgZ31dE!`?$QWJ)R`#9GB zJM(el84!DZlT80OAT#1$*0QVMr7g`F0nzNOTTa@|wz_y|w-t`-oqkM-aBMtvbPk!4ZS(Mo^-HPQlTZS>o~22D1_bubcnHR3Qgo~};mjYH#Ls^mP#DOX zmprZ;TRV&nomJ3}xkQB)ZnE{uhnsa8dP7k>=v~`Rflk32%74*^{|^^YqLU=2 zz%qKA8(04XG1@V%xvX3ax(*zknqhRH1X6l5_lIKqrF-tU#hi)IBY2a)`2I*r@ zaShD}dMay}??@Uk-8D-4!u!)bO^Nf8ej8jy$6kV zHM^iX;URM1FVEn(;B!Qd3NK}{YB}*!-pSwvbF_P)wFshIjr4Sy{L?2r2|VVv8#Z0B zI+v%6bC$r&){#QZ^AYH;8m!8WbJqMZqed9$+uet8P2Oe=zRuz=QnA0^xd8t^0KiBu zF-?ozGXG?9O`Kf>FxX$$!On6CYDMj~cqvJ&hz;5j8^Iu>(&agn73Vb?=h%#F|3fx# zMjxO+By5LRMtnCN*}22$C6aARvRzXL@v)?9yPpG6MznPI!I<;4V6>A4=3}qL>Iv+1 z+gaZ&{u|dGp-ReL@z$f*b>n6%sOlFTub!a#WNh_`0^&!pF658TwHDj2lFGS>j zY@MMj#hJ<9<+6fL@;xtry>%46_ooySGb3;<8xx2M)>AGn zD^wK2%0M)Tqvzg%A@`hD84AF0ai4^`T^%`>Gq#9FoDsDF6O~xi_o6T;i z-cPVwlSY|aL5UekRXACE`8hG4Na1wVEj%^$mU&9(Lgxf967(CpqNW6t^^4cS2R52^ zw)tARo;?j^;`d+C1kKVX4f#sUNi`zEmpf>H*QAvnFD>tkWc|{5_&qoapa#Uf{-H`R zb4K>pE^c!T={Jmzv0ipQC{XpvZ=Uq#kuS{MMU-cQC+8Cfn?WVW3u@q+F)@CJbcH4) z5k0!fomUhFx2b{r55L~zsBr4WCo+utr*~Si%_cm~X4pmnL`Mmcd_gSJ3M=jg8mJ#_ zz_PUj2w;@LRNzHj1mqrY#lx6zLS(sb*0w=#A1M*R_ z)==UE%eDLEu5I$;`7lc}Q{~|Gzw{@dN2vffxVtUpyXfshqdZw9OfHzKJKkni#@nXK zt=a5d(-dO9KWiWdv-OnIu*>+@y#%(4dcwMEh;E9o<;f0NuFtp5cD%A=_T-&{QZ)VT z<&R~Rf+KHsgiQSXR3>2dgZ0IzaY4V-bDXd@b*nOo=tL_^gRHS;_{fxp!KssjYT*`c zb~Nzd;{S*|79rNued)!-h%B(Z8DrP$bpyV(E7R1zyGf}8>0HYW;F4;xz4;yBemZ%D zE$g~3uP%+A56Gj(n@o8Ix2wWmX)mpNUIZqAxKPZ_a?C4_d7$0x<5Z;q{UNVl6D-wu z0;)_Vy|VfrXKg)s5mXA~0_}pa8{&w#1@VO-Q$U`=*PVRS zSfx5@;J4)dWtOnCtAxvDyZj$(INIWjEv1Fr1p3Ngc8*vds1t6o%Y5C_r7bu{TNO2} zNy1pFvJaBu-DpJ?OFDk2>0Z?KJ(>=a?e=R$q2hyil5v6fZmX9hSuZZ7U$0;qf)u;$(kC7^^g`-B@@0Qj5l2KyYx8{im!F^a*GUu?g zgMM<;43q@t%0=6^ywYM`f&#h4uZ%=j_$;d-ykB{;;*SZeMWU7Q{qIOxQX?JMZPk83p9iIeOeU z;%l+q+TX^)zl5!>$@k$BOEq`IaLR?FfwaM%B7$HK1Pt^F;i!=C3hAsCglI(YD@=9r zoERDyM|1^)zx*E#u7_myN)W1maSZd}C|ZZv+PUA1lT1^QgCFRYf9OM5Wdy0YdkXmQ z@r#A6xPnPW*k2icwU>@k&ZN2H>5X?j#7dih z_CKUot`<-7-ZaCR5@2?`nhl?V6Di|g_eo5CzE6{Vqb+j_z1t115{tz$vU)38lK9a* zwSIRpqFbi|ewHI?tPkeyEQC-L&QqF?kyNRcJQmGKJKLEf`pf0@rX*H`i@V5*;4A|x zgnZBO^qzE-K`Wd*IK{`V=k$&rO z%FC&n?%NQ_5Hamd7kDvp%TfUnKQf5Ggp@Bv8~`^H1@!rm%Xl``sZ2KQ?!tu~)owaj zM`rR`1H3@MqosLw>Om@+o8zTv3RoyiF3GJx?Y^V$e|5pp+oO2(Ax6+;$Fl;Ln4QH95P`cO6c?`8L z0{rDzKD=rP(`nLpKXI0T?&EOUk7McjD8IQjb%5>H5W#~V1;S&Zn5ObMp)h|`quz+{ zJ}insu(BFX3+N&VD`2rBP25qc%|wu9kg^8%=aM!j!Df$Pc#BtZr#1ftvj_g={rg~8 zRhb}3NjC46Z#89(3kKngNKwch*}N%;QuSy(3ju+e`VCehmeG8h!SS|hL?0%1Z zadZ2b?n3g72Cfs`997C|Z_q)VC`{#<_Ce7p&C{9ntxHW#h zd)m5>?%WBG!^Is;56+U*?ee;@G8TM3l~X(}lMRr{xsgp%c79{eU8(#Q@m9l(@I7F2`pa=pFRD z^YSXEGEZfv4{AQ&iyyjtDR1pC?c84zS&%Qa*Hi;wk-cLd%Q)CX@Myo;lj#QVUviu~uy7gV#T@W(ulLCf?(f|p%d?wJ%adCNI znX^=S$sj}JB+&oXGpV-zg2-jDAl$8djz}t)+c4#`yA-T3yrN^TwrhOeudS$qtp?8w zeVs-CQ{uEL(3ZQ#f_PC}?UWs4vj=C(@|g{YQ>G9D%-{_6UaUy4i|YkdVRMp03`1%J z@I-3Gkf@!Y6tLdB%6JW3L;8ER3 zz$vcEKsrVn-64fPdWgYAS?cFg4}YJ9;k)<4*E0r<&bR^0-(%;5{}eKr?;Xz=dnvIZ zdtUm+0(}xEj+8BTSQEzPvvFg}=H0ws%rlB}hQLGGjFG^T-R=dl!*?OIm!1;mJ0>7~ zAKdW|4~Z~ii)Sj;1gkq3Cf@Oyt`+;*|Jypg4>1gJmaQj6!GAOhic8OO|G zL#c^K*a4BIZ-;(#KTu!`t>kP^p0~Vx?qt`rc(Y%2UHFkb*^(aMuHP{&>?O&AiFfWD zx~!Qo<*J#h+ZvO%?+=&ECNGzSMjBNnU)E<_yT&Yn$Bl{YO4@D@K`sy~U7p4=Vtdz3 zCT-$inI{C$Fm+mK+qr`IPX?VCG|ro9Z5lBsyrIAQf}`5P;4HB#^Q2B2vJ3mN+zxt% z$r;u2pYt>2s9D(V(rE7h^iHLP;k+GQt>8;!XAfm=oMik%pY-ZsdT+{H7RHRnJOmlM z#E`$(e3iIPiu>#9f4vc;XAl;)WjlZI33$@)eRCc;l2b?du6`;kQoX-(O2rlJ*Ak$i z^2k(mMQFsEw$ZN1v8RyQXY)mQzhEZ|`-+OaG&e1A?`3X^=R;HYuSB*n-8CYTx4}fZt#2f z4Upd%AwMqOy@Sh>Sc!11-0-^rcpM}^S>YyAWX#wHB01pNjDIqrbglR_W@wPg`F^Ak zfKO^DS~ieneJ&3jtJbJY8%>tm$S0)Vq|_AL$a+Kk>)hB^-4cNtvfZPs-^zGoo7-p^Vi0U| z=e!ew)!MM3T6$en6rc32<-_rUn?+;#f=GVsT0F*_eK^l6S?Z-@zYk0rs}Rs!3@Siw zs=^+wIK8{3&_0OYZB&9IY=ZCri`i5myWk9Cb zPH!IydZ%8c&C1My$~HromJ!#$p*606PQp1Zbfv02>`Rdc9IdmBrmvdBFuAw?GJU~$ zFo?Ramdh~;e*O|p5Y8Lfoh=oF1)`$n>n=fPoOy+|rS83t)rtG-dW@|HT^D~_?6gH5 z78|$ib%q}SsOIrV3cHH5l~rYDkqMhI5;Mf%R$5+?z1_$Hr>dSPx25<=v4hd`%S<=MjwcBiBoCa@ONrWB&4WG8Agp%0fP#O~zQRoWr8x5zGP-F&i8- z?H;AK%Gs9FfdwQ(De-rwWj{4DM}16#%9z6-)wKHP(c|tbk|Q>y=ShY_9_;gvrn6>; zYY;3&hN#-R$wu6t2-qWf`$H2W?w24Z1m)DJzF!BLvZDtm|F89$NRW=Gif(Nqb&5Rb z^_9j~WO~;cl`p-0-vr!?B`6^h@X(}{WWWZr^Ie=#J^)7?Yo<&OkMDpt0eQKTHVs~F5dhYaTAqn zr82N-_ooT^&AA+Hx-U2}SkX%(w@U|`!847@)Se|OQLu9wE^Ng$=UX_S#G#RNa-v9+ zt?nQ((UaahRhbTC>=W3k*||{?MgIcpNhtzr=(WZ&ZDXwN@Kj)1wvkzI zg23}Oe)|v#J2UP{KPKjLOtw{vOSR~A9Il*|T}`|xJl zG^zPF0nm*~geoze;nAX^MW%B>=oG13xfL-Sg;vt5qq`$8V1OoGPe1q#vBo;`YC*%8 zON@G+RAt*iVsl+_a$jWzzF6aT9_*p-?V4#dMo&)h^vkQp#b>eGJUt&j@NxhfOc7wA zMG!C>XvE)5J{1;lTL)0C^VkA;g5;BNSjd}Hibc_j4nuvl8F2LRWoD0g+NeMVuT5;p zm@wWj)t=53+I+X-K^@P${i|)g@lR-=hR3~wHo;cS$z`hRC)2XI0+D^V0t*c?^U5@uqUuh%_|AWGWdYd zLNy4EI)sl{;>@+cuC|ijJZlRqx=KO=cstNismOlk4jBd!+ovz(vpyOyF}tJ#52{vG zHf-nz1)n{$%pU3FX=~6@11x}sO5bQ$y3${@>+;df9|Ma?f5fZ;@?|nA-H3NGu)?T1 zsam8+gNX!Zb&~1%(y<|u*?X)==h8Y4_aLLS&;)q>9rNItA(xQ>$5GV)m%O!doCgK< z>XRz#vr4fY`89qY2_cLNf=ayWuoQ+gBv}LnaYH>cIXEW#fNC4}REU0Sju*~IB~o@t z&jOA?4jK4_9TUK1RylarjxskdjUzz&0Jzfdn$d^8y~ZbU#BPoBBBvX zVB5z#1SYi$UXd*=t1f%P+TSvVA$oH~9mL(T5YDdxR`KAw@jh8(3^@Up+n663cMv(p zFuOp1%qJNzfBcmWJUNYysl%QR_pryZb97NAb_m)MHGY%~t)cSY1}QD{d#q-QVx3A) z4}d8|m;PF^58Q#1S01r*VI0C3k=zP85Ok=2M$%2`M*XT+k0{M}9DRz#YHLlvQhNU2 z*V8X+)c5h8JS&kO00Q4qpNX83w2yD#5-9sB;B9X@VW9s>gePnHiO`OD>t4@`j~b87 zVtB% zmd0bi7iufij#!3IP;@r&8ik1t;|zd*J;_Z#Jr3ald;1O}VZf*!@h5R$U57sBregaI zbl<#!4}RZi%HnXmpK#hkJ&YF+Kyi*VHn5!gpn@F!SQOlBCHZ!`)(sU4GsH_{o44%~ znTM`SWN|vc&tj-Mc>V3R0)>g1CZzQo4G~xo4e{OtFHd6n=}y%T53nK0CRuLY$MHp9 z15q%P^QBi1XG##wLS#^-v+*hy#R~_$hL;E!P5k3--|DJkubkb@B-hx8BSjJu7iF`$)G!ZmHw3r;2Ytn9Fc3UO&)Fl_q<`LZ$AEFhvPIho;= z*i>0_-HQMwJgVr=7=PPq<_jpO($*816>WBrH{-2+M-yxRmw8F;{`(osgbWakZ2X|- zd2}%u&+Q6to!uiOCnu;my6REhZ|BmMm2g%8U75uwPVGn-QKz0t7j_o#I+Ob0}FVZ~JCeM?WC z8)c*7muGBQ%DrrNu1;Xf-GTqiHM#lh*qyVFzdW5^YOEOFfy%Q+-p)u&n=73z3L$bU~RpkCZ&!s60;o2o8T;4KG%*C-51u_x{2-%LR+r7 zzmIP-uwduQSPDO$?Wa?uQ`xUxa+)_k(@Dg<-Uu;PBAx2+*|;lf%%vIKgpl*pG93*2 zF}AQ4Dr>ow2h83!vyk(5k0Y|FQ~Dk}c*D9U7_Tiv2-j&hRl$l}cT=-S5Ss6julJ%| zS}3Iz)Su=xxZ{4SCafM&Hob5t;39@xpl}0y zf^Ce8UQ<8Le~WBB#mR!MH2yzAcDXFGatv1!;>Zv}Ixf9v+xx3EziV97y7lB2(%|@5 zMmuo7Lmr)TXZ^Bv>rsuoS=T%?{sAg}n7J3A({7Cf*XJUAF)MrAE_r%g`&oM?yFWGg zUk3p&H#@kJBbq-JGrfn6OSlB86TRqZ>ziU6rrY{AQf6J7G%u|qml}CxycvP$)fatP zE3Hqs7vPpP9dI2>@P$(YE{Xqy|5 z#guRo*ok+<2G=($w}7RN!k}Iy%lAePE?>V?`4k6DY0Xqwqs@&e1{Op>j*snSes&Qq z`C>0Nhr?%>v~)R!>X&36rZG#joTTDpWO6gA`Q|ti>thwgfN2wtEb~j->kY{|6yQj-~R}W)XoiD5FaRl=DJHGGRw%LMwVP$dVw%Fz!HuV z@4D*xxr>=#^6(Bd3*x-g|A_0@DE8laNGh@!lniF-9X5a*o@Vj1sn;7Tm;ub|P=l8a zIh~Gk)RMmfS&j>#UBWL!&6qYjc4IhPuFJULn4Vb+coH@$aU({oj)CGf7rk-VJnv&I zQ;O~3LOt^$3?RMY);{0 z)XN|2xquqN)ed`!7D8xb`OM`J&D@LI^nm>4fYmM!-Yy)PHZqLz9`rz@*y^@=M`(xS zJ*NE1Io{K)s1`G6ww583-=PtJs?cDkLWD}m3EBq+nJlJ%sj+N0)nlwzJlVMI05427 z*mx6}_e#%gx9jw#KdmiN&Nav#-gYwEM=H|jnyQAhvDVE6x(HcuY1MkCEPZ z(wJ&8MA*;FV|8fOPGrnefxeUTr}l@$G>WP!plVX1r?X0G8~m{wwjQhjbJtwMwsLeO%GXm_e%h5V`Tc7 zDn1?=X+8m@qh+ru59ztl#DdZZMEIjTFirTqW$^Jq+3^<7#z(PT3`$i2loeguN?u`ovgl=X z7%rxL$)GX8>~x93@u=QQ=1xXjsBZ$BmY%PLd0zW$5tPQXkR66Q{1+K9)#M4UHdXeP ztk%dBUZ~+7aQuBE3oMNu(b!fsR+`Xv^myJ{B8>(JAJu;#TbAmHoi2Xbnuh-CAI!bb zM>1>9P0*RRy!R=Nv17RW_bMfM<%%QgW?uVBM)a-;F+@aLir8LM-jvYCO<{IN9qZk2 zNh;=gLHj-inE_G&){?I$C4FR4v_Siqg&8|gRQF(m5lhjcODh1-uceBAoB7>pMRC44 z*1oPRBWk|D26RJU2Vrj$UAW@1;s}pTNE$2<%9wfmCigFE}MM_GA{OV9p2ytB?G=tS0QrnWEql)pp(twvPC-62gvbCYTYZX{;K<;f^EF@x8W~~ppV7as&I!7tpkiz~pc&p?A<(;AM%n-lHcSE;2lRpva?-6$9J=I#nc-47nGF#N%2ZMIau72t-Hbi%O z_`sUPm%5jB_LYP+h%DfGVwR8f5_b!RoAS_r5XsuwWhZ?Krlf{az4mneI}dfi^xq$a zXQ7AVn!!BJ8_cE8*axYRo&sKWy%El;m-<)oYZqq;XY=m=aLexs*aVlI=Nch~3*oZj zz=S*VD+Vx39tHmuZQx9zUS-e&R|5}!2W#s)N~Z{+%Lm?9GZdaIP?XkHwqgsT0;tsm z_S!?opmtHe79Kol92XcPQMGVv(fqeaooO~*@FwD0AJ)Lci?E}cLJ5)yn|5LrejHp_ z74DfT<&GsWc_A>!Tv}S|X8$Ib1v;?-z~sw(|6TK5UTOfx&YuUw(Gif8KB+1*mi32Dsz!+c83VP64Wl%FNxg!st&8iYI)k{Yh9Q^)cfq z>jcp?y=J@K!uJeBwWcfJ7H<5wUGpG{R6P2SE-=yXj1Vy^jmb@0D5n%S-9BzgZP$#a z)m4TBqCg*{ff?}*mlN9ucbf9Gcb#vvS*=ghbvSX)2LsEIEe1Q?BK6>HYsAc5?~qF^ zCqKe;)ej}}kb(64@}=(GZ$36*a188OgOCW;H-`|1XUIvm?AF(c-4jC|)>ZZEE- zfbt0tX25L5R72F@$q=zTy@km8b(rT3F7gK@gvOGC7z6+sQ`V%YwrbiBE37ARSm=!gsYsWH zZKAXD<_p8;NktqX#%g(Lkn$q9nR(o0V;}KlGUXiiJaEb(%twfeAWL*BS>K_GOSgSb zpBY*j3O+6|?J-~&$Rtgu5j{(XvJd1P#NTxyEp9#!w93~sbb%vKU6ZnZS{E++L+73^ zr`}6et3U82>E96NiuCmUc8mOUs_d%ZKju3pF@emf!h*Vj-@;8v<9#piLSJ?TRX$nc+V)3cfl-y!YDs9hN;B_n~}(CIapdT+gO4aOkl%3pV=*r zTED?9{{#1;&5)n*g+pX}&f8Bxot^tPM`!!d;xlg-lGZu}42EdYda;S?mgF zD9hO6asa6B*%Fx-V8F;uHsG{)7wjd?LXJ+KR!zei2tbDSk$M7vzp1Lt&;nMXNqKqG zTqc%jgMf1u1Nn>$J6LFGi0mn4VO;GxhoN)sn-+tKesAm)$T;c@$M0J9NPvD3l=nG}&Vn(4K-~}IJR*|qR zjM%&TY;YctntP`DWMKFRgv1it-Rri_92-pCzLt!_4gQ>dfgy6{`d_Gy0gS)gUFV%8 z_Dg9~cBMV2I-)u_{W#m|$G#$Zy7~gUcmZB?JFYPhmN-R=*qNK*i<_JVis}O^IzIZ& zB%vaU>lZpROsf{rKtC;R~K1_p>JN*Q3GDQmuv* z`y*2P)Yt0fIq6K@*7KG*^Rkv-l3nob1yxq|MDL_AN0j{J_U2S4J z`JHIFCE@}2J#1JrLMw;uJx6xoG`Cdx-JHNVKp+ge=TmH@sd1fg{uoepvJxkkdOun6 z=&S8#wnp;!_L(k5jqkH>dyC{;XzDYy$~s1fZk3~vz53DZ83-GbhyFWUuWMrs6Z zrUzo<2F&`zJV?UEiU3KQPN{ie0$`Ll4Ro$u7et9I--O6}Od{Wx2iVfF&|SpkvuqZswLuhixV(Kx(6bY9YyfI7l~k z6y=%j3I{8o4C`d!H0+Ini&t515E{tyDPkVml3QoCkBp%VA>oDvdnwSa1MKV@>$XV* znEVm-2m6~H&skWcW9XWh-c|?d%|-A&&XJyisprFx+Of@vn&)_NAle9mAH|tEWHh_g zd=6*WBTdvtml;^7?Z2y8z71;;u>pp|;Y4>Edh{s5_-(C7!{y^42|(g|+bJ4({9L7u zn>|Ne>0;_iLLg>;=u6VX^8ZkF3y}Ko|1`cX&g#ZjU@egCC4zvQPM4lA2n5jKX5(vN z#??v{*mXkj2tx@hDtcVDZ+1tc0&wHMiAvRH=fjO!Qxz(yK`CN~o@QS2jy~ai3J}g5 zx7qcV>;w)W-{m6==&b-Df05Tu)t2Hx7!3=sjsf|v(6qzYiIh=trJFO<{FT!`02zst zylN4|{&h_(W_xKYuu2Vgo9$T34Iq5Dm!XD%86a&p%w(S;L2juMy4>~{y!V;LcuP>A zJBLwmO{LRtlF@_sURFRS{6ocYY2quDurcv1fj>_uyHN^*UTA^#N%Zc;65gl%s2b0r%UzODtk3g+wDy5&u7 zYJ`-*s~Pr}%+N?8q1Mk$nL8Ux*42iHCrlzAcrGST*+1s)0p)UG?9R(ja@$tX%3haC z|B4E!LVipXAKgLr>AL+_gr7-||7nA*;!t-9vUs6atgfO@&~}7Egm(i0+iIydu1n%M3P@H`sDsr7T=_%WWM)@d&bRtrDp|G zAqOeFvm_l%8Qkj-Gd^7i7UVqB)VZz890PKDsVa*RIc3ZkPO>bzmoHIfDdxP_-p)_z zO1{ndSU0mi=-8LTZo@fmE&pacBn<5&uYR6Ocfh_3UKB~f1Dd7p(!PBcl2V#B-3)lShi?Tzg#cS2AVNV5@da7KgJl z5UHk+BUX`*P=HrLLCIB|He~9E8(e=9$Kg+lYn*-`%OXnd-vxDNH|Wal9v*-2BuY3N z8QrzfYwQB4>k?kF%^kGxh4hn{5aS0yyks@2r}zDAF|zMZTV5<{qtLN9v|wV2dvf^p zZA!ug5D$(Xm8`HRRi%e-c-v6>5!B1B;`}b5eFx;+f18Oicp2`u=p*jfSvXXJc7}@$xbJ)_46b1fm({gg0$U zi5M|y)x?CrCalvW2`S393wCuRGG;i@cK*MU!SBJs+za>___AxML%41h{bh=F#x9}< zwD1#yrQC^LT!;ZCa~ip#HU&kpRAYcn!V_k?3W0)3m3YS%r6hA_Cz*@^bjzv4X*u03 zY$%#6B#;>ph+hw5L!I}onP;qy;reM6V_&ilW^kr6;t-S%H}h{@r0Z_s-~rI5#7!Y| zuvEC(&*6YYC7LKe7%?8!I^DhIJ-t#l64Q4q5w>9B;#CKY(QCc=wGR^yHjGnUK8RPQ z7pK>RGZo7TrN>kM_k+@N+g1lmTNnpy5gGz(9i)8!^r6>^MFEYmZ z@TWxJ4_*;Go#-%lPxFofGomg=y+@CodUZ(vGwj{k<59|yd`Xd=!uT-Nj#R+5$tUdb z%ju~}-z8*1q5!`FW{rqc4I!!LQ@&SC(HW6agwhyD%ffI&mYYsN0V_``n93FM#*Lnj zYc-2ShNt{@B81mSzIn#1pLtlho3*IO_D)S28i?sT)B?Wlo^x&5C$~jNpPO4Dv<3#6 zci(woxwRFxDJ6Y36wDZ8w^WA+zx?8EV>tnLKBt|qOvXX#h?KJ9&k_ez*ZP-gjm{YS zP&TH(ES@YKE4xvn5C$DiTP4#4)Lkk*OlK42p3+F_YD)QUePPh;%sZVNiiFW{3TiV_ zOXSWN$6=Olcb=j6LX?&P74e~C^$c@U`q%+5-}vQ)6#3)upCVxtuQ}6jNS!h2iuRiM z#dT9CRyeUUX8Po?vdg-lhp}j~dfzcCL_>4&N;5l?E*~B*{iTHux&Sps<%Ow)eh8OF zh(VXyet+yhSIwc-ZMW{RFPe28kH3(qzo+~{NCN-( zeNN|uu$L$K4z5fsUda`FBZ7C2gzcw^-@I|!HDm_$cbh8t(oX?C27Aw|-uILPp(wMm=5?+=rZvN$J4z%9!_)>1?0m zp03$Q^E_7g%BMR)AwVGOYy=C9o%oTDSbvwts}l)kv`x@ncVUWREI^%R702YgL~>5a zv~2F4>S*4GYd0peAc?sai}!z7ffe0;_v=vq+RhJHYr>mrS<#Y~S)H~s2@0A2Qc(SW zwC0!c4&-l;%Vjw=-^eDULDXzZ`DO&r4utCeI6K^u6vhYeL`?y#qEW<%%5atZG67!$ z9=ITz8W>kqd(rwSNfDt3Kr}p#dy>9;#d^ZsQj6kb&Z&=21O*2O`rX+HDiW?}B&SN{ zWXm}3soegr2Q4v;&8#1;fpLvluqpuO55zum|L7^%-%dnIzS{%}+8V3_H~rGQDJ>e9 zbsYGeQyCnRX@r}keWYX5!Rf{V zOwL}AQHEwOZ%Q32dGNvnzy`Q2!UEMcn6K569Fq3&?&$CyWm;y@hoJ)|i zj$)8i=~^6y+4r|6L(K3_w=mEhac@(Eh3wMu!4fo!SBZQy%Nhbs~bZ_0dD#$%Ut$ zLf$NXS;2GD0wJ5Je;biRkLpQKpBCF|l>s3sgL6w)FvYfGlJt7M+nU`qd-`)6 zCaE3S6@O(eZ4)4EbGR{ZNQc*AouBk=q|ffUNmMZmX@NxIIE1E9mx@>yf{QPbv+#u_xgkxM#IV%c+P4*W#t zx$O6Axe0IsQ$%L(zOvi*z}-*XDtj^D8u}=H_|UbO*lS_Op{C(R z-p|ZqPk4Rl`v8LK2fLjt0A0ICy9671k!KKLQJ>-pQE$X;@7YkYE@q{H_;P;0ab5;j zgNY4{SyuMRnC?{wgzf`lq~ zNHxLBtt3od>ak1t4?PY3x$ivtxXLK!%xxcPKz3^|CcJR5xO@!QR?6nBEosbhTv%Yc zb8;aRakk1>ZlfzeUD33>ohEFE^(R|c&L*uo#jRs9qFG=@@25_PIN4RDx*d%6ic>I`D+jwb?1a zzj4yDC^V0)Nt&zN`WABXP}tcpqnxa>4V(UIv5j^7Tr2<`*9W*$erLS#PGD~*MTO!` zEpPVdackj@O&Q6DQbrbDCXEcy&7BTj(9ZFvY`a!UQQb3>b%*zC+D)Ea$CP!*LfWN( zMm~=X>D=3UVcFMUyBekAvrX41{f8d4X+WXfQ3 zQ}b>!cP}Rde+uBk$$T;MiC|oMbx>t@T;P;q8D3}4x4E)8N$J#d6u^~`COyxI{c!E{ zEAdzRRrNC93feM>O~c;jJf)4%^RkwJQCTBZv2%^|mFpZzZ$miF7SFTNC0c$VO<)2K%e#&7}6XJ|1RpzN9BUozRsSSkSXNW)@H=N zg|DNzo<;_|$(KoxyRu6$>k*t9Xpo*Hemak*H7iM@8%AtI^`#&3aV*YzYtFg1`@~p_ zcCA=N;_^cAxw=e1$xUQ(QRP+R3EJCWic+3Z`>+~CkG0=CXcm|4*xY5tCKFTq=*r6g zH>P6da(Qk_ZQvdAJH`cfbOTT$yhEwT%)Z-anUyWt-AJ#+NtS-LG?D4R(`hm$$LmwJ z=W$r_MhQ&7!g$m<`7PAI(!g>u^)mB+qDVUts|opTvi$bdSfTWQ2xE;!sNGlC0@|up zzaM(%bv(=CtAe1Yi)=A4M~Gr~c~pbLb5`7$Q_%_WqA>n#&o#eOFzIE@1bGW!&B34* zN!w{ln+mpjSyUS7Gb9e6wt~0Gj1tNC#Bszl^CbYqGIh3(RiTS+)a#zKU`~Xzw^5l9 z188Cq;7PdN({hC~{T@*nYWalN$roJ&{&jW421Q-INI4AN_jllHShlrIQ{gimBVP1L zL1MSoYhlh~`xlv^6ZpFm2%*$>Lt&c0TYuHxDrQEmP;Lp=cE#LziRtaJ%jHCg$@#n+ zp4$9QkZBxR7%Z*PdJLjAsi?1FR#dv{6C4A2!5t>WGP<_Aa3I`TV^3D1*Ia*nNVqFK zB~!&0HP1V(o&`ZZjf4J2*wZMSaTv9iV5N7GAy3txJwNYX5ej6>pRclP>F>$LHZfof zp)<=AuRaMCDT?eGw8N5kUr2ykhqP<9OJE6^dPheXhni6lr~W<-&3tbbat-G*IWa>X z)R%IfWO~+?M=UtEfTh~glNrx!_rEhn?6=u52}nP5@<+$4w%t_k$WPjFfl;dF2R0tE z3qIUbL7#a3|K_13Qu3QG)2U{@fw<{>R`NM4TvR(t8QZtKt(lHbw9sbJS9}n|PhzY)IgRw)?y?!g6D!^s|qDqB^%oE(u+uV_2Tm7gr#J_BM&X z)2&z2wPUznpN*bv-j!g3_#}9Nef~Y;-9dhXMO@$-+bSD9-qz~!c1L4mFYp9q%X>vP z>^RHeoT%)AvZnlNfoIxDgyg2nh}7KVN`4hBE^Dwgg`il{`0raS;))?z_}Q;nVTdpv zX@oj-0WJ3u+l!P3B=BJdN;K}x1iUqoN%$W5WQW+}no+W62QDh4FLmz((l9z#mZUet=)BnN+!JQ4VADR3fB!za10-XLm87BAIi=%A?$X3jiRGpuCk`9XT_R-=LjU z$A|*e{BRz+*IvQo4ffz@WV`wu*y>k z`Cc>r{g(huGh^`PamH}nScLoG?*4 zQ3n!#0y$Zz89vdtbC96R1KFc3RUya7aG_eTAg z?pIhO8L6wc8DflkoFur>(bkeOZ(Mb`1TUNC%{{gxqg_N|5JtGM3~~|AJxRVNNE{3e z5%^{YXZ8b1{7eOjI$r7@*KQT%?ys&P%RLVXk%q1=cS6$JXkv?~{8tsCn;e6FFEp9QAEqeIm@LE8lDOO8YA5Y4 z$-0RY9XcLZ9iQTg?F?e9#U(+pIza8G8%kRXgLU!WimM*PCLWWoM78l^W`6r!>mHJW zv`L_c^V{oQR8-fP&%L_)X>whyLK4 zEdc*N0KgA$e(g&44@*{cwD^H=A3=JDk|dsbQ^$$20C_uEcuboDnT}V2LYGG(+9Ob| zxLsLT!2S$YUVCdt&i_Yr9uz6+8|=F0$$Zl@A4W)@)-~#E&31800L4Q4I3VubJ3(@t_OBwKxLW=Yud0l zpYM1ygTv8!*;g*btpcBLo4e*)0=r zCPwYuLKuCUa6u&4q(pxghw(u&j5V3Yfpdw}^@6MBjTZ70gB9$*eV|?{7R1xOB^rJ< z9SJV5elq#Vq!LA+;lmtk-pN3Gbk%59*Z+=D!l|(2ehSP%NWw2)9uJcp2e4N;1B(Xj zM;7rG7Z^M{Qd$raFoUUEoJc#ViDKZd*UD%JjClyx3>C*lZD4aW?Ur`f%h$dIL*5r% ztzagFaTDOl;D+#*$aSH&Z$jN!??9S+t=)^@3_P+Rd3sw0_M=iu+&%vs6tvy8c^b0P zaA!}Pmp;!-hJOVE1PLNDiZO`pbw@crd~=giy|HNb8mW&OP-mzNsR5Ws7R|Ra|AziosmmXwkaN`aA1#+o`R7qQUG8h+W%u zIo5w1{995G_>@U_KM@F{SXq}iRJ#jY2D|EZS#?i4xQIwyQH7RTe4E?xdX`;I;u zovVetDE4{qHIdlr%{2Q7og8NvqP+w3-u*19Mjdf+iMeGRk0rIPK$5l=p&>jUvJ*g{ zcHWh{S74Cc>APrxZ`|gA(rR!dkcj2UrdXZv3`G}5nWD~y{jilcmk2H=)KJnGfPzI) zb#Dj!JJwJ!NC^;s_TU^pIfXMl>Y)KlY+%-+2iG6VO@iqrSXN`6aDyV0+e+PG-!AL_ zbuSDMzn8W(uYRuvuV_iXfRcPP)JBWC$fbALk}rL`7?+7G{+oFdKu;ruRgln@HW~h9 z+2Y$P8seeVlml=*Lqp^xD+rY;EKpNF;wG0DClE0`uio=mz77v8#QDk!h*(k2Yb%7f z&(~3t>W8#`Bt}r#(%q~- z#};U5&?^RsAg#^8FFfl`&2K&t%Lo%fS~}c-Zzu^kwl#3~%a4?>LyFLygA6&#O~}d+ z#MVhv0_7m>GCR|kRYDP$HX_3nj#Mx17jQkJxYwwV+JO7yuBH znl5e)A{PPRrSj**KE(aTJb%_Iht7NARl;joAiwEnnB)Uj8K8=ai_6&NYF(JT$1<~ z;t_aLT>!l$f%9|oU!)%y$fkrO#ylO+qH?!Q%7xKUt=Z$q_Fy5!ua%(8H6Cr2l*l+S z6i24hGg$-`xe+ZssJ@yn7Mjh{!UVQp@@%cY>cZq$f{Y86Tmw4ZY=ZO)|8Qhi&uts< zoQFman@p(yKaJi9%r~z)lG(WrkI9NT+t%wsg0o$!Belj{TCM8bshX=-bL=k=FCVff zOqqd8#=mvh&Q)z4IEy13fd4<>>0JqjT@#8K7C}oR+~xAMUR>_`yMIf0%O?67BQCB? z-zh7(l2*JOK!NHvsc{s2s|{#@A!%&ZPq-vK0Rl5&_toJQsMdv)HW5lt9FF%_;fAv~n@en?LXmyBMiASgUV>4?#bR=JRd-2UH(4tNoP)jnK+B$urj#HHRyvFC0ZE# zpv@3+cu!h2Bx4gsqcvEBsm16#V_A5NL789&V1$-7CkZ!4y!bo|C0t%T@uMZSFCrlD z(#rLy+3*k8VY`~D?;U&M zK~o_<=Y34-a|Z3Ev@jEHIb))%AHMtBpOVLs>VF^~8tZ3P@dCzWCbp=+v7R@00kSq7 z@wLpU+>3}f6Ko@2^v`Npu2ZDv(ielLY_XNhyg}P!QI2}O6DJdD440@$mCA@w`I;t1 z$o;-6Y3fRXTb|$5=0)SR6Ow30O73rvNxD_2zYpEy|I=2;no4iM;Y28ekGlDMZzVbq z)y1~}A>8e?4GRZvIQ7cpHD{>3sA+)`S2Q)7$WM|H zEN|UlI3%%f$=3~Ko&J#;jViBuFgyP;7@v+1ZB=qyobT(4aUCY=bEHW&PZHU(A$#74 zn>NUKRYslvnn*sx+}o_qtgC!4Un<8~TH%ZMLzmW)Ga?CpO+*<1H%lcB~-v&Dl67IW0P*iq+Y`3HXwF)6)g{AyWh}h&6%y(b3rl z(UiNME*MfR{$9rIT$njY-oLsHdfz0^^2o?L{%ObHgIZG<4FSnZ?gOJL9Vb^b{`SuX zK<1@eYv2K77_cP4fuVW&+|9fEd48`q_R=8be(l8-2>I7$0kOH2(rX`E?(TE%>qt79 z1ocNo+0>UAA_N%kt0i_${y2;i{Hpy9j_4JxlJxTa>GyT-&7jG|;9sOQD$vyQ{)@I~ zoC|m$5Qei-Rmm}lIO|nb0WfeZdzZmkmH9o6c)%=f^Ftkcw`r&DP6#(#IDI!P`lOO~ z1jC1kCW@@IIV>!miP}5X&z|pFnUG~AU@|DbNFouH0;R1x7C(^iX@B=o(cLkB_sh4(1OWR&Oe(6H|gLtDWCTtuv{sNS^sptSlM zZaRC3v2CI(?{zgBR_AAXy@ap%-ZfHwc&nPof0Tw)BX<=|BkW(GWAci4j(GlAknBHT z8?MEE%833&7kYgh6hOZmZ~*J&ItmImDRz`&xKdc&(49%F@=3~iPT4jR zyFrIw3MHlL@nF5qdIP@_orKAu9vT?LI>L$4#fZ|Seh<$ITb;S_P0Amx9GJD4{k&@q zXwo$7^?CoV&83h?zmH2f2Bn(UE1c)eZeI0!G9uZ4cxX~W=5ZD-iVcCrJ4HXt>oF6u zUh!q>c2efv*ov43(2!)>w*71nV7ZqI#l62eUu3ghV}%+HEV-Y>bAB9FG-#S7 z&frAihFByz1yn>Ft_0V_(g63KT{UTB_GvbV5WQYwAHK_GM$mep@*CRdPciE!9u(-! zwhYa4I7n2=*B^;krZo`84`D~EPeu+%-X<*sn{080L%>;I*gDnh!gao-6T-wd6wyHT zv4kLDS3mZK@`rj~dyqMRCDR=N4>U-(t(UQ_l|C;??TdEeFTr3tYUkT!Ia{O`V-hvc ztdsOHkbd);&ENU=#J1ZUOQjT5k3wDZWKd;Eg(nS;AD^I?glzQ#wo+M6kIkKO-vsYB z)0aQl^l>(A%mdZwo-Xj)7I~WJJJZor-5L!|sq>lw5c^~Uy-+-q972o7vk*Hoj5 zoOfC!SSmfKJ2)x3S?Hah#PnMj9$jKsDUv2(tDkrTp(i@7WiTHc?Kh~L1Z$%#wdT#SH+nP)LUdu(E#0bostw(8TaTpcyrjtVb{_vUs9*7WUJ~{l9r-D* zskP_kF$M!|`x=pPJnbXS8qkPb+s0%>nxn?VwxGVOm#0OtNo)C@(N>|`$MZVu{jap} zYL8&ot+!5o1Ph`{I0xwhiOkI;;85ffztRR&c$@YRxE{-nmYOHtwB*CWGqk($6#>?n zWws>CIfjZkm+r5E91DF-xKm$O?m>D3)MP0-3gqg=7fD!Bp-PX429^i5__P)RB|F3L zU;k_D&ez)swXdeb%ZS)5wJ$kw=WtPH&XGPz*4*8%`1+i{2!o9FO8EgPsg%jzv>_qg z9b;Ao5kxgtymzOLo==3_+EwJhsrTl_VA<_;U0lmT)wh91Omg55K_gWyv4az}$*> z)j~$@p7l0N{?^p zm*XJi2~$S7QwAMST?@0uNr2b!| z#qknedCDhI+|c0-wxP9}ya>v`Iv?TjrUI`@f~2s(wk4JV)n& zE_=UO6@;dMas&B4RfOmf&J1~g7nRn`GhAjn}vh_6XA)12zOHO+*a; z^fE_PKFWGH>bU|+#?P^~3<|7t!{~10QdM5?C{zxM#uMa8akEs3=xs+bUGb01^nxfz ziN9FtXiXHX+p7KuJw*9OY@q5cOV}h|JXbazYT(`ymre+qP{C>ZL)OZ{XSD$aXdh5e znuva9M<1S~7D9ZYy;343kiAS%+OVFZO9(C5dsTJxs&K8nZdjSnxrW2@zLD$2P}2kv?$yoJPte$(%# z)rkx(qP(Ki>U$dc0yH+FFeezH^2@Mft0tr$fVeU_1mHj=z6Y<1zfv_&*7vL<+EXlO zLGV)BP?8>G-@}nT%kpQ`J|r>nPzfmlDT{A5$*`@Ar=Q<_o8zGvf+LXd?jc7|O#(l+ zZ3Wa(JM;(D$`UdZ*srpmu>x$x_shIkVGAiq1N-4YNI@6W1ck^h@CXMiQBcExUz-lU zhLH8b=5UG}3*TZxGUBTPx7%dtSK4cZ)ZU9(M9`W!Y##NY%&i&z^_5_&V*hB&18jfp zG2kF(Dmktv2tTrA=RJu&{6+)X*Hsr14*g;gpxGm@^^9&QtknPH&`&9|#eQm{!`fkX z2?%CIvW5-&MJ!UKD??{7Q1s0k?9!e*T>Tpo{C$xMvGp{?apqtagY`K#eF8U(1xH>X z0I`wok3yS3C0I><(Ho=HH&!aG`h&vLpk513Jn~09QeK0vKw~69?8)>IJ=0AFNy7>0 zqY{>>hod9Fdo|$}K2KN!R;$;TUA)hC@5)l~{mg?eTMg@fh`PVDyH=QqP1n-^V!zZr zrO19Y{@>mOL{H@8 z0TQgK6yGX9OItHe`hu88J7Wy#{fM8x3eW`Q0g?QmR;4dP#Y}FeXRZB}`?WG;3(`aF)^fw`8b)>(?0#ZHfP1g{pPi#$dm32Yz(0O{SW2fk0?i#&s z_p|1haQZkPLL1KcrFJ0DkYeXlRHP48snKEf%7p6VIi@A6=W_|i4`I3 zzI?Y6B>YRfK1-rxz}6`93Z0A`)|k{S5;{MmG9r>zV+TO!yfMH*#U331b`DPCSz`bA zP5}rPxWRiCHv~Pz_nM|blHmT*>71PkFh8%`Z&AuouHs=bMz@7|d;c%r$dt#7LsBLD zlt5DlL9t^i&Jt;a!>}hsnw;n+_v6rU=K3|-fJ{1a9P$+3c#?8k1)9^h038*(7!8A_MYMpCI+y7DRa0IZMC;BhLQhI1lA<3Pw(%UTSRVfreeD@Y_J9~I}Ga-K#b z*u|t~5*-$&RYi!p->?qOyjRn(A9~J^KT>H*Qy$NUebg&Opo;S3qj^R$T5r41mYD=m zJOb^);`NInS)|B|*mC=Zv<{dp*2k>58s%?T0dy?@@!JC>o6mBuUM)Q^GKS1c_25I~ z^+9O4Kw<+o*w2#*uqMoGuv7bzdY(eb_gHxPj6LIiVd-n6vyOrx65a)wgx*L11lFkk z&`k8L3C0)gB)gubbKOm(Z{4>9B|1s-8Yn41vP8iJ)5zI7JiMHkw=J*c@Lrk*kT|(J zbuT(&tOx&@vu1Z-56O6__Ad}A@Y1u#3QIq%+3vGT40QsB;~7xBEZ4$G0!u{+d#2yw zaW*sG!B{)VKqH>RJwg-tO=JjAc&mg5)}xDE5!)O!r6^GEHfP72EWB>gyii`61sFyx zmOF6b?dIP*Nf+Iqr^bWZu&?0q>)tQn3zxN6XfN%A=Yt*f@q5jjA`H|S!?M>mcLNY! zcE##1ks-r2(HQVRWcgp^oO~<{Zv>b>?B{ms1TuA|F+V^z;Z1{LK-9)w9=;Goxt7#l zGea~HVi8`OQh=)h8<9*( z7Yuu>tr8sBwk_PJMhpzks`?`)ZpSXMe_VuWV!UOgwXQ_8z#^AG-Mv9v{v{bi@=Ii^7;qVG4hxjFt|fhSbXH7*wf`)6Zzt zK-kG}8=FZYRgCaerVuYdM9wP2-e6tE0j_7kA&B7kglK!5u0uUIbqV2b$lx@X$uj;Cm2OY97#fz=|3}J4`i%!W zy%OSAh{p9}v--Zibx>W?f<(QJdEu|8?^y9TTMhv9mTkiUB@83>Kjq{m@>CaQDwQBq zyI;>^O_gfyfl{IT8DO6Gun8KiB4-FFC3+ytJ&HieTsXXPeA2>P^x}#1$Cd{}Hq!Q% zw4Li8T)=L^gK;Y7v?;<%@EC=`2&5#r3$7`KgJ!@(bS_E1vto0_p7a#ixmkF&mbkfB9QxWK1u*(j=43GX&!rp-*qs!iTa9VGU%mG^ov zwG*<^Yzfp{SvqOkgah0gYZdh?qi_?#}1$_r*pz z74cwnEmU+Ru`zO*ryv8mD0jU`%w)7K?YGXE+1?pOG?UXFkLGOPKq5W*>YH&LvXm}V z2r2DUcQXJ#dSuqgQ<^fo8zeu>RdE;Gr(V_j^-a!b9S@B0`95m|HAjYg240WSvi@eY5+R$5A4PFFkF|uMoOQ-`-0TVx+LTn z67u}Y*XkdXgollaf=k#X1-nX&>Tla-ubhJ?14_KRP<}ptZx7&9s&PeQSjJ}hzMbO} z{tG_G!5ixVK!y39vu2#qbJd5GemjyL2{n$M)2ldYfpvwP-yd2Kzv*-fG43N-O0U9- zAp|olXObDd^ma&?Kl)!TMb>~=GnUW3^SPex-z(cYpOrEN_BYeBo)fbv7^@=Vm_bD`}E@SX_3})Z8 zpFhW-ejMHsa-u*^ENs{}?I%;(sm#~;-`=wGYBwzlMxkIZtwc_RsJqB893&iReTwl7 zd}nmb)G%bg`uaCaw@WWI`~?Io_ADonpL3jA-ON$VkHo?9IaMV-?>t~&Af&UEf}(SL zjA5iMxr;o`5rQGaH33hRCi~-6AKj`-?%MR>(lrvwE}DjI>3xrrKh%io1KNtEa|1J1 z=n$9q;-P5o1B4A7NKu&Z$wq9E3S0^{MU7?;Y<7YicQvLSvx-A(@DtB_9v3H{q3}!E z88_wmB&~0aRMtEoeT3Dx-yyE+pDPGm9$Tlch{b$-qfJUXY&%4k-JeFXD;n4Zy56@C z`s&z#BtCsHKCzm(O?1>&>YU3tKMS;p9rk@OWh|(sO;8mE4P6ZB#|PkTB9e^`k$3BP z5oYHj8E&J5;zuXn{jU63F~X6^#{hab#Kgi!5q-Zuz$?l@;VeJQouOzh$Grv_#*OxZ z*Cud_d#xtJvHAE;kFNwg88GdJ_6V+$GH)n7ozWp1ygLSF9G0&(g>I?_ zZI0POc9iebylC7UcH!Ta&?Mr=?^fgz7`I&`kYS##J{2f3L964NZC5<)I&x~CtDUfO z!*^iE6E=}^fRRyRA%j~bm`tS@QzB)3EWEPu+xaXxl3WO|J0LooYO*^3>Zy|7B~ma8 zFM+C5vPZn^VftjpV+b&HT~Zpe^EBt}D?0bsH;;0(<9my*(QpcV;m^>6Y&(f|2WlO% zTTd5(%Zg}BENt{|hvS#nZX`=Ze!%sQq9Q)ZQDZ0#-U)_e{Z*qBuH-m`hGrSJ+My^+ zvTKE3mfcEzDbs};NTK1d*Q4RIo$*2)P?1Mo0Z^rS4fqi}{aj=Yw||z)rWw6tRv;03 z0`+zeyqtiKNRar$xbCz~r!N9w<6qVW;e;pmNuO3AZmBiqQ44HCoh+n~#Un`lZk3FR z2L-B*YLzIgkH7M z#$9~JMLn0Pj2bk>I01t@nwVi8ju_e1RMO#lvO>(J4ot4iJYs2KgKF4HxM+nfsjmkG zJOKAXIQ7M7jV^KyYayCv+%ThQ8`^|jZtH=re{bjLXFMvo20TKoKFS|~I%J5wkm6*- zJ(d>2efBiI{J@dgKruvz@2ip&OXBRMF9SSxrIZV4EM;Jj8ac$&#R=&K;^qO+H=1_5n3`)8HQk;j^=XWzJOnKK-tFQ*qvdma*`MMw!>8IU=*hg8eooJn*lT zcrPno<^`!K^NVuX&>#6Sz(P(qU_bX;g16uPqFeyLlVVa%{x%Ww7}GYmEp~i|^ug9|51q z!Z!=FsF-~Uv8=k-lBFLVqHh~_$Wm5#J(S3-fX1?ds66$ob+)(In*>$!2JZ-I!j#Jv zv{(%xK9D0JLUCx@O!_tkk9VIs>o-{K98TTb|qdOA%qb(GXjkY+6;D@9VS!_&O=<^&Utmw>2K&!acJDm%a zAjwiP|Kj-c67!RRAIJ}zh}>ha3xZd{a1pT?Y8t-&hoyh+RLD0AoHI5GK>)P#ru{I_ zo_P_&mM;?gv{?>+@i&MeB5#SiX^@;+t^W$5mhkV5O4gbd+0+zn#r3jS>J_v(lSiQ> z%u|OT?rbi}0ri+L-0%IIl}Vs8h6V8=YvR^G4!s~)nSF4ASh5*XRybL+FeT|;{6X>7 z%}e^ZRzOda%<_Gf*Bv_@DX~&E_RyBv4P=5BtM7tkjbW{F9#geAI34czCZ7Q zg+NFyzvU2kl0d3Ea&g44k0byB=Se9>_ST*ARJ6du)kksEfYyIt;-%wqvfU!u4de}& zh2-NHKOhQ#5s;ss}4c1Rnw=sE(HZ=+W*V$;wP@ym05gfRmb%fJx&<3ZR$ABnL1J`?3<#pVRUoKV{HzEO9qNwJ4@CrKJIPIC#tx%4_Vv^~?D-N`I}FCJ zO|>4hfNSO42li9N&psf!P51WHG`|(Q7zW*Q>oZj|s4o?fXI0R~-9-ldhk!Bc?Q{x1 zB%gj?vN(Pp&XHUHmo!7_M0AYE&`x~3PbN2@e8CxXwxTlCod}7f?tvcjA(ADk65;{; z>f%3~vcBvffuF1M4015(K#jQxfrlh#k{}!jdQ|qh0bv*!Y+A>{TEv;Gg}COAjhVEQ)Ysslw&5Rq8>h3QCo2e4 zyAO=h63x?Ci{ZnoCo(gk1BZhtce%Kg8v)tx`qiElVcXd`n1`K9GdZU8&&?^ri@Brl zWDa?t9%@>{(OU5s+b4`nr8<55#`%QYOV~-2)1gxQDLRFPV(TS%p`W2n$*#R|=|ZMR zQpvIgZ|9DIVEY}pdi6`2T8!@Ypu~H$bPk`;r8w=kIU&zg_W=tf3$t6C$w4%;w9_w0upeYW!ET8!ZMe()es_pE_$e zyQ=7v@`5_sfiPOIDcd387=2};`Wdx}v|!ePI=9=z$I2_fufjBbXCi%@ zO~z2!>K!OP6mz2=E&RW_D3W6dk#m0yXT9SMjN)W@0Y&GUQ~c4H2qy&*E4m5vLdvRL z;$pAF3J!dc0_zG>?vQ~0@cBawP8&QOk|h(AGxw2_wDfO6MQuURQz|sSbx&1Mu`hv0 zFR@Ku?3Y#ft0Jq-@1i-JKE9?a*%-AJ#HpnzsStw+i;Fy^FzuQ#)l6bzjC)k~rrpAm z<*9#A0J~9U0Dxtd1fMDB4!(PgUGb3`6iKG5MlQr6EUV z@kV=B1x9PebCbRVIETkxMIE46G3A2+B71nI7AGY>8c-$x~0jNtF%CnS`* zr_t=Tv-v)9^e17)fRbdEreV=oaAl+H7r}3dIUM=+xw&WSYf^t5 zTkmP8jUv{_c`*hgpMHM6VTy^KB=T-B?K*d!zFK_inP^aI^h@yG*KQc}UwX^Q4&1q^ zhQev91do?XfNh9b%W-Ut0GvG()}|Ex>!EjAz$;iPC0ktqja=j4#(iI)$e>A78K@6D zP_Y2E)dxPnasw2Pg1;0%O;J;;?+wz2>T(6>M_PeYn3!waHl{skW z%*uMq17+DPn6c6g3f}6U|GvPpMzIIT{YRQWxcfVL;Y_)fq>gTwlI3}r+p(ecYz}P% zJuUL}MYkl9Eh+e+8!IYz$vKn-<2ER{OLipphHUGd^w^jdwgG49@>pX#45tK6KRC?w z3hD0`$zEBnVwNu`3f*P=fnpf~b^mvX=mvjIv~~XQ+5H*GR0oI{EUuuSE{KB=_>^Sn z+I*3%PV;!!l_=z`#Dc*|top~Wxz1I9;0zFIX;J1dqMA9FluV81K2D-B2!Sc*cgY)L z`y<94&L$ln3T2PsSsYip8yExF0odQQRPb6-%5W(m)1vM<*r~gqK=`XG1_yIdEA&MSZA@YHl2)2sr7QIH*0*r7@ zZl)6z;g3dbxD<~4eoP-o!W)}xn1mS_XI`$qZ7=tn>j*0cCPqJ&ytR*^AAMW>)%4N7 z&eHy(`4Z3l${!N*(q)qcVxUrmMi`IRFFb`h-)C)w4uo2S-Gc$H!$m=!_=n9c5L{jx zmO@7FN*PsI)YkVNG?il3m;duAj8O!Af`Tdjyj#6Epv(6cc0euNp`!TMs7a11(1gI@ zqBU_d1=rvYSGeVpxYL1ppknfxMCSo1C{Am}0e;4UvY~w%9LiN>3 zu-W5o_!HR8-||J*VHQl^q}x}PmgUPIOYGZZ!0q&1Ntx4IW@|&fkTv$rv4N8Fuiy<{ zT~KU<;is;{Xh;@D=l5KM+zu6e4ibxk+(g2YL(XUwu@i#!F+pC`A-M?D%n6+lmw-bP zJOUbd&Nnm&5DpNnXLDT-tzFJ3>pyk~A8<0*VM6!V*&fYYK{OOGp96|9 zF#{JGQPZ`J90h6Q=(Mn|3u~Lcp6}R$;m&!b58lguT5CWGy)W`cdMIs-h zZb5TlYkQ7^0c9KGnB3)bfwXJX-j80J#nl{UGz-VDo4+I#2KtAM(E}OkHGUx7XPG^f z`;6w(%f`T&w$gLXF)I$94IP^vtn+C1Zo3dF3A;%tN5PJ5nEhsoTD-ate*-w9{)jI5 zm8w|R>$Gr7B68PcoB7{`Ln1N_I>XeX2X0|u*m$Jy6AL~!@XY?uJri(ck>f4p3+0+} z4thBx!mxGzN{_UuJY7tk<-t2NyAmU;(C$e)Li9gi8VM(mH{Y+iba);FIW&clg4tY*w6j1`%hwc z?fo%Zc&9lw>crbj0mN60ap~9DjTWM&3`C)#5yHG1Y$R@NZp})Lx@9j0yrD4A&oh*k zhi$-!3c72j`a}3Vgz{r45$UZxs$8GWQP*g+zx_~K}56zJ4B3jiDlC=XUaRR=@Qj^p})>R+$ z+cB=fojC$cc>zQl%>nxdYtL;dg8EHYYQ|w6YW=?F*+GYvS02UOs>1~zRwCc)9OI_` zXW=QIlm|_bG>44SRKJ`jl54^L8L7Dz=*f5TT2F4$cw8FX3+f^p*mZIZG3>_*!%D8@ zMJIB~fB|gVc*2Ra_!T+Y<~bgf!M}_>8l+C!k{b!fY7Qcj08Mt zdUeYf{1O+c_`*q(ryHr?QVNHC6%zcE}V-20K znTDei@CKJb4Cc8fa|vFHwaAJZoWCC8-NV(I z3hLXp&nzcAL2DB-JvL9csZ?;+QQ}0rXa_%;(|bW7Nt(4|vB88a2I+Y4^54W-2s|9`zb&9^2XZ#)9 za~gx2KdeuqLN_s;0%w=rV#ZWOb`cSc&I*4KJeLusMl24{MzcJ*nDwx~qf+kLXd}dZ zuZvPf&Hrw`_wxaBscuYP?2nmokzjZ}*86P-`4`kZ@VM6fRv>atID+3>#>eW281WD| zF(frK`=7K|(WgpD}xJ47G}98gmAF`)uO2^)?ec%lMj82GVZYirp(Rp-MO z_}44FS$`yhFh~2ki@;42h=+CylPXDBJ(EF9TXOE%p-d8lrhEUT=Tw+PCaDzi0u21o zCug)*Qo^&jo)eBhKhp2Htm&}VjMCE>C69e`*@0Vp+F~ir&>>&v+sQnl)ubga>I5Pe zj53TIjs%e$ckB1ds47-42M-EJXKtVA&-W!)jQJe#TRU8w9;6+a~1N9rT+U$^ipZeQ*JIM6JijAJlg^gG!NVuou;bx^p?|eN5|n>Gm0=&Y$_5LR3xIDrCQ_6}f{BD@M@KsD zo@fJ9=nOSz%r=mG#TE`X;<6mZyQhQOZ786L#JY-=XzKk9yNX!!wTVDY+LI&qZFCjR zs#L)rs>L^C~we4}A*P8-5o zi9>w2U$+?HX=nzF&chomS0tbxvJ`4GSVmc>t=Mm;Wznt|LpLUNUsPu@5ho6p-fy1E zJJOXb6h$AZelgr42ILMDSuxd8asB`{-BcWA;jGB$-mXnOYKw0hcbgn+iWb*oyfQQ6 zkBK?Bi@iW`&vhu)?_N7$Y>yx4E?NATUV87&3KRUuSQq$n6W@6WyeX84g?8)T7MBKo zPLKLhSqi`WY#ZQP3#pN506;-wz3I_Wq?E6w}~`yka^R-%}zQ7Yj}Qw$4$?H`3Rx3}A9sy?w<~&*NFuu~OB8Aqww3^f zarVdTXx+)-JFn8Kk*le{+#6CNuP*%J>xK#Jfa2Py{5`hk(1GdU3pwzJYx>}|>N&X<^ZZleq&PrxVwo2PKT zg;U}cs&@ldTL6gjb^|)yj*1oR=^D zBR;Hq@p)x#9=v4V!Rgyxy0uc3d+rUtXw3yzh5_xTMQ?ef*mgCa(xE!1S+rCX(F1sh zk1o^w;DF;fOn%}X@z|PbwEmOh_STUz@VxfT%Co7^CdLGjiC%=>@7QWz?h(-q&wxf5 z{M8eWX=<@%Nv9+ThCVyH$wh)c3TF^e(qDU z?PF!@^}0}~&4!dL*F63s6eCURG_z*^h$8Lp`}4Y^BotnoipGDmRGKM!;6;!4F( zpnB?%XKkB81Zav{2uvZf^Bx(;BgMeeLFEI-epPJ_B%lB$&4JqEa({1gNimx^ zQx?s}w6uZJbqqiae`b5OHOj3os4(#hU%KaXzmeJl+dA!^KBO+@gdJ+}6SAh&u(*7O zb8R!SB^eqrLl)0h%yLuIL%oRqre87tUc}utReT`8|EVUC578u-`f`V^H)$r{rC$(Q zA6PU;)Xvsx()euR{(1S5LdY2c`lc*9-2mZK0BSdBwi7j1ssutXcGu@5d^gXjdROqW z;q^`xN8>?DPj`IHUz}OIDpLYNNI-oul{=@#Q7*$NcKJ;NOLEn4d!P5iNgM#fV)2-a z+Xin)6rPIxI%rc54=bKVZI>I)Yv-ez5DDcr+(;Z%K;t z=~Ozx;Fe2owVn>A8}b9q>o$%_x;1ddXBo?sy55qsxn+1pKA;AkyBJ~ISfFpt|;vkP`x7z%C?!eoKY~T7ql_LUAP?KyD zj8x91J{>V_=xy{hvilO(LXjkR+dnNdJkzjj_)$Pf_0hWC z_s0X=iZQJi4du_4XXC|F==hSLzIk>I)zo#-#~`cPAsb)v!ngjpL`CJDM*UO*Gf1Pl zG0n%x_>nEnXvoWk2;dfz=*9!2gmlJ_GhnWfE7cxCW%N!Xr~*p)*XXq03EEr(t2D8;nj_ZOy*CpTdvz=ff@o^y6G}zcnT?eCV#K}9$R0pdYnOXzC?qsC{ z8T5icDNE9&G2y+&JM?WGPues#P|ezomy+_%N80S?kM4bT4xYWY*EhV%x^SE_IQ$L_dhwpO1|7cp#@af{k z;DF2^Sx)_{`IN|x;_AC5Ori#pv=@=MlnR0#zA^Pl$^|qWDI^C-gs)WPu$~SncJazr z5O#^XDAvO%aNN@ndH#t_DUD$3oabC)^ZcX~miD|bdIjsWWfM6c{aQooaZe zjhgI`+}&Fz!9%=!h)!-S9>fmZVmpOU_&BO%1j%UxE;?!{T*Gxb2?bbS4hG3EFSp-1SX zH=}rAJp~t4Ojz$2^I&mQC#s%DhYnv>_2f`cad0!1ePI&x2W<|dMp`ZDqL(yM?5t`~ z{OjTYH>w(Hm!-o$?_6OvLv=-jR~lUv`NJf&0bHkl+U!%AXbkJhNN{8XuiKTt10YxX z7mkaHMYoB~5Zn8Pss?No+rc4!k5XLbp`z|_=l?wSHG06Z0T{SvOy+Lh#tnnR&*A!DzIGf=VLUm!1$LRlOb>?!G}Rz@6qC~ z&h~&DO;xh4UM1i3VjV~qekr(!6z0w1Od7&HM~GMFv7`Ay7Qc8lkezsN-~fD)%&UQF zY)k&`n9A=jB#yh=^GUx-dtarhAGUiS9&@@QZNnF7Lw__9(8f&icC&O%P6|*5^Y;JC zszl*2X5e1LK>+_h0Km&b>~di2@ub=5O@BBR?%eQuv?j+&@<_9QB;*rxju1%1D&(7w zq-}KWuU8~A`6?Xu2G|<~xN$GnQEl(^OF&9 znB92%a1KlO-nXQBuY86JNp>whi5?lX*Uze5?`E3mX8%IcB|Xu(bg_kG(M$YVrT7H0 zbdCSHT#;kkUTurvQ*$BoL%plQ5@)_3`nJ3w86f*Vj?s+r)|e0?SCxm{2bDxA&4ITc zOl!tzueYMr3REnJiq+{sgi?nu#|@6d^$21iO^%|pP*ny85%Im7Dxi|OqE6Jwk@s`% zjcHj;2GQHIOiw6J$% zOp5owm%nUli8)-%fNxcd_6|ht`~XiA<}#@oX$nmG?!6%C_dzX6o<=zVLC5B6x<@&Q zH8@b+-`0|p5l?~Ju7JVKgGb!SG}9C{$5-^M6C^nC<3nev`Q0_SCAFNf3&_HQs=(CA zCj&>61+R{D@nt>$p5n+VUHG(p|LuUubI(OoxB7^nm~F^wzj~Mb|Ff1XyY=RF6Qd>rIth zYSBC(hot&ngCpQkoPIuE)G+Q~YT~kOdIgCH_u8Jgm-m@+uf^41k%O1|OcMG-9_X+vK9 zPrNkiY2GTv?uUL1hpJB7a0fx}Om$R)D0>D!f+|;imE4IfnEdmlrk*nm=x3S9pEyum zUSu*OkmnwBh1}irLL6G0Pt?(`<2-G!r{#9($wG9ye<2*4ljf5Fzfh$m{OqzMsx!vGaYPTN92w3)9@#CvN=y51aEebqb|3vD8^Ld!1_-8d;ZxNut`#dSpb7%*}? zk%c?tdEG1ZZ-B$?lPwm_Bcpkjfz8+C?qcAf3H+W~nMb;WmwBDP>U75P2Ka=j?n3dx9 zx)l!d*=n_*ooc}-NLHaGiVnuSnM)86>c!8D zRO!hy0M#L(H;LlOw8KX-)Dwx0cZC=Fj;c-_eXzi51>!otep<3YKiEOUCqh3)l+fF= zs?CRaSU_;1Xk+s6o|K~7m<1uA^<&nQ``7GGE%q#(_y6JId&VRE@k6M4b;0v@kz!sg zK+oS2m;FI=Q&9>5jCAb18g3Az7S+cY{%noH4{Q3(O8CSJ9uFP6ib6LQ^Q6){T#tXi>VJ^*7&IB{r!G>RIb6d-zr{RR?oG1*YCod8Qs5mag@Z<=`KMDLa7^Upa3Ft#i(XD0E(Nd~&E@2WJR~U(vQ6 zWl%AtOeI%wXM3wwlb;sFgVHDsQJbeQ09ApTsNh4ap-4w|1e6XRKR2Xj9a@(}q=&?P zG%0dWy8Wz&+$U%O+bLhG%@YFx2+A+EYDhp;us=22iG<}es$R1c$w~}m z@``}~=`{jU1@;K2^|qIe8xP~e*V5a0XY278f6}v^A@)g3YB10b`LN|Zb*}cQx%Q)| zhs@hTuYU?q2YJK9)?pr>rV78Gf>^pe)b?PPt%dJ(J5CCu!FU!mSuC0Zd;b7-H@C*o z)&6*1?4sL>o z#-poi{1Ku4g?>==kxB)oUM9W1d8=dI z5*cAM0Z!oD?1D7m0##=!w)CTsZaxP736#E@|A0(r#*ipvGIq5!y>8Q{{24P{8L{PMkeM(qkHc3=7 zyKcIUoA!AP+B88AiBc+8YZ)U9+^!hwizCSg(r4oYHlR zatEby605OZ^-bUtwRyvuo;-Bn>QD2>Qd2*4P$32sSL({5v!E~>8@XlJJ#;@gVyu4> zdH$;jPCXe`%=HxlZbUi;_~F?-zeFyhuY}&sq;&Tm2)SVl+?GV3tZUhUTXfU~G49l~ zS_!pjXzV8nTUXT;aR_IzUg4*yzp(~hYE4hibOh8M;Nqs!`Zss;kmo49 zZ3!PvTXuxzf1fw{O*|e)Hp~7`pS%p?WS!?e5JGnl^|i@PCl9O4!sZ@*J zn|U@_U6s*wjVhFGPZ~5$Xv!<}y2C+n7j^g?~$ zejL=Bn6={r8y)rx`mF7F0=nVw+3v6^EhTa|+1_dyE&BMeV7n_YE!$fno}TzyHHfrW4` zH|@pvL;qTd4t|sh=s=MnRChDF&z&)nBY_IbZ<*O#Sa#d$jMT*b9z{q-Z53-ktxedqm&j`P}m=I#Y%3+8v>5I{Du!?JH40kNUXhMkzc+*mtyEjpQG=)G%tKo^su z@BKcxnBRuB>eVrrDyJz>62b((MT?x&-=}^fZwhoTAQ4TPqd;w-7RF2~xhD}mcjyWy zvN3_y{G-~a%(g=IOIzJivv(6 z@J@ZMoG0@A8|G26kktfj@mw`cqH$oFnfQ6&Q~)y~B`8=L8{^9`pc22FKoM=mbIWrL zV_@9!!vftlGE2U`qy7UXpzN$glJ!L;x84q3_x5XW!UJ)Fzpr-VVVb!`|vzqjFgtk#-WaG+Zc?W67*%@ux zbGx9)ul*obTGimy@fEPV699}G0)JrTKXR%^bAtL^Podgx2YIi8O(rJY|6o`J z_75ZuoUJ7Coz$}a1`nRewI(SgRlRGEaZnQ%O5&h&_*$5v9@Wf;>K6nS3tD-YnUMB^ zM`UnSpTUtXyga3}k)5YT@7?f~6gDZ24#nTn;ghn~E`8^UJ@7X&*`I6(>~&0u^4dN+ z8^%_SE-{Jc)y>~Hu~5JFop123db-arF(O=tEo5wI>7{%I*EeE~u>w!JpA7}l+{7W2 zYQz#MlHD`Mj{dqNR`PWSLp3?$?k&r8QlrX-DgV*BEeAmbvDDF_^7hFss8XoB>Uz17 zEA8uHWTy?+ec{N}D>#LB)W_y!Kx(2k{hDTss()!URfi-)ogGXh24hjFqauej#4~~e zz?E1~b_H$8h$FL$olZGG=`Jrs$SYT*YiuRMb!}p(*Qu*>(T*o#*}5g`Cka6v z)FLMZGG$p!W~w&l(eDyPsy1mN=Xg&8j;X&5!pSmT#b2=ufaJY@`yG0slJl5f^v~}~ z*LU|1DHB96%Mp3KhfIhqPgS}<%Fys>2!8y=`2)W+#jt3yy8O-^a}r&>+z8&NSbi)q z$!}S1%>`a0*tIndDkD;Ho6O$}MJKvoG|ZrP?7fe0o@?0|P9`1Em9>wm7Tf6G?sX1aD>LgmG--P=TB~n`Bi+NEtWrnIC z-K-Mo+0NoUuuqh6OK3dAnr#2Jw0X1b;xxrP8qM6Spi0LBbE3I#JqOn2n#02RRV^*@ z-q!8!16{vM1|(@?DaOp9ko15#fsgmA)2}u+aa-H_;bQxC7zp_N<#ssRt_v9ZwC!i# zs{+%)mrSj!MzqJ^Q)kv0$}ehKwC1Zn5O*iP4P%D&8fqw1tbp(K4@P@91;Zf<+y3d0 z9)1ox{Jig&-gGcd1DK)59p#+A*~Ll?tXfvorqLrTFm)ebG~`e6j|D9$aF;?p17aQS zkz12{-y-hTtNpFP_`#QU4wpMg&v+mTtzaO;!*x7bLVXj*;(M(=>Ok+mQruvls-W`9 zQ!Ghz1Di_zVcVAc-%N^L<$F~@hhWxlC!70Y$`9(Z$MdVjh4Mg>>-}v#zU!ZAwm{3$ z3>#r|a0U6)-yeLL&(&r;N?w=_L@-0EvH{Da5p9Y`Vtvy6BcE#dw18FgJv?IDgm5Ya z^^s!_0M*1AccCgOpOS^#IDRX{yxI~TTyt%rBi5#A`Hrj%v+=!U!tudU=*>(idXpcd zl(aBckO_SG-{P^?#Dv|MKOO^9Mw&%+YU?$@2$p#p-UO8I9{}ARV zEuEm<3T15XH!Au77L0|}E~Rr$K76X4F1d(S zi^q0b-gyTikZ$drp?+!&j60l4yH?0m7+N1(lS|!#ZRSgqr#3k)pfqSREUG2o?MvH- zB-xeDTpdSu>eZGXA2%|#bI6iDs*C>tvWH6)h50m1cI6@UB6SDt2HH-GN8~b64LNvcDvn<};E1glIgI-{sF&qmS&Zu$kN*E)JM~ zzTfYOtpDqKCyU_@#++vk87t}TiRe);0e$WjiHiCt~MWV zJxyXS8^Q&2F3WABvqRFG5EzDxLRAy2{I|gx0uDQE%UTpsg+xR=w~tMzKujEa57Ox0 zo}4$Q@CIYb;Liv#AodYgNdAX=GZSpW{kM7vvl&bQl`Rv)* zpz6V!fE}?}mZssOO^!462|~atE-USj-#;2`7`RY9(R5DWe-oBLA*BtgZLQ!W`s0!0 z`E`Wuy$Uy>hx_ONLM_}8$lp-agh=@)V#^?rb9C)jwDjU16K}jsk?+o)F*GY(*1s0$+*MbIO?yxX%Z#zqmOIK#cXVgXe#F^BD z^$C8HDa`LQtfx6p4~!TkPHg@C;TjJ;!+Ich-CH_V6vHWpmE-Kj&I{~0{;FW%{`T!G zGlpYRHdl_OG`r!6uc3+OoZG5kx>H=pBn z3fq)fw*tvZrt`|^CV??k6E!(gPEiovSD5|cDA9oY6~Y>{F%|(pW=(^b?kT8GkXasN z50!R?ez2>}AgDQS28l(ADUpixaC~1BRz#4>%c!Z>B$nuptq8_31gd%vo>)TY5rBrz z2Mo$Ie{q~wYVQ!Pb&J3xj#xGFQ-QpCtMjydK;skMhd)6+eWxQ6-l6D)sc5{P#Mi7n+0{(8ofb-EHtdzMIMT z98(;CLfYzkw>9{V{swDye#8udyM2yKt{gz4qM1sDIh;I(Gqt1t%Op{&oBga_OTd-V zRL7d0PEmx7l*Xwpz7$x|-WvbVRd${!h=Bg^m{<$_G=FO_6|MVw#rkbCZdCv$0uzB~ zm1C0EG~S+6q1yJqg;o$G_mIpf!^-*y)m9`vdo&Pj%1H*Q1cH9UyFiA1f1cwW73n|^ zya?YeVSyN2A}C0V3(w%s3oVxW_V=TSnN=jo5Xo?ux%@L@B0>;+nDbEcT}U((d7!3l z9+e|5k@SvW@-;zi$QpRXe*Dd(x^{Ax=5=c6wHeRAh^&hph>t00 zw*-E)npX#CaMW%~F6mlm_0_Rx)9+;UFj?r1KIQL4iR2p|ptg6f1E1g9?&tzSKg8vO>W#qv=+ zE}Vo1uMd}`vpVNu8Wm+M97Ep%^OGAIo)?C&8`idR27a0yVNrQd|2T*Nb=wWKMv-_? zjW3C*b*MbR3-dq?ub8Qzwm+>lhRh7zdv;+3!~nWVbX%QlL1>|PG$ulZ(@y#zHQ3qc zBr6&)CUAI3&-~42{0~minS&V)zWct~$s_5! z-C`Ax4(aX7w{!2Ima6>D28Y{#alN(p4{4mQ?#KZ&8a-DR%*{zR*38|H@m__oYJq18 zio(o7r9g+n!lU#>^%4wf1myMM!YnJTN$&L$3w{HThW(Yt^f4+kB-=U9c>e9Bje;~X zz~7R_bB*2^^B#x!5{XP*r9)W$^>aizvN`TbqjWCk$Wn79WDe=~9KW$J)zG?fQ0}o& z=?R*5?32PE4`TvGaQU>SF!HKr9HZtDwCx`0TU&(*5bFPCM~v@7JU48x+NAWC%pnv> z)zqGBoO4ysFFmcGEB<7T!+7qN&2hkPXJSI^fwK*hkEN4VP(iWs(8sG57K0S^>dQ{W zzzwS!>L}lm_5AP#p{vSaL+8nV8 z)aOZrdf`)S6xF+7JBf2UzQSEli*FtGM;Z8S8oIInb-@x9VCYs}+YVOb*R@Gd$NmF? zvHHITjd!L&a5jr?cHPg@Y4?Pd0II9Uh<|GieG4%>#jC-5@cn1RdBCKs=OUF97#qE_ zF)OEeG~cm3*l41z9_<`y?z{M5B+zILmY*1%zHnHnZkw@Yv4E4*Z2tKIxCa5o+_44u zy?te{7ZZnrBKwggkkUJ@UyDcq4Wnrl+h;}2Eeema?V5Z)l!WoGojF0Tg0Uc?)|4)U z%#1jFSwWV_w~i4L4P4OJ#`HZGll4vX4+OZb3?VTPl5M)jO18u0zoiL^C6Q zDj9UmPA)P7v>8bW5-Jw4+GuIQd7_X@co@-Xcs5?wSJ@$^di>GJ?E9k;MlL`STlKa? zl_Ot#rTjbo-y7kneYlvXX@sxb{nJhK=fNgxjf(y9P0OXY37&>^7|LH+5E``Bq~c>H zT8s-hllBc2ls4#Mn$EM`!_9%2_1yEvs&UwVVk)b>2$%ae6VT?NGKhS3sGV+Z%g@$9 zy5(FClo$&Sv^U?&D6(t77#Wc%_PWPkjmvB1kNac4GWLMB&f~g6jHU(#Wl8RXuRLYT zZK2DFgI|gsFIke!cG7#pW#IJeowJ#1MA9UFal)2@HX3|>Hp1Y}evj|)NGLz8ZRq8Z zPlA0wLE`~k+L-OrZ^;u<%3o-WXQJ>U9+ zGC70G?j|ZVx742JK+!Kmt}AG%37#MJZiRHP}u6@l6p-C)ub{NiN*c2_n@Mx>zFR#UD9}QRNP!kHdlUH*aK_tPLM8Iy2-Y0M# z>;+yal`D2X=F?`FDvM>fDV8k#N;i|-Qa!_7qWD8*%kSy=9&nvpqQL<7sX$<}{Y3WH z+^}e6)>xNL&JJ$fW3GWf#NgWwRf-P6;rirF zNje~jQiMQyztN@kK6(anVQDp!8p2{sN0G!y{hDW`zB>N zQ3lF~D;2h9gP`8otVYf$Lq3L3eN0C>TGeU>Rb-9kz9YnvY&Ic=jU^#FN>v!!!v`hSq(W(j&Kr0?Z^O?w2Lnt1-wMh%kFJG|KuH@b#* z7SCrx<7}|Aue0PCo&RUB@1aGLzW&hI6$1u^Jq-^moJUcI?z&lZ>RA+teh?5GMdhwF zVpblNidY{1G0G>JKtxp92}a<{YGrU+*wKW2HPfXq1lbn z3N-B8A!eD=pbr-yX~TK$A=3`Q#vIb%UpBLW6e1Ho2biyokuA8yok-n=chbE`5$+z` z-H#B#6sw55>@ym$QU7MEo}#i|_i=@=eqO@@AoRBH@B;P$L4qOUvdSke(ngihR?HbP zWG7*OdDp2uD3FM^N%a+MzR2Bl4h0{7FGqmal8hYBpgjt1KtYQI9ZD@Siyc}xY<%XMiBnfFM>a6aWk6hwZQ=T=9l23c&`n*- zwU6xFNpZBv=75QX#LbTLN<&8=b1wqhO?(q>zc3zQ5Kb`u^)ciSrMun^(WX!rYp;*TN) z)}{{xJvz?@5XKd;k@6{dpnjF#)mk7Dn%3C z8R~*5?UlzJppvt4S1+ItUAB8p^X1Ev;k6vdbu|%35X!a zLSeFJf5IWOG)y-}Q(t(r7Vg`EHQLOnQF&&yZ?z)M2J#3|NE586fJ)IVZq6T-FprU# zc8EAI%BxR_=kH4>izS@l(Rt|vs<{6Hf%ad%2#nXmDh9#AJj?O2wRpal9F>Ioz?u+C zy_7ed86gQJJT2DTP9|z*@-)t-ad*7XsoN4;iq(vEy}3~+^wK*@sc637+n(dOI_62gz_2OclM>K#@GMtyFRZ~WXh@l|!f=l;f~#~9c@m-qpk+uf z4{2ulrr_SQ>F(-MM`ncOPnb1VcLULw7vQtYX~Tlyp{T@!E+3TXWFrC^PoJ{uTT(0n}lZw5daoC!;MtSwYD~kbO4SLk?PeyJGa#qThSNdS=}_ zi3+<5U-x;(WK|M*hAj!#(m;XtMV)O_g1D%K689SUP-x;A*53ncK_M~wkW7O<6SJ$# z8e>rx)Rdm(I-Fa5;D)SjV$buZ4D%OBEu$D4^osxg>oTJwpHnF;vMavf?M~qgJ=TqR zfm}FtTvb45HjOUH$T4b11uPhc*P*_fcBL_J2LWgk`bQ+%Q#jg5xcajm`@BJ#H4f$Q zW#>UAMMXS&wSDhQw;!m4Fc^iQTX{CViXG8@4z26x^o-<#e5RyeN0@ptU-euVXnyR0KTh zo)_f8qVfV18j15L6kauE&klQCU{$cDpjtx~5-qx;EIW^q1_QVqx~$zfdL^|p(Y6K3 zm?phuG&qh~3?ZqKCgKC6Vzu@72}h6_c`$h~GEjtJho8G_Fi)0)yP-mR1`tP-x$y(b zIX?lD&O4?0EpK7163ogHki!)fm8@RNH0rF0QEd#B$jXBL;82ng3egm}SrJdTMuvo! zpCxLq;0O_)BBpZB!vv?TBor5NFdjeCH`dFzTqe1GFS*+=MWB6jBDlS>Q9skUKJkLv z1e`jk0LCeKFOcOeKM`+!4K-veG|%T+EblzdF6Eneaz^!Hfph1w#e$~c;q5$CU#H@yGIRso79S15ryg-=mP)*5d*D&_?b(i2xA_6#DjyuGH>c+63C~;gLB^>X~gl&4RW)#7e8-+TP>w)22TOr zM5Sd1-2Ov9*<)Qe{4YSU-bkgT(~H9{x}SKEb%H1_)dr^Bmn*B$JbnL!J*@L%yDn?n z-M>dTAhy0k%GX+Y!e9+~0utD&QW}J4XHSKX%h8li0SQ$gcd!Cs(_O&Yt~N>Gv5pt9 zBJB$dtwq(@SGz}j0_3Hbyx7mUkQaaHH1r4dkfhvEzwUNrI>GCeiAi)-1gD8S~BDFqe$k7^Mgd&c^w<`_ql)C#KtQDm|ByT zx4Xh7K<2?a?;u;3aCDl*W7p`0F-bKaEZ#DVxX8PesNXL08r#f3NCa#_B81_1fRv47 z)8+dUP;>nEprZ%FK~5l2V=85~#VZhz+z?^1zG=AyQCu>wq2^NOa#Zs(izBf#>Hup$u!HkW1-ST;{bk8pW&dy)8USKnBne>Wbz$p8T@=EsIQUoFF%1QabV z`H{^N{@tUOI*+kH%O7=BA~CExf;-t-3VroTN>yuwkC@6A{7Px1RJmZD1tVJ>hfQmU zP6&6l(Y3(vIV#;)ogh2ZIMi^}-9-1SAv5I4AE!OEBNUF;FFCk_g^WHKSG zre|0*Mv{F%O9nfBFz3o0?%n6s0AcCMU1eK;IfYjUoF#Dcd%yBw#E1jmi9R_hmfN-d zYmrf#WFxkv*0Qr)S}FrTv}Vb(j6ZNK9(s9cac7OzETEc0OyXDSj%8iUtQqPy``HJi z?9*B&uJzRU@rmK#hd=xKQ&vA90R}s`Nh8l!oQV?D=7g|sEpLVK+%?Q{k7^lJ_=~pQ zepy=%t57zcjduTe>Xc#L2k*pDBF%5WwxA>OJ`tXlro;aDf$5$p09+P(k8`7e;|`w6 zBfnw})OlV5p zg>f@#p`fab?>qR8D58L3^uJgf|9;aJnGR|$dLw}gF5FW&a?5wIkdCK+R5Ohw*3bJ? z?XocBvcVrGXysYD<|rn4R?D;HKZLDAwvHl8HoS)_5mP@WwL>Pq&d;KUS&Qy;c}-e^ zKS|QwAdB_n-aoh_WKMsjp!p*%?Og2)Y|^(Q$xH@KNOfNMw;{0)?}BcoA{e)?nV$b{ zwt=>t#Iwd#rtU4#&D<-WxBOz1E1@Ekc&s6FJy zN)?y7I%}UBt~1%C#+{7Ak`FP=)?+*^i8gh$4I<;l6yTsgzqnf{F@`LDupJd9SF|LQ zd0$Q$YXe-2**@vV82OTkR4JjowbQbv?~A3l8rYd(%>i-ul1eiY4(b4yP^OYXq_HGf zkXiZ#6oaFRyU)|i<7i@?^|yU11A^B*dBL|mS^eCRCK9@B^eDHU3$-+5Msc;!UVq`HsC~a3(%x2q;qyoNS4Q=-OG-N8s={2@WOnT*Q5#jY2~sAaaqIP z6qIyn{nP3;Bvaj87q~45z5`CnnRL^uku)`lg^w0N%ytT)R!TSJtA{FjziLEm(mmV6 zV{`nVXN__I!A2c6zA|g<;}v>|$}WL9gZH&-4&2%i zu36C5%$KF6oQk8{`AM;fk#X>7%vO0M*(d49wi(TGA!B<6!H;>irg5hJ5xIjRC>k>? zY&;htFA7HyUa35gkpNM|CwmSNmFI6NpDP2q7VroOIu|~Cb`l&lPt;Z1{S`Y2Q~Z)Z(`q$LuuojmTb-2b)-V6GU|oej@E{=!bF%L?G-%Z{^Eg<*=Wik=ETKlq;ETycXkm#kVFD-86zxSO@BKDAje1GYlVvUUx z2mDVhp-a4sT|37Kb1fjMjj3NHq|7*@WzjQWes$uG-wRuu2l%2Usd2h9!45sX(H$H7 zu^ePH$rWGrpQV&4le|@CZ84VX8(oAVG!OBxLLhBl^ckn$Xt!lgQeD6Ov67I6CFeA; z1EB*63?H#MyBM9`k~bY`ebl0im8+RGSW_Z}TevFu#W(Y=0X`F~h- z?on9KYGy>mW_@jkrn5P8yq4uo)PXzV^&6|22}VDD@)cr6i!l!|2wT|uKQ|O*?}p0p zf5+m%iY>qOr6QSUuyu2Hi2HP|nx_(@6=2qyfm0^deHIq|~<0?i<$w z&p&7XC$5+yGMxWe4xHq$;bD{(dU6_g2QS0?27q%rsbkK+%Ec5CoU2y|U~Fj3BG7y} zGu(!0+^Va{NrYf$hV%cTCdN1c`s$ z?8&BE&z;_Cz2}%i`grvs3{%tSl{HaowMGsY+wr0p%$%7>lOG?`j|u!=1miFeLD& zTrXbfw4q&t0D`L3-qs|eMt?tvag{Vz0|RzEZUxU-`q-z}BEIw`#1B>%!!YN-5>Tp= zcNJGd8g*yN*4E2Qgf%(>K*YV9Cx#?LSm*(NzW(r_1QUcd7`Bz^@L^g#&Pno42r!k~inO=!Y7uMs30=%=-=W;{?w)p@ z&6sB;2+iWs`kDg#E)5M0iKOwb8^avHaxNSToROQGxC#f^5qG>G>XxD`i&Lq>DRpz* z6wDa;qK_5q_Op?k#8itf9q)N>%|he559-jDyNr>pYtjYPuxW(&b4M5D>J`p@4D4Ug z%$Et7;bJ&p{!Am>c|<5bz%oTY?DjeA;8g&%4X~4%Xji=Nn_ zd>48_s4V8kH7IEA7d`R3_4q$PXS1%IyGxay*yhc0yk;>HH7`3Jl3i6^Rz-Bj4C7fg zj&PM?@=RZ;xe#Cxg|c+XLoaoR;pn+M6sK6NAXCEJ8P5_Y8e2q=~Zd47Tw+l_0H%D_K>f-S2K z_ZLk3F288LNKjUch?=81wQtV`qu!cRbK%cLdJrk5#c$E8Mn;rd%@U-@=vbmwPOzU2 zlj2~vT}v?wj6y{RH3#yp9T;N`?)?%#brqo5E{j)kV1w4Tz6-UIe)=Zir+j;MdKMt~ zR0|7~gakV%H_Ak7YW^Ja{cKtQpzk@_Mt_s_gmA#^##lI=pI-VzllIA(!K`ST>)&TpnUz*}^vI(!EQ+DweAwdd0B^ zcKre>T}eM`Rap+El-%GfGrEG~bv3^HliFV53u&iP7zfX`r*f6&o6rS+rP)Bnv_-Ab z0W*pDQ`b0*m{cgP_-ZTCBM%K=W6QjQf_t^(WZt;|oXXI2pbsjN#;)HnE9n&(pCcUu zOw-PpWU_p1h#vBA#^uzapImwl-PqGEd!=Pr=$ly>G@=&2K? zc=eD7ZByFBg@4_CatzhUDase!>;(Q^qEI^Qn5yw;;H1I;MUd3UGNbkF65BGUu*8_q zyHj0p-mN?8h$a9WyUCWx`6lKIJ^%xncUBvlK(45)&H&ebh_TLW-A0Mz(#hGGy{lzr zeYrcH!E%hyJ!oK^u^!qG0NC~;@31Bs7{@T$c? z&<}oaOyMqs$BYs@R`6kDPg#)iy7B5ZSIiuolxG2?#=yRk+ym{tfc{@bb7l>DGA=$t zO>IKlC^an8y<`o!yy#%;wewbm?eVlnD!icDSm6>>-O>c&Hb)t%7Xz+x>(+E!)S{4# zh%L}-EX~DUGPeZ!?xI@rzokOepZ@9S`xPg*z>R*uEj3I#O$cY-)Ch01mTtDe9o*S( zHsAuHEpKr2z<>Q*=3}~ea~&N{VVd`@($r$;mLtyAFgzT~TCL3IJmjf4)ah(^FMFltiBO%FWUI5Oz->&2gCO&s}wp<-p{_s{Z#aQ)jPgfs`rjbXx!@4#_4s8Pb ztmO9`Z|6$CO`|VO9(>`BfWwI$I0jzz@u_=f9ucsY0jX z`ZMfSBltw`)7*_GgMTBR&oDIoJ7s1#N%HQN8w79kd(`2!klT_K@BL8%VFsl_iL&&7 z_Mk~pyT<*pP_1>tasPQ1w9-|W5ox;$vP9&nzIiV;?UpTE;x*ErDWj*@ ztwheBDNH%ie1pWf_Gkp(;4R6i18%a|Z`cGgu_x~!Jokfiyftd%SY?kHCKk;2SXTo$>a>6rAXwKOaPGHPkp!=F)ql2L=(|R?0E%=SC61q^r9#8B_qDHJWH8jDiG7)k)vJEOPT zsHv}C5C11d#P{ExGn%(T*%saJELOnHyQmX^fy`Gua}<2IaLZj0$%9<@h~q)~s+R-`IeVp@MI-RZ3~sd0k?QFUFrQ|}JO<{>g{Bfj4RO!^AGBnJPZ zY$rrzQEF*_2J~e##JnugZVEq5>0UkT;dPcC*&o$=TS}j$v>@oaeKv-^HL4m_3l$hH zSP62_vW1KTy)D7hs;7%)XBfpMRl#W0g83e-MPl$y z^h}C_*Y|QXATfWK-4I`7JB_aEyQ)0~bVVOW-+ zkifeRO?T>H@1UV~+^KAnSx_LcBNH!X6&YNFCyCyDfH4n7#=C+V-cr)6>< zO#1n5;~NTXzGTYgEdrazk7E}`Fve5}XgfL`jrXMmZ19_JBsbKo{oH?;Q`+{%ClNuP zBP^**VN^d0Xq=20PnE!;1AsI|K4P;}=K3EU%@Je~P$n_@t}&vtV+EIaePZRt9f?Zh zGWe$Y9)!mny!R*#;WZsoEdc*N0Kofd>+-c5SoMwfVBLy-IFG`WG3#AkF|sZ2cWOu^ zXHYWXTtTF5|I>EnnkU2(B2?Uqn;A^Z4UJ=SXy|wI#{YY4#?dDK3#y<~um+OSb{5An z_}?wjLFvM5yGMqIKpyRI*}_RX>Zjo8Gf1w`eHVZ9fQ8uN&N82XrD5;fnf=f+_1`^+ z)N`dml5`zyar<@Xbr~oQ<|*w8y&+-SucF~RCbd%c@1jOGLG)Aw<0A0)#qZGc<%`DkvC^Q1EH&Tm}`M*-o=P|D+Jj0iWsY%bi zeY90CD|$C3A_d5N)fM$>mJ>E2>KVQMftj`Dg=zJ5Ej$>n@WvlTsu~LLn|hsl$trm* ztXJ{fkyOY-_;z!vF61s z0Me>5_%2CO-$tCtmPKt+6gLnFC`a{|Z2jEAwj2BHAJY|m9BrB4%*L|qGG|Tgv)ga7 zZNPIhY<88ozagXjWDCHhG4ov#>(xI|I`grv4PQ0E;J}i;@_^xw=~5=$dATET z*2nss>bj?Z?0Dh@^~`!4g?oOF7`U&1Ijw-V|1YIz({qn z+OdSN^*b^|jrX2U05bJm1V}$g8wf17ofD?xyp3io>PyV6swB?=kRkJeVoRM#}(yx>#=+NXUXVU{pad0pu=xUXl*v8lxU37E|4RheNz&Am`^vm;2wP0;I(pLC$#})ti zGg>Xi*SJK?7JY^6$ZST8S;1E0{Y=3s976rC!dxa!;Xc;IkwAWJ=1JWkLd&x~scUah zU=+x#Meo4h#V|;Id`r{?yDK?%it@py8sdYI4ymmg!NJd=Iy5`-DanCZwxc)}QR_7L zf_Nx&kNZ{4-}Fa((^JM?OilJFCltqRahUFAYyXh3JqdI6>vP0ec^>MIbqhYW`;XgX-v&$)TAg>?%kshYx zcaWsw9+P`oe>!Uj`Nj`cUVy`U2R&?1ux$zvg;01Bb{%GwBb+E;BNxQ(y6?B}xQ&P?ck6V72{`^|QqhT?wMq z{lw*eb~3E}*&r2R`DTS4ey|l=Sx7@tp%o){g8O@xBck1tr@)s}j|`BeErH9u6$MCY zbDZ&5M#Y)*>ZwC^#|S)#g7G*N>?wf?wM*cyczm={u*b*Ro1krL0u-CLjCT}%c9HfI zK*k)|D~RGJy-z3Uogu$n_~O8qp>A3q#CWKv3M&qbN4T9DKn8 zG0pu(9m2>(%f~)-hOXj@~9|8vO@f5<%R5tT|5SM0Rb({Xq=ZXxE*7-Jp z|92lHWX+u#BI5j=3TW|jqo3y|6g|Dtf6Xn**kY$GyJxU-6GM&9NF0F2S>|UvNGTrc zg20fA08i?SSYW|O4wL@@d^mn;0NGPTTZtgq(5a?qNl|wtQ59u zBm~G*&5bZ?y%w4GnG>8KaRd)@S*O8)s4S>3_)hq5 zHL9-0Xa7~+JFM~Gi)E9b8Qv|J$V9Z|%*hMZsu)TfKnMacrSrdtu~P{E-B;b#)uah% zUjo)LMI~e?-<&|Rt?El7F8-*LS&-+d-u3*_aLyqOVvD**IJd)%$*08+TdM>D)7ix@LM>pmsnYHuQ(e`*m zu;++n^Cmw+p5^4`YX8dYUs;woF66@4p!a(HK&CFpsv7?)DMuO|lH; ze18hR35cV@w>|{sTsg(3R&gfWhj@srRk=xbbSq0A*tr}q(r~QVGOYM zIdj8AhX+wp33kDh{{TwCKbZQ9UD1ADHAoHbN-&n?vrtOb{_02}7DOiWXKuZ*M2@Ng z=Dz13sz?dlLeV&iV5;Z7)wwwZ=^Uvt1!kG>FNPOY?GyTYiuvK|Ap^US1TkWr*$23~ z8h81Z3mM0Y12`-tu0bS!AOEb{V?0ZOAW=RqzO+VjyF&u@SF8F84NdUsl+#MiGiZ%5 zeRM(HqBjL;8I*Ud==}gOhll400hvK}^wG_sDs||8%TM=8+OI!4wR>Af1A`WDPY9-k^W_6Esf-LT5Ez}0203w`q2*|Jk-O+D$7l7419PckH8$Ov1_(b9H7$>2BbAwg!Q|mpR3?N$&Bh}P0(y|5cyln8T!N!Lubz)71 z5A~6HwrEA(*~RNrx9=&VKa8Tzk6moyAOfJtnlUJR69Wln@Ow7{%3togvl%3w5iZ@= zfGKZArvC}SUy)pYEstE-uwJusa<*Lo(h_JC#fG0t^`g!pg`y}!D-Kf>_6PXrM3e^R zv#=R9h3}PwG9ulZ$D{)F68?j)h&t9?zABu<9uOMnCiYB~Or9lbl4?|Sx49XYaAsw3 z;;~@>WVTv5!tJ{86HtvwRBVhuN1^z-i#?pnb)2h(?97*MYMzb`9;}1zjl>MtSn@{{ zr5kacR5km)YnirtudRC=?qDzg`#X>SN;`0*jp#1fhx`Z8_Kb8$MAGY?4zadbjv1FH z_w}nR3YM|#I~$_^z6#50xHIu$+0ikSq=ODe~jeWfakpR6uKI^eCXaw2-zCP*&3h#4382j z-9)t@#u(*Y9YJKUW^9pYpO?>GW)xinh9kb#J*Ht=;V+FVv5M_n3l;~y&LRAeA_z0G zIfX`2J;)}-O{^_k60Z#iq!nkp4OfWE=E@RRKA@72S6m;_-|~Hg9ZULgb3QxPGSM*J zWQAvC8gTnsbn?D9cB}-Bqa)MX7_Vmh=48yQ-@Omhr&Jlbzm5uiRBgOAS#RtDG~9yC z{7NDuU}OvRFV5mnQ)X~=P(IxRUfR1jWyvt4flom9CFPJL_*}K~*--D(U4S9%%{weV z+Rq_}>)yg!+Dzn+bI+gLWCW_GB-B&p?9%~UE?rY}^Z5SFG1#i=3 zn=rXg-d4kowSP(~&-tofNZngM{t7U`N(`O&gH3)7iY}{c*&5bE# z3hFn5OTrW)$8!EK z0RH;OK}t6msVRr&cXrJ6Cz78WXu%CPD{@;~Wy4SfjV-~7Wq$s56N+mWJ@lTC!2@P% zx}#G#?EcNO9_&Q&U(TkNHb%1v_dJxoYAa>(>ouuZ=ZMgBoLv@By1Q&3NJ%$4pM*-c zYh!`999p)k4RY4!=3u!rX(lk>JJLRGv`SxfnoH?$g!}~=Hg}zy;rNlmF5&AmRG`8! za_5V3pzX*)S*Y6)KeQaGt1zb(|@>I@bce(X{>R*lb-< z%S^GdHIm3qs+z(7ZTRoU zyZJ5tOm8fyFazF5K6OmI4$ilYH$q-;0DHX?0o<7v#9}L0&i2vEx!Z2i+;_e>%0fyx zCPrE4FRocnmTKP6{;v*Tbnk{xksrmwu5rsCpFRDa^J_&RviIjUpZ_IjHgdB zfTusWE1s4g7rv%H{w0^cK^5xw8FM>1^f-5GQcGT^0p=UMC}{W?nGIF}w>yGvToqiP zKqJu*XSg%e%VjFtr;W^~5`EhM+Y{*GnsqO>nIBJtenxTTbc^}AK)@%uhyE1*-MMf8 zC`v*fVFz#*{L6=F=iJC*tD7{;iMXe90VRJ`mZ|kgPj5n9#%PE>bVESMO^I^;ksUoA zESjq9wp0b^1IOtEfJxp>=RrD&mWy`?xi`rV4xBMpcJ1wLPzDx#k24Z!n;$DmIdJdb z<>gy8$PbL-WR4y2dpf4;Ixj=o?N-mG0Ov72=~n&)UVPUtq-e&k1B~-ZF#6|RZ1|R} zAZh$Cm++m?pz}Al^Z-?0J?xt)w{ z2AgWaX7x>Dzq!6W1EsBAZ`1Y8E=3yuJwP3nMW?#w#K~-xnPc1A|5ZGPknSh|m;f%c zQ+lP^QeOY|m>*Ag{EB3B(A0xje;J~bRlC<@OvkH}1=O-LUuCq(Z5H1DY{^F^?Xa>fPhlUb6m`GXn)s{xYNXpm^AU-{ z_+PRa4JuVf1hRq;9*=+dpgnaEX~{|G0S^hRM-@Sxh+-AXS=b*8jk8sFqm{%W`fK_^ zOxNbI=RR-Hq)x(}Rw>UnqNMo5+Z1mU7+>kKe}`@azrvr9q7&soN?U^RV3-S?(AUN1 zke}NJbUC>Md(HlWPfQHM03g44GT69M>ja;MX1wV36-^yBO0~=b)DWsIXWL3vODu$v zv51bX*cC#Hulo$y0dh3x0QFnR}ON$Szw3g5rYD^ z`Llv7&<5(IlCK%@L6bnW&)YetRfP;e5vvhKQHYHh;9<%&x-NT>;m0XnKRG*P1BYj_ zBM1sJ*t-L22WP@iK0X%qI`Whrv#-|&pt|I9NX9Has7FH+2F86Ot0K{ z-X)g~8qIv<5W|@S?wbs%7fXG>40?e1TL%FUn&}ex<<+3w4}-?xC=#wfCqtR@VLF)| zDNT7p*?M(?t(Mz-=S-X%oY~gzu}p^4|K{^snkttN3Cy3;9S0Krr^6c5BUo0^&aLnl z-oMNUv|d@mOWBs8w@%xhgDqG=IhHDapj3novdv(O|$ z5#5hxW490b!EP;`yY?%9v;jVsIZ)SyuQI^ z+keQRWW#;t2EPN=ALc|=W8HM{5z=2?&3U$reEJ>ow`~WUW_C&q?lhuxZEdV7uV*m{ zj`&G#(%1L5`J!OS2#-IP)<5~j>`$r1LX}i~_mGzqOX1z2v;deIjscGW%WPmgX=$XD zw4Xf}1F+O_N1A_I;IPf8K%RYGQov%rhCl*LJTq5Q!Ai+AP(*Tl-M z>G`FS)iX^S?Csni&x&tI;vyXg{;-zvTHfZeDxizD=Q2+#wXZYjx)6mD@q-mvggj*T}BmL>sk>E*(>H*_SjZmw`7!Y4W0t>pTwq{BEl2 z_^?~;qQ%^Jm#Ij3eh7z(d{(07qRYI~Iw>Aw7C_0HxC-1&E|18$baF&$nuxf95e={# zq5jcP$}sTXdT5SHdFB<6b?H%V-Qol+JhaWhQbn;n*uLMr_u&On@hRcqpAvPq^JGig zt#|zJEZ_vOzR^KYObD@s!tU8oBG6G*IW;6sQTZ$}UY-U7-z@dp!;b<)2wc?QY=bNm z&MM>&CjWy9jTP;378jdBDzi8?&3Bydy5Mw>>LByz2m(2<%BEjGt&b++Ua}Mstg-fQ z^YzKsjNjG$B676<mm2ASSlr7TZG56CkwFal2x!&b%uY!E8bG+URK(Z=|l(fC**JkfHa-ROCh zCJc&`3p1K4^&e~)sK#8WEr0n8#lDdbKbXPL_^j!7rZtawP*LBmJJvgA`7Y{6v22_i ze=9?F^m>RKMMX%KTf*oo8iC75-@1U@dk zfb^*>nRO0&h3Cufjd571$Qs18^bBi=F3O5h8lQ>?!^ey-3u}VO`t&BYtvPIwO-~kq zHi-y}OSy$e+C!6)T*rHZ*t#Ku_)gx`WFPlMi-5ni&PEwb^_u%&Nz(eK~<+?N8-q&Mnk(U7XB;Frv39x({aVBq7gcq{(R`y>Pa{9G`1P z7K0Rirhkz_i;|qvbUy-u4lNIzQYfhI=qUUpuqdymc1SZb*I5AF{U_&kxp;u41pI}X zulpz+IomW8)5(E2=VX-XbZK!V%+T_r8W0=_kYVX;*elO_S*Ej8Itepf&S~fYAN4IQaJs493}I;2!`PwdQ0PGkp?*V zz|0F3mUSRb_ltS6l@F}=n#FcKQH5bHm>aVb!59f?T;Ou6K_HJo76p=X^Tj#&OMnEp z<+4(35oqv3w_=av#l>Mh6^mVUf^I5-8X{_PNu zTyL%XW$3pSB6t{1Rbpse6PaI4u|ycF&xXCkS8O$knuKfZ;~43Wlt*GgJ#Ul_rBykx zSrlDLvMxr3gZaxZMA2f2G!UiKNc?PJ@cp$9-R?~`lB#}l9tqy&O8)Y z!S>{61q_(Ijx{N0D;e2V#{uN_=Uf0++Ncm^L9;`tFYZv`GBGeyTOuc6p9+9nqX}Yf zGda>M4pp{65HdGDdBI|}H2(+Tn$*-d8=+8ym~&RHCtO>Sc&d!wjk3UlEKYITz7Fpc%VttbzNtXQoE10B5E^IFGGX7s7A7_uOO zfo#4yis`4GFff#@47eE1@;aCaVW^_XfoF~r&}>gK6X4E9e~$p zteaSX`(6Pkw|G>Mii9IgFgsTU2gmAwcYEiFb1BF}5oEZ~#6!{sD5NfD zf!YcM|DB^Y3;3$oU`kB7RBOBBc~EGtK1${T@}z&9x41*Ky2SAEZ65)3?6kaJQu8Mj zahnci42C(Tp*0k;mcBvbVfTm5f=1^r$>UqKsEVhRB`lh#hbYxB)5SIhAM>9f+0~KR zvM(w6Gi4vm4KM2I&d43%*a|r)#Q~Qm{#(tUjWUS#NC?3A_Is`^6z_E*8UWJaki1V z|IC|oqdbwAaPBJKapR-E?W@Mz^8f6fFjK6z-~S^jrfC}6RVRm%F^R1#-4f_l#QXb z8{&)iL-ROOoqj=tpO|SOC4T1&K%*C%_K)<2)c#BP*>5nEU4eZ$+#4 zl?SYLJ1oW6CzS~D7BO(BHLsUfNS+m5sWZ$pD+K0`g|F`m-aT!{AmYKwld0fNhjk?A zfUqItCaorGwKq}5yqNM1+y3HnyS_G~11H|`!pI%N%zT|W!Zy4dZbcJtI6ozgcY}`y za)MFG>L|g+MF4bdkkUcxd{gu-E+2v+q9emqhV9M5{Ebc{-z;aZhXIkN6xzC!f)x<5 z5Dw{UP^~X(G{gW%yMMI<5Zp`sXS@PzI^$*wD^60Oi_WHI-LR^R8f@vHs<@~se!gg2 z_iXSjj@D(HT5%oLl-Hy6D9>3o$Fh!JAVxC7xi|T|-CA4K#w9GyQO_dp^a8~k0C3u# zqe06KbP$!z4-+!3ay+-74b|nDAg?f~`<%?(D(obH8Nm}vb~S2**kB%1P z0v1YhprF!;aTgK{758;LI-fC&60_P6Vy9xC;2HK*kJNMqgziM>dyQYxyY)H0ht%xm zPp_#sfMKYqm)wT014+5-Z+%*M5s*)}2!sDl_H4xMQU(&gfdX(-U5ow&@ICz` z;7bJiU#)}*GQJhJ07&xZ51jI>P@=F$xGa=+m|xe-k7E^mf;yTG9Pbso^MlJh05xv#;xRI$}s z3x5$pG5$7m#b@e+%6t;^&v+J-lko-E`ncX-c7QvquA@!rdE!g-!~Rap|TE1 z4oE`QyX#piUtp*s7o)_L5+;A=U9Aag&@nfgEV^I@@AT|RvQ#QdNo&;~)#75?=5?dm zt9>J2mvRd(6)z0KCq!mrjBt@SkD2!&xp)bFOKE>ryPghse5|rr2|R6;L*a?q z-xZShvyp87*OD(_6%u*!HQH|AN2@@QPCbFOL_-0S$dC@yWsx1BFSTyXiKgNVo}WVa zelp$oPDS)M5uxO_DWYA3D+c+{zHqu%*5FwPvb`B6;vOqAg*;}t*@(uwY)CR(;*ExyyVLLhgjb@egZJi&20-6L+tjUXar^9UsVF1bJ)H;UD-I?4!E5{f}A zkk|W%f2E;;>Jfwsu|r|Y$#90#Vmc0b;c;kn-gyT6W24jC*dRq}OgfrCjOx#(Hd1VSju)62F-Zf=3u%TQWLRT_KCcr;_ zm}g!BsTLLR>8_y9n6bw<83*YB^xXW9ZXAHpv5D^9CF?RBvBgfziJK*USsorwJT{p+ zRJ!%jRlxM~R=&fR`tWQAM1RxG?jwAR;fEE)mu=Z$7WA7F@eRfSRy=Es{v}!M^ zmZm1pD0PxiByBA5#kKj%%Uy6SzGV*xkQL~O^vm6Sr!XErtkVbuzfbnKSP~dAm#FH7 z6Tv;Q^RfO#?0=;e5n9lXp0a0+4c<`n?D9^H%Rp=Q{KxT#+i#FDil>TYmF-9do>L)Y zbDCH*aKPW%X-`jd^?A&Oyjxm=&anm+jxG1|T7O^25V>p1TVY@D>86rAa@Oan__9gJ zdqj5}zu}~+l;Q5|73hsJ3W#PT_8Ji#_GsSH>!~yVstHo;Sq7NMKoy0G41cWOZ{?mL zS;<0JsvHc^&da6IEJSMRamb9g87#+efx0EL0Cm4bd*UxiTm(^jLdb}EEMwn$yr?Ym z?k$b@&%(~5H zc^LIMBkTRioYLZ$J9?EAi;8NFcD@-ob-n}Na0u!k-_w~7B(dnLR#POnN!KjHh(U4DEDY*g;LJitRVbP8l9P~27&IH3U?-gj zXy-6O6ki_0=>VSqU{j)>E}5s~)c_mgl7qd^T~3bA*>n1tmd>myis;YipK>&?NN+Sf z3~}H<9FLg+Q6C+njvq^WTKK*!_La$ZGv6ZM;d7dZJ;n&ONN~Hu(^i-}Zfp*MY~+`o z?bOP8A&ILVX7TZ;X(r_|X{%8m{^|S+K=<4-REMm}i??W@i$H_B=QKl0wcv}^$kJp)DUcBL)3=}x$Fd>HOX}$XDYT_3U@(B=B@V&*#*XhYYW{0CI`91 zU;7IB(v?|4M`5p=e3E7tVS}iK#4IL~DjH z7s2>gaqx_0S5u3=HcH%MyY5K=OZv_9LWqo&EpOvg;L1i^pn~=l z2wo#Bli1GU>~4*KaoRoH3LuOE)F#1Vcjqs2dKGv*QAaQ0opoC}^N`-nB`cf1O+EAP zf_WjzD@f1~47W8@t&&gr4MA3sHQ?6DJFm4giq2-)qL z*`L6`$dRdU*L0JD7^WUhonTqTdd$K}{?07S>XQxTd)Xu+IuSm9_^UfVqW>qEFqxja zVSyn{S(Lo|>?s)A3Uc9ocKGh9SWg?S($zaKnxeQYS3z#=z6jvC#{yfw;ois}qm`%? zzClMu1>(%j&+GrW-%^?Hh3l{2_Kni0iXpP9G^gqUCNsv)^1Z{(BnX|mhO+0Q-yJJ! zc*XC}2&_Y(L%EN_w}VWIr|ToW`p`ijevl{NyPUN~sY>UD?x)XpmyP~lR8_9e*yb5G z#6E&IGME1lKpB&YEtTDy!#gyqAXZfg@I?{u!Y_?4o>MZn(DMH?4_I=wkrI3`!`DWC z*L;xhbm1s6i-Z}qET}DP2tk8%?T%*Jx?(D`=CY@v=gG3R0QkvS~nkORX!tE_G}9ZDLuV9d{g{&b49qyW3031EE%U8pik9 zJ!>RT3SqU#(8sV@Uml;|LGIu5G|ZyK`UFMYwABkEllQn(D`8utNdfdB68{f8o#JV< zF*0hb`pu!xGVkAMP@rMC+<2eO+DIzr5y#+uEUt9d1T0UjG@%mh7AREkml!nWeUiSK z+ZzU{zx9zil2j+Dswd2Uc3l}!#p$71HF#<>J-&a08(h^v7;nI`0~x8q+5 z-fPD!-couHV=(IQ67qT)0l~JdpmZawX`Q$yS>H@ zzCp~?j#ssDEjCNN=~u}j`?bY*tj$Y4vveBcT0Txdm%ia7!lH@yfzgyiF4cW+Xhnw) zu~H5W8ET(VYwV84c2x_@?m(ZxJ?0>Ezyu?dIW=D~26x$fy)DBvJDfJ)Qs&?~MCb|T z#N`pYo~ikFN0Uv#fZtftg+@Q~vigUaRt0JLwv9};lA@T>y)fUyfx77W2TmXUEW`m# zSBKaoz`aruIh*&qcU45)$mTh^YD}&mO_J{>;72qs#xGL#By7GBP1m#B=a$10<%MEs zym;#od_^qj|I*1i!$@@mSNcqcdeGUsQ}SYwwojKX(Z|i^7Ph4za%^#9*f0iYJrhCT zlq;#q`86fkcSsVC`@^K-&@)WeHlEt41NE<0`7;W+_heyozTC7^hZ)R~qI{=c$QZza z*ILrVHb_qBk~xN&+7P45e_S6RGF{phGbE#?oj z7))~h2LQ2w51&LlmDvHQ1m@iQtFojIh*5=};VbuTz)N<@htRL|86v4{#0iDx3`U;y$V+?w7HEX<0hXXgzr+ zX;;mWpqPupd@b=@oTZOA=BPQB4!)Vb#6{jve&z_R?P8}kJE|r58iEeilcR+B`~GWc z!8)-d_@2>}#z%o|z)6$z{rOaQyB0L++B`cKjamoW{20GSX0BzQSw?TT%?DTeY#2H| zVWK`8JfoNZLzwACXu&X=D9K`9v9FIIyVE)AC`BnTCLI#&`ny=W7A1uKZfi$o>qqKo zaGNVVXpOzlrcxH^qkE(!A&((Y^MfuB2pXYyo+{{}wn9LdKQTeMKx9nJSI)$ZU}qp% zyeqKg-w`f0UY&>`hZiX_(^f~gGeF|5!|Jhq!dkyErC%Uj*v;Y~r)5BZI6utVWK1Md+i!5kEL?F7qE2Z&&|Uv`uWmBwUkZ#dP6BnbFn^dSC> zrEVO_>yqdLzv10c+G3I4RMHwLbQo(oU2fxH2P0yb(c^*sS!QI{R+~+>WXb^XJg`5> zftuGl3m6#WbWj4#8IF8EzhkgMLb^azpV?>0FAykyVy1~Z1pg6ds7qg6v_14RMRz3h z5_40$lX|}Cdb#=7%0UB>r9qN=!Wz0xEye^|AcDHK+N;7>;r18@tz$D1+0%qrNI&nF z@i`>gf>&d&F@5Ys_1nslW-eY6%ntGa(AD;ReW;#1eM>S0nmAKrawRj=&imwQ`8c&b zkEZY?J&^|F*bDQw8#h~Th^m*MV5$TKmy&GJ0(sY7?GLzE+EvS>i4&91K#aNh6;&uD zr~9T_Rih%7<9567!|Ii=G)#3O}eO zS-SBAwgLfGK zz=?fJqCj#;F^Adw&=YAZb8c*d4rRlvvgd^VCoQI)R}EZU5zxg6-gOr2@lSKew~l?d z>YWDDbuFxeP(iSJLVVcr+wsniB$fH|y+~mx=Y$$%wH$xSj*R?BcPCqz=r%|h@dcxB?Lz*VhzhPEU%q1UFBN>^O?zZ=GuO2@;`RmZrQ z6dtJ2mJHn{-^i7@=q}trrE}&#RA~%B&9dm!jeL$(n?OayC|ok`Rz7D<9VI^S;d9iC zg&HMO<&=;`O~JK-WoFXeAD#3LysH1qS{oSa8C4tU*g~?!Alu7?=;J!QT-lLVqry1Y zIR?NQ%S=Tibw9Ft?@WP{I8}BOnMtPAl2IgY*7^ivvm?ltB&m8gKEUTdCuJ)3e+VPG zTNJm0^9o%#NlWVulD@@l8qx7jNTHN}@!_M8mLyv8t-Cop5o~0x1)5YoQBP?yAg>y) zd~S;E-)79OQkqp(!v5*1l(LgN(~0<(m!l~3z-DbfzE1lJSpbo8 zdCIaL*h!M9BuQ7SVhK~D3?fK4)V1rR0<5+tXkyA2P;_02=bEL zH!1oxBwk#Xcte*b5cUN=@H<7D-~CAG(H5%T_lP~E(wV)sb8QuS_Bw0&_u)6gES8+V zX>N*6fcX4mNc1ZgY^2Ho(uB0<+l}%xmC`O@x0Tj8SX1r#fqNem6T`az%|nG~3twjr zc}5fE72DOssSmKpSH&jX&sR)5VhV=pfb$t5fkxs^C zUS)7#9dHVAk3n(bzYEY+j6X1UiZb+^fpgY+K}R{q6i`rh(;tg}(bCNfhiG+K(}9D{ z88P=p8tm#cwU=2nYTPiVNEnB0IHdG;c6NsKEBY@57D{cv*SrD!)8qYmX8!o%MZOXB z9mW3XoiEPfBQtR7sShYCI3ePEU#C3C5(%QX-^!Y>I?BqgL47gidA9-VN$F zKiwDFZ!kUFBu+Q=y~J&Sw&hDmWr02Tl!~Oo_CsUGVyQHy(5;8}Vr!ZbEo^PU<3&6g z9d1yO6S|PJMzJQ_tz*i3m`P_Tm6Tg(bkUCI=e$15<2A=lLxqee2o(Nj?1pHxH_$^n z+g#AX>$~U_7}#{?`tq%7cO9FlqeTbFYPlFE0}i$(%_o}Suy+MZi5gI1AL?_kKzS#z zv6tDPUW$lmFWS@X?=&~w zpndLdT}^pr+~knBo7D*#vnCVf+dZ&NK`Pdplc~Xjq7vEJI|H&t5^bpikQHLbj~2_k zUE^!wGjaaEm)oiu|C@}p-KilAVcwD3o=FkIb)?KT1qL61+}Kf%2*$zAjRqf8tUPnc z=**I@!_9@Lj@$tJyFSN+ln-gkkj;e?GedV&6mTCCA#IS%awMo+VWzP9zL+vh-KJ*KP%)_`fJ2%Bc-qK$`F=--B z0~MZ*+X`Z9g|Df+(cO~ei?%@(3Dk)iPuV0sf0bM#ITYT47?9a3RbR7XnKnaD0OQ$*JRzNj~?XgFRs~FU8q} z*PP~MN$BpDDi}0_e@DPl-N&Df3YDu&FiE8li_Olvbhza4M@w?SroCc*(z^W3f(EXC z00#$m*UM?n3+8B#w!V*q89uC%SCh6b{0drPDcDCRt=-MnQPo?Yb^n_S{?)!A__VNG z07?G4>aQ}Mn<2+1wd4vM5niOhg+AL#KFdW#NwoP8Sxke^H