karrio-server 2025.5rc34__py3-none-any.whl → 2025.5rc36__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/server/VERSION +1 -1
- karrio/server/settings/apm.py +9 -2
- karrio/server/settings/base.py +13 -0
- karrio/server/settings/cache.py +21 -5
- karrio/server/settings/constance.py +29 -5
- karrio/server/settings/workers.py +110 -109
- karrio/server/static/karrio/carriers/teleship_icon.svg +3 -0
- karrio/server/static/karrio/js/karrio.js +358 -260
- karrio/server/static/karrio/js/karrio.js.map +1 -1
- {karrio_server-2025.5rc34.dist-info → karrio_server-2025.5rc36.dist-info}/METADATA +1 -1
- {karrio_server-2025.5rc34.dist-info → karrio_server-2025.5rc36.dist-info}/RECORD +14 -13
- {karrio_server-2025.5rc34.dist-info → karrio_server-2025.5rc36.dist-info}/WHEEL +0 -0
- {karrio_server-2025.5rc34.dist-info → karrio_server-2025.5rc36.dist-info}/entry_points.txt +0 -0
- {karrio_server-2025.5rc34.dist-info → karrio_server-2025.5rc36.dist-info}/top_level.txt +0 -0
karrio/server/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2025.
|
|
1
|
+
2025.5rc36
|
karrio/server/settings/apm.py
CHANGED
|
@@ -49,12 +49,19 @@ if SENTRY_DSN:
|
|
|
49
49
|
dsn=SENTRY_DSN,
|
|
50
50
|
integrations=integrations,
|
|
51
51
|
# Set traces_sample_rate to 1.0 to capture 100%
|
|
52
|
-
# of transactions for
|
|
53
|
-
# We recommend adjusting this value in production,
|
|
52
|
+
# of transactions for tracing.
|
|
54
53
|
traces_sample_rate=1.0,
|
|
54
|
+
# Set profile_session_sample_rate to 1.0 to profile 100%
|
|
55
|
+
# of profile sessions.
|
|
56
|
+
profile_session_sample_rate=1.0,
|
|
57
|
+
# Set profile_lifecycle to "trace" to automatically
|
|
58
|
+
# run the profiler on when there is an active transaction
|
|
59
|
+
profile_lifecycle="trace",
|
|
55
60
|
# If you wish to associate users to errors (assuming you are using
|
|
56
61
|
# django.contrib.auth) you may enable sending PII data.
|
|
57
62
|
send_default_pii=True,
|
|
63
|
+
# Enable sending logs to Sentry
|
|
64
|
+
enable_logs=True,
|
|
58
65
|
)
|
|
59
66
|
|
|
60
67
|
|
karrio/server/settings/base.py
CHANGED
|
@@ -67,6 +67,7 @@ CORS_ALLOW_HEADERS = list(default_headers) + [
|
|
|
67
67
|
# HTTPS configuration
|
|
68
68
|
if USE_HTTPS is True:
|
|
69
69
|
global SECURE_SSL_REDIRECT
|
|
70
|
+
global SECURE_REDIRECT_EXEMPT
|
|
70
71
|
global SECURE_PROXY_SSL_HEADER
|
|
71
72
|
global SESSION_COOKIE_SECURE
|
|
72
73
|
global SECURE_HSTS_SECONDS
|
|
@@ -75,6 +76,8 @@ if USE_HTTPS is True:
|
|
|
75
76
|
global SECURE_HSTS_PRELOAD
|
|
76
77
|
|
|
77
78
|
SECURE_SSL_REDIRECT = True
|
|
79
|
+
# Exempt health check endpoint from HTTPS redirect for Kubernetes probes
|
|
80
|
+
SECURE_REDIRECT_EXEMPT = [r'^status/$']
|
|
78
81
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
79
82
|
SESSION_COOKIE_SECURE = True
|
|
80
83
|
SECURE_HSTS_SECONDS = 1
|
|
@@ -385,6 +388,16 @@ AUTH_PASSWORD_VALIDATORS = [
|
|
|
385
388
|
AUTH_USER_MODEL = "user.User"
|
|
386
389
|
|
|
387
390
|
|
|
391
|
+
# Session configuration
|
|
392
|
+
# Use a unique session cookie name to prevent conflicts with other applications
|
|
393
|
+
# (e.g., ORY Kratos sessions in the shipping-app frontend)
|
|
394
|
+
SESSION_COOKIE_NAME = config("SESSION_COOKIE_NAME", default="karrio_sessionid")
|
|
395
|
+
SESSION_COOKIE_PATH = config("SESSION_COOKIE_PATH", default="/")
|
|
396
|
+
SESSION_COOKIE_HTTPONLY = True
|
|
397
|
+
SESSION_COOKIE_SAMESITE = config("SESSION_COOKIE_SAMESITE", default="Lax")
|
|
398
|
+
# SESSION_COOKIE_DOMAIN is intentionally not set to allow per-host cookies
|
|
399
|
+
|
|
400
|
+
|
|
388
401
|
# Internationalization
|
|
389
402
|
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
|
390
403
|
|
karrio/server/settings/cache.py
CHANGED
|
@@ -14,9 +14,9 @@ DETACHED_WORKER = config("DETACHED_WORKER", default=False, cast=bool)
|
|
|
14
14
|
# Detect if running as a worker process (via run_huey command)
|
|
15
15
|
IS_WORKER_PROCESS = any("run_huey" in arg for arg in sys.argv)
|
|
16
16
|
|
|
17
|
-
# Skip default Redis cache configuration
|
|
18
|
-
#
|
|
19
|
-
SKIP_DEFAULT_CACHE =
|
|
17
|
+
# Skip default Redis cache configuration only for worker processes
|
|
18
|
+
# API servers should use Redis cache even when DETACHED_WORKER is True
|
|
19
|
+
SKIP_DEFAULT_CACHE = IS_WORKER_PROCESS
|
|
20
20
|
|
|
21
21
|
# Redis configuration - REDIS_URL takes precedence and supersedes granular env vars
|
|
22
22
|
REDIS_URL = config("REDIS_URL", default=None)
|
|
@@ -60,8 +60,16 @@ else:
|
|
|
60
60
|
|
|
61
61
|
# Configure Django cache if Redis is available and not in worker mode
|
|
62
62
|
if REDIS_HOST is not None and not SKIP_DEFAULT_CACHE:
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
# Configure connection pool with max_connections to prevent exhaustion
|
|
64
|
+
# Default: 50 connections per process (2 Gunicorn workers = 100 total)
|
|
65
|
+
# Azure Redis Basic: 256 max connections total
|
|
66
|
+
REDIS_CACHE_MAX_CONNECTIONS = config(
|
|
67
|
+
"REDIS_CACHE_MAX_CONNECTIONS", default=50, cast=int
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
pool_kwargs = {"max_connections": REDIS_CACHE_MAX_CONNECTIONS}
|
|
71
|
+
if REDIS_SSL:
|
|
72
|
+
pool_kwargs["ssl_cert_reqs"] = None
|
|
65
73
|
|
|
66
74
|
CACHES = {
|
|
67
75
|
"default": {
|
|
@@ -78,6 +86,14 @@ if REDIS_HOST is not None and not SKIP_DEFAULT_CACHE:
|
|
|
78
86
|
"KEY_PREFIX": REDIS_PREFIX,
|
|
79
87
|
}
|
|
80
88
|
}
|
|
89
|
+
|
|
90
|
+
# Django cache health check uses the cache backend directly
|
|
91
|
+
# Only add Redis health check if REDIS_URL environment variable is set
|
|
92
|
+
# When using granular params, the cache check is sufficient
|
|
93
|
+
if config("REDIS_URL", default=None) is not None:
|
|
94
|
+
HEALTH_CHECK_APPS += ["health_check.contrib.redis"]
|
|
95
|
+
INSTALLED_APPS += ["health_check.contrib.redis"]
|
|
96
|
+
|
|
81
97
|
print(f"Redis cache connection initialized")
|
|
82
98
|
elif SKIP_DEFAULT_CACHE:
|
|
83
99
|
print(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Dynamic configuration editable on runtime powered by django-constance."""
|
|
2
2
|
|
|
3
3
|
from decouple import config
|
|
4
4
|
import karrio.references as ref
|
|
@@ -22,6 +22,7 @@ GOOGLE_CLOUD_API_KEY = config("GOOGLE_CLOUD_API_KEY", default="")
|
|
|
22
22
|
CANADAPOST_ADDRESS_COMPLETE_API_KEY = config(
|
|
23
23
|
"CANADAPOST_ADDRESS_COMPLETE_API_KEY", default=""
|
|
24
24
|
)
|
|
25
|
+
|
|
25
26
|
# data retention env in days
|
|
26
27
|
ORDER_DATA_RETENTION = config("ORDER_DATA_RETENTION", default=183, cast=int)
|
|
27
28
|
TRACKER_DATA_RETENTION = config("TRACKER_DATA_RETENTION", default=183, cast=int)
|
|
@@ -29,7 +30,9 @@ SHIPMENT_DATA_RETENTION = config("SHIPMENT_DATA_RETENTION", default=183, cast=in
|
|
|
29
30
|
API_LOGS_DATA_RETENTION = config("API_LOGS_DATA_RETENTION", default=92, cast=int)
|
|
30
31
|
|
|
31
32
|
# registry config
|
|
32
|
-
ENABLE_ALL_PLUGINS_BY_DEFAULT = config(
|
|
33
|
+
ENABLE_ALL_PLUGINS_BY_DEFAULT = config(
|
|
34
|
+
"ENABLE_ALL_PLUGINS_BY_DEFAULT", default=True if base.DEBUG else False, cast=bool
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
# Create feature flags config only for modules that exist
|
|
35
38
|
FEATURE_FLAGS_CONFIG = {
|
|
@@ -161,8 +164,21 @@ PLUGIN_REGISTRY = {
|
|
|
161
164
|
config(f"{ext.upper()}_ENABLED", default=True, cast=bool),
|
|
162
165
|
f"{metadata.get('label')} plugin",
|
|
163
166
|
bool,
|
|
164
|
-
)
|
|
165
|
-
|
|
167
|
+
)
|
|
168
|
+
for ext, metadata in ref.PLUGIN_METADATA.items()
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Collect plugin system configs from ref.SYSTEM_CONFIGS
|
|
173
|
+
# Format: Dict[str, Tuple[default_value, description, type]]
|
|
174
|
+
PLUGIN_SYSTEM_CONFIG = {
|
|
175
|
+
key: (config(key, default=default_value, cast=value_type), description, value_type)
|
|
176
|
+
for key, (default_value, description, value_type) in ref.SYSTEM_CONFIGS.items()
|
|
177
|
+
}
|
|
178
|
+
PLUGIN_SYSTEM_CONFIG_FIELDSETS = {
|
|
179
|
+
f"{metadata.get('label')} Config": tuple(metadata.get("system_config", {}).keys())
|
|
180
|
+
for _, metadata in ref.PLUGIN_METADATA.items()
|
|
181
|
+
if metadata.get("system_config")
|
|
166
182
|
}
|
|
167
183
|
|
|
168
184
|
|
|
@@ -218,6 +234,7 @@ CONSTANCE_CONFIG = {
|
|
|
218
234
|
),
|
|
219
235
|
**{k: v for k, v in FEATURE_FLAGS_CONFIG.items() if v is not None},
|
|
220
236
|
**PLUGIN_REGISTRY,
|
|
237
|
+
**PLUGIN_SYSTEM_CONFIG,
|
|
221
238
|
}
|
|
222
239
|
|
|
223
240
|
CONSTANCE_CONFIG_FIELDSETS = {
|
|
@@ -241,5 +258,12 @@ CONSTANCE_CONFIG_FIELDSETS = {
|
|
|
241
258
|
),
|
|
242
259
|
"Feature Flags": tuple(FEATURE_FLAGS_FIELDSET),
|
|
243
260
|
"Registry Config": ("ENABLE_ALL_PLUGINS_BY_DEFAULT",),
|
|
244
|
-
"Registry Plugins": tuple(
|
|
261
|
+
"Registry Plugins": tuple(
|
|
262
|
+
[
|
|
263
|
+
k
|
|
264
|
+
for k in PLUGIN_REGISTRY.keys()
|
|
265
|
+
if not k in ("ENABLE_ALL_PLUGINS_BY_DEFAULT",)
|
|
266
|
+
]
|
|
267
|
+
),
|
|
268
|
+
**PLUGIN_SYSTEM_CONFIG_FIELDSETS,
|
|
245
269
|
}
|
|
@@ -22,117 +22,118 @@ WORKER_IMMEDIATE_MODE = decouple.config(
|
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
# Detect if running as a worker process (via run_huey command)
|
|
25
|
-
# Workers always need Huey configured regardless of DETACHED_WORKER setting
|
|
26
25
|
IS_WORKER_PROCESS = any("run_huey" in arg for arg in sys.argv)
|
|
27
26
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# Parse REDIS_URL or construct from individual parameters
|
|
41
|
-
if REDIS_URL is not None:
|
|
42
|
-
from urllib.parse import urlparse
|
|
43
|
-
|
|
44
|
-
parsed = urlparse(REDIS_URL)
|
|
45
|
-
|
|
46
|
-
# Extract values from REDIS_URL (these supersede granular env vars)
|
|
47
|
-
REDIS_HOST = parsed.hostname
|
|
48
|
-
REDIS_PORT = parsed.port or 6379
|
|
49
|
-
REDIS_USERNAME = parsed.username or "default"
|
|
50
|
-
REDIS_PASSWORD = parsed.password
|
|
51
|
-
|
|
52
|
-
# Determine SSL from URL scheme (rediss:// means SSL is enabled)
|
|
53
|
-
REDIS_SCHEME = (
|
|
54
|
-
parsed.scheme if parsed.scheme in ("redis", "rediss") else "redis"
|
|
55
|
-
)
|
|
56
|
-
REDIS_SSL = REDIS_SCHEME == "rediss"
|
|
57
|
-
|
|
58
|
-
else:
|
|
59
|
-
# Fall back to individual parameters
|
|
60
|
-
REDIS_HOST = decouple.config("REDIS_HOST", default=None)
|
|
61
|
-
REDIS_PORT = decouple.config("REDIS_PORT", default=None)
|
|
62
|
-
REDIS_PASSWORD = decouple.config("REDIS_PASSWORD", default=None)
|
|
63
|
-
REDIS_USERNAME = decouple.config("REDIS_USERNAME", default="default")
|
|
64
|
-
REDIS_SSL = decouple.config("REDIS_SSL", default=False, cast=bool)
|
|
65
|
-
|
|
66
|
-
# Configure HUEY based on available Redis configuration
|
|
67
|
-
if REDIS_HOST is not None:
|
|
68
|
-
# Calculate max connections based on environment
|
|
69
|
-
# Each worker replica needs: (workers_per_replica + 1 scheduler) connections
|
|
70
|
-
# Formula: (worker_replicas * (threads_per_worker + 1)) + api_connections + buffer
|
|
71
|
-
# Example: 100 connections = (5 replicas * (8 workers + 1 scheduler)) + 40 API + 15 buffer
|
|
72
|
-
REDIS_MAX_CONNECTIONS = decouple.config(
|
|
73
|
-
"REDIS_MAX_CONNECTIONS", default=100, cast=int
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Connection pool configuration with timeouts
|
|
77
|
-
# Use BlockingConnectionPool to wait for available connections instead of failing immediately
|
|
78
|
-
pool_kwargs = {
|
|
79
|
-
"host": REDIS_HOST,
|
|
80
|
-
"port": REDIS_PORT,
|
|
81
|
-
"max_connections": REDIS_MAX_CONNECTIONS,
|
|
82
|
-
"timeout": 20, # Wait up to 20 seconds for an available connection
|
|
83
|
-
# Timeout settings to prevent hung connections
|
|
84
|
-
"socket_timeout": 10, # Command execution timeout (seconds)
|
|
85
|
-
"socket_connect_timeout": 10, # Connection establishment timeout (seconds)
|
|
86
|
-
# Keep connections alive to prevent closure by firewalls/load balancers
|
|
87
|
-
"socket_keepalive": True,
|
|
88
|
-
# Retry on transient failures
|
|
89
|
-
"retry_on_timeout": True,
|
|
90
|
-
}
|
|
27
|
+
# Always configure Huey for both API servers and workers
|
|
28
|
+
# API servers need to enqueue tasks even when DETACHED_WORKER=True
|
|
29
|
+
# Only the worker pods will consume tasks
|
|
30
|
+
# Redis configuration - REDIS_URL takes precedence and supersedes granular env vars
|
|
31
|
+
REDIS_URL = decouple.config("REDIS_URL", default=None)
|
|
32
|
+
|
|
33
|
+
# Parse REDIS_URL or construct from individual parameters
|
|
34
|
+
if REDIS_URL is not None:
|
|
35
|
+
from urllib.parse import urlparse
|
|
36
|
+
|
|
37
|
+
parsed = urlparse(REDIS_URL)
|
|
91
38
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
settings
|
|
130
|
-
|
|
131
|
-
|
|
39
|
+
# Extract values from REDIS_URL (these supersede granular env vars)
|
|
40
|
+
REDIS_HOST = parsed.hostname
|
|
41
|
+
REDIS_PORT = parsed.port or 6379
|
|
42
|
+
REDIS_USERNAME = parsed.username or "default"
|
|
43
|
+
REDIS_PASSWORD = parsed.password
|
|
44
|
+
|
|
45
|
+
# Determine SSL from URL scheme (rediss:// means SSL is enabled)
|
|
46
|
+
REDIS_SCHEME = (
|
|
47
|
+
parsed.scheme if parsed.scheme in ("redis", "rediss") else "redis"
|
|
48
|
+
)
|
|
49
|
+
REDIS_SSL = REDIS_SCHEME == "rediss"
|
|
50
|
+
|
|
51
|
+
else:
|
|
52
|
+
# Fall back to individual parameters
|
|
53
|
+
REDIS_HOST = decouple.config("REDIS_HOST", default=None)
|
|
54
|
+
REDIS_PORT = decouple.config("REDIS_PORT", default=None)
|
|
55
|
+
REDIS_PASSWORD = decouple.config("REDIS_PASSWORD", default=None)
|
|
56
|
+
REDIS_USERNAME = decouple.config("REDIS_USERNAME", default="default")
|
|
57
|
+
REDIS_SSL = decouple.config("REDIS_SSL", default=False, cast=bool)
|
|
58
|
+
|
|
59
|
+
# Configure HUEY based on available Redis configuration
|
|
60
|
+
if REDIS_HOST is not None:
|
|
61
|
+
# Calculate max connections based on environment
|
|
62
|
+
# Each worker replica needs: (workers_per_replica + 1 scheduler) connections
|
|
63
|
+
# Formula: (worker_replicas * (threads_per_worker + 1)) + api_connections + buffer
|
|
64
|
+
# Example: 100 connections = (5 replicas * (8 workers + 1 scheduler)) + 40 API + 15 buffer
|
|
65
|
+
REDIS_MAX_CONNECTIONS = decouple.config(
|
|
66
|
+
"REDIS_MAX_CONNECTIONS", default=100, cast=int
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Connection pool configuration with timeouts
|
|
70
|
+
# Use BlockingConnectionPool to wait for available connections instead of failing immediately
|
|
71
|
+
pool_kwargs = {
|
|
72
|
+
"host": REDIS_HOST,
|
|
73
|
+
"port": REDIS_PORT,
|
|
74
|
+
"max_connections": REDIS_MAX_CONNECTIONS,
|
|
75
|
+
"timeout": 20, # Wait up to 20 seconds for an available connection
|
|
76
|
+
# Timeout settings to prevent hung connections
|
|
77
|
+
"socket_timeout": 10, # Command execution timeout (seconds)
|
|
78
|
+
"socket_connect_timeout": 10, # Connection establishment timeout (seconds)
|
|
79
|
+
# Keep connections alive to prevent closure by firewalls/load balancers
|
|
80
|
+
"socket_keepalive": True,
|
|
81
|
+
# Retry on transient failures
|
|
82
|
+
"retry_on_timeout": True,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Add TCP keepalive options if available (Linux/Unix only)
|
|
86
|
+
try:
|
|
87
|
+
pool_kwargs["socket_keepalive_options"] = {
|
|
88
|
+
socket.TCP_KEEPIDLE: 60, # Start keepalive after 60s idle
|
|
89
|
+
socket.TCP_KEEPINTVL: 10, # Keepalive interval
|
|
90
|
+
socket.TCP_KEEPCNT: 3, # Keepalive probes before timeout
|
|
132
91
|
}
|
|
92
|
+
except AttributeError:
|
|
93
|
+
# TCP keepalive constants not available on this platform
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
# Add authentication if provided
|
|
97
|
+
if REDIS_PASSWORD:
|
|
98
|
+
pool_kwargs["password"] = REDIS_PASSWORD
|
|
99
|
+
if REDIS_USERNAME:
|
|
100
|
+
pool_kwargs["username"] = REDIS_USERNAME
|
|
101
|
+
|
|
102
|
+
# Add SSL/TLS configuration if enabled
|
|
103
|
+
if REDIS_SSL:
|
|
104
|
+
# Use SSLConnection class for SSL/TLS connections
|
|
105
|
+
pool_kwargs["connection_class"] = redis.SSLConnection
|
|
106
|
+
pool_kwargs["ssl_cert_reqs"] = None # For Azure Redis compatibility
|
|
107
|
+
|
|
108
|
+
# Use BlockingConnectionPool to wait for connections instead of raising errors immediately
|
|
109
|
+
pool = redis.BlockingConnectionPool(**pool_kwargs)
|
|
110
|
+
|
|
111
|
+
HUEY = huey.RedisHuey(
|
|
112
|
+
"default",
|
|
113
|
+
connection_pool=pool,
|
|
114
|
+
**({"immediate": WORKER_IMMEDIATE_MODE} if WORKER_IMMEDIATE_MODE else {}),
|
|
115
|
+
)
|
|
133
116
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
117
|
+
else:
|
|
118
|
+
# No Redis configured, use SQLite
|
|
119
|
+
WORKER_DB_DIR = decouple.config("WORKER_DB_DIR", default=settings.WORK_DIR)
|
|
120
|
+
WORKER_DB_FILE_NAME = os.path.join(WORKER_DB_DIR, "tasks.sqlite3")
|
|
121
|
+
|
|
122
|
+
settings.DATABASES["workers"] = {
|
|
123
|
+
"NAME": WORKER_DB_FILE_NAME,
|
|
124
|
+
"ENGINE": "django.db.backends.sqlite3",
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# SQLite-specific Huey configuration
|
|
128
|
+
# WAL mode (Write-Ahead Logging) enables better concurrency for multiple workers
|
|
129
|
+
# Increased timeout helps handle lock contention under concurrent access
|
|
130
|
+
HUEY = huey.SqliteHuey(
|
|
131
|
+
name="default",
|
|
132
|
+
filename=WORKER_DB_FILE_NAME,
|
|
133
|
+
# Storage-specific kwargs for better concurrent access handling
|
|
134
|
+
journal_mode="wal", # Enable Write-Ahead Logging for better concurrency
|
|
135
|
+
timeout=30, # Increase timeout to 30s to handle lock contention with multiple workers
|
|
136
|
+
cache_mb=16, # Increase cache size for better performance (default: 8MB)
|
|
137
|
+
fsync=False, # Disable forced fsync for better performance (default: False)
|
|
138
|
+
**({"immediate": WORKER_IMMEDIATE_MODE} if WORKER_IMMEDIATE_MODE else {}),
|
|
139
|
+
)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1200" height="1200" xml:space="preserve" version="1.1" viewBox="0 0 1200 1200">
|
|
2
|
+
<image width="1200" height="1200" xlink:href="data:image/webp;base64,UklGRkBeAABXRUJQVlA4WAoAAAAoAAAArwQArwQASUNDUKgBAAAAAAGobGNtcwIQAABtbnRyUkdCIFhZWiAH3AABABkAAwApADlhY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAF9jcHJ0AAABTAAAAAx3dHB0AAABWAAAABRyWFlaAAABbAAAABRnWFlaAAABgAAAABRiWFlaAAABlAAAABRyVFJDAAABDAAAAEBnVFJDAAABDAAAAEBiVFJDAAABDAAAAEBkZXNjAAAAAAAAAAVjMmNpAAAAAAAAAAAAAAAAY3VydgAAAAAAAAAaAAAAywHJA2MFkghrC/YQPxVRGzQh8SmQMhg7kkYFUXdd7WtwegWJsZp8rGm/fdPD6TD//3RleHQAAAAAQ0MwAFhZWiAAAAAAAAD21gABAAAAANMtWFlaIAAAAAAAAG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAAAAAAAAAkoAAAD4QAALbPVlA4ILBbAABwkQKdASqwBLAEPlEok0YjoqIhIzkYaHAKCWdu8pa3/HgWADn/2dy5n7R0H13r37DeGfpP7d+7/tmWB+4f2f/Hf8L/A/t397P93xh7i8vnqj85e4X0P/wz+z/s3/8/kR/gn8L/vH8w/2X7H95P+++mT92PXo9cf/y9Nf0//Wm6EX/0fuX///lw/if+T/bf///MF/Cv6z//9ZQ+F/2H/N/3D/E+RX9h/xf5M/1b94vQh9J/f/77+zH9f58Pv/gd/L/wz++/v3o53l/kv7n+zvsC/hX8R/t39P/xH62+9H872tWkf7n9k/YI9cfvP/99Wqdz+Mf8vUb/8vXvvyv9/Qw+GH8x9Rf+bhtSxICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBIBjg6Z5T//d8u0lpSjI+oPsJf7JYkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICP0iXpaQtSP1HLMCImbbpRGHdJoCDfJxMjAqNPCt49A9oEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJAR+ZkeTo+Ob+Vp/kCfuVkxIR2UGodFoMx3c5BPZBujyckaHGJLR08vueEw6re6TBiQEgJASAkBICQEgJASAkBICQEgJARk/KCvci03/VdZczFTPq6MQBaBy5rSTVu98W8UwKjC+HbmPoMY4pP5ukwYkBICQEgJASAkBICQEgJASAkBICQEgI/MBcDVc2e1lRv5mgRH4VOXy15IaZHFoK3AjUdiXE3a9yE9dOYJKvEcc+Mc+6TBiQEgJASAkBICQEgJASAkBICQEgJAM7SovI2Xf/zxMQRHgr61u2V0gOOZstQDpMGzgHUEUn+aZ6ECgcLIFBluUdxG4BmEw6re6TBiQEgJASAkBICQEgJASAkBGct6QOfysx0hsssPuf/zoFHjpSsTpMGJASg2a9Ij4XCEImo+9pE04bwLmgZAOkwYkBICQEgJASAkBICQEgJASAkA//t38WxrCHWCeFtk4ZnSU1HukwYkBH464Gl+l1IUOEGxYykBICQEgJASAkBICQEgJASAkBICQEgJChkXsEtJgvGiK2C0qGNUeo4OuKDoSPxzPdJgxGTAf/N/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rYOM+j5pFezAPOj7yPYSNABfJkWtS7Y6ARghxaMt8i3v0z3SX/QoOwpkIItNoh9j75TUzUpEyzkf6q4a0K/uMF4ZIv8fq9NEq1K1b3mpTDqt7pMGJASAkBICQEgJARlZHwBhMR7pt6cP/BRcYp79WxlsyyIu44gSmOH8tqpSY1RZbvSFIUv6T+u5rq2MuqVrMTBiQEgJASAkBICQEgJASAkBICQoZKpwxICM0KDr7OUmWech82lsz7w6re6TBiQEgJASAkBICQEgJASAZhcXq/bIapgPpRu4wJkZSN5QY1elhupmXkEJLDtHzpvr+GEuaTBiQEgJASAkBICQEgJASAkBICQEgIz5CMpOtfej7V2EE63iGMaz/475fBAR+gswe/f4dvjC+ZUsoPh/khjQbVR6IhWbXbJxATDqt7pMGJASAkBICQEgJASAkBICQEgIxtXSZrM6Tc0UyEiZ3GPEYK7ZpjjmtwswaI6nCydisq1AA+l0v3UCD9QERkFqOr6XOhwGnLJYkBICQEgJASAkBICQEgJASAkBICQEgI/JruwQEb3eNanvwZKO8miuvSM+swfaxCpCpLrHcMLTECRf1UHNzFmkNFz3bTIy2Z94dVvdJgxICQEgJASAkBICQEgJAMc8mt27v7/WYOGNezNtwIWFU1TZag6oYWFu0T7cdz07jI02vooRZ7i4bf/pONB+KD+8Oq3ukwYkBICQEgJASAkBICQEgJASAkBICMrSYbYv4EnIwxnu1kvS4jSG0nCqpaS2qWsAYGodUv96j66iV7cfNEQJd/eHVb3SYMSAkBICQEgJASAkBICQEgJASAkBICQJx1Fx8pF/+jF/mBmuTjDAIZYRXfvPIM7w1/HU9bmf5hQWZ94dVvdJgxICQEgJASAkBICQEgJASAkBICQEgJARvEkJDMSsFdllWvqGaPpt394dVvdJgxICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgJASAkBICQEgFwAA/v/UaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3StT/svw7++aWgjxSstJ6VUQkjOEp1PYB5BJGRuoH8XidJ33IwbksoMDMPQl4xLnkKybJmQWe323cKPlr83F0zcLfkJl0ElteH28tGmDtUATOKtmPMRtXOj51+U9iWn4DjpoAAAEllZr2+cITOZyfk4KsL7z0FraE95jHTVPSwg5jEPTC4xm/eu6syXDIVenr7SIBH76rz4jFFtLKNo1j2odjVJmD1bWLI4tIhrFSH/RyyQvnNAtgUlZx/A+kP5NIOlSdN35/o8R9amnFfl1aFIfuNKKOZO93xcfk82JcRSmH8OOD5opqpoHiSWyPwg/mr1jzbyFCB+7DC5JVWdcM18aexRkPMJmlEDxyMtuZmF0x+b9lYkPRvdk4YgMfP6v4+5bGMMwOWerTSITyYG3uviS6RNSP8PNc+DW52sEVkeSguuAug75Th4ESgAAAUJXLMhvoG07ctobTAQvVRdXZf3g0G8LS1uJeJVQNYX0wZE0hmTwybljbjHcAMQ1jtIgNYhYQFV+YJINHGyuVgUBikgY9wtJkF8Y09jcrxf4r1RmEm49bYWVnDUgFWANyhRrn9MU5lfv58aoqEoRzF+qPfEEqC4JY35IoWbm8BBRbL3r1ybx0Llp+ZSh5LyF7GJQGJcICFktjae+iU266tlmbPnMwmVyPlZNFqgJVN/35CEvuSii74u+b77wxlINIPAvuJUWg8VCmUlM5t8dLAEM43DWmBDSWHJW7SlzhoQgjxIfFo7cb+WCFOT29Bw4M+HsA5yVbGhMv5cEliDjYtBejg6bExrei/1ZcfAAADmIHpc3tPLVvDMFoC2tsaKcFj3av6QSCMGAEKzMixJSFOv8dI4BfiRdzBVU/0rMmvdWkC69MTsWN1zRL+R9P8/6iLuE62//ZiSdoyoj8xhNp1QRyJCzP7Bxn0AB7QtScPwsYqfXxsKN++LGwYzFfYVRPXDb2CGp+IQIIjKwZOH5JNBvk67/hDotceyvcVG282Iih+4YB5rCEDHBs5SyRsGaosJ5vut8a67+hsIRC2QACTrHxzd3z/vV+GsWX6znCTJr1nNRaCYGLlt6ro31KdPztt6vtfTAgG6rnyRHBGfbs3+eIn0noWI856xbKuZVXBfdWUdMolYFDI8bgZldlo8H1loc3NpyPXcvigAAAkn6iu3GpWuTeEZCWUHiziJxWbw3h8mnAYfthYSmx6X77viGw5Loq3Ebq2XTSWuyJUIaBcL5yo9diJ/x6X56v/tadX4PAFsKXVxYBdeP+5OfiB+YN74sTLufjxqM8xghTnPxwOcPsQG1AOs6GZSkc3/EcYpTAIK23DMOHwS+REBbOYBSaEhPNdZ62nxDXsnc1h3i4ACDawq7Sh5SyGXAGxo6WmtcpAlHOPygHaeqnbujCvk49g+OVORfNSO6ffpfjgE736Hf4gWsqmY9KMmMj0IUbLuxvB0PdceIuqQhDIs8ehIo5uMPwCJM5kMYKSGxTEeCRx/9D3Fq2HOmI9eP0NQAAFEW1Xaqmrv98IJxO6e82nbMBT92Fghmvifao3pZYyZDD/yAoP98Er1HIhRMT6AreEOEhBGehgY3224jjEAnW0HAJ9k3ogZILOkzgA5utwXRtl+KZpE0JjsZTi+VUgvDBWAdKkIs/NwXSvingAndK9UTpceeOkdaW8aifhD1M2xRJXnFKEW3TbMLk13thVqu+kCulEGmfcAPjxBAsAc/9oaCkrXkYiSg4sXxRCt6w+ZBSb5vknk9+MOv+yOdS2aSJc7iYhypTkmG2n3Zx6OF88bvr986xG9sRgalJ3zJZzjL9k9uX/GLfwyMJF7Zkwql/jbpaDIRYfLvfM3G/0qXOMsxmiV0PDS52jAABA7DgXbMZ2mrgsMBj79ClVeSe0z6uR90yKrIp17MojSCXEvQ8O7RDdRC22bgK7Taq+hh6D9pSkZKC6KYWrKWKKPcXcDat0XsMQo86hEuUauDyh0Lrub4vlqCm6S3PiE5gyLslNxKW3UrZkpg7XqL7lG/OfKijSejIdZGw5aRi+kPzAA/1sAVtaXF8F3p6/wVBAElcTnITIvdMZhyiE9fFJhMQgA+ysVjyjyiNVUbLQTuB8FTxJrsSh0zVydMONVk+sxFzlEyqoguTyHFYq46HdvN8AQyxJO0PgFg79rm9zb6KRuKeNFOEArdMZx5T1HDSHQAAY29CpbJNFocmWGBLYJzs4qwNgrWEvbpYAe0i1iEpIOWtlhIoov/DQwRDLwYsPbpmMUwMLhakO4qoT4cGX8RNLmmdmAEAJYnniXDkqCB9o5ZmKSV7kh8mbiIwq/5hk3hX0kILEyki734iWEAn7pzrxtW4rrrj7t24fewGvBMat2aCoNKZ6qMAuz1af5jV4b83Z6QNWblgAISMgyRZ0QLuQ+cJ4aipe/pXcQ4bOM0OR/OQIn8YFtBFF0uzDB/m9mDCY6jREJBgAAU5ekZBf8CCzh7W4EvCtfn3e8f5ehc4uU3pb9DIIlg28YU8jAJ89keRQXdcxasNMYPxI8Kbk/6RWPzpHdmrMhuYj1S7h3mkRm3PCv94KJoiu+EynI2ZtHk3RlcUPxrLiW7RhTeC4ZNzTfImZJ+0xwnhO+kVMTrpNIw5oXZLfQhaTOXBbFoPc1RD4oCC6HLomFQUKrhRzE9SLzaW4qHo9gXj2xLt/7YECbs8M1lmF0n6AQsOGeh61b1F4Ag2AsHuvFUzoi+S8pPcsJiOq9xUcPUf71sis56pe2gfWOAdMTtva/Z9h0ClY7Iag4CrBSXxgT5QoNK0ENTEVrbtJiuF+IWJmCuHu345qIWwYThvwmnLV3yrfxOl/cV+gTCKOQxWqFO3bxF6Ji9khw0wFmLwAACeNPYW0ikERJNGHtBmLF0ZeojInTgAPkeXs+QxBJHaqYSLH5yp430MYhMogLjopc1nYpBiPWh2aFxJQTDZIK8prR5BOZ2IKBEcwgzIwoI6xYH3eHg/sVlJovHCK3VbPMLfQb6NuFrSlPd0/MAXFQbem+huOuJjmpeLYWcR/q4WD/57kkb9Y+PT7U2OTCY40MTPU9rsNPx0iW2H3KtodPtGI8WRXXOJvhjJH5Buv+uQmvQPHBb1WYpufaqXYFUMSeXie76GkqFgEBshprLbBtJre3/XA8kJPJ9F0pYvAXWEObdW2sEg8WjN/WrMe70bA8JQk40iY5dGoaR40SsKRhWZzWFi1tYskA/JstC50n5GTUZy5ZQDIX1LVoQsAriWrLe8pox5Tcp97upo912pLlzy5KLwiyBPNiB4IOUx1IVtEjo1LrpSO3p9ujoGsJph+HgLQDoDFkMp02JHcMfaNKG3g7Ior0sg14eluLIsxlA0QQwhKARfyoRBatgVAHPD0m4tRPfM/tH1kdfG2VGi3cDPAGGksmSFzOq70oN1UnIJOTIzhuHr7fxA1D5FY1t1eCL4ZlWYrBS6aG/Z+oskxGtIqduIWquhiaK6vNpBUZKSTy1fKHmv3omeVkSKu7bAAtnJNBdcxROelHUQyQN+Nq9pL7Yj0tbF14YfDWNSZ7IAuXuNSQUED7afAH7nQj09aK8rM7nqVRDa7d4sg0b48g7WB0IIDF3pKGEyguqlTEVsThJMSLFIB9laNUi0W9WqcPO3kjnO0aE8fsS+U80TpQjF/68jwnjOoYDnQOi+PSuqIabtjdQD1XFXPT1phA9vuGCOPRaYsNP82HyG/RWyHlCUfwMg+29v6+J+dt0fH1cg790W3jEjoTnzAzXSSgWz+wq2AbLVAFhuuLyGYjvlmvukh3EWtZlJrcIauYOAW6zrtPkl3MVPGjRQnRtU1MBAyzJ7bmX7B7qXXUyoIuYg+9BKYRUFrlyD2jiQewZGscjIAhUfO1c4nIO9BXWGCitkAORuyRUNwq3+4av2q5tCljLjUX1bJ25uWeC4CPThnYqHgIe0tiCmwzH1KKze3f5MHEjdBK5jW32ne8mm5VXUURTCSas4kxQ/+jS+gbQuDYqv1WUvOqeLLQYvUCi4uZh99RQ8KjuAcLnopcTWvNSXmA5Fw+wEdF8lhcv1n1xk3AvlxljSsvRXq8qIAhcce58rCxciJqZKDrHIFmK2inHUO0/YazI2qTTurWMuB2Jeq78MJaANiinDJhXN5EeM8w5GwO9SNUhef+kL4xWDk6L7GAC0koYrQy5vu1wLaKHkz7M1Pv3PqNOS3reb0w/Aj7bfiCkkFtIC3QVgPqQQjBCKR7eascK1NP1saocMlfvm8o5BUZnGNRfrV8clHRs9+tlyEQrETzQlTyS5N0Qx8zfCgjHBfylpBRsMEwkkmLmiwV7Nrhcrg9Xd1Q+K99NjQrgXiz3u9x6+piyzwObFhmCHtq0Ow9qZn5nXVU6tx89IR/cFXnlBfsYWbSnn1d0uV3qgm7fvKNJhZBGJQT/BYCzBNytU8+EZstnhTxhtRYV6gBL+eemeTkmwKs/99owICeJvxaqLhy8lVC1r+vn2Y2S2O/LJBHj0AOslamqPN+Um7lK7DLmjF/BV8Ez9i8gSr9S2eHwLTHpUBiqRFj6igQQsQHOEUXPdfrDaz/CaXHeXKiq7N24eex2R9Pfj+hRXyfGFnZ6UuWbdEGRZUZ2z885K0oGjbd8rIHNBOYr0XxySp24DM0e8CjHziXtOVrzudevvjdk1waOTy6MqXyEDmD1H6R166hO1khNdstcVw71/lHdTe3XKK/JVBGtaCmMzMUAvdqAhFNCgQ4CtACjx3ZX21i2GF6nYd5ra5V3kLrRyJIxqdvzxwl4E028/+yM8O641pp/QTG6Gc/HnnsPhU4uzwGhgvIiogo5bzgxnGiYxUNxhtfdq8vKKPHUhWoUAqzUsxNVANrfmST4uK4I/zIK/khEjGY6qW9plUmt4gtfgk5fcEp2kh0+I6+m7SD8DCV0p+azRda2brNwP6OGQgaeOTnb0ydMcsH2DFZuR768j8Soz+EQAaN+09z90BQa5TvHw9eFuuLFVfVIA67LerduL6M4oph8KI1e4Wi16PTyFyU0QWAgcgDLwyrG81Xdbia1KNtTyVoX1Yzny5oTLfVY+widsK0/sg7I6UF9j1NBdvs4Gi9av/lxdyGTHUikAx+SLUv+UCBA7RA9KRFAQLc3EK9Jc68HwPAyBOo/mk6ZWHgdhoN4FVyUOd+BlLOieWT5T433VXCDMa41vQi/JCAgtVZKAIK8kNJ6hdUDAMczmO6XiCJK8EI7lsRYndA74Pg5d2jwAcdavVFBl+0PVPI6DQoZ1bZ85siJMgNh+tlV7SrkeSn41Z5XI7ZwLmB9N6cy2t8biDH2PeWuPgkfkQouxCCQ+uVTW93+A+fxZdw2HCXBqawvi6vKJAA4wNhkCandYGWdpB9MqmW4DIahem7hwh2kUFFJeCk8UkWCpkKxv1ihVf/0gB/nbJYe+/b9+T4lcuhALHFCySMKoz0LBd57dR9YG5ehHQWwZykhy7v4Daego3JiKjH2tp1Y8qus4IwqNIaapY+j+78fLUozsWMgrCh1J2CPrg9RjlL2cIVCzOoZfTs/t+WkWAP5YP73PAGr4mY3tIXzMqyl2JrE98qoQCIa4d+Y2jV9H+yvG/r7LK1NEKsdU8+o6O5Zb1sLq5An3BRPRpsDotpP890aGFLcxgB8GYKGm4uhHTca6fybJhAEYCFFgU1LRE5YPseH+xbEvR7pEEWmfWTfhBcqXwagbUXpGsVIfhzA3vFKdDUhoITxm/HscbhCSYR7YOJQAT399yw5iy0qv5T89w9UwOb/iLbWd30uejdkd3yDZ4RqkEJDsuSpGb8oUB+s8i6KhVA927bMg+oGGjDpErH17QY/rKKk2LYpsL2gr+Cag9XVuW/vy5bFZ0uIxPF+3yVFm/BzFWwseLI6E1umagc8X1WNhlAgAWGurxeZXT6ZeaYtgegqVlvKW37U8rZtGeKCvHcDh8Y3q3DMobh8yxMB2FJXvrCSHeMug5JLdobisiS1tTqG2eBY6e+nC/t/3J9Mb1xBKVV90RQ9UhJMcgmAlUKvJxQlm9/q0isb8gxhNgQqe12ZGjstTEYGwVVZ7P3GdXlmNfEyzYE6WvwrVWntuwmmODDn2My5mza2n79nFwkFcE/s6Lu5yOHJT6ETa8JPpKrJmeLtfFvFqu1otpDMTZwAlyAn5cuCntODGW1U/Alsn66Byy2Yf/sltnWb9gQM6SCNBqNKTUC/KYRgXodzpS+k0X5nwChPhTw3DZ7WvyZJZvYW3KcqTu2vLBhKsv3Oz0gPEQwyYYogP9zHVztkY2aXuGQ/CEMyEqhgJCh1eoALM22G5sUGyU8yOb5KAsM/uFfNa/IAGVJHm7zgKLTOp4thHEYfxMTGbJv16YP2zBIX8T46MQUZrOvk2HdhYSzP3I46OJTk04Ak1iyN7ANg3QsS0rXRvVt0XusXM9oXMkIQT7Ihbefq6hZFXCKklSJjwInMMkyH1WQ+iViohH1MN3w634oW0X4lpYco+Sdp5tw0/kuO7UQz5W9ijCoY6DXviVAICrJQMuG50jIgbYp1O/olvsmux4rz1iFZobwj9I3ARYABFF2bu8aVoISD7KQGfegVWdKs4qEbbfE5Bw55Z61H9oP+48LPncRvfQBCqerLdrDotH/szHEhxVSDJg0PIJrwmUYtJr16qgbFELkKiVRVYp/ocBqjaoV5vHf2g2+kw/6giTpwke61yon33P9D85TJQe3MVBcOUg3aZfh+LY1f7HnTMP/7IBQrdaIQUBagnuzTRn642qCrsf67ot855nOI+Bns/AH0T99BshdRDtOcI8snYuwH02uwrfTg/1Hmv20PKiQmHmoybwpupBox9o6l1oWTnf84QYim3PgvN7DF9r3yHS2jW6eG5udAd441UzdaSIAAEDVKCBAs94y8Msbq4VGl/Zev4sbr7pfgt4IReJt+lH5bKynC7bdgsBkNynJ+JkXaQpu7DxBra5RYvMwA0phYiw/UFHz4fVq0Y7V4tKjm7TUNjft+4LddU1RLmI4FGZv2NnIrXhbs4q7ItVlGrm1F4IEiiWrlWPRnxGGS3TNpoZPRezAQB6psiyy0F9GaKsuQnoAmqCgmY20EIA6IiohY8jUfVdiZDGN8WrmeaWGAEy4TDnfLog8Iv+mMSmoPv9D80ZGscblaRftZytCCiUe5xLd9CRpJPz/j6qOunnu1oxUaW5LyQv5ScD9wGC6lcKeGqQA1mVCe60pk3QQHvD8cN7hmW4o30PgcLCdWKj8x3omXf5y7R+7BeEIbVJCVN/sYrIAaBLximBoe61Fi+m4XSBmbWxPqJpnQrd8VmBAjxfFfTmZdeKn2ojay5iKg1+A64KacXlUgJrI/vFkNDyeeuidptSFTfQQqJB5/FKQTEw2oPFgm91MKpM17n23jrKcFqughjqtkeGViago0G93jQY1zkAJ33ELZHlAL7ZYhYI33cg3EPvhjml+13xXkOXLBfQj3dm+fiaYCGteGFa0iu1H4O/k+EU6kxLmzrz6L9XvnxxJ9ZUxFSZpja6p7nc2WEh7DY+ilVD1Ppau3H17Zw9jxg/TcLecwdwSzrcYIUw9CVLWv9dtEumoqhEKoFIxCdq0nSPz+o6/TGqJO3JNWo+QfhnxOvP+rnjJ4OKQobFAGOMCxqeYbLF+WTmXGh/9QwswcE/AaW49r7NWpZFS9/BGadQu0u2bfnlPZkIDFImrGrHYhfbdMhm2hOv26KiA4gvL5UffhUnWNX1n9BzvSMZ1iLaZUB4a9eJKMZCMFUC0gnDvsQt4DpoRB6Nd75U+Wz1oPQNpuQdbcHlMFhT4L6XgYMu7PM4dCCgA0y8mlXvG3v6yk1AbeEpOs6+s6Z3nV67jFI2ddP8DYP/L0+hcAEMV+EKHGektf7Kf6NxmU83tSz17DwaWLipSyd8VWM/wl/iGmk/G6d5FGOPsmPfyInxsyyhoWokK/9N/+jA89VzH4IGni5vhRUmv0eOW0vznX1rq/ahqd0ye5EF5N1rXrDXJt/uosM1s6k8MOtYTxu6HsAMMag6hcVBAZPCbngBsWACRoP55KxuwqFlYRSeD9jQfqKV1hM282aQM9BIn0TB2TCHvofkDqxNJFlvOypXLAkBawjGgLhXm0V+3P6WILnBZrA7UePGetfYWjPN39ktzdUCUMbsORPu/ij9o2veTeDxfVZ5P+JguVA1l8Dd2dkULaWzOaRSNug5qIh7M1r4/wWFzgM+OhG1lzN83z8QBQ2bFbHhFwaeibk6gDK1bIoRMqcnvuc7jDWLnbVqgkPltY8S/xA/ZjAIMMkZEC6N7zeF/1rSCg9SNpbXeq/8qLCdxCtlO242q1xrUqSfbZ5VSN/ykCAdG9P/ccSBXjes5sixwKMDmgTHiNDoidcF99aauL3gUY5c0gDwFGa/tfOQqY6SLeF7IInovw8xUPLkeHM+ngq8fkfJzVMl33dnJ2Ia2a9aHSMqleabC2CTP+O8ZVwYvZGQHZwfqGftsJuenoqRVzANR6OnN3QuyUn88fuBzc1HD4nnee8jtlYm9H3J2VOJcuxlXu5t6whtnIzlPyUE4XvDJzq+MWWyADb9YCkqYOUPSVhn9sUlH8/5Pz1EqF/Xd8kOXPxA7gtWXoB4KijY8wPj9jfw2M8xk6qXFDWdJ+7jIqQgv8c8E6f7qGZQMqzJoEyldvEFl7uydTmp9Vr2ZLW+PpOPiVtloBSml7xESIXttbXUedAT4p/KYTbySIhXwn8aNB+pcILkDDckmYtWZlLJgAI/QICtfpWqT4U4gAADWvHONQBfKVsqxtJYhQFqXuHkaRQqIV7cCKQKfi/nR+YzTDqu51arbE6y9kCByeW3RHVtn/yIhe0X0mS7f+x3ZG4WlxSyXnhPYS1WEHUkqVjaRd8TEOt8s+tzRl5rKymNbJ5mJAyIg2OKLDqwjqbC4L6MROMFgu/T4ottlrICpS6K2ABjQtv8Ffm3nRK2ElggVgKlvSmd9o0YoWF1o4AT/3Q/DZbFo8ZbzKtvcCLmEKHYEAuTWSvCfpIp4XhLej6wxTs1eFbGEACTW21wB5VpgqV9s1qbo/wgNWVmmTWguJDPlVc2AEvgqeFmYauV0LGOqfPx+6oEL9A6rlJAWpKr9JAcB6k4FgBwy0RMdY1BxpxH3sD21zIup7/7OT7zGUJtYkw6YjWHJBLuLsMY4YkkR6VT26CAx/Iq+chuzmh/5J74ocv/DMk45Dv9XR8hTkJY7MKdqZmSBELpE20u/lLWauDhXrqB44nOAxNC0YMBfJbOzEs3aRj45j0Jaev2fC4iK0j/P1GDWDvloOEZYpdKteAtitjsO8lkWKJ1Ucp4ntrD43fMyexMpxQeLatQt6SNMt3jFnnNrcO1mSQq9S2hffFmmKaati+WJiyYMDo3F3MKu52I8Vippros8SCXHe3eY0WhULAHK1iEfcnhyV3UDBlmfEeI0G3GbmhP3u27aFhxuGt/aOOxE6KzAIj4l8mlDp8zZfOTX9DOW0R8XKDC7Vk6uKGy0aSpMON7kiWHm5mYWokCx9XWk/FOEorz4N+3rm34c+vHqEMZDC/FRPn1soMZliBXQMG+rVwapU2JJ+QJRH5VWbQADey7CrdCFuJ5D0xO5xtOZJxPLPW9wFuxWaOJrj4Oqiv1xrFvTYuDPCi/88f41AMb/J5G65z7oG8brhmRPMMfMlyXCoBF7qTmm+SI3NGjslylyCN/6soOqt5W0fVgZFmSNFnOQLdKgk1ZWpj1M2grSt9vY58ICBQsCgiSsFPeP7uPuM7PcSxpv/n73L8ADoZjk7JKT4OlvxK27j/duYj7uwBiUaF6HeexWegz77UAZhayL6KNBondb1H3aSt0rfwsG/wbt9ZVmBPFSCrtmJq2mTT8UA/YR18i6e5WWDVuvj/+rOcnbuL6rfA20QpW30/K1xLFMQe3aGXey28k2vKezvLVIm6iOKINexbJOjgCVPoT8j7WgDdsHIsQA8lUd2VbSkY53hPBEEyy7fLNyjiErxWW9QP9RWtIW0briq37pGT1Vq2uQT2P+DHEufhRbb0swK8WAhqPKZ6j1se8I2+tG3VVbqbKiioCs7PVPV1TLJKfgkw1cxgt6OI3qy5UaiSy02a9h3WhjVbdo44NbMMN05SaKMHaypiOy+Vjz9qNQrRmMsOzSlpFaa31PRIKOiZlHjqSCZiPirovsTHbvMLjCZ7wmnNGkY/WJM1CRDu2B1cFGzoFmiWLX9y8rannHwlvk4VxJGiL6/2GyITawIid9SbJwe0zkoU1qvKqvwCjyoA753a99O+h80+z22O+cTR7dfg7YrQgTgPl0WJS+WEUDWfUwZ50MOPepP2W+AOmR0oAKNYdXitRCW0EjyhUppYdvX5Wpld4A/dAqHWTdCejbaGkYlqHRCsVCawXAYZEyIoivnfg4Kr7u2KLmNP9+FrXkqVgKezgVH6GYDKxVXWzHzfP2S/s+s3vtcPDHM3pYqu159v64ZejRjk2R36XY+vrZBGmyTa+QTZEONMCeLCaks2Gbax8ZzIzH0abc7Sg2DGBeABfYtyD7uFsFM+qkBAwESnEuGZDJZRoZGG0WO2OKlEsQcOSiwp/Pq52JERlsBwQSAI/T48C4+N9YBEgX1NxaRlgoLe5v43upnNx/2IYprHCtez5xHgq1XCC0wK2X3XkIfc8lE7f4alR29k3M+hBJapMtL+6z5wnvt6VqeMPx1m8KcZgTLlmT2ECmg9eDmko3+8ppUOHEbrgFCHHCNgCJKsu/bWjXwc5CQJkwbwdweco2rUMLGHwziDRnWdqBmmS30I3mOIqLh335HVzaLu3HAul0cAGX9jPUmWgIEX+qU7SKqIQRSbV7z1ZFSUsCe9Y8eVL9MLJqZAkQTI+osEHBBWQz66x11K6BZPxRMIwrSyfxlK+ImQcZbFj0skMOF3zsLFbxZqaZl7CkD2QW9gk9DV3aaQeq4mWyD3x56DdzETtQyzxj/R/lHOr42vpYr9f14CjY3p9LJk5aNkZUFgE6L0PRHOtMF2TzenRKIeg074K44VN52qPjMFQNSUdKFiHZ/YYlNwHhR3z5MF+iVZZenYKGn0jb64COx+e7saMAjfgS+xRre+pbUPf9HfyMKU5vmg0RPib8rPbDKonjThRD5MjjnyKUQlf+KJwOdMYMevLN4mxyAAYG1ovRt2DJMP3kRJcACxVgCHlVFbwAzna34Enj5Qh5DS38fFp2rcPh06/21tGJYlVcZ5O7Jecp6jnNS954S44vDiEX4xqscCQxZq2WuMucridUVwQ85zOOv+2XpOgA8ym0442pd2Y3hafCBko4E8EepIQ85cNLiVqOomSOyCiBNFVSVS3dZuGrs868EP3B+nllhHYk84CV2IVIXmoB4xnHio14p0UINPi9DGccHjD7Gbx/ntsUdPPSh2SagoTjULN3LcYD2SvxbYNKgCftXYBeA6SPGyEpF1vVpB+p6vRD0CYLGOL9pkZIDHxKP8vbD5wBzzmFbWoYZHpFdZfedxgO7g73ePky/MdUjca+ovQPH3wxHBJO0Z+b6qp3vQ8axoWAqTMVKHOSuzHK+FWZVq893vIbHvYQcqEZlmh6kUlK0xBPEOQMnC6WbSrmc/gP+I3Ks91eC9tz7mvh+4j2Yd3VgTYUok0MfGAYeyAFDJkGQbrU6234hEwTnYGqEzGUZ6/KiEgiYkvMYoZ8Kb2AQJjNnPgUF86elRtKp/qsJTKU9Luf76uZj437KVly82Xe6a6ZDw7uS0pXECaCwOCb4eSbrKsG1e+ilVgX4LTd1nq+beUw8Zovr+WFAwDyEMDfB0BRuNFEufqgqA9ZuS/XK1uHfUwYG/dDhueb2MlYZ93deoGtJ/bg/mssN8r4wh9doVqdjdXJa5W9feQb0nErx9ktkMhMmvA3FJ7wny128LJ+fZK2ygJpazuQ20B7COM5hamwbJaet+oi8O9fiXVQUOHq+HjtkIX3ke35JSpFiN3i0E5Jd0+q1HJI4Jj+5qDyRE9CBfiIMphUwiyUK0k4R5RbMVxw62HDl+PwGxEYD5fFvPc61Tucl5uYqCT1Sx8bje/oWpTnpEtM6+pJZJ+mH6sbQdPIHJ2aem3JT7EcTZLEI8kiRoBY9COWxLkotwKR6SdX+MeYHXnLXmIY7ckeHoGOLTAhN24ezo1UL0avuKpf0qolRasElsgql08OaKAHjoznXcavRJvijTnQa3kRTkXNOpjWRpTmbczrNCfJKJvzCTUwEStuGl3sPgACuzSwcy5aIklyWGB3SljTPNBleCDVtwRGmIa5bVNkyj1Fjo27OUovJbVRd2sdra52sLVYzV8JY8o2JGgOGzsleT1NXceoRyNRz6t7j5FTiGm67WHLNfI4SfyV8tVOF3Z7AZ03fwOT3GL8LjmmVtmCJYarBevES0q8Hx7tNJkmf7vRLNkMcuu26R9DNU2wDQuUrmRkux279cQypKaVvKIMlaZVPfzEmLQYELRy/j09BGONTG5Zi+fjKv+5JwlQOc03HM92/VrhM7HjndAJysTjHOQJ/v52Ti9OS98tYHfyn/NTFoEYR25JtS5vaA3IgLoEvz5opaDV/V2y6waU9GwsLnHVplW5Wxtyg9PuG/XZZzj5DxCist+avzx1hARtCpdQ8cWadACZYAHU6JrA9PPfTxIoG6BytAXUSl4W0oXReqf8vRxqh1tT0Tt/ZUTBV+lzr0v/H02LFWosZ5EK/vOVa/v4F3hXjsmYOh5mHPYmEMiJKHUr4z8JFjYo1T6ZlbCDO+1+j0NZzCWdD2W95IPl/hHAlxRKjvTlwP8cftoQXugp04r5UIutBScY2CenIFZeZxsyk7uGHhWiv5O8itFr7pGGbQrLWmh7F0Xso5EXgZH70rmRtRdS1R9fQchSPFt1fdcxMnbxQxCO5DrtpgFzaCYW158We/4ddK5ODIMU+5kN4WSDHwM9TGQd/vKO2vvYHV99XdQUi78ElutIAeswaxwLX01P+NjU8qCAUbgXwhbGXBgBUD+wTnXpipIr76wcDOjGv8JQnzRkwCVkS779v90AmmjKellObJPzBeE4NyvLD8KwlGhGaQeAbkk4EpnpQGGC7mIpcQNmlMjrH9VlISinQ/xvp4yflxmgzn9n9HJKkWA5IMsvitnRfunZPK/pSi8VS/N/EKyh95NtYvuH/58jZXnaVaOzBZLwuAmxmmeNHo9jCEQa4OaqL7OlJU/65AqT9bxulSNGTgJ0MZzpf0sdgrZNU6slcJc45faR30cg98OWSElrViRKdtxgp6yaE+pBiUHskIVYwGw0jJ4Tm8T7tZZ0nebwfwjtdoURXCIx/dJ3GE0xOv1Y/vAUkUd+7snPz9czKY+wEK1HJGszRgid3TQpb2lPfhCSELrZ8MEAGdvd94olRHn+e7EnM1C9JFrBaQ0H76GjLDbnL0niDGo407X9Qdwh84AIGLxPWOEaLnJQKKcu7DPAs7EWST7/oFsNmRFmceGHt3ENwe8rLM/46ToCbF7rMNhanUP8ggN1tXsrzFR9xXrqb0EJjphrAJeQT3v83nAYi0wIRhlNIHcINEUjDMH5lz7wociCyZSGcgkdNuqsRwRw5hysRLO8JzvEPvxRU55SWhwJVPcGohJ59TJ43ATVuRFJMunEQCIycedbjVSrFiO4+8TgvWNVsH0jTBlBJeGzMX63/qrWfp/7a8iby35BHy8pdBqJ4hphc6zNaiJA9ErTWbm/WCnVxxrlk7HmaGeRryGhmrjb2FTrTdBzmXk8/CpJaTFI1/yZux4zyjHIy56mtgMQSmEBJG48X2YYuyf8RYUL7CsAwlOasJJxJatJW40qHqlBGa/vamIGGT0MTxxHtV3zPFFtyhVEWfSw/m7PT3kAPRyBdTI8D/6osEadcCBTkzkhO3KCSxjLL5YszeAkzim+pW9uT7ESl+B2IrbFHqNAlfC8JqtXHEJnp7DdfyamOoGCCzz8mU9VFzYklq+56AFA3bZPYholMKJ4GGpqqepcZ4IA2tns/+aoZdCB+PeP6jweFkFHSVVd+Bb/CrPjT6kKf5RffWlL4d/3aKsrsI7R6wLrkUXE28wtACTWI3EEdmYOYwroiMHhFFncJED69FTr0AnEIQNsohuMqmKNjdWQnR9CdXoux9Naovh7B/5W+m/4K1SoqKvlUYow2RPTsCN9F48aMT0WMR4mZc4QtYe/9VA9zznkhFbhJ1tfpInKfQlFWj0HaJr/nLfF52/MRQkHMsUPr+b5SSiCQTwoNVSsqXhTuQnVhUnzpnnaDlTp7PD/cYrDisv1WKfzbbdcKiY3+Da6BUysPvlUqUID84dUkcVfntm/YVV4MaL9a5fmhE9sR3gCOf+LZePJuyMivH4s/8KIZs6pQ6JJ9nyqqB2PTRcfEZjdWjSgikGEuuqNI0mZPvyihjE6glkLNsEdJ4a3C3bZOjX8z9MIVZwwKq4ZcvvJvSlOXsOgalPkAFjco8LHXxLsIFfNU3LbROENRqUnCCMBsbsRKChAZhwTP4GrnjpqyoXEvocJ+R59c/qxW5eMdk4Xa5I1EhCIWd45RCEltwRDSVQOWpW55jZ7Yg0hZT5ZTg5fuOmm/hrwkd0uoYGm84TrhlfS7jpLX+iPgYuAvmPc2ExDCWcYAAWmtlsp/QeEcqm9p0hpz5+dMSG4OL6h34itP9qfw7UEpzp0TS33abnyCfdBSQD5CQAn5FExUMZBBlVyvtJRx2v4c4vqb6p2+bDMIEOEPHlc/Jp45ZXVQ2S3xmUj1JRigYhGONxlK7NCnxpZ9eq//bkuC3QdWJmzmKBLvHzL5a15pvz8MvKs8avAHfg5dvffAJfMRXZC5tTgAJQ4iz8gkosvHoN0/1DfD7QZdy7NAOYQPlAbvIhBSjx8JS2PhKwNMJa6aZjkldXrqlWiuFg8JerdUDzCywxWiuy+LJgKYMk985ZrEfeT1AHyn+06GT9Tkgy5pGxpsgdiv6YN+KpZzvWGqzw8Q1kG4GLlvWsxxngzaYPsWxOoQ+4MpjPlRRV9ReX4BfAZl8hy04vNcKg0Jokej5a+Fv0o47XLua5tEzdmflWPK8NZP+fVWSL4yZeugKkxtjHf0SPXLhxQoFaNVXnrFfLkeyOJoyTxzlqnLojdlCCxxMXvEDsD4nZadegRuOBqXtK9q9I/i3UEoMGzxXyFv+0DPgeoYPmxrAQXHUQFXgc49jxmaFs5/DKX14q5zRvXAXsfG1Cn5sAoLGQcBr+TUNECG0ZLM5xMCwEL9mutuinP5KG6w1suS7ADau8/s0FzTxmFoDcw6jtlBScpPkwwU9ZMwU1RXnS5pxnCWdX+UgXO6gXOMKfWc+le+4iTAOlaZKucoIDzLY/hVjhken0XNT2q7saLqvx87BJTXR+ZAPDeELksKhIh48cMfRnII5yrQBScfF0io8zygPTdmTxy/0klJYTWPeJUzrQ9fCucuyj8X+JT7cnP+qiT1POYDbiXsIJI43brCK0mo+pB8f1V1vaq5REdKCi5q8Ef+AfAJwhihL1dnUaHBiO4g8+mdMhzd1ds5g9rf1555ssyXparw4hHj+0dYlgv9cBJhUDUuhJJtCYxt8jlJT5SNRd6HT09MTHlK3aJZcBaFbquqxi5O3in/4YxTyocfWJLVyV+Sr9rMlw+m6g88CbSGjQ1cCwOJpkOgQG7a4Qd15CbmkSjdKAaEyt8hp+V6BzDGs1FLSX677Pim+0q8wVUIIEqvrXQaPMRRqA8tQybtAIkkb+TcEemMxiEw/33da3ZVRYVk2c+NKs/3rjGuSTgI0VgztT6ChTrk0x63AZz2iEQOrBvWdmSaB9qFsqK697e+BMLHFZ39raBlQsEVYr4jRhXMR01L3JERPcBp6BuPWVAIv3xxp5cVCwQdhk6J8OcgKSwRTV4ACWzZqPdL5Fl2/sJg3wo4NACFADxJpAsQ+r/OKueJvoR/4YCPc3WJoLlzUCkb4zQgJulYuj1l95sCkaKB4+cj9WqDTkVouhCHyApV6onK2eMriW1rXVk40xodNLy61AbTXhnrYN1ZHwIAYM5bda4wvwutMH+zZ2YpTbq60eviiOnpbwM+HEL6mafjBLzFtB1wfUOjDpcGORroY10MauFc6B4SFE8tNXNt7r8iICWRU7EMSpFdgZtQt2cPVRu0369gRxyCN+f8zwWoCUW7bHW6W7bKJ6tI3qA7bCG3IdIO32M/vXUIiLJSH9DqKuh/b3Q3reIR8HcBx/3M6tkVxhxi81dO+itNUE4WLgc1cPq9DpU87NaPJpI4+dJCD3JhkTPcqZK5LYzSO+NewG3MmumOTsN1WpdJOlGrfWWCHxQH8tO5Y3Nd42imD9fb25vfe5F97EjAifG5P/1mg8P1DK5s21a/8vjpteU6aZ6hBNXOGgIQADNvU4aVwBvDBi/NgIkte6KxjDDYWu448VW6uu3o5kCioQiUJE3KhYbwaFbhHsDBPlsGBElL3XVk/VXE+VP+3pghBLHSfKHcLY3HmYfDFpefPzq+TpdVqaNUVNK0hxSueWw7cA+UFsdZL+Twz6QPyePnPM1MfzAmKEG13rRz4uhnGMTZipAyI4oaQKhd3XWu+rwvhbGF+FOR51LbWY/ns0GSsbA02xRmrgbHoK8klRsHM4n/cL2JbyNPDecrY4RZsd9D5x3Ob/cguRlyGSfsB31eILEPlfMA9IxfiUquAPBOJUSOStVUsTtmNvQg/L4UNF6w6kwV5UO64QodSa9X4R20lZVFknen8DHgOe1GY4BgmmVoKOxI1Us1lM9/YZZnn8mcnbsLkQAwnK6u8xa6QAuLHaHGtw8gL7JqRRhCOvLiJG4njL9unlOrJ4yOhrLH18yI9NMsbNlty3K9ZENmQDuoVkzSZLiR0KBx25qDLRIkntcZ8/OEP3lbnjk7epMUakMH6eFfrSAqhWbdyGbn/8v+R9RjaRaxM2OIkF954wI4zO7z5YJDlLI5iQXCKgZjR0ujAG2yHGHx6Sro7ke+E551QGsxv49e+jO3TOyWrWlu6AG/Rc/1BuPl5hBPlZuAy8Lfgiz0/d0iyLdMav8zwU4+CAmmkTyJG1ueI5Ufi7vyiucL6iS76aMvOvnnVye9REkU7MSRStxa2trL2adxuprWUi1ajGCxN9uZaWnn0ZHxyH9/oTsx12Pem66x7FpDSZQPYIn0XOd1k3SU62TN3HEdM94V17oR5IzUVBQh9cSHYKNlnoQANZwVWmyQfzKI8Nw/mgGPBla1bLUULbhuIlsGIpUEUCU0okzOMgOfirG0RN0/3BEEKBoV9KW6HySdY4re+ZCmDve6Qouu0XP03gPYhces8s0TVaen6aNyOA7YjsyDjN2X0Czu3I9FqLgm7XBr6b/ea9N46XKrKFPBl2oAImF0Pu8qyjWaWy59Y/AZl7ZiWb9o78nuLcvHeFY4J++WvL9/SEZBt7BG/981e3K41Nk9fZoYQyquF1gJkD2q4LZ3ayTxDiDzc7ALUkFDXUWNn6UjObbjF3aHlQSXTV/jx+Gn8XgV0DBtPwRBzNhPPlvZxI1ObfSOduZqdrL5vuCD46Td4WIE7iKfeF6WKmXyYo8ieSrtGZL9JkgXLTLrlnArJcni/3Im+WsdpHgJwK0EZs3t2AdFoYRW5XVOdfwtiTyW9/1k+kJw9ADlEyKrgS2TEmghkRGFNeHRL14KTRXJxT7OrxF9eCq/K2hrfRKW0TF90azsVn5EM6icSgzI/Jbp+dRFWyHfGM8SS3+LngBC0tjHXRiItkdovdrRIXz5ocCJEh9HcE3EjuwPBLwmhdCJ2P+oTa1CQTdkutCKRKIR8Nm/HmhMdfZSEcpULdFmPDscrzS4xPipnMVYDhPVsIPr1kFYIAhopW4KHwBC+B7wwFHW2wAyf9056wWUf0fxm75C7PX0oG8vhfGdMMBgm2awjEv6uGGNAUnPVqCUOw70sGgpBX1Z8LvMiM5I2q8eO7aHHH6tqUcPu/sR3FNnsc6XI+1t0fwkn1/BKh160NxvxEyofvT/LqC6xhwj4z5QCWKQAog/56joR9cNLfVR12Wv3XumYQ4ctx1fnA/XZQrzfzSwA5FhWs2J75CrzryMAXpm1c0niZhL2tNj14AtrG1oA3ZQc9mFhDWLYjsZvJnhR2rN/CBcRVmJKQJ/ZPkmR6ssT2FxJkjQURDnFzWU8mvbNQMmQPy8h2WIv4d74e8trD7yZUpGMoHPQ8pkdXHwr6XkW2yn7AzWXGYgf/pWJdVpLFij/8B573E/khf+DD8OQ6vYqp6dXNEXW0QZQlVMYDM+lEUrUqekdY3XzV6e2xJK4Z/zwacDlWZyh4ikulPFZv1MY6+n+7BFgW6b/4FByz/GF82X78N1xjIs7VhHn3pS40INo2Qf+XlrjgeBtpvEzxK6uWsOUt7LcNQIiiRwgFM93mVNdCJ2RXGKtxv3yBcdcnAb3gHkrImKU39zI2SGpRXUrZegm39LXK1Qx20YyQgMd1MmFK5lNac+iKF0yKee8ctdZRXZDO6OqK6rWiVWPdl7CIzCVD3QsiJfpsvEBMHvpF+YFgP9JFel7qqlwKr/+Nq2eBoNVK7OhGN1VS4IhcU19vbhdnAquqgZsyqVGYCe7IEcdfupOS4I7wm8dfkbdKZ9dopuHlWfQ2Daq7zs1Jk5Y+Q3G3mOngfCl4CxAeAu9ou6jyy1awRQa+stweiFV1+9NYaIx4wWX/lnb/dlo0o5Elz5Ak/+xfNXkGogI/Xl/WkvGaMoyjBfle8urvZFjS1EL30n4481XkPIWQ2XjAc9SFGEMz9GiaUFpnozB1GmPJY3sPTjJ5pnXGACIUsvXGuwRSyuUjvAFE2HL8nQpphuz7KsCaNiDUcpW2ng9CYjHnZb/CzO27ecm7sWfFLKeGUo2xqjj1WEl7/OKL4OgomAtGF4mUacI7PFJ89ra13EIH4j11qiLo3MuwtZ1GCUYjhuxdIyaFos8FVHQRlTxtarKAHL1X678eRLfNV2lTzn9XbxEYgmp2NuLwwd0vDuD0AA+dFVxxzfyrIRJYYy/IdG7F6PIrinK7i/P0H4WgpFhwzocwHiwqmSDAYfvz0nSDBGZ9TRg7Ek3iaJwhM7Y0sI+l5csTR6v8Xam6fGAgk9YmG3+fiXidMzdCvujVsx275kTtIXE046GcJ8R09MZsIaCOvvHeoiumpN1A1Gd1yCRbnU0qP/iRo3isOJUeGutXZNJDhV9z+63mLtTysEDfAb/s42kggoo2fuJ5VHWiavpZjAEhILhSw1MKM92ldXc9DItW4ylkSAYKSV3t+Kwrv7t7wz60nVoAt0NT+9yq0ljdZmSkOm+rJRmF5xTuj1Ub1dij1w0yAGzlEADgunTcPlviRzn3ZDLv7fOezw81pkQP2UaDhaLcwlZdc/xyMEva/cVRTOupbBmblSXbwTvbGluhqXaKCTprmXSlSghb7H3119/tnj9//o+jCkDKTNvpU+g1Ne3cQ5gfCG2ZZx/KRZKkLZGTzt78zk6ZbhvuboR7QFcEis98QXS0VfcRahyRv/KvMk+VEBANAyKxFRQJy6cf7lsxMo9QuJMFmIrg38m6vugLRLZLkuSruhUVGmWfHWrz0x4yBs0R3YAIxKL1ymslO+1QR+OShaKmu5fX6yVlF14qwQJESKu7XxbNLw+l8u0iB1B+XSOm8dWcMJUXMZCT9u8JTOCSjWNCjJ1rNxADhvpsNBZdZd8poACYxtSLjUctZRiyRjwUDpiMuhE7JalAC1s001i5GKR89tlLxE/VgnP2y+9lr5w4XwdhzS8VexzA1kp2l23zdHOt5YgKi8KHS+Jk9VPQW8bUYIMolbuNPmQOmI18GTH/4MMIRQO4BhKQNJdJUmtg7tfWkqFvbdXi50na68lJdYjmWwJ5P5TvIek60xZuQjOe/SCL9s4wpKxQEZformJLFDzGefRT+gAADkb8CyKqoVF+albCOmlIitQgPVb5hjLRm5WsHFETgQ/XgsXGhOFG8ET9znJ3aD6Aczqpapg0d+YGAn8DlZKp8A5PvDD/ojbsXidIi/fYmGVQeAAqGv0XUpnrRTPboBkEoVSVwXMXZwNhZH6NhSgpfHL9lY4Z57rQcRgKfUqgWL4LXfXPq9qkFl1UYqUHPaS6Op+WBtpztAiuZAMULagfz6N8UmNYzjTQxn1SgC0DTyRQbp38Q5RqRfPodiHAGsFJ7SD43Tu5qv/IPQfR2dv3kizeGk0gAQoNfyfCdUbSS/pk/loUErPT6Ek6K+kuLgyyOpqexJ8FH2dkBYYbgA9T0AP5I5uXX3rpg+Tp1k/SI66Zypjyz2aYY4t4njFHdvZ6ejkd/nRYpbKrJ3zMYHKNaUWYIZbzB4K4ZM0xFhdiSr06+5Y5YoYbjGgKlHbMrrDy+yvDZewMPdgfim5KMqW+f4w6NDznHLhEpmOeI0jSNgoEa/I4XhpMBtFL5P/p0/Oj4ySVc5fKHAGoUZV6hmmHUC9wHnJ9vZhJuN3UepUdqgsAlIGGS04WTp2yTv5oZhS8a5l4zWBLpDp5GgcDfgQoJaidPXKfxS9dWl8cOdMSUEtYE/aIRoOx+HUDhBy/ADwgAALHb/92idU+z0e8IdUKj851Z34t8G3eA2oaWtCkRDDmGF/iwVDzP/RDptF84mqlt4Q1qpupTrm51SYcGMmyenykdd42velH0UIQmCJStfKd/dMGdxiI8SiRC1tTq71TpeSGyYkldy8lA1rfJf1kWZl7ooe+dxYW+hMmF1I6dgoLZgwjvRDvOyd1qRWURdJPYb7z7tXlfw8AGQk5nVUf9Nl0fxSwhqLWLx54qK/KjTer5TuP41HjKx9bItcVIVdSWypfiCK9ukRXXdy7LAgMC4BjNbnZ3s9uKqJtE4meHaRh9Q5wtYwP+vRX3sNIcHmNhybDMk3Ic71j367tAotIWvoQ7L+cPCEUijS3tu34h8ERvqwpGq3GfpmCKS7cV5S8yDPl4lYES9znbfrMUe0cdolbsRcw2fh/iuhvBecwyPTy6NP+1WP13ajG6tnhjjV8dhRkIaAhTJQNqx9pMO3bGeUZ5etcdKGSvkXo37axEWtyHYB5Rw4LFWYCTdoHvnfxZ12wMZe5Mup1yJ6fNKCS5oa+suW9ZWF4xB8lX9rbRyyHmkBShPUS8vgjyGpYVk4F8X2M8LAnC0iRfguwK1Dsn8ovZ2wgGZYec8vyoI3aVJpLmB8ccBqUK0AFNm+5GM2LmgYoj89S4vGmEDn1mK2FVNHHuevHBfwPPAtdXoVzFfrESgJKyA6RFZ4+wcE6b1Y9jkxo5x8KZrvEagJn2/fz3UHEIlapwxlzN1YAW63npApPPV7jIFgm6w+ABBAABV1COZDImPsbe+y6LKtFgR8dyrOLO0RnRF+318eB5NmRXS/G+mM12ZeVLjTRJdEySB59y6IVXj60EDZjyS9Jal614e22ofst0SpAtN4jZddkXRuiD6I8DKSYmuokVOhMhaeXtqgfoSszPF2949VjP4R+uOYc/QB6yqn290HSrIQa+vICo7jZyAACCFtDf4FcV3ZzxKT6lDPPPADEjMenar8IKn1Wn1WNdb7xUsaZwQYW4Zsf7k5ie76q/EPie3riDTLFk2UVZJV56LT7hZ/0SBKxXoD+itnwNe8O+88VAu7pjKQGMkCVTdUjs3h36wwIajCRf8mzvziliURMYaoRSWhNHrM6q9ZMy0zIpjlsL35avEI2/wUpFXwwDvSzXzhe0sfHawW6kHnDd6FOZn0sXiN6fz9RtVgAAn5cwAAALcx4JhDQNosst8bRq9XmxtqxzHn5piYtRLGVfhB7JZiJ/bUiy7DGFBAgRDD97dLRouEyAEyrRbwQKWEmyEgQIqlD/lV3rt/NmhkVD3dTxv8Eofabwwz0MMJuuIv9YCeKu5kosyzcVKrpKMdplOPnaohV+/9jrY+fU5xO13fBBXYVwmQCbVOKjCjryAAAAAQvJLgZfxDqrtsGLKhmMzxroY10Ma6FPuwAABOoU4hr/byJf7IiMfoF9V3V5w83WlI6wiyWJFYkgh6P/kQN98PzuF3HQAAE+PB4fba8gxcfJilBPjopHb6BcY3ILOcYu65UB/h/d4cmYom9D0dDLk7AAAjdY562uaC7T6wYh8jGWiQJ+cY9Kn9RA/i/CRdeccGeUzAUwSZDazE0K8HVGrqdlOB1YWP0nPbRSitz8/6S0v3qv6W6xujvqI3SRxj+xe6UPP6JpuOKyRDMRx9LpQ0qXkbNK8Z/fjvtDvD3INa5tQkdy5WccxwXCVWRCO+aSQ3yIMANoeO2P0RP+n7gtvsk5Ps9CXE1h6O8rhptu6C4hZEg4HNmA81eDEoANSQSGPf0nlrHnP47chrCwwfN27TBNQUzk2OfEmiUdMrFyKuhaBvXRce2EzgGUP0zw4LCgeAYyaz0dx8xxoTcfvbVms/5fVtiZeAAEJZyex441yp11z0QBuW89268XkRYJvonRvavMt91yqdnaxIq9wmzBR3Tzn32V5dtsiatgUCuETQMl6JgDsAWcs8XUgCJccJz7AgiCAaQ291cLUIljX8T/Bfeip+5y/7i1khfYxntGar2cLpGPk9/h9y2w285DBTkyezZHOxnU5dNcj4dGO9V8yrNpl8hcoF6nToNsTBnQDBfZlX8W2TjeTzexlKfEROzqgl03H51rBaED2qXLce0WaiVZatAOatE6cgzeEVU8rWRL68N/6cXUYKMeRJ1GLYDHOBWk6QYSJbuMPU++5hSccZb0ACAdvGN4UEBgN4zmXsedZeSlHHcqmwoMEAAAAALXZobyu6EsWODY9bTLDx+4LwPRAL75a3VS5uYy/4UjORP76ZQSZrCjYyt00nmwaYZ73l6gKWWQE1QGAQbH1nIjHYjbWR7Ulyacer+Ba/m8jzRMR2AKOt5wsgyf1z42Xbs9Ve+qz3/dPlLWIbYz7TrfEOuQc/bDaPkVDdNgCt3073fpG/nBcoSg3OapkdOAJCT8jrEBrI3A7QwmxM4iwc+GJDuCH+33BjVzEWScMVpMinYkGbs5di4faA8Bp1ynTYbjyzpirb0mkRv3k5PhdUvpuRo6D1Xx63O3wWR3alvj+lGuh5hTOHTWYivGecZUnl9empfQJt0hX8NNgvdtu7r5uKGPl6MU2T8SgAABIPAuPc5vDqVS8YC+21RRsBJQP1ZvcOOMs99aOzy3um4dTN9V3+dJnlemdmFHF9b9HI577cKa58eTsCozxG4pRSiSLMQdocl2TofnQI4h03YFTEzIQ3tJB2aeZoYBmqaB0jueQqdHcA6zPwvEjTVz2SofG3nhrxbjwAM9YZGeMQjAxnpNraHIYZw0MTbdG07MHijGq4YaLgH8sR8ZUM6D6+/1QIASy3Sgb6wTsCxUCQCR6Xi6bp+vytqXmreUbQ7Ir2kZ7Tq9P+wHmn2LbS3dD096aOk08bhzUipXlP49agNUjP/LqcYYgQGxmoFW4ys+HqQlHVZRIY3YAWhPL5WoAAABjNoHYiZ3P9RKy/8wlz96jzOcMiF/0PJ6FbXHCIs7yHocsO1ZgEMJ19NhuB9h2DyQACFwkqCsTs1ycS7HdDEG2xnIv1waLSKoLXcBjFP1pGfFQOr/jtvG5bDsbpaofvfwsEuc/KCpDvEGjV0BljnEttULcMQCdeg0YIlIRCcB905QBCh0M/kYaMEvxy9YhJNB7CsxvgBXmsJ7FNJCuZOPHEOYfqF5lEDn6DgcbtxgoieUypO/WjtICmUZCLGoyl66G04tw/uAjdFj+D1UQzIk9Ylbg/SBxH0zIn4bN08LnSfpGwdZTUYDLWgtlzQi1n/Kiw0VgNdex1ajTqicAOMWAAAAFtcrJGWSrTyIVUWqxR6C6xgqaBystia53yMKDH+G94SS3JXTDC8h6RNVxAt4ivovICHdxLZZ3undnc1xJDHgWKZmXeBPu1OkJnZAb5XOI+GttoNuRU3usyr+LSxVj8wxLxhWOUR6W1/XS2GI1LrnFc0sFrcdEKRFYOGH8OJTJeWS0VjOOM3cG0KYTN99VI2nyk7XMu6ZpeQoXPfOgiCcr9X0B1lwLcwfAAICAAAAAFCrN113U4CabcDBTi2zbTZdvnu8PMgTYMf5/ulGUeQm5cj7Z7KMN1kmUQ+8Cax3LGuZU9NI+FrTVa+SAIKeKjZiEkSZUmYNC89s0i9W6wYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFWElGugAAAEV4aWYAAElJKgAIAAAABgASAQMAAQAAAAEAAAAaAQUAAQAAAFYAAAAbAQUAAQAAAF4AAAAoAQMAAQAAAAIAAAATAgMAAQAAAAEAAABphwQAAQAAAGYAAAAAAAAAAHcBAOgDAAAAdwEA6AMAAAYAAJAHAAQAAAAwMjEwAZEHAAQAAAABAgMAAKAHAAQAAAAwMTAwAaADAAEAAAD//wAAAqAEAAEAAACwBAAAA6AEAAEAAACwBAAAAAAAAA=="/>
|
|
3
|
+
</svg>
|