patchpal 0.24.1__tar.gz → 0.24.3__tar.gz
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.
- {patchpal-0.24.1/patchpal.egg-info → patchpal-0.24.3}/PKG-INFO +1 -1
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/__init__.py +1 -1
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/agent/bedrock_profile_utils.py +26 -1
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/sandbox.py +122 -11
- {patchpal-0.24.1 → patchpal-0.24.3/patchpal.egg-info}/PKG-INFO +1 -1
- {patchpal-0.24.1 → patchpal-0.24.3}/LICENSE +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/MANIFEST.in +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/README.md +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/agent/__init__.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/agent/function_calling.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/agent/react.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/__init__.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/autopilot.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/interactive.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/mcp.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/cli/streaming.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/config.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/context.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/permissions.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/prompts/react_prompt.md +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/prompts/system_prompt.md +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/skills.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/__init__.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/audit.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/browser_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/code_analysis.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/common.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/definitions.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/file_reading.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/file_writing.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/find_tool.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/grep_tool.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/image_handler.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/mcp.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/repo_map.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/shell_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/todo_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/tool_schema.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/user_interaction.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal/tools/web_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal.egg-info/SOURCES.txt +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal.egg-info/dependency_links.txt +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal.egg-info/entry_points.txt +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal.egg-info/requires.txt +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/patchpal.egg-info/top_level.txt +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/pyproject.toml +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/setup.cfg +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_agent.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_cli.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_config_dynamic.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_context.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_custom_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_enabled_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_find_tool.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_guardrails.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_image_blocking.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_maximum_security.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_mcp_config.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_memory.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_memory_locations.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_operational_safety.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_optional_tools.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_permissions.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_react.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_reasoning_content.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_repo_map.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_simplified_prompt.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_skills.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_streaming.py +0 -0
- {patchpal-0.24.1 → patchpal-0.24.3}/tests/test_tools.py +0 -0
|
@@ -29,8 +29,33 @@ def _extract_model_from_arn(arn: str) -> str | None:
|
|
|
29
29
|
else:
|
|
30
30
|
region = os.getenv("AWS_REGION_NAME") or os.getenv("AWS_REGION") or "us-east-1"
|
|
31
31
|
|
|
32
|
+
# Check for custom Bedrock endpoint (VPC endpoint, custom domain, etc.)
|
|
33
|
+
# The control plane and runtime may use the same VPC endpoint base
|
|
34
|
+
custom_endpoint = (
|
|
35
|
+
os.getenv("AWS_BEDROCK_ENDPOINT")
|
|
36
|
+
or os.getenv("AWS_ENDPOINT_URL_BEDROCK")
|
|
37
|
+
or os.getenv("AWS_ENDPOINT_URL")
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# CRITICAL FIX: Derive control plane endpoint from runtime VPC endpoint
|
|
41
|
+
# Scenario: User has VPC endpoint for runtime but not explicit control plane endpoint
|
|
42
|
+
# Problem: boto3.client("bedrock") defaults to public endpoint, not VPC endpoint
|
|
43
|
+
# Solution: Automatically derive control plane VPC endpoint from runtime endpoint
|
|
44
|
+
# VPC endpoint pattern:
|
|
45
|
+
# Runtime: vpce-{id}.bedrock-runtime.{region}.vpce.amazonaws.com
|
|
46
|
+
# Control plane: vpce-{id}.bedrock.{region}.vpce.amazonaws.com
|
|
47
|
+
# This matches the automatic derivation in sandbox.py endpoint detection
|
|
48
|
+
if custom_endpoint and "bedrock-runtime" in custom_endpoint:
|
|
49
|
+
# Try to construct control plane VPC endpoint by removing -runtime
|
|
50
|
+
control_endpoint = custom_endpoint.replace("bedrock-runtime", "bedrock")
|
|
51
|
+
else:
|
|
52
|
+
control_endpoint = custom_endpoint
|
|
53
|
+
|
|
32
54
|
# Create bedrock client
|
|
33
|
-
|
|
55
|
+
if control_endpoint:
|
|
56
|
+
bedrock = boto3.client("bedrock", region_name=region, endpoint_url=control_endpoint)
|
|
57
|
+
else:
|
|
58
|
+
bedrock = boto3.client("bedrock", region_name=region)
|
|
34
59
|
|
|
35
60
|
# Get inference profile details
|
|
36
61
|
response = bedrock.get_inference_profile(inferenceProfileIdentifier=arn)
|
|
@@ -144,6 +144,7 @@ def detect_llm_endpoints_from_env():
|
|
|
144
144
|
"ANTHROPIC_API_BASE",
|
|
145
145
|
"AWS_BEDROCK_ENDPOINT",
|
|
146
146
|
"AWS_ENDPOINT_URL_BEDROCK_RUNTIME",
|
|
147
|
+
"AWS_ENDPOINT_URL_BEDROCK", # Control plane endpoint
|
|
147
148
|
"AWS_ENDPOINT_URL",
|
|
148
149
|
"AWS_BEDROCK_RUNTIME_ENDPOINT",
|
|
149
150
|
"AZURE_OPENAI_ENDPOINT",
|
|
@@ -162,6 +163,18 @@ def detect_llm_endpoints_from_env():
|
|
|
162
163
|
# Ensure it's a valid URL
|
|
163
164
|
if value.startswith("http://") or value.startswith("https://"):
|
|
164
165
|
detected_urls.append(value)
|
|
166
|
+
|
|
167
|
+
# CRITICAL FIX: For Bedrock VPC endpoints, derive control plane endpoint
|
|
168
|
+
# Scenario: User has VPC endpoint for runtime API (e.g., AWS GovCloud private network)
|
|
169
|
+
# Problem: Model capability detection needs control plane API (get_inference_profile)
|
|
170
|
+
# but boto3 doesn't automatically derive control plane from runtime endpoint
|
|
171
|
+
# VPC endpoint pattern:
|
|
172
|
+
# Runtime: vpce-{id}.bedrock-runtime.{region}.vpce.amazonaws.com
|
|
173
|
+
# Control plane: vpce-{id}.bedrock.{region}.vpce.amazonaws.com
|
|
174
|
+
# Without this, capability detection hangs trying to reach public control plane endpoint
|
|
175
|
+
if "bedrock-runtime" in value and ".vpce.amazonaws.com" in value:
|
|
176
|
+
control_plane_url = value.replace("bedrock-runtime", "bedrock")
|
|
177
|
+
detected_urls.append(control_plane_url)
|
|
165
178
|
else:
|
|
166
179
|
# Assume https if no protocol specified
|
|
167
180
|
detected_urls.append(f"https://{value}")
|
|
@@ -177,18 +190,37 @@ def detect_llm_endpoints_from_env():
|
|
|
177
190
|
if aws_region and (
|
|
178
191
|
os.environ.get("AWS_ACCESS_KEY_ID") or os.environ.get("AWS_SECRET_ACCESS_KEY")
|
|
179
192
|
):
|
|
180
|
-
# Add Bedrock
|
|
193
|
+
# Add Bedrock endpoints for the region
|
|
181
194
|
# Support both GovCloud and standard regions
|
|
182
195
|
# Also support AWS China regions
|
|
196
|
+
|
|
197
|
+
# IMPORTANT: boto3 uses standard endpoint names by default, even in GovCloud
|
|
198
|
+
# Only use -fips suffix if AWS_USE_FIPS_ENDPOINT=true is explicitly set
|
|
199
|
+
# Scenario 1: Standard GovCloud → bedrock.us-gov-east-1.amazonaws.com (boto3 default)
|
|
200
|
+
# Scenario 2: FIPS required → bedrock-fips.us-gov-east-1.amazonaws.com (explicit opt-in)
|
|
201
|
+
use_fips = os.environ.get("AWS_USE_FIPS_ENDPOINT", "").lower() == "true"
|
|
202
|
+
|
|
183
203
|
if "gov" in aws_region:
|
|
184
|
-
# GovCloud regions
|
|
185
|
-
|
|
204
|
+
# GovCloud regions
|
|
205
|
+
# Add both runtime (for LLM inference) and control plane (for model capability detection)
|
|
206
|
+
if use_fips:
|
|
207
|
+
# FIPS endpoints (only when explicitly requested via AWS_USE_FIPS_ENDPOINT=true)
|
|
208
|
+
detected_urls.append(f"https://bedrock-runtime-fips.{aws_region}.amazonaws.com")
|
|
209
|
+
detected_urls.append(f"https://bedrock-fips.{aws_region}.amazonaws.com")
|
|
210
|
+
else:
|
|
211
|
+
# Standard GovCloud endpoints (boto3 default behavior)
|
|
212
|
+
# This is what boto3 uses unless FIPS is explicitly configured
|
|
213
|
+
detected_urls.append(f"https://bedrock-runtime.{aws_region}.amazonaws.com")
|
|
214
|
+
detected_urls.append(f"https://bedrock.{aws_region}.amazonaws.com")
|
|
186
215
|
elif "cn-" in aws_region:
|
|
187
|
-
# AWS China regions use .amazonaws.com.cn
|
|
216
|
+
# AWS China regions use .amazonaws.com.cn domain
|
|
188
217
|
detected_urls.append(f"https://bedrock-runtime.{aws_region}.amazonaws.com.cn")
|
|
218
|
+
detected_urls.append(f"https://bedrock.{aws_region}.amazonaws.com.cn")
|
|
189
219
|
else:
|
|
190
|
-
# Standard commercial regions
|
|
220
|
+
# Standard commercial regions (us-east-1, eu-west-1, etc.)
|
|
221
|
+
# Add both runtime (for LLM inference) and control plane (for model capability detection)
|
|
191
222
|
detected_urls.append(f"https://bedrock-runtime.{aws_region}.amazonaws.com")
|
|
223
|
+
detected_urls.append(f"https://bedrock.{aws_region}.amazonaws.com")
|
|
192
224
|
|
|
193
225
|
# Azure OpenAI: Extract from resource name if AZURE_OPENAI_KEY is set
|
|
194
226
|
azure_key = os.environ.get("AZURE_OPENAI_KEY") or os.environ.get("AZURE_API_KEY")
|
|
@@ -207,8 +239,15 @@ def detect_llm_endpoints_from_env():
|
|
|
207
239
|
return list(set(detected_urls))
|
|
208
240
|
|
|
209
241
|
|
|
210
|
-
def build_network_restriction_script(allowed_urls, test_mode=False):
|
|
211
|
-
"""Build bash script to configure iptables firewall for network restrictions.
|
|
242
|
+
def build_network_restriction_script(allowed_urls, test_mode=False, block_dns_exfil=True):
|
|
243
|
+
"""Build bash script to configure iptables firewall for network restrictions.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
allowed_urls: List of allowed URL endpoints
|
|
247
|
+
test_mode: Whether to test restrictions and exit
|
|
248
|
+
block_dns_exfil: Whether to block DNS record types used for exfiltration (default: True)
|
|
249
|
+
Blocks TXT, NULL, SRV records and large DNS queries
|
|
250
|
+
"""
|
|
212
251
|
script = """
|
|
213
252
|
echo "=== Pre-downloading required data (before network restrictions) ==="
|
|
214
253
|
|
|
@@ -276,9 +315,70 @@ fi
|
|
|
276
315
|
# Configure iptables
|
|
277
316
|
echo "Configuring firewall rules..."
|
|
278
317
|
|
|
279
|
-
#
|
|
280
|
-
|
|
281
|
-
|
|
318
|
+
# Extract DNS resolver IP(s) from /etc/resolv.conf
|
|
319
|
+
# This locks DNS queries to only the container's configured resolver,
|
|
320
|
+
# preventing agents from directly querying attacker-controlled DNS servers
|
|
321
|
+
RESOLVER_IPS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}')
|
|
322
|
+
|
|
323
|
+
if [ -z "$RESOLVER_IPS" ]; then
|
|
324
|
+
echo "❌ ERROR: Could not detect DNS resolver from /etc/resolv.conf"
|
|
325
|
+
echo "Cannot configure secure DNS filtering without a resolver"
|
|
326
|
+
exit 1
|
|
327
|
+
fi
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
# Add DNS exfiltration blocking if enabled
|
|
331
|
+
if block_dns_exfil:
|
|
332
|
+
script += """
|
|
333
|
+
# Block DNS record types used for data exfiltration (SECURITY ENHANCEMENT)
|
|
334
|
+
# This prevents DNS tunneling attacks that use TXT, NULL, or SRV records
|
|
335
|
+
# to encode and exfiltrate sensitive data through DNS queries
|
|
336
|
+
echo "Blocking DNS record types used for data exfiltration..."
|
|
337
|
+
|
|
338
|
+
# Block TXT records (type 16 = 0x0010)
|
|
339
|
+
# TXT records can carry up to 255 bytes of arbitrary text per record
|
|
340
|
+
# Commonly used for DNS tunneling due to large payload capacity
|
|
341
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 10|" --algo bm -j LOG --log-prefix "BLOCKED-DNS-TXT: " --log-level 4
|
|
342
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 10|" --algo bm -j DROP
|
|
343
|
+
iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "|00 10|" --algo bm -j LOG --log-prefix "BLOCKED-DNS-TXT: " --log-level 4
|
|
344
|
+
iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "|00 10|" --algo bm -j DROP
|
|
345
|
+
|
|
346
|
+
# Block NULL records (type 10 = 0x000a)
|
|
347
|
+
# NULL records are explicitly designed to carry arbitrary binary data
|
|
348
|
+
# No legitimate use in normal DNS resolution
|
|
349
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 0a|" --algo bm -j LOG --log-prefix "BLOCKED-DNS-NULL: " --log-level 4
|
|
350
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 0a|" --algo bm -j DROP
|
|
351
|
+
iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "|00 0a|" --algo bm -j DROP
|
|
352
|
+
|
|
353
|
+
# Block SRV records (type 33 = 0x0021)
|
|
354
|
+
# Service records can be abused for tunneling
|
|
355
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 21|" --algo bm -j LOG --log-prefix "BLOCKED-DNS-SRV: " --log-level 4
|
|
356
|
+
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|00 21|" --algo bm -j DROP
|
|
357
|
+
iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "|00 21|" --algo bm -j DROP
|
|
358
|
+
|
|
359
|
+
# Block large DNS queries (likely subdomain encoding for data exfiltration)
|
|
360
|
+
# Normal DNS queries: 50-100 bytes
|
|
361
|
+
# Queries with encoded data in subdomains: 200+ bytes
|
|
362
|
+
# This catches attempts to encode data in long subdomain names
|
|
363
|
+
iptables -A OUTPUT -p udp --dport 53 -m length --length 150:65535 -j LOG --log-prefix "BLOCKED-DNS-LARGE: " --log-level 4
|
|
364
|
+
iptables -A OUTPUT -p udp --dport 53 -m length --length 150:65535 -j DROP
|
|
365
|
+
iptables -A OUTPUT -p tcp --dport 53 -m length --length 150:65535 -j DROP
|
|
366
|
+
|
|
367
|
+
echo "✓ DNS exfiltration protections active (TXT/NULL/SRV/LARGE queries blocked)"
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
script += """
|
|
371
|
+
# Allow DNS ONLY to detected resolver IPs (SECURITY FIX)
|
|
372
|
+
# This prevents the OpenAI-style DNS tunneling attack where agents
|
|
373
|
+
# send DNS packets directly to attacker-controlled DNS servers
|
|
374
|
+
echo "Locking DNS queries to container's resolver(s):"
|
|
375
|
+
while IFS= read -r RESOLVER_IP; do
|
|
376
|
+
if [ -n "$RESOLVER_IP" ]; then
|
|
377
|
+
echo " $RESOLVER_IP (DNS - A/AAAA records only)"
|
|
378
|
+
iptables -A OUTPUT -d $RESOLVER_IP -p udp --dport 53 -j ACCEPT
|
|
379
|
+
iptables -A OUTPUT -d $RESOLVER_IP -p tcp --dport 53 -j ACCEPT
|
|
380
|
+
fi
|
|
381
|
+
done <<< "$RESOLVER_IPS"
|
|
282
382
|
|
|
283
383
|
# Allow localhost
|
|
284
384
|
iptables -A OUTPUT -d 127.0.0.1/8 -j ACCEPT
|
|
@@ -830,12 +930,23 @@ SECURITY:
|
|
|
830
930
|
|
|
831
931
|
FIREWALL RULES:
|
|
832
932
|
- Only allowed URLs are accessible (auto-detected + --allow-url)
|
|
833
|
-
- DNS resolution permitted (
|
|
933
|
+
- DNS resolution permitted (A/AAAA records only for hostname lookup)
|
|
934
|
+
- DNS exfiltration prevention: TXT, NULL, SRV records BLOCKED
|
|
935
|
+
- Large DNS queries (>150 bytes) BLOCKED (prevents subdomain encoding)
|
|
834
936
|
- Localhost accessible (127.0.0.1/8)
|
|
835
937
|
- All other network traffic BLOCKED and LOGGED
|
|
836
938
|
- Web tools and MCP automatically disabled
|
|
837
939
|
- Ideal for sensitive/regulated environments
|
|
838
940
|
|
|
941
|
+
DNS SECURITY:
|
|
942
|
+
* Blocks DNS tunneling attacks that exfiltrate data via:
|
|
943
|
+
- TXT records (up to 255 bytes per query)
|
|
944
|
+
- NULL records (arbitrary binary data)
|
|
945
|
+
- SRV records (service discovery abuse)
|
|
946
|
+
- Long subdomains (base64-encoded data in domain names)
|
|
947
|
+
* Only allows A and AAAA records (standard hostname resolution)
|
|
948
|
+
* Logs all blocked DNS queries for security auditing
|
|
949
|
+
|
|
839
950
|
Use cases:
|
|
840
951
|
* Compliance: Meet data governance requirements
|
|
841
952
|
* Security: Prevent data exfiltration
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|