diff --git a/electron-ui/index.html b/electron-ui/index.html
index e91f1ba..a9d86ca 100644
--- a/electron-ui/index.html
+++ b/electron-ui/index.html
@@ -114,7 +114,7 @@
Ingest Data
Rockwell PLC
- Import Rockwell L5X exports (.sc files or directories)
+ Import Rockwell PLC files (L5X, L5K, ACD, or pre-exported .sc)
diff --git a/electron-ui/main.js b/electron-ui/main.js
index 4bc2e67..4fb12a2 100644
--- a/electron-ui/main.js
+++ b/electron-ui/main.js
@@ -192,9 +192,9 @@ ipcMain.handle('select-file', async (event, options) => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ['openFile'],
filters: options.filters || [
- { name: 'All Supported', extensions: ['json', 'sc', 'L5X', 'st', 'xml'] },
+ { name: 'All Supported', extensions: ['json', 'sc', 'L5X', 'L5K', 'ACD', 'st', 'xml'] },
{ name: 'Ignition Backup', extensions: ['json'] },
- { name: 'Rockwell PLC', extensions: ['sc', 'L5X'] },
+ { name: 'Rockwell PLC', extensions: ['sc', 'L5X', 'L5K', 'ACD'] },
{ name: 'Siemens PLC', extensions: ['st'] },
{ name: 'TIA Portal XML', extensions: ['xml'] }
]
@@ -211,10 +211,17 @@ ipcMain.handle('select-directory', async () => {
});
// Ingest PLC files - Rockwell (with streaming)
+// Supports L5X, L5K, ACD, and pre-exported .sc files
ipcMain.handle('ingest-plc', async (event, filePath) => {
const streamId = `ingest-plc-${Date.now()}`;
try {
- const output = await runPythonScript('ontology_analyzer.py', [filePath, '-v'], {
+ // Auto-detect Rockwell native formats (L5X, L5K, ACD) vs pre-exported .sc
+ const ext = path.extname(filePath).toLowerCase();
+ const isNativeRockwell = ['.l5x', '.l5k', '.acd'].includes(ext);
+ const args = isNativeRockwell
+ ? [filePath, '--rockwell', '-v']
+ : [filePath, '-v'];
+ const output = await runPythonScript('ontology_analyzer.py', args, {
streaming: true,
streamId
});
diff --git a/electron-ui/renderer.js b/electron-ui/renderer.js
index b3e6188..ed2c8f1 100644
--- a/electron-ui/renderer.js
+++ b/electron-ui/renderer.js
@@ -109,7 +109,7 @@ if (loadIgnitionFileBtn) {
document.getElementById('btn-ingest-plc').addEventListener('click', async () => {
const filePath = await window.api.selectFile({
filters: [
- { name: 'Rockwell PLC Files', extensions: ['sc', 'L5X'] },
+ { name: 'Rockwell PLC Files', extensions: ['sc', 'L5X', 'l5x', 'L5K', 'l5k', 'ACD', 'acd'] },
{ name: 'All Files', extensions: ['*'] }
]
});
diff --git a/rockwell-ingest.ps1 b/rockwell-ingest.ps1
new file mode 100644
index 0000000..569b923
--- /dev/null
+++ b/rockwell-ingest.ps1
@@ -0,0 +1,204 @@
+#!/usr/bin/env pwsh
+<#
+.SYNOPSIS
+ Process Rockwell/Allen-Bradley PLC files into the ontology database
+
+.DESCRIPTION
+ Unified handler for all Rockwell PLC file formats:
+ - .L5X (Studio 5000 XML export — component or full project)
+ - .L5K (Studio 5000 / RSLogix 5000 ASCII text project)
+ - .ACD (Studio 5000 native binary project — requires acd-tools)
+ - .sc (Pre-exported structured code files)
+
+ Auto-detects the file format and routes to the appropriate parser.
+ Can process single files or entire directories containing mixed formats.
+
+.PARAMETER Input
+ Path to a Rockwell PLC file (.L5X, .L5K, .ACD, .sc) or directory
+
+.PARAMETER OutputDir
+ Directory where exported .sc files and ontology results will be saved
+
+.PARAMETER ExportOnly
+ Only export to .sc files without running ontology analysis
+
+.PARAMETER SkipAI
+ Skip AI analysis (import structure only, mark as pending)
+
+.PARAMETER Verbose
+ Enable verbose output
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input "Motor_Control.L5X" -OutputDir ".\export"
+ Process a single L5X file
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input "project.L5K" -OutputDir ".\export"
+ Process an L5K project file
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input "project.ACD" -OutputDir ".\export"
+ Process an ACD binary project file
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input ".\PLC_Files" -OutputDir ".\export"
+ Process all Rockwell files in a directory (L5X, L5K, ACD)
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input "project.L5K" -ExportOnly -OutputDir ".\export"
+ Export L5K to .sc files without ontology analysis
+
+.EXAMPLE
+ .\rockwell-ingest.ps1 -Input "project.L5X" -OutputDir ".\export" -SkipAI
+ Import structure into Neo4j without AI analysis (for incremental mode)
+#>
+
+param(
+ [Parameter(Mandatory=$true)]
+ [string]$Input,
+
+ [Parameter(Mandatory=$true)]
+ [string]$OutputDir,
+
+ [switch]$ExportOnly,
+ [switch]$SkipAI,
+ [switch]$Verbose
+)
+
+$ErrorActionPreference = "Stop"
+
+# Get script directory
+$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
+$scriptsDir = Join-Path $scriptDir "scripts"
+
+# Determine which Python scripts to use
+$rockwellExport = Join-Path $scriptsDir "rockwell_export.py"
+$ontologyAnalyzer = Join-Path $scriptsDir "ontology_analyzer.py"
+
+# Validate inputs
+if (-not (Test-Path $Input)) {
+ Write-Error "Input path not found: $Input"
+ exit 1
+}
+
+if (-not (Test-Path $rockwellExport)) {
+ Write-Error "Python script not found: $rockwellExport"
+ exit 1
+}
+
+# Check for Python
+$pythonCmd = $null
+try {
+ $pythonVersion = python3 --version 2>&1
+ $pythonCmd = "python3"
+ Write-Host "[INFO] Using $pythonVersion" -ForegroundColor Cyan
+} catch {
+ try {
+ $pythonVersion = python --version 2>&1
+ $pythonCmd = "python"
+ Write-Host "[INFO] Using $pythonVersion" -ForegroundColor Cyan
+ } catch {
+ Write-Error "Python not found. Please install Python 3.x"
+ exit 1
+ }
+}
+
+# Check for .env file
+$envFile = Join-Path $scriptDir ".env"
+if (-not $ExportOnly -and -not (Test-Path $envFile)) {
+ Write-Warning ".env file not found. Make sure ANTHROPIC_API_KEY is set in environment for AI analysis."
+}
+
+# Detect file format
+$inputItem = Get-Item $Input
+$extension = $inputItem.Extension.ToLower()
+$isDirectory = $inputItem.PSIsContainer
+
+if ($isDirectory) {
+ $formatDesc = "Directory (all Rockwell formats)"
+ $fileCount = @(
+ (Get-ChildItem -Path $Input -Recurse -Include "*.L5X","*.l5x","*.L5K","*.l5k","*.ACD","*.acd" -ErrorAction SilentlyContinue)
+ ).Count
+ Write-Host "[INFO] Found $fileCount Rockwell PLC file(s) in directory" -ForegroundColor Cyan
+} else {
+ switch ($extension) {
+ ".l5x" { $formatDesc = "L5X (Studio 5000 XML)" }
+ ".l5k" { $formatDesc = "L5K (Legacy ASCII)" }
+ ".acd" { $formatDesc = "ACD (Native Binary)" }
+ ".sc" { $formatDesc = "SC (Pre-exported)" }
+ default { $formatDesc = "Unknown ($extension)" }
+ }
+}
+
+# Create output directory
+if (-not (Test-Path $OutputDir)) {
+ New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
+ Write-Host "[INFO] Created output directory: $OutputDir" -ForegroundColor Cyan
+}
+
+# Display banner
+Write-Host ""
+Write-Host "========================================" -ForegroundColor Blue
+Write-Host " Rockwell PLC Ontology Processor" -ForegroundColor Blue
+Write-Host "========================================" -ForegroundColor Blue
+Write-Host "[INFO] Input: $Input" -ForegroundColor Cyan
+Write-Host "[INFO] Format: $formatDesc" -ForegroundColor Cyan
+Write-Host "[INFO] Output: $OutputDir" -ForegroundColor Cyan
+if ($ExportOnly) {
+ Write-Host "[INFO] Mode: Export Only (.sc files)" -ForegroundColor Yellow
+} elseif ($SkipAI) {
+ Write-Host "[INFO] Mode: Structure Import (no AI)" -ForegroundColor Yellow
+} else {
+ Write-Host "[INFO] Mode: Full Analysis (with AI)" -ForegroundColor Yellow
+}
+Write-Host ""
+
+if ($ExportOnly) {
+ # Export-only mode: convert to .sc files
+ Write-Host "[INFO] Exporting to .sc format..." -ForegroundColor Cyan
+ try {
+ & $pythonCmd $rockwellExport $Input $OutputDir
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "`n[SUCCESS] Export completed!" -ForegroundColor Green
+ Write-Host "[INFO] .sc files saved to: $OutputDir" -ForegroundColor Cyan
+ Write-Host "[INFO] Run without -ExportOnly to analyze with AI" -ForegroundColor Cyan
+ } else {
+ Write-Error "Export failed with exit code $LASTEXITCODE"
+ exit $LASTEXITCODE
+ }
+ } catch {
+ Write-Error "Export failed: $_"
+ exit 1
+ }
+} else {
+ # Full ontology analysis mode
+ Write-Host "[INFO] Starting ontology analysis..." -ForegroundColor Cyan
+
+ $analyzerArgs = @($ontologyAnalyzer, $Input, "--rockwell")
+ if ($SkipAI) {
+ $analyzerArgs += "--skip-ai"
+ }
+ if ($Verbose) {
+ $analyzerArgs += "-v"
+ }
+
+ try {
+ & $pythonCmd @analyzerArgs
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "`n[SUCCESS] Ontology analysis completed!" -ForegroundColor Green
+ if ($SkipAI) {
+ Write-Host "[INFO] Structure imported. Use incremental analyzer for AI enrichment." -ForegroundColor Cyan
+ } else {
+ Write-Host "[INFO] Results stored in Neo4j ontology database." -ForegroundColor Cyan
+ }
+ } else {
+ Write-Error "Analysis failed with exit code $LASTEXITCODE"
+ exit $LASTEXITCODE
+ }
+ } catch {
+ Write-Error "Analysis failed: $_"
+ exit 1
+ }
+}
diff --git a/scripts/acd_parser.py b/scripts/acd_parser.py
new file mode 100644
index 0000000..c407366
--- /dev/null
+++ b/scripts/acd_parser.py
@@ -0,0 +1,359 @@
+#!/usr/bin/env python3
+"""
+Parser for Rockwell/Allen-Bradley ACD (binary archive) project files.
+
+ACD files are the native binary project format for Studio 5000 / RSLogix 5000.
+They are archive files containing compressed XML, database files, and metadata.
+
+This parser uses the 'acd-tools' library (pip install acd-tools) to extract
+the project structure and converts it into SCFile objects compatible with
+the ontology pipeline.
+
+If acd-tools is not installed, this parser falls back to extracting the
+embedded L5X/XML content from the ACD archive and parsing it with the
+L5X parser.
+
+Reference: https://github.com/hutcheb/acd
+"""
+
+import sys
+import os
+import re
+import tempfile
+import zipfile
+import struct
+from pathlib import Path
+from typing import List, Optional
+
+from sc_parser import SCFile, Tag, LogicRung
+
+
+# Try to import acd-tools
+_HAS_ACD_TOOLS = False
+try:
+ from acd import ImportProjectFromFile
+ _HAS_ACD_TOOLS = True
+except ImportError:
+ pass
+
+
+class ACDParser:
+ """Parser for Rockwell ACD (binary) project files.
+
+ Attempts to use the acd-tools library if available, otherwise
+ falls back to extracting embedded XML from the ACD archive.
+ """
+
+ def parse_file(self, file_path: str) -> List[SCFile]:
+ """Parse an ACD file and return list of SCFile objects."""
+ if _HAS_ACD_TOOLS:
+ return self._parse_with_acd_tools(file_path)
+ else:
+ return self._parse_with_fallback(file_path)
+
+ def _parse_with_acd_tools(self, file_path: str) -> List[SCFile]:
+ """Parse using the acd-tools library."""
+ results: List[SCFile] = []
+
+ try:
+ project = ImportProjectFromFile(file_path).import_project()
+ controller = project.controller
+ except Exception as e:
+ print(f"[ERROR] acd-tools failed to parse {file_path}: {e}")
+ return self._parse_with_fallback(file_path)
+
+ controller_name = getattr(controller, 'name', 'Unknown')
+
+ # Extract data types
+ if hasattr(controller, 'data_types') and controller.data_types:
+ for dt in controller.data_types:
+ sc = self._convert_datatype(dt, file_path)
+ if sc:
+ results.append(sc)
+
+ # Extract programs and routines
+ if hasattr(controller, 'programs') and controller.programs:
+ for program in controller.programs:
+ sc = self._convert_program(program, file_path)
+ if sc:
+ results.append(sc)
+
+ # Extract tags
+ if hasattr(controller, 'tags') and controller.tags:
+ ctrl_sc = SCFile(
+ file_path=file_path,
+ name=controller_name,
+ type='CONTROLLER',
+ )
+ for tag in controller.tags:
+ tag_name = getattr(tag, 'name', None)
+ tag_type = getattr(tag, 'data_type', 'BOOL')
+ tag_desc = getattr(tag, 'description', None)
+ if tag_name:
+ ctrl_sc.local_tags.append(Tag(
+ name=tag_name,
+ data_type=str(tag_type) if tag_type else 'BOOL',
+ description=str(tag_desc) if tag_desc else None,
+ ))
+ if ctrl_sc.local_tags:
+ results.append(ctrl_sc)
+
+ return results
+
+ def _convert_datatype(self, dt, source_file: str) -> Optional[SCFile]:
+ """Convert an acd-tools data type to SCFile."""
+ name = getattr(dt, 'name', None)
+ if not name:
+ return None
+
+ sc = SCFile(
+ file_path=source_file,
+ name=name,
+ type='UDT',
+ description=getattr(dt, 'description', None),
+ )
+
+ if hasattr(dt, 'members'):
+ for member in dt.members:
+ mem_name = getattr(member, 'name', '')
+ mem_type = getattr(member, 'data_type', 'SINT')
+ mem_desc = getattr(member, 'description', None)
+ if mem_name and not mem_name.startswith('ZZZZZZZZ'):
+ sc.local_tags.append(Tag(
+ name=mem_name,
+ data_type=str(mem_type) if mem_type else 'SINT',
+ description=str(mem_desc) if mem_desc else None,
+ ))
+
+ return sc if sc.local_tags else None
+
+ def _convert_program(self, program, source_file: str) -> Optional[SCFile]:
+ """Convert an acd-tools program to SCFile."""
+ name = getattr(program, 'name', None)
+ if not name:
+ return None
+
+ sc = SCFile(
+ file_path=source_file,
+ name=name,
+ type='PROGRAM',
+ description=getattr(program, 'description', None),
+ )
+
+ # Extract routines
+ if hasattr(program, 'routines') and program.routines:
+ for routine in program.routines:
+ r_name = getattr(routine, 'name', 'Main')
+ r_type = getattr(routine, 'type', 'RLL')
+ rungs: List[LogicRung] = []
+ raw_parts = []
+
+ if hasattr(routine, 'rungs') and routine.rungs:
+ for i, rung in enumerate(routine.rungs):
+ rung_text = str(rung) if rung else ""
+ comment = getattr(rung, 'comment', None)
+ rungs.append(LogicRung(
+ number=i,
+ comment=str(comment) if comment else None,
+ logic=rung_text,
+ ))
+ raw_parts.append(rung_text)
+
+ sc.routines.append({
+ 'name': r_name,
+ 'type': str(r_type) if r_type else 'RLL',
+ 'rungs': rungs,
+ 'raw_content': '\n'.join(raw_parts),
+ })
+
+ # Extract program-scoped tags
+ if hasattr(program, 'tags') and program.tags:
+ for tag in program.tags:
+ tag_name = getattr(tag, 'name', None)
+ tag_type = getattr(tag, 'data_type', 'BOOL')
+ tag_desc = getattr(tag, 'description', None)
+ if tag_name:
+ sc.local_tags.append(Tag(
+ name=tag_name,
+ data_type=str(tag_type) if tag_type else 'BOOL',
+ description=str(tag_desc) if tag_desc else None,
+ ))
+
+ # Build raw implementation
+ if sc.routines:
+ parts = []
+ for r in sc.routines:
+ parts.append(f"(* ROUTINE: {r['name']} [{r['type']}] *)")
+ if r.get('raw_content'):
+ parts.append(r['raw_content'])
+ sc.raw_implementation = '\n'.join(parts)
+
+ return sc
+
+ def _parse_with_fallback(self, file_path: str) -> List[SCFile]:
+ """Fallback: extract embedded XML from ACD archive and parse with L5X parser.
+
+ ACD files are essentially archives containing compressed XML among other data.
+ We attempt to extract any XML content and parse it.
+ """
+ print("[INFO] acd-tools not available, using fallback XML extraction...")
+
+ # Try to read the file and look for embedded XML
+ xml_content = self._extract_xml_from_acd(file_path)
+
+ if not xml_content:
+ print(f"[WARNING] Could not extract XML from ACD file: {file_path}")
+ print("[INFO] Install acd-tools for full ACD support: pip install acd-tools")
+ return []
+
+ # Parse the extracted XML with L5X parser
+ from l5x_export import L5XParser
+ import xml.etree.ElementTree as ET
+
+ results: List[SCFile] = []
+ l5x_parser = L5XParser()
+
+ for xml_str in xml_content:
+ try:
+ root = ET.fromstring(xml_str)
+ parsed = l5x_parser._parse_root(root, source_file=file_path)
+ results.extend(parsed)
+ except ET.ParseError:
+ continue
+
+ if not results:
+ print(f"[WARNING] No parseable content found in ACD file: {file_path}")
+ print("[INFO] Install acd-tools for full ACD support: pip install acd-tools")
+
+ return results
+
+ def _extract_xml_from_acd(self, file_path: str) -> List[str]:
+ """Attempt to extract embedded XML content from an ACD binary file.
+
+ ACD files contain compressed (zlib) XML sections. We scan the binary
+ for zlib-compressed blocks and attempt to decompress them, then check
+ if the result looks like XML.
+ """
+ import zlib
+
+ xml_sections = []
+
+ try:
+ with open(file_path, 'rb') as f:
+ data = f.read()
+ except IOError as e:
+ print(f"[ERROR] Cannot read ACD file: {e}")
+ return []
+
+ # Strategy 1: Look for zlib headers (0x78 0x9C, 0x78 0x01, 0x78 0xDA)
+ zlib_headers = [b'\x78\x9c', b'\x78\x01', b'\x78\xda']
+
+ for header in zlib_headers:
+ pos = 0
+ while True:
+ idx = data.find(header, pos)
+ if idx == -1:
+ break
+
+ # Try to decompress from this position
+ for length in [len(data) - idx, min(len(data) - idx, 1024 * 1024)]:
+ try:
+ decompressed = zlib.decompress(data[idx:idx + length])
+ text = decompressed.decode('utf-8', errors='ignore')
+ # Check if it contains XML-like content
+ if '= 0:
+ xml_sections.append(text[xml_start:])
+ break
+ except (zlib.error, UnicodeDecodeError):
+ continue
+
+ pos = idx + 1
+
+ # Strategy 2: Look for raw XML strings in the binary
+ if not xml_sections:
+ text = data.decode('utf-8', errors='ignore')
+ # Find blocks
+ ctrl_matches = list(re.finditer(
+ r']*>.*?',
+ text,
+ re.DOTALL,
+ ))
+ for m in ctrl_matches:
+ xml_sections.append(m.group(0))
+
+ return xml_sections
+
+ def export_to_sc(self, file_path: str, output_dir: str) -> int:
+ """Parse ACD file and export each component as .sc files."""
+ from l5k_parser import _write_sc_file
+
+ os.makedirs(output_dir, exist_ok=True)
+ sc_files = self.parse_file(file_path)
+ count = 0
+
+ for sc in sc_files:
+ if sc.type == 'AOI':
+ suffix = '.aoi.sc'
+ elif sc.type == 'UDT':
+ suffix = '.udt.sc'
+ elif sc.type == 'PROGRAM':
+ suffix = '.prog.sc'
+ elif sc.type == 'CONTROLLER':
+ suffix = '.ctrl.sc'
+ else:
+ suffix = '.sc'
+
+ out_path = os.path.join(output_dir, f"{sc.name}{suffix}")
+ _write_sc_file(sc, out_path)
+ count += 1
+ print(f"[OK] Exported {sc.type}: {sc.name}")
+
+ return count
+
+
+# ---------------------------------------------------------------------------
+# CLI
+# ---------------------------------------------------------------------------
+
+def main():
+ """CLI for ACD parser."""
+ if len(sys.argv) < 2:
+ print("Usage: python acd_parser.py [output_dir]")
+ print(" Parse ACD file and optionally export to .sc format")
+ if not _HAS_ACD_TOOLS:
+ print("\n[INFO] For best results, install acd-tools: pip install acd-tools")
+ sys.exit(1)
+
+ file_path = sys.argv[1]
+ output_dir = sys.argv[2] if len(sys.argv) > 2 else None
+
+ if not Path(file_path).exists():
+ print(f"[ERROR] File not found: {file_path}")
+ sys.exit(1)
+
+ parser = ACDParser()
+
+ if output_dir:
+ count = parser.export_to_sc(file_path, output_dir)
+ print(f"\n[OK] Exported {count} components to {output_dir}")
+ else:
+ sc_files = parser.parse_file(file_path)
+ print(f"\n[INFO] Parsed {len(sc_files)} components from {Path(file_path).name}:")
+ for sc in sc_files:
+ tag_count = (len(sc.input_tags) + len(sc.output_tags) +
+ len(sc.inout_tags) + len(sc.local_tags))
+ routine_count = len(sc.routines)
+ desc = f" - {sc.description[:60]}..." if sc.description else ""
+ print(f" [{sc.type}] {sc.name}: {tag_count} tags, "
+ f"{routine_count} routines{desc}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/l5k_parser.py b/scripts/l5k_parser.py
new file mode 100644
index 0000000..93770e4
--- /dev/null
+++ b/scripts/l5k_parser.py
@@ -0,0 +1,736 @@
+#!/usr/bin/env python3
+"""
+Parser for Rockwell/Allen-Bradley L5K (ASCII text) project files.
+
+L5K is a full-project text format exported from Studio 5000 / RSLogix 5000.
+It uses keyword-delimited blocks (CONTROLLER, DATATYPE, TAG, PROGRAM,
+ROUTINE, TASK, MODULE, ADD_ON_INSTRUCTION_DEFINITION) nested in a hierarchy:
+
+ IE_VER := x.x;
+ CONTROLLER ...
+ DATATYPE ... END_DATATYPE
+ MODULE ... END_MODULE
+ ADD_ON_INSTRUCTION_DEFINITION ... END_ADD_ON_INSTRUCTION_DEFINITION
+ TAG ... ;
+ TASK ...
+ PROGRAM ...
+ TAG ... ;
+ ROUTINE ...
+
+ END_ROUTINE
+ END_PROGRAM
+ END_TASK
+ END_CONTROLLER
+
+This parser converts L5K content into the same SCFile data structures used by
+the existing sc_parser.py, enabling the ontology pipeline to process L5K files
+without modification.
+
+Reference: Rockwell Publication 1756-RM084 (L5K/L5X Import/Export Reference)
+"""
+
+import re
+import sys
+from dataclasses import dataclass, field
+from typing import List, Dict, Optional, Tuple
+from pathlib import Path
+
+from sc_parser import SCFile, Tag, LogicRung
+
+
+# ---------------------------------------------------------------------------
+# L5K block extraction helpers
+# ---------------------------------------------------------------------------
+
+def _find_block(text: str, keyword: str, end_keyword: str,
+ start_pos: int = 0) -> Optional[Tuple[str, str, int]]:
+ """Find next block delimited by keyword / end_keyword.
+
+ Returns (block_name, block_body, end_position) or None.
+ """
+ pattern = re.compile(
+ rf'^\s*{keyword}\s+(\S+)',
+ re.MULTILINE,
+ )
+ m = pattern.search(text, start_pos)
+ if not m:
+ return None
+
+ block_name = m.group(1).strip('(').strip()
+ # Find the matching END_ keyword (same indentation level tracking)
+ depth = 1
+ pos = m.end()
+ end_pat = re.compile(
+ rf'^\s*({keyword}|{end_keyword})\b',
+ re.MULTILINE,
+ )
+ while depth > 0:
+ em = end_pat.search(text, pos)
+ if not em:
+ # No matching end — take rest of text
+ return block_name, text[m.end():], len(text)
+ if em.group(1) == end_keyword:
+ depth -= 1
+ if depth == 0:
+ return block_name, text[m.end():em.start()], em.end()
+ else:
+ depth += 1
+ pos = em.end()
+ return None
+
+
+def _find_all_blocks(text: str, keyword: str,
+ end_keyword: str) -> List[Tuple[str, str]]:
+ """Find all top-level blocks of a given type. Returns [(name, body), ...]."""
+ results = []
+ pos = 0
+ while True:
+ result = _find_block(text, keyword, end_keyword, pos)
+ if result is None:
+ break
+ name, body, end_pos = result
+ results.append((name, body))
+ pos = end_pos
+ return results
+
+
+# ---------------------------------------------------------------------------
+# Tag / member parsing
+# ---------------------------------------------------------------------------
+
+# L5K tag declaration pattern:
+# TAG : (Description := "...", ...) := ;
+# or multi-line within a block. We handle the common forms.
+_TAG_LINE_RE = re.compile(
+ r'TAG\s+(\w+)\s*:\s*(\S+)'
+ r'(?:\s*\(([^)]*)\))?' # optional attributes in parens
+ r'(?:\s*:=\s*(\S+))?\s*;', # optional default
+ re.IGNORECASE,
+)
+
+# Simpler inline tag (inside PROGRAM blocks): name : type := value ;
+_INLINE_TAG_RE = re.compile(
+ r'^\s*(\w+)\s*:\s*([^;:=(]+?)\s*'
+ r'(?:\(([^)]*)\))?\s*'
+ r'(?::=\s*([^;]+?))?\s*;',
+ re.MULTILINE,
+)
+
+_DESC_RE = re.compile(r'Description\s*:=\s*"([^"]*)"', re.IGNORECASE)
+_USAGE_RE = re.compile(r'Usage\s*:=\s*(\w+)', re.IGNORECASE)
+_EXTERNAL_ACCESS_RE = re.compile(r'ExternalAccess\s*:=\s*(\w+)', re.IGNORECASE)
+
+
+def _parse_l5k_tag_attrs(attr_str: str) -> Dict[str, str]:
+ """Parse parenthesized attribute list into a dict."""
+ attrs: Dict[str, str] = {}
+ if not attr_str:
+ return attrs
+ m = _DESC_RE.search(attr_str)
+ if m:
+ attrs['description'] = m.group(1)
+ m = _USAGE_RE.search(attr_str)
+ if m:
+ attrs['usage'] = m.group(1)
+ m = _EXTERNAL_ACCESS_RE.search(attr_str)
+ if m:
+ attrs['external_access'] = m.group(1)
+ return attrs
+
+
+def _parse_l5k_tags(text: str, scope: str = "controller") -> List[Tag]:
+ """Parse TAG declarations from an L5K text block.
+
+ The *scope* is used for labeling but doesn't affect parsing.
+ """
+ tags: List[Tag] = []
+
+ for m in _TAG_LINE_RE.finditer(text):
+ name = m.group(1)
+ data_type = m.group(2).strip()
+ attrs = _parse_l5k_tag_attrs(m.group(3) or "")
+ default = m.group(4)
+
+ # Map Usage attribute to direction
+ usage = attrs.get('usage', '').lower()
+ direction_map = {
+ 'input': 'INPUT',
+ 'output': 'OUTPUT',
+ 'inout': 'IN_OUT',
+ }
+ direction = direction_map.get(usage)
+
+ # Detect arrays
+ is_array = False
+ array_bounds = None
+ arr_match = re.match(r'(\w+)\[(.+?)\]', data_type)
+ if arr_match:
+ data_type = arr_match.group(1)
+ array_bounds = arr_match.group(2)
+ is_array = True
+
+ tags.append(Tag(
+ name=name,
+ data_type=data_type,
+ direction=direction,
+ description=attrs.get('description'),
+ default_value=default,
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ return tags
+
+
+# ---------------------------------------------------------------------------
+# DATATYPE parsing → UDT SCFile objects
+# ---------------------------------------------------------------------------
+
+_MEMBER_RE = re.compile(
+ r'MEMBER\s+(\w+)\s*:\s*(\S+?)\s*'
+ r'(?:\(([^)]*)\))?\s*;',
+ re.IGNORECASE,
+)
+
+
+def _parse_datatype_block(name: str, body: str,
+ source_file: str) -> SCFile:
+ """Convert a DATATYPE block into an SCFile representing a UDT."""
+ members: List[Tag] = []
+
+ for m in _MEMBER_RE.finditer(body):
+ mem_name = m.group(1)
+ mem_type = m.group(2).strip()
+ attrs = _parse_l5k_tag_attrs(m.group(3) or "")
+
+ # Skip hidden helper members (like ZZZZZZZZZZ padding)
+ if mem_name.startswith('ZZZZZZZZ'):
+ continue
+
+ is_array = False
+ array_bounds = None
+ arr = re.match(r'(\w+)\[(.+?)\]', mem_type)
+ if arr:
+ mem_type = arr.group(1)
+ array_bounds = arr.group(2)
+ is_array = True
+
+ members.append(Tag(
+ name=mem_name,
+ data_type=mem_type,
+ description=attrs.get('description'),
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ # Also try to pick up members via bare "name : type ;" lines within the body
+ # L5K DATATYPEs sometimes list members without the MEMBER keyword
+ for m in _INLINE_TAG_RE.finditer(body):
+ candidate = m.group(1)
+ if candidate.upper() in ('MEMBER', 'DATATYPE', 'END_DATATYPE',
+ 'FAMILY', 'CLASS'):
+ continue
+ if candidate.startswith('ZZZZZZZZ'):
+ continue
+ # Avoid duplicates
+ if any(t.name == candidate for t in members):
+ continue
+ mem_type = m.group(2).strip()
+ attrs = _parse_l5k_tag_attrs(m.group(3) or "")
+
+ is_array = False
+ array_bounds = None
+ arr = re.match(r'(\w+)\[(.+?)\]', mem_type)
+ if arr:
+ mem_type = arr.group(1)
+ array_bounds = arr.group(2)
+ is_array = True
+
+ members.append(Tag(
+ name=candidate,
+ data_type=mem_type,
+ description=attrs.get('description'),
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ # Extract family / class info from body
+ family_m = re.search(r'Family\s*:=\s*(\w+)', body, re.IGNORECASE)
+ class_m = re.search(r'Class\s*:=\s*(\w+)', body, re.IGNORECASE)
+ desc_m = re.search(r'Description\s*:=\s*"([^"]*)"', body, re.IGNORECASE)
+
+ sc = SCFile(
+ file_path=source_file,
+ name=name,
+ type='UDT',
+ description=desc_m.group(1) if desc_m else None,
+ )
+ sc.local_tags = members
+ return sc
+
+
+# ---------------------------------------------------------------------------
+# ROUTINE parsing → logic extraction
+# ---------------------------------------------------------------------------
+
+_RUNG_RE = re.compile(
+ r'(?:RC\s*:=\s*"([^"]*?)"\s*;?\s*)?' # optional rung comment
+ r'(?:N|NR|D)?\s*:?\s*' # optional rung type prefix
+ r'((?:[A-Z]{2,4}\([^;]*?\)\s*)*;)', # ladder instructions ending with ;
+ re.IGNORECASE | re.DOTALL,
+)
+
+_ST_BODY_RE = re.compile(
+ r'ST\s*\((.*?)\)\s*;',
+ re.DOTALL,
+)
+
+
+def _parse_routine_block(name: str, body: str) -> Dict:
+ """Parse a ROUTINE block into a dict matching the SCFile routines format."""
+ # Determine routine type
+ type_m = re.search(r'Type\s*:=\s*(\w+)', body, re.IGNORECASE)
+ routine_type = type_m.group(1).upper() if type_m else 'RLL'
+
+ rungs: List[LogicRung] = []
+ raw_content = body.strip()
+
+ if routine_type in ('RLL', 'LADDER'):
+ # Extract RLL content — look for rung lines
+ # L5K rungs: N: ; or just ;
+ # Comments: RC := "comment text";
+ rung_num = 0
+ lines = body.split('\n')
+ current_comment = None
+ current_logic_lines: List[str] = []
+
+ for line in lines:
+ stripped = line.strip()
+
+ # Rung comment
+ rc_match = re.match(r'RC\s*:=\s*"(.*?)"\s*;', stripped)
+ if rc_match:
+ # Save previous rung
+ if current_logic_lines:
+ logic_text = ' '.join(current_logic_lines).strip()
+ if logic_text:
+ rungs.append(LogicRung(
+ number=rung_num,
+ comment=current_comment,
+ logic=logic_text,
+ ))
+ rung_num += 1
+ current_logic_lines = []
+ current_comment = rc_match.group(1)
+ continue
+
+ # Rung type markers (N: = normal, NR: = not retentive, D: = delete)
+ type_match = re.match(r'^(N|NR|D)\s*:\s*(.*)', stripped)
+ if type_match:
+ # Save previous rung
+ if current_logic_lines:
+ logic_text = ' '.join(current_logic_lines).strip()
+ if logic_text:
+ rungs.append(LogicRung(
+ number=rung_num,
+ comment=current_comment,
+ logic=logic_text,
+ ))
+ rung_num += 1
+ current_logic_lines = []
+ current_comment = None
+
+ rest = type_match.group(2).strip()
+ if rest:
+ current_logic_lines.append(rest)
+ continue
+
+ # Ladder instructions (XIC, XIO, OTE, TON, etc.)
+ if stripped and re.match(r'[A-Z]', stripped) and '(' in stripped:
+ current_logic_lines.append(stripped)
+ elif stripped.endswith(';') and current_logic_lines:
+ current_logic_lines.append(stripped)
+
+ # Final rung
+ if current_logic_lines:
+ logic_text = ' '.join(current_logic_lines).strip()
+ if logic_text:
+ rungs.append(LogicRung(
+ number=rung_num,
+ comment=current_comment,
+ logic=logic_text,
+ ))
+
+ elif routine_type in ('ST', 'STRUCTURED_TEXT'):
+ # Structured text — extract ST body
+ # The entire body between the routine markers is the ST code
+ pass # raw_content will be used
+
+ return {
+ 'name': name,
+ 'type': routine_type,
+ 'rungs': rungs,
+ 'raw_content': raw_content,
+ }
+
+
+# ---------------------------------------------------------------------------
+# ADD_ON_INSTRUCTION_DEFINITION parsing → AOI SCFile objects
+# ---------------------------------------------------------------------------
+
+def _parse_aoi_block(name: str, body: str,
+ source_file: str) -> SCFile:
+ """Parse an ADD_ON_INSTRUCTION_DEFINITION block into an SCFile."""
+ # Extract metadata
+ revision_m = re.search(r'Revision\s*:=\s*(\S+)', body, re.IGNORECASE)
+ vendor_m = re.search(r'Vendor\s*:=\s*"([^"]*)"', body, re.IGNORECASE)
+ desc_m = re.search(r'Description\s*:=\s*"([^"]*)"', body, re.IGNORECASE)
+
+ sc = SCFile(
+ file_path=source_file,
+ name=name,
+ type='AOI',
+ revision=revision_m.group(1).rstrip(';') if revision_m else None,
+ vendor=vendor_m.group(1) if vendor_m else None,
+ description=desc_m.group(1) if desc_m else None,
+ )
+
+ # Extract parameters (they look like TAG declarations with Usage)
+ tags = _parse_l5k_tags(body, scope="aoi")
+ for tag in tags:
+ if tag.name in ('EnableIn', 'EnableOut'):
+ continue
+ if tag.direction == 'INPUT':
+ sc.input_tags.append(tag)
+ elif tag.direction == 'OUTPUT':
+ sc.output_tags.append(tag)
+ elif tag.direction == 'IN_OUT':
+ sc.inout_tags.append(tag)
+ else:
+ sc.local_tags.append(tag)
+
+ # Also find LOCAL_TAG entries specific to AOIs
+ local_tag_re = re.compile(
+ r'LOCAL_TAG\s+(\w+)\s*:\s*(\S+?)\s*'
+ r'(?:\(([^)]*)\))?\s*'
+ r'(?::=\s*([^;]+?))?\s*;',
+ re.IGNORECASE,
+ )
+ for m in local_tag_re.finditer(body):
+ tag_name = m.group(1)
+ if any(t.name == tag_name for t in sc.local_tags):
+ continue
+ data_type = m.group(2).strip()
+ attrs = _parse_l5k_tag_attrs(m.group(3) or "")
+ default = m.group(4)
+
+ is_array = False
+ array_bounds = None
+ arr = re.match(r'(\w+)\[(.+?)\]', data_type)
+ if arr:
+ data_type = arr.group(1)
+ array_bounds = arr.group(2)
+ is_array = True
+
+ sc.local_tags.append(Tag(
+ name=tag_name,
+ data_type=data_type,
+ description=attrs.get('description'),
+ default_value=default,
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ # Extract routines
+ routines = _find_all_blocks(body, 'ROUTINE', 'END_ROUTINE')
+ for rname, rbody in routines:
+ sc.routines.append(_parse_routine_block(rname, rbody))
+
+ # Build raw implementation from all routine content
+ if sc.routines:
+ parts = []
+ for r in sc.routines:
+ parts.append(f"(* ROUTINE: {r['name']} [{r['type']}] *)")
+ if r.get('raw_content'):
+ parts.append(r['raw_content'])
+ sc.raw_implementation = '\n'.join(parts)
+
+ return sc
+
+
+# ---------------------------------------------------------------------------
+# PROGRAM parsing → Program SCFile objects
+# ---------------------------------------------------------------------------
+
+def _parse_program_block(name: str, body: str,
+ source_file: str) -> SCFile:
+ """Parse a PROGRAM block into an SCFile."""
+ desc_m = re.search(r'Description\s*:=\s*"([^"]*)"', body, re.IGNORECASE)
+
+ sc = SCFile(
+ file_path=source_file,
+ name=name,
+ type='PROGRAM',
+ description=desc_m.group(1) if desc_m else None,
+ )
+
+ # Extract program-scoped tags
+ tags = _parse_l5k_tags(body, scope="program")
+ for tag in tags:
+ if tag.direction == 'INPUT':
+ sc.input_tags.append(tag)
+ elif tag.direction == 'OUTPUT':
+ sc.output_tags.append(tag)
+ elif tag.direction == 'IN_OUT':
+ sc.inout_tags.append(tag)
+ else:
+ sc.local_tags.append(tag)
+
+ # Extract routines
+ routines = _find_all_blocks(body, 'ROUTINE', 'END_ROUTINE')
+ for rname, rbody in routines:
+ sc.routines.append(_parse_routine_block(rname, rbody))
+
+ if sc.routines:
+ parts = []
+ for r in sc.routines:
+ parts.append(f"(* ROUTINE: {r['name']} [{r['type']}] *)")
+ if r.get('raw_content'):
+ parts.append(r['raw_content'])
+ sc.raw_implementation = '\n'.join(parts)
+
+ return sc
+
+
+# ---------------------------------------------------------------------------
+# Main L5K parser
+# ---------------------------------------------------------------------------
+
+class L5KParser:
+ """Parser for Rockwell L5K (ASCII) project files.
+
+ Parses the entire project and returns a list of SCFile objects
+ (one per AOI, UDT, and PROGRAM found in the project).
+ """
+
+ def parse_file(self, file_path: str) -> List[SCFile]:
+ """Parse an L5K file and return list of SCFile objects."""
+ with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
+ content = f.read()
+
+ return self.parse_text(content, source_file=file_path)
+
+ def parse_text(self, text: str, source_file: str = "") -> List[SCFile]:
+ """Parse L5K text content and return list of SCFile objects."""
+ results: List[SCFile] = []
+
+ # Extract controller name for context
+ ctrl_m = re.search(r'CONTROLLER\s+(\w+)', text, re.IGNORECASE)
+ controller_name = ctrl_m.group(1) if ctrl_m else "Unknown"
+
+ # 1. Parse DATATYPEs → UDTs
+ datatypes = _find_all_blocks(text, 'DATATYPE', 'END_DATATYPE')
+ for dt_name, dt_body in datatypes:
+ sc = _parse_datatype_block(dt_name, dt_body, source_file)
+ results.append(sc)
+
+ # 2. Parse ADD_ON_INSTRUCTION_DEFINITIONs → AOIs
+ aois = _find_all_blocks(
+ text,
+ 'ADD_ON_INSTRUCTION_DEFINITION',
+ 'END_ADD_ON_INSTRUCTION_DEFINITION',
+ )
+ for aoi_name, aoi_body in aois:
+ sc = _parse_aoi_block(aoi_name, aoi_body, source_file)
+ results.append(sc)
+
+ # 3. Parse PROGRAMs
+ programs = _find_all_blocks(text, 'PROGRAM', 'END_PROGRAM')
+ for prog_name, prog_body in programs:
+ sc = _parse_program_block(prog_name, prog_body, source_file)
+ results.append(sc)
+
+ # 4. Extract controller-scoped tags as a synthetic "CONTROLLER" SCFile
+ # (everything between CONTROLLER and the first nested block)
+ ctrl_tags = _parse_l5k_tags(text, scope="controller")
+ if ctrl_tags:
+ ctrl_sc = SCFile(
+ file_path=source_file,
+ name=controller_name,
+ type='CONTROLLER',
+ )
+ for tag in ctrl_tags:
+ if tag.direction == 'INPUT':
+ ctrl_sc.input_tags.append(tag)
+ elif tag.direction == 'OUTPUT':
+ ctrl_sc.output_tags.append(tag)
+ else:
+ ctrl_sc.local_tags.append(tag)
+ results.append(ctrl_sc)
+
+ return results
+
+ def export_to_sc(self, file_path: str, output_dir: str) -> int:
+ """Parse L5K file and export each component as .sc files.
+
+ Returns count of exported files.
+ """
+ import os
+ os.makedirs(output_dir, exist_ok=True)
+
+ sc_files = self.parse_file(file_path)
+ count = 0
+
+ for sc in sc_files:
+ if sc.type == 'AOI':
+ suffix = '.aoi.sc'
+ elif sc.type == 'UDT':
+ suffix = '.udt.sc'
+ elif sc.type == 'PROGRAM':
+ suffix = '.prog.sc'
+ elif sc.type == 'CONTROLLER':
+ suffix = '.ctrl.sc'
+ else:
+ suffix = '.sc'
+
+ out_path = os.path.join(output_dir, f"{sc.name}{suffix}")
+ _write_sc_file(sc, out_path)
+ count += 1
+ print(f"[OK] Exported {sc.type}: {sc.name}")
+
+ return count
+
+
+def _sanitize_comment(text: str) -> str:
+ """Collapse multi-line text into a single line for inline comments."""
+ return ' | '.join(line.strip() for line in text.splitlines() if line.strip())
+
+
+def _write_sc_file(sc: SCFile, path: str):
+ """Write an SCFile to disk in the standard .sc text format."""
+ with open(path, 'w', encoding='utf-8') as f:
+ # Header
+ type_label = sc.type
+ if type_label == 'AOI':
+ f.write(f"(* AOI: {sc.name} *)\n")
+ f.write(f"(* Type: AddOnInstruction *)\n")
+ elif type_label == 'UDT':
+ f.write(f"(* UDT: {sc.name} *)\n")
+ f.write(f"(* Type: UserDefinedType *)\n")
+ elif type_label == 'PROGRAM':
+ f.write(f"(* POU: {sc.name} *)\n")
+ f.write(f"(* Type: Program *)\n")
+ elif type_label == 'CONTROLLER':
+ f.write(f"(* POU: {sc.name} *)\n")
+ f.write(f"(* Type: Controller *)\n")
+ else:
+ f.write(f"(* POU: {sc.name} *)\n")
+ f.write(f"(* Type: {type_label} *)\n")
+
+ if sc.revision:
+ f.write(f"(* Revision: {sc.revision} *)\n")
+ if sc.vendor:
+ f.write(f"(* Vendor: {sc.vendor} *)\n")
+ if sc.description:
+ f.write(f"(* Description: {sc.description} *)\n")
+ f.write("\n")
+
+ # UDT members
+ if type_label == 'UDT' and sc.local_tags:
+ f.write(f"TYPE {sc.name} :\n")
+ f.write("STRUCT\n")
+ for tag in sc.local_tags:
+ desc = f" // {_sanitize_comment(tag.description)}" if tag.description else ""
+ if tag.is_array and tag.array_bounds:
+ f.write(f"\t{tag.name}: ARRAY[{tag.array_bounds}] OF {tag.data_type};{desc}\n")
+ else:
+ f.write(f"\t{tag.name}: {tag.data_type};{desc}\n")
+ f.write("END_STRUCT\n")
+ f.write("END_TYPE\n")
+ return
+
+ # Parameters / tags
+ if sc.input_tags:
+ f.write("(* PARAMETERS *)\n")
+ f.write("VAR_INPUT\n")
+ for tag in sc.input_tags:
+ desc = f" // {_sanitize_comment(tag.description)}" if tag.description else ""
+ f.write(f"\t{tag.name}: {tag.data_type};{desc}\n")
+ f.write("END_VAR\n\n")
+
+ if sc.output_tags:
+ f.write("VAR_OUTPUT\n")
+ for tag in sc.output_tags:
+ desc = f" // {_sanitize_comment(tag.description)}" if tag.description else ""
+ f.write(f"\t{tag.name}: {tag.data_type};{desc}\n")
+ f.write("END_VAR\n\n")
+
+ if sc.inout_tags:
+ f.write("VAR_IN_OUT\n")
+ for tag in sc.inout_tags:
+ desc = f" // {_sanitize_comment(tag.description)}" if tag.description else ""
+ f.write(f"\t{tag.name}: {tag.data_type};{desc}\n")
+ f.write("END_VAR\n\n")
+
+ if sc.local_tags:
+ f.write("(* LOCAL TAGS *)\n")
+ f.write("VAR\n")
+ for tag in sc.local_tags:
+ desc = f" // {_sanitize_comment(tag.description)}" if tag.description else ""
+ default = f" := {tag.default_value}" if tag.default_value else ""
+ f.write(f"\t{tag.name}: {tag.data_type}{default};{desc}\n")
+ f.write("END_VAR\n\n")
+
+ # Implementation
+ if sc.routines:
+ f.write("(* IMPLEMENTATION *)\n")
+ for routine in sc.routines:
+ f.write(f"\n(* ROUTINE: {routine['name']} [{routine['type']}] *)\n")
+ if routine.get('rungs'):
+ for rung in routine['rungs']:
+ if rung.comment:
+ f.write(f"\n// Rung {rung.number}: {_sanitize_comment(rung.comment)}\n")
+ else:
+ f.write(f"\n// Rung {rung.number}\n")
+ f.write(f"{rung.logic}\n")
+ elif routine.get('raw_content'):
+ f.write(f"\n{routine['raw_content']}\n")
+
+
+# ---------------------------------------------------------------------------
+# CLI
+# ---------------------------------------------------------------------------
+
+def main():
+ """CLI for L5K parser."""
+ if len(sys.argv) < 2:
+ print("Usage: python l5k_parser.py [output_dir]")
+ print(" Parse L5K file and optionally export to .sc format")
+ sys.exit(1)
+
+ file_path = sys.argv[1]
+ output_dir = sys.argv[2] if len(sys.argv) > 2 else None
+
+ if not Path(file_path).exists():
+ print(f"[ERROR] File not found: {file_path}")
+ sys.exit(1)
+
+ parser = L5KParser()
+
+ if output_dir:
+ count = parser.export_to_sc(file_path, output_dir)
+ print(f"\n[OK] Exported {count} components to {output_dir}")
+ else:
+ sc_files = parser.parse_file(file_path)
+ print(f"\n[INFO] Parsed {len(sc_files)} components from {Path(file_path).name}:")
+ for sc in sc_files:
+ tag_count = (len(sc.input_tags) + len(sc.output_tags) +
+ len(sc.inout_tags) + len(sc.local_tags))
+ routine_count = len(sc.routines)
+ desc = f" - {sc.description[:60]}..." if sc.description else ""
+ print(f" [{sc.type}] {sc.name}: {tag_count} tags, "
+ f"{routine_count} routines{desc}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/l5x_export.py b/scripts/l5x_export.py
index 341a1c7..e78d8f0 100644
--- a/scripts/l5x_export.py
+++ b/scripts/l5x_export.py
@@ -1,7 +1,10 @@
#!/usr/bin/env python3
"""
Export Rockwell/Allen-Bradley L5X files to structured code (.sc) format.
-Extracts Add-On Instructions (AOIs), their parameters, local tags, and routines.
+
+Handles both component-level L5X exports (single AOI/UDT) and full-project
+L5X files that contain Programs, controller-scoped Tags, Tasks, Modules,
+and Add-On Instructions.
Usage:
python l5x_export.py
@@ -11,9 +14,12 @@
import sys
import os
from pathlib import Path
+from typing import List, Optional
import xml.etree.ElementTree as ET
import html
+from sc_parser import SCFile, Tag, LogicRung
+
def extract_parameters(aoi_element):
"""Extract parameter declarations from AddOnInstructionDefinition."""
@@ -273,6 +279,424 @@ def export_datatypes_from_l5x(l5x_root, output_dir):
return datatypes_exported
+def _extract_tags_from_xml(tags_element) -> List[Tag]:
+ """Extract Tag objects from an L5X element."""
+ tags = []
+ if tags_element is None:
+ return tags
+
+ for tag_elem in tags_element.findall("Tag"):
+ name = tag_elem.get("Name", "")
+ data_type = tag_elem.get("DataType", "BOOL")
+ usage = tag_elem.get("Usage", "")
+ tag_type = tag_elem.get("TagType", "Base")
+ dimensions = tag_elem.get("Dimensions", "0")
+ external_access = tag_elem.get("ExternalAccess", "Read/Write")
+
+ # Get description
+ desc_elem = tag_elem.find("Description")
+ description = None
+ if desc_elem is not None:
+ # L5X descriptions can have CDATA children
+ cdata = desc_elem.find(".//{http://www.w3.org/1999/xhtml}span")
+ if cdata is not None and cdata.text:
+ description = cdata.text.strip()
+ elif desc_elem.text:
+ description = desc_elem.text.strip()
+
+ # Map usage to direction
+ direction_map = {
+ 'Input': 'INPUT',
+ 'Output': 'OUTPUT',
+ 'InOut': 'IN_OUT',
+ }
+ direction = direction_map.get(usage)
+
+ # Handle arrays (dimensions can be single "10" or multi-dimensional "10 10" or "2 4")
+ is_array = False
+ array_bounds = None
+ if dimensions and dimensions != "0":
+ dim_parts = dimensions.strip().split()
+ if len(dim_parts) > 1:
+ is_array = True
+ array_bounds = ",".join(f"0..{int(d) - 1}" for d in dim_parts)
+ elif int(dim_parts[0]) > 0:
+ is_array = True
+ array_bounds = f"0..{int(dim_parts[0]) - 1}"
+
+ tags.append(Tag(
+ name=name,
+ data_type=data_type,
+ direction=direction,
+ description=description,
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ return tags
+
+
+def _extract_routines_as_dicts(routines_element) -> List[dict]:
+ """Extract routine dicts from an L5X element."""
+ routine_list = []
+ if routines_element is None:
+ return routine_list
+
+ for routine in routines_element.findall("Routine"):
+ routine_name = routine.get("Name", "Main")
+ routine_type = routine.get("Type", "RLL")
+
+ rungs: List[LogicRung] = []
+ raw_content_parts = []
+
+ if routine_type == "RLL":
+ rll_content = routine.find("RLLContent")
+ if rll_content is not None:
+ for rung in rll_content.findall("Rung"):
+ rung_num = int(rung.get("Number", "0"))
+ comment_elem = rung.find("Comment")
+ comment = None
+ if comment_elem is not None:
+ cdata = comment_elem.find(".//{http://www.w3.org/1999/xhtml}span")
+ if cdata is not None and cdata.text:
+ comment = cdata.text.strip()
+ elif comment_elem.text:
+ comment = comment_elem.text.strip()
+
+ text_elem = rung.find("Text")
+ logic = ""
+ if text_elem is not None:
+ cdata = text_elem.find(".//{http://www.w3.org/1999/xhtml}span")
+ if cdata is not None and cdata.text:
+ logic = cdata.text.strip()
+ elif text_elem.text:
+ logic = text_elem.text.strip()
+
+ rungs.append(LogicRung(
+ number=rung_num,
+ comment=comment,
+ logic=logic,
+ ))
+ if comment:
+ raw_content_parts.append(f"// Rung {rung_num}: {comment}")
+ else:
+ raw_content_parts.append(f"// Rung {rung_num}")
+ raw_content_parts.append(logic)
+
+ elif routine_type == "ST":
+ st_content = routine.find("STContent")
+ if st_content is not None:
+ for line_elem in st_content.findall("Line"):
+ if line_elem.text:
+ raw_content_parts.append(line_elem.text)
+ # Fallback: some L5X files put ST in text directly
+ if not raw_content_parts and st_content.text:
+ raw_content_parts.append(st_content.text.strip())
+
+ elif routine_type == "FBD":
+ fbd_content = routine.find("FBDContent")
+ if fbd_content is not None:
+ raw_content_parts.append(f"(* FBD routine — {routine_name} *)")
+ # Extract sheet/block names for context
+ for sheet in fbd_content.findall("Sheet"):
+ sheet_num = sheet.get("Number", "?")
+ raw_content_parts.append(f"(* Sheet {sheet_num} *)")
+ for block in sheet.findall(".//Block"):
+ block_type = block.get("Type", "?")
+ operand = block.get("Operand", "")
+ raw_content_parts.append(f" {block_type}({operand})")
+
+ elif routine_type == "SFC":
+ sfc_content = routine.find("SFCContent")
+ if sfc_content is not None:
+ raw_content_parts.append(f"(* SFC routine — {routine_name} *)")
+ for step in sfc_content.findall(".//Step"):
+ step_name = step.get("Name", "?")
+ raw_content_parts.append(f" STEP: {step_name}")
+ for trans in sfc_content.findall(".//Transition"):
+ trans_name = trans.get("Name", "?")
+ raw_content_parts.append(f" TRANSITION: {trans_name}")
+
+ routine_list.append({
+ 'name': routine_name,
+ 'type': routine_type,
+ 'rungs': rungs,
+ 'raw_content': '\n'.join(raw_content_parts),
+ })
+
+ return routine_list
+
+
+def _parse_aoi_to_scfile(aoi_element, source_file: str) -> SCFile:
+ """Parse an L5X AddOnInstructionDefinition element into an SCFile."""
+ aoi_name = aoi_element.get("Name", "Unknown")
+ revision = aoi_element.get("Revision", "1.0")
+ vendor = aoi_element.get("Vendor", "")
+
+ desc_elem = aoi_element.find("Description")
+ description = None
+ if desc_elem is not None and desc_elem.text:
+ description = desc_elem.text.strip()
+
+ sc = SCFile(
+ file_path=source_file,
+ name=aoi_name,
+ type='AOI',
+ revision=revision,
+ vendor=vendor,
+ description=description,
+ )
+
+ # Parameters
+ parameters = aoi_element.find("Parameters")
+ if parameters is not None:
+ for param in parameters.findall("Parameter"):
+ name = param.get("Name", "")
+ usage = param.get("Usage", "Input")
+ data_type = param.get("DataType", "BOOL")
+
+ if name in ("EnableIn", "EnableOut"):
+ continue
+
+ p_desc_elem = param.find("Description")
+ p_desc = None
+ if p_desc_elem is not None and p_desc_elem.text:
+ p_desc = p_desc_elem.text.strip()
+
+ tag = Tag(name=name, data_type=data_type, description=p_desc)
+ if usage == "Input":
+ tag.direction = "INPUT"
+ sc.input_tags.append(tag)
+ elif usage == "Output":
+ tag.direction = "OUTPUT"
+ sc.output_tags.append(tag)
+ elif usage == "InOut":
+ tag.direction = "IN_OUT"
+ sc.inout_tags.append(tag)
+
+ # Local tags
+ local_tags = aoi_element.find("LocalTags")
+ if local_tags is not None:
+ for lt in local_tags.findall("LocalTag"):
+ name = lt.get("Name", "")
+ data_type = lt.get("DataType", "BOOL")
+
+ lt_desc_elem = lt.find("Description")
+ lt_desc = None
+ if lt_desc_elem is not None and lt_desc_elem.text:
+ lt_desc = lt_desc_elem.text.strip()
+
+ default_val = None
+ default_elem = lt.find("DefaultData")
+ if default_elem is not None:
+ data_value = default_elem.find(".//DataValue")
+ if data_value is not None:
+ value = data_value.get("Value", "")
+ if value:
+ default_val = value
+
+ sc.local_tags.append(Tag(
+ name=name,
+ data_type=data_type,
+ description=lt_desc,
+ default_value=default_val,
+ ))
+
+ # Routines
+ routines_elem = aoi_element.find("Routines")
+ sc.routines = _extract_routines_as_dicts(routines_elem)
+
+ # Build raw implementation
+ if sc.routines:
+ parts = []
+ for r in sc.routines:
+ parts.append(f"(* ROUTINE: {r['name']} [{r['type']}] *)")
+ if r.get('raw_content'):
+ parts.append(r['raw_content'])
+ sc.raw_implementation = '\n'.join(parts)
+
+ return sc
+
+
+def _parse_datatype_to_scfile(datatype_elem, source_file: str) -> Optional[SCFile]:
+ """Parse an L5X DataType element into an SCFile (UDT)."""
+ dt_name = datatype_elem.get("Name", "Unknown")
+ dt_family = datatype_elem.get("Family", "NoFamily")
+
+ desc_elem = datatype_elem.find("Description")
+ description = None
+ if desc_elem is not None and desc_elem.text:
+ description = desc_elem.text.strip()
+
+ members = []
+ members_elem = datatype_elem.find("Members")
+ if members_elem is not None:
+ for member in members_elem.findall("Member"):
+ mem_name = member.get("Name", "")
+ mem_type = member.get("DataType", "SINT")
+ dimension = member.get("Dimension", "0")
+ hidden = member.get("Hidden", "false")
+
+ if hidden == "true":
+ continue
+
+ m_desc_elem = member.find("Description")
+ m_desc = None
+ if m_desc_elem is not None and m_desc_elem.text:
+ m_desc = m_desc_elem.text.strip()
+
+ target = member.get("Target")
+ bit_num = member.get("BitNumber")
+
+ is_array = False
+ array_bounds = None
+ if target and bit_num:
+ mem_type = "BIT"
+ m_desc = f"Bit {bit_num} of {target}" + (f" - {m_desc}" if m_desc else "")
+ elif dimension != "0":
+ is_array = True
+ array_bounds = f"0..{int(dimension) - 1}"
+
+ members.append(Tag(
+ name=mem_name,
+ data_type=mem_type,
+ description=m_desc,
+ is_array=is_array,
+ array_bounds=array_bounds,
+ ))
+
+ if not members:
+ return None
+
+ sc = SCFile(
+ file_path=source_file,
+ name=dt_name,
+ type='UDT',
+ description=description,
+ )
+ sc.local_tags = members
+ return sc
+
+
+def _parse_program_to_scfile(program_elem, source_file: str) -> SCFile:
+ """Parse an L5X Program element into an SCFile."""
+ prog_name = program_elem.get("Name", "Unknown")
+
+ desc_elem = program_elem.find("Description")
+ description = None
+ if desc_elem is not None and desc_elem.text:
+ description = desc_elem.text.strip()
+
+ sc = SCFile(
+ file_path=source_file,
+ name=prog_name,
+ type='PROGRAM',
+ description=description,
+ )
+
+ # Program-scoped tags
+ tags_elem = program_elem.find("Tags")
+ for tag in _extract_tags_from_xml(tags_elem):
+ if tag.direction == 'INPUT':
+ sc.input_tags.append(tag)
+ elif tag.direction == 'OUTPUT':
+ sc.output_tags.append(tag)
+ elif tag.direction == 'IN_OUT':
+ sc.inout_tags.append(tag)
+ else:
+ sc.local_tags.append(tag)
+
+ # Routines
+ routines_elem = program_elem.find("Routines")
+ sc.routines = _extract_routines_as_dicts(routines_elem)
+
+ if sc.routines:
+ parts = []
+ for r in sc.routines:
+ parts.append(f"(* ROUTINE: {r['name']} [{r['type']}] *)")
+ if r.get('raw_content'):
+ parts.append(r['raw_content'])
+ sc.raw_implementation = '\n'.join(parts)
+
+ return sc
+
+
+class L5XParser:
+ """Parser for Rockwell L5X (XML) project and component files.
+
+ Parses full L5X projects or component exports and returns SCFile objects
+ for each AOI, UDT, and Program found.
+ """
+
+ def parse_file(self, file_path: str) -> List[SCFile]:
+ """Parse an L5X file and return list of SCFile objects."""
+ try:
+ tree = ET.parse(file_path)
+ root = tree.getroot()
+ except ET.ParseError as e:
+ print(f"[ERROR] Failed to parse L5X XML: {e}")
+ return []
+
+ return self._parse_root(root, source_file=file_path)
+
+ def _parse_root(self, root, source_file: str) -> List[SCFile]:
+ """Parse the L5X XML root element."""
+ results: List[SCFile] = []
+
+ # Determine export scope
+ target_type = root.get("TargetType", "Controller")
+
+ controller = root.find(".//Controller")
+ if controller is None:
+ # Component-level export (single routine, etc.)
+ # Try to extract whatever is in the root
+ return results
+
+ controller_name = controller.get("Name", "Unknown")
+
+ # 1. DataTypes → UDTs
+ datatypes = controller.find("DataTypes")
+ if datatypes is not None:
+ for dt in datatypes.findall("DataType"):
+ sc = _parse_datatype_to_scfile(dt, source_file)
+ if sc:
+ results.append(sc)
+
+ # 2. Add-On Instructions → AOIs
+ aoi_defs = controller.find("AddOnInstructionDefinitions")
+ if aoi_defs is not None:
+ for aoi in aoi_defs.findall("AddOnInstructionDefinition"):
+ sc = _parse_aoi_to_scfile(aoi, source_file)
+ results.append(sc)
+
+ # 3. Programs
+ programs = controller.find("Programs")
+ if programs is not None:
+ for prog in programs.findall("Program"):
+ sc = _parse_program_to_scfile(prog, source_file)
+ results.append(sc)
+
+ # 4. Controller-scoped tags
+ ctrl_tags_elem = controller.find("Tags")
+ ctrl_tags = _extract_tags_from_xml(ctrl_tags_elem)
+ if ctrl_tags:
+ ctrl_sc = SCFile(
+ file_path=source_file,
+ name=controller_name,
+ type='CONTROLLER',
+ )
+ for tag in ctrl_tags:
+ if tag.direction == 'INPUT':
+ ctrl_sc.input_tags.append(tag)
+ elif tag.direction == 'OUTPUT':
+ ctrl_sc.output_tags.append(tag)
+ else:
+ ctrl_sc.local_tags.append(tag)
+ results.append(ctrl_sc)
+
+ return results
+
+
def export_l5x_to_sc(l5x_path, output_dir):
"""Export L5X file to structured code (.sc) format."""
@@ -289,6 +713,7 @@ def export_l5x_to_sc(l5x_path, output_dir):
aois_count = 0
datatypes_count = 0
+ programs_count = 0
# Extract Add-On Instructions
controller = root.find(".//Controller")
@@ -299,15 +724,110 @@ def export_l5x_to_sc(l5x_path, output_dir):
if export_aoi_from_l5x(aoi, output_dir):
aois_count += 1
+ # Extract Programs (new)
+ programs = controller.find("Programs")
+ if programs is not None:
+ for prog in programs.findall("Program"):
+ if _export_program_from_l5x(prog, output_dir):
+ programs_count += 1
+
+ # Extract controller-scoped tags (new)
+ ctrl_name = controller.get("Name", "Controller")
+ ctrl_tags_elem = controller.find("Tags")
+ if ctrl_tags_elem is not None and len(ctrl_tags_elem.findall("Tag")) > 0:
+ _export_controller_tags(ctrl_name, ctrl_tags_elem, output_dir)
+
# Extract custom data types
datatypes_count = export_datatypes_from_l5x(root, output_dir)
- print(f"\n[OK] Export complete: {aois_count} AOIs, {datatypes_count} UDTs")
+ print(f"\n[OK] Export complete: {aois_count} AOIs, {datatypes_count} UDTs, "
+ f"{programs_count} Programs")
print(f"[INFO] Exported to: {output_dir}")
return True
+def _export_program_from_l5x(program_elem, output_dir):
+ """Export a Program element from L5X to .sc file."""
+ prog_name = program_elem.get("Name", "Unknown")
+
+ desc_elem = program_elem.find("Description")
+ description = ""
+ if desc_elem is not None and desc_elem.text:
+ description = desc_elem.text.strip()
+
+ # Extract program-scoped tags
+ tags_elem = program_elem.find("Tags")
+ tag_lines = []
+ if tags_elem is not None:
+ for tag in tags_elem.findall("Tag"):
+ name = tag.get("Name", "")
+ data_type = tag.get("DataType", "BOOL")
+ t_desc_elem = tag.find("Description")
+ t_desc = ""
+ if t_desc_elem is not None and t_desc_elem.text:
+ t_desc = f" // {t_desc_elem.text.strip()}"
+ tag_lines.append(f"\t{name}: {data_type};{t_desc}")
+
+ # Extract routines
+ routines = extract_routines(program_elem)
+
+ filename = os.path.join(output_dir, f"{prog_name}.prog.sc")
+ with open(filename, 'w', encoding='utf-8') as f:
+ f.write(f"(* POU: {prog_name} *)\n")
+ f.write(f"(* Type: Program *)\n")
+ if description:
+ f.write(f"(* Description: {description} *)\n")
+ f.write("\n")
+
+ if tag_lines:
+ f.write("(* PROGRAM TAGS *)\n")
+ f.write("VAR\n")
+ f.write("\n".join(tag_lines))
+ f.write("\nEND_VAR\n\n")
+
+ if routines:
+ f.write("(* IMPLEMENTATION *)\n")
+ f.write(routines)
+ f.write("\n")
+
+ print(f"[OK] Exported Program: {prog_name}")
+ return True
+
+
+def _export_controller_tags(ctrl_name, tags_elem, output_dir):
+ """Export controller-scoped tags to a .sc file."""
+ tag_lines = []
+ for tag in tags_elem.findall("Tag"):
+ name = tag.get("Name", "")
+ data_type = tag.get("DataType", "BOOL")
+ dimensions = tag.get("Dimensions", "0")
+
+ desc_elem = tag.find("Description")
+ desc = ""
+ if desc_elem is not None and desc_elem.text:
+ desc = f" // {desc_elem.text.strip()}"
+
+ if dimensions and dimensions != "0":
+ tag_lines.append(f"\t{name}: ARRAY[0..{int(dimensions)-1}] OF {data_type};{desc}")
+ else:
+ tag_lines.append(f"\t{name}: {data_type};{desc}")
+
+ if not tag_lines:
+ return
+
+ filename = os.path.join(output_dir, f"{ctrl_name}.ctrl.sc")
+ with open(filename, 'w', encoding='utf-8') as f:
+ f.write(f"(* POU: {ctrl_name} *)\n")
+ f.write(f"(* Type: Controller *)\n\n")
+ f.write("(* CONTROLLER-SCOPED TAGS *)\n")
+ f.write("VAR\n")
+ f.write("\n".join(tag_lines))
+ f.write("\nEND_VAR\n")
+
+ print(f"[OK] Exported Controller Tags: {ctrl_name} ({len(tag_lines)} tags)")
+
+
def process_directory(input_dir, output_dir):
"""Process all L5X files in a directory."""
l5x_files = list(Path(input_dir).glob("*.L5X")) + list(Path(input_dir).glob("*.l5x"))
diff --git a/scripts/neo4j_ontology.py b/scripts/neo4j_ontology.py
index a4e54e5..215e93a 100644
--- a/scripts/neo4j_ontology.py
+++ b/scripts/neo4j_ontology.py
@@ -385,7 +385,7 @@ def create_aoi(
Args:
name: AOI name
- aoi_type: Type of AOI (AOI, UDT, etc.)
+ aoi_type: Type of component (AOI, UDT, PROGRAM, CONTROLLER, FB, etc.)
source_file: Source file path
metadata: Metadata dict (revision, vendor, description)
analysis: Analysis dict (purpose, tags, patterns, etc.)
diff --git a/scripts/ontology_analyzer.py b/scripts/ontology_analyzer.py
index c9e7ac2..85fb57b 100644
--- a/scripts/ontology_analyzer.py
+++ b/scripts/ontology_analyzer.py
@@ -21,6 +21,14 @@
from siemens_project_parser import SiemensProjectParser, TiaProject
from neo4j_ontology import OntologyGraph, get_ontology_graph
from claude_client import ClaudeClient, get_claude_client
+from rockwell_export import (
+ detect_rockwell_format,
+ parse_rockwell_file,
+ parse_rockwell_directory,
+ find_rockwell_files,
+ is_rockwell_file,
+ ROCKWELL_EXTENSIONS,
+)
class OntologyAnalyzer:
@@ -696,6 +704,122 @@ def cross_reference_directory(
print(f"[INFO] Parsed {len(parsed)} {platform} blocks from {len(files)} files")
return self.extract_cross_references(parsed, verbose=verbose)
+ # ------------------------------------------------------------------
+ # Rockwell multi-format ingestion (L5X, L5K, ACD)
+ # ------------------------------------------------------------------
+
+ def analyze_rockwell_file(
+ self,
+ file_path: str,
+ verbose: bool = False,
+ skip_ai: bool = False,
+ ) -> List[Dict[str, Any]]:
+ """Analyze a Rockwell PLC file (L5X, L5K, or ACD) and store in Neo4j.
+
+ Auto-detects the file format and parses it into SCFile objects,
+ then runs the same analysis pipeline as .sc files.
+
+ Args:
+ file_path: Path to Rockwell PLC file
+ verbose: Print detailed progress
+ skip_ai: Skip AI analysis (import only)
+
+ Returns:
+ List of ontology dicts for each component found.
+ """
+ fmt = detect_rockwell_format(file_path)
+ if not fmt:
+ print(f"[ERROR] Not a recognized Rockwell file: {file_path}")
+ return []
+
+ print(f"[INFO] Detected Rockwell {fmt} format: {Path(file_path).name}")
+
+ parsed_files = parse_rockwell_file(file_path)
+ if not parsed_files:
+ print(f"[WARNING] No components found in {file_path}")
+ return []
+
+ action = "import" if skip_ai else "analyze"
+ print(f"[INFO] Found {len(parsed_files)} components to {action}")
+
+ ontologies = []
+ for i, sc_file in enumerate(parsed_files, 1):
+ print(f"\n[{i}/{len(parsed_files)}] Processing {sc_file.type}: {sc_file.name}...")
+ try:
+ ontology = self.analyze_sc_file(sc_file, verbose, skip_ai=skip_ai)
+ ontologies.append(ontology)
+ print(f" [OK] {sc_file.type}: {sc_file.name}")
+ except Exception as e:
+ print(f" [ERROR] Failed {sc_file.name}: {e}")
+ continue
+
+ # Cross-reference pass
+ if parsed_files:
+ xref_count = self.extract_cross_references(parsed_files, verbose=verbose)
+ if xref_count:
+ print(f"\n[INFO] Created {xref_count} cross-reference relationships")
+
+ return ontologies
+
+ def analyze_rockwell_directory(
+ self,
+ directory: str,
+ verbose: bool = False,
+ skip_ai: bool = False,
+ ) -> List[Dict[str, Any]]:
+ """Analyze all Rockwell PLC files in a directory.
+
+ Finds and processes all .L5X, .L5K, and .ACD files.
+
+ Args:
+ directory: Directory path
+ verbose: Print detailed progress
+ skip_ai: Skip AI analysis
+
+ Returns:
+ List of ontology dicts.
+ """
+ files = find_rockwell_files(directory)
+ if not files:
+ print(f"[WARNING] No Rockwell PLC files found in {directory}")
+ return []
+
+ print(f"[INFO] Found {len(files)} Rockwell PLC file(s)")
+
+ all_ontologies = []
+ all_parsed: List[SCFile] = []
+
+ for fp, fmt in files:
+ print(f"\n{'='*60}")
+ print(f" [{fmt}] {Path(fp).name}")
+ print(f"{'='*60}")
+
+ parsed_files = parse_rockwell_file(fp, format_hint=fmt)
+ if not parsed_files:
+ continue
+
+ action = "import" if skip_ai else "analyze"
+ print(f"[INFO] {len(parsed_files)} components to {action}")
+
+ for i, sc_file in enumerate(parsed_files, 1):
+ try:
+ ontology = self.analyze_sc_file(
+ sc_file, verbose, skip_ai=skip_ai
+ )
+ all_ontologies.append(ontology)
+ all_parsed.append(sc_file)
+ print(f" [{i}/{len(parsed_files)}] {sc_file.type}: {sc_file.name}")
+ except Exception as e:
+ print(f" [ERROR] {sc_file.name}: {e}")
+
+ # Cross-reference pass across all files
+ if all_parsed:
+ xref_count = self.extract_cross_references(all_parsed, verbose=verbose)
+ if xref_count:
+ print(f"\n[INFO] Created {xref_count} cross-reference relationships")
+
+ return all_ontologies
+
# ------------------------------------------------------------------
# TIA Portal full-project ingestion
# ------------------------------------------------------------------
@@ -1013,9 +1137,13 @@ def main():
load_dotenv()
parser = argparse.ArgumentParser(
- description="Analyze PLC .sc/.st files and generate semantic ontologies using Claude (stored in Neo4j)"
+ description="Analyze PLC files and generate semantic ontologies using Claude (stored in Neo4j). "
+ "Supports Rockwell (L5X, L5K, ACD), Siemens (ST, TIA XML), and pre-exported .sc files."
+ )
+ parser.add_argument(
+ "input", nargs="?",
+ help="Path to PLC file (.L5X, .L5K, .ACD, .sc, .st) or directory",
)
- parser.add_argument("input", nargs="?", help="Path to .sc/.st file or directory")
parser.add_argument(
"-p",
"--pattern",
@@ -1066,6 +1194,11 @@ def main():
action="store_true",
help="Parse entire Siemens TIA Portal project structure (PLCs + HMIs + interlinks)",
)
+ parser.add_argument(
+ "--rockwell",
+ action="store_true",
+ help="Force Rockwell mode: auto-detect and process L5X, L5K, and ACD files",
+ )
args = parser.parse_args()
@@ -1167,34 +1300,85 @@ def main():
# Auto-detect format from flags / file extension
is_tia_xml = args.tia_xml or input_path.suffix.lower() == ".xml"
is_siemens = args.siemens or input_path.suffix.lower() == ".st"
+ is_rockwell_native = (
+ args.rockwell
+ or input_path.suffix.lower() in ROCKWELL_EXTENSIONS
+ or (input_path.is_file() and is_rockwell_file(str(input_path)))
+ )
# Process directory or single file
if input_path.is_dir():
- ontologies = analyzer.analyze_directory(
- str(input_path),
- pattern=args.pattern,
- verbose=args.verbose,
- skip_ai=args.skip_ai,
- siemens=is_siemens,
- tia_xml=is_tia_xml,
- )
- action = "Imported" if args.skip_ai else "Analyzed"
- if is_tia_xml:
- platform = "Siemens TIA XML"
- elif is_siemens:
- platform = "Siemens"
+ if is_rockwell_native or args.rockwell:
+ # Check if directory contains native Rockwell files
+ rockwell_files = find_rockwell_files(str(input_path))
+ if rockwell_files:
+ ontologies = analyzer.analyze_rockwell_directory(
+ str(input_path),
+ verbose=args.verbose,
+ skip_ai=args.skip_ai,
+ )
+ action = "Imported" if args.skip_ai else "Analyzed"
+ print(
+ f"\n[OK] {action} {len(ontologies)} Rockwell components "
+ f"and stored in Neo4j"
+ )
+ if args.skip_ai:
+ print(
+ "[INFO] Use incremental analyzer to add semantic descriptions"
+ )
+ else:
+ # Fall back to .sc file pattern
+ ontologies = analyzer.analyze_directory(
+ str(input_path),
+ pattern=args.pattern,
+ verbose=args.verbose,
+ skip_ai=args.skip_ai,
+ )
+ action = "Imported" if args.skip_ai else "Analyzed"
+ print(
+ f"\n[OK] {action} {len(ontologies)} Rockwell blocks "
+ f"and stored in Neo4j"
+ )
else:
- platform = "Rockwell"
- print(
- f"\n[OK] {action} {len(ontologies)} {platform} blocks and stored in Neo4j"
- )
- if args.skip_ai:
+ ontologies = analyzer.analyze_directory(
+ str(input_path),
+ pattern=args.pattern,
+ verbose=args.verbose,
+ skip_ai=args.skip_ai,
+ siemens=is_siemens,
+ tia_xml=is_tia_xml,
+ )
+ action = "Imported" if args.skip_ai else "Analyzed"
+ if is_tia_xml:
+ platform = "Siemens TIA XML"
+ elif is_siemens:
+ platform = "Siemens"
+ else:
+ platform = "Rockwell"
print(
- "[INFO] Use incremental analyzer to add semantic descriptions"
+ f"\n[OK] {action} {len(ontologies)} {platform} blocks "
+ f"and stored in Neo4j"
)
+ if args.skip_ai:
+ print(
+ "[INFO] Use incremental analyzer to add semantic descriptions"
+ )
elif input_path.is_file():
- if is_tia_xml:
+ if is_rockwell_native and not is_tia_xml and not is_siemens:
+ # Native Rockwell file (L5X, L5K, ACD)
+ ontologies = analyzer.analyze_rockwell_file(
+ str(input_path),
+ verbose=args.verbose,
+ skip_ai=args.skip_ai,
+ )
+ action = "Imported" if args.skip_ai else "Analyzed"
+ print(
+ f"\n[OK] {action} {len(ontologies)} components "
+ f"and stored in Neo4j"
+ )
+
+ elif is_tia_xml:
# TIA Portal XML file
tia_parser = TiaXmlParser()
parsed_blocks = tia_parser.parse_file(str(input_path))
@@ -1236,7 +1420,7 @@ def main():
action = "Created" if args.skip_ai else "Stored"
print(f"[OK] {action} in Neo4j")
else:
- # Rockwell .sc file
+ # Rockwell .sc file (pre-exported)
sc_parser_inst = SCParser()
sc_file = sc_parser_inst.parse_file(str(input_path))
ontology = analyzer.analyze_sc_file(
diff --git a/scripts/rockwell_export.py b/scripts/rockwell_export.py
new file mode 100644
index 0000000..8f796d3
--- /dev/null
+++ b/scripts/rockwell_export.py
@@ -0,0 +1,322 @@
+#!/usr/bin/env python3
+"""
+Unified Rockwell/Allen-Bradley PLC file handler.
+
+Auto-detects and processes all Rockwell PLC file formats:
+ - .L5X — XML-based project/component export (Studio 5000)
+ - .L5K — ASCII text-based full project export (Studio 5000 / RSLogix 5000)
+ - .ACD — Native binary project file (Studio 5000 / RSLogix 5000)
+ - .RSS — RSLogix 500 project file (SLC 500 / MicroLogix) [detection only]
+
+Each format is parsed into a list of SCFile objects that feed into the
+existing ontology pipeline (ontology_analyzer.py → Claude → Neo4j).
+
+Usage:
+ python rockwell_export.py [output_dir]
+ python rockwell_export.py --parse-only
+
+Examples:
+ python rockwell_export.py project.L5X export/
+ python rockwell_export.py project.L5K export/
+ python rockwell_export.py project.ACD export/
+ python rockwell_export.py plc_files/ export/ # Process all Rockwell files
+"""
+
+import sys
+import os
+from pathlib import Path
+from typing import List, Optional, Tuple
+
+from sc_parser import SCFile
+
+
+# ---------------------------------------------------------------------------
+# File format detection
+# ---------------------------------------------------------------------------
+
+# Supported Rockwell file extensions (case-insensitive)
+ROCKWELL_EXTENSIONS = {
+ '.l5x': 'L5X',
+ '.l5k': 'L5K',
+ '.acd': 'ACD',
+ '.rss': 'RSS',
+}
+
+
+def detect_rockwell_format(file_path: str) -> Optional[str]:
+ """Detect the Rockwell PLC file format from extension and content.
+
+ Returns one of: 'L5X', 'L5K', 'ACD', 'RSS', or None if not recognized.
+ """
+ ext = Path(file_path).suffix.lower()
+
+ # Extension-based detection
+ fmt = ROCKWELL_EXTENSIONS.get(ext)
+ if fmt:
+ return fmt
+
+ # Content-based detection for ambiguous extensions
+ try:
+ with open(file_path, 'rb') as f:
+ header = f.read(512)
+
+ # Check for XML (L5X)
+ if b' bool:
+ """Check if a file is a recognized Rockwell PLC format."""
+ return detect_rockwell_format(file_path) is not None
+
+
+def find_rockwell_files(directory: str) -> List[Tuple[str, str]]:
+ """Find all Rockwell PLC files in a directory.
+
+ Returns list of (file_path, format) tuples.
+ """
+ results = []
+ dir_path = Path(directory)
+
+ for ext in ROCKWELL_EXTENSIONS:
+ for f in dir_path.rglob(f"*{ext}"):
+ fmt = detect_rockwell_format(str(f))
+ if fmt:
+ results.append((str(f), fmt))
+ # Also check uppercase
+ for f in dir_path.rglob(f"*{ext.upper()}"):
+ fmt = detect_rockwell_format(str(f))
+ if fmt and (str(f), fmt) not in results:
+ results.append((str(f), fmt))
+
+ return sorted(results, key=lambda x: x[0])
+
+
+# ---------------------------------------------------------------------------
+# Unified parsing
+# ---------------------------------------------------------------------------
+
+def parse_rockwell_file(file_path: str,
+ format_hint: Optional[str] = None) -> List[SCFile]:
+ """Parse any Rockwell PLC file into SCFile objects.
+
+ Args:
+ file_path: Path to the Rockwell file
+ format_hint: Optional format override ('L5X', 'L5K', 'ACD', 'RSS')
+
+ Returns:
+ List of SCFile objects extracted from the file.
+ """
+ fmt = format_hint or detect_rockwell_format(file_path)
+
+ if fmt is None:
+ print(f"[ERROR] Unrecognized file format: {file_path}")
+ return []
+
+ if fmt == 'L5X':
+ from l5x_export import L5XParser
+ parser = L5XParser()
+ return parser.parse_file(file_path)
+
+ elif fmt == 'L5K':
+ from l5k_parser import L5KParser
+ parser = L5KParser()
+ return parser.parse_file(file_path)
+
+ elif fmt == 'ACD':
+ from acd_parser import ACDParser
+ parser = ACDParser()
+ return parser.parse_file(file_path)
+
+ elif fmt == 'RSS':
+ print(f"[WARNING] RSS (RSLogix 500) files are proprietary binary format.")
+ print(f"[INFO] RSS support is limited to detection only.")
+ print(f"[INFO] To process RSS files, first convert them to L5X or L5K")
+ print(f"[INFO] using Rockwell's Logix Designer Export tool.")
+ return []
+
+ else:
+ print(f"[ERROR] Unsupported format: {fmt}")
+ return []
+
+
+def parse_rockwell_directory(directory: str) -> List[SCFile]:
+ """Parse all Rockwell PLC files in a directory.
+
+ Returns combined list of SCFile objects from all files.
+ """
+ files = find_rockwell_files(directory)
+ if not files:
+ print(f"[WARNING] No Rockwell PLC files found in {directory}")
+ return []
+
+ # Group by format for reporting
+ by_format = {}
+ for fp, fmt in files:
+ by_format.setdefault(fmt, []).append(fp)
+
+ print(f"[INFO] Found {len(files)} Rockwell PLC file(s):")
+ for fmt, fps in sorted(by_format.items()):
+ print(f" {fmt}: {len(fps)} file(s)")
+
+ all_results: List[SCFile] = []
+ for fp, fmt in files:
+ print(f"\n[INFO] Processing [{fmt}]: {Path(fp).name}")
+ try:
+ results = parse_rockwell_file(fp, format_hint=fmt)
+ all_results.extend(results)
+ print(f" [OK] Extracted {len(results)} components")
+ except Exception as e:
+ print(f" [ERROR] Failed to process {Path(fp).name}: {e}")
+
+ return all_results
+
+
+# ---------------------------------------------------------------------------
+# Export to .sc files
+# ---------------------------------------------------------------------------
+
+def export_rockwell_to_sc(input_path: str, output_dir: str) -> int:
+ """Parse Rockwell file(s) and export to .sc format.
+
+ Args:
+ input_path: File or directory path
+ output_dir: Output directory for .sc files
+
+ Returns:
+ Count of exported .sc files.
+ """
+ from l5k_parser import _write_sc_file
+
+ os.makedirs(output_dir, exist_ok=True)
+
+ if os.path.isdir(input_path):
+ sc_files = parse_rockwell_directory(input_path)
+ else:
+ sc_files = parse_rockwell_file(input_path)
+
+ count = 0
+ for sc in sc_files:
+ if sc.type == 'AOI':
+ suffix = '.aoi.sc'
+ elif sc.type == 'UDT':
+ suffix = '.udt.sc'
+ elif sc.type == 'PROGRAM':
+ suffix = '.prog.sc'
+ elif sc.type == 'CONTROLLER':
+ suffix = '.ctrl.sc'
+ else:
+ suffix = '.sc'
+
+ out_path = os.path.join(output_dir, f"{sc.name}{suffix}")
+ _write_sc_file(sc, out_path)
+ count += 1
+
+ return count
+
+
+# ---------------------------------------------------------------------------
+# CLI
+# ---------------------------------------------------------------------------
+
+def main():
+ """CLI for unified Rockwell file handler."""
+ import argparse
+
+ parser = argparse.ArgumentParser(
+ description="Unified Rockwell PLC file handler (L5X, L5K, ACD)"
+ )
+ parser.add_argument(
+ "input",
+ help="Path to Rockwell PLC file (.L5X, .L5K, .ACD) or directory"
+ )
+ parser.add_argument(
+ "output",
+ nargs="?",
+ help="Output directory for .sc files (omit for parse-only mode)"
+ )
+ parser.add_argument(
+ "--parse-only",
+ action="store_true",
+ help="Parse and display summary without exporting"
+ )
+ parser.add_argument(
+ "--detect",
+ action="store_true",
+ help="Detect file format only"
+ )
+
+ args = parser.parse_args()
+
+ if not os.path.exists(args.input):
+ print(f"[ERROR] Input not found: {args.input}")
+ sys.exit(1)
+
+ if args.detect:
+ if os.path.isdir(args.input):
+ files = find_rockwell_files(args.input)
+ if files:
+ print(f"Found {len(files)} Rockwell PLC file(s):")
+ for fp, fmt in files:
+ print(f" [{fmt}] {fp}")
+ else:
+ print("No Rockwell PLC files found.")
+ else:
+ fmt = detect_rockwell_format(args.input)
+ if fmt:
+ print(f"[{fmt}] {args.input}")
+ else:
+ print(f"Not a recognized Rockwell PLC file: {args.input}")
+ return
+
+ if args.parse_only or not args.output:
+ # Parse and display summary
+ if os.path.isdir(args.input):
+ sc_files = parse_rockwell_directory(args.input)
+ else:
+ sc_files = parse_rockwell_file(args.input)
+
+ print(f"\n{'=' * 60}")
+ print(f" Parsed {len(sc_files)} components")
+ print(f"{'=' * 60}")
+
+ # Group by type
+ by_type = {}
+ for sc in sc_files:
+ by_type.setdefault(sc.type, []).append(sc)
+
+ for sc_type, items in sorted(by_type.items()):
+ print(f"\n {sc_type} ({len(items)}):")
+ for sc in items[:20]:
+ tag_count = (len(sc.input_tags) + len(sc.output_tags) +
+ len(sc.inout_tags) + len(sc.local_tags))
+ routine_count = len(sc.routines)
+ desc = f" — {sc.description[:50]}..." if sc.description else ""
+ print(f" {sc.name}: {tag_count} tags, "
+ f"{routine_count} routines{desc}")
+ if len(items) > 20:
+ print(f" ... and {len(items) - 20} more")
+
+ else:
+ # Export to .sc files
+ count = export_rockwell_to_sc(args.input, args.output)
+ print(f"\n[OK] Exported {count} components to {args.output}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/real_samples/AOI_AVERAGE.L5X b/tests/real_samples/AOI_AVERAGE.L5X
new file mode 100644
index 0000000..b282f10
--- /dev/null
+++ b/tests/real_samples/AOI_AVERAGE.L5X
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/AOI_CV_CONTROL.L5X b/tests/real_samples/AOI_CV_CONTROL.L5X
new file mode 100644
index 0000000..aa09f27
--- /dev/null
+++ b/tests/real_samples/AOI_CV_CONTROL.L5X
@@ -0,0 +1,483 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/AOI_DEBOUNCER.L5X b/tests/real_samples/AOI_DEBOUNCER.L5X
new file mode 100644
index 0000000..5634d70
--- /dev/null
+++ b/tests/real_samples/AOI_DEBOUNCER.L5X
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/AOI_METER_ORIFICE.L5X b/tests/real_samples/AOI_METER_ORIFICE.L5X
new file mode 100644
index 0000000..0940629
--- /dev/null
+++ b/tests/real_samples/AOI_METER_ORIFICE.L5X
@@ -0,0 +1,591 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/AOI_RAMP_BASIC.L5X b/tests/real_samples/AOI_RAMP_BASIC.L5X
new file mode 100644
index 0000000..8d451f0
--- /dev/null
+++ b/tests/real_samples/AOI_RAMP_BASIC.L5X
@@ -0,0 +1,363 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Buffertank_Program.L5X b/tests/real_samples/Buffertank_Program.L5X
new file mode 100644
index 0000000..6655ef2
--- /dev/null
+++ b/tests/real_samples/Buffertank_Program.L5X
@@ -0,0 +1,23807 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+= 80 then From :=80; end_if; // starting pos can never be higher then 80]]>
+
+
+= From then From :=0; end_if; // starting pos can never be lower then 0]]>
+
+
+
+
+
+= 81 then From :=81; end_if; // ending pos can never be higher then 81]]>
+
+
+= End then End :=1; end_if; // ending pos can never be lower then 1]]>
+
+
+= End then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Result.data[1] -> Result.data[2] etc. ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0 then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4 then // if wrk_RecipeNumber is bigger then 4 set it back to 4.]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=4) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=2) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=3) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=5) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=1) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=6) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PackTags.Status.StateCurrent then // compare current state with requested state done above.]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MachineState) OR S:fs then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1 then PackTags.Admin.ModeCurrentTime[1]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 2 then PackTags.Admin.ModeCurrentTime[2]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 3 then PackTags.Admin.ModeCurrentTime[3]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 4 then PackTags.Admin.ModeCurrentTime[4]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 5 then PackTags.Admin.ModeCurrentTime[5]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 6 then PackTags.Admin.ModeCurrentTime[6]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MachineState then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+AlarmValue_HIGH then]]>
+
+
+
+
+
+
+
+
+HMI_Sensor.OUTPUT then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ wrk_arraySize then MovingAvgNumberOfSamples:=wrk_arraySize; end_if; // prevent controller faulted]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+= Scaled_Max OR Scaled_Min >= OutputValue) AND NOT Simulation then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+= OutputValue AND OutputValue >= Scaled_Min) AND NOT Simulation then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1 then cnf_Direction := 1; end_if; // Prevent wrong direction input]]>
+
+
+ cnf_Direction then cnf_Direction := 0; end_if; // Prevent wrong direction input]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0 then Sts_Drive_Stopped := FALSE; end_if;]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0 then EquipmentModule.EP_SEQ.Aborting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Clearing :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Stopping :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Resetting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Starting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Unholding :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Unsuspending:=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Completing :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Holding :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Suspending :=0; end_if;]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/CIP_Program.L5X b/tests/real_samples/CIP_Program.L5X
new file mode 100644
index 0000000..e27a159
--- /dev/null
+++ b/tests/real_samples/CIP_Program.L5X
@@ -0,0 +1,20670 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+= 80 then From :=80; end_if; // starting pos can never be higher then 80]]>
+
+
+= From then From :=0; end_if; // starting pos can never be lower then 0]]>
+
+
+
+
+
+= 81 then From :=81; end_if; // ending pos can never be higher then 81]]>
+
+
+= End then End :=1; end_if; // ending pos can never be lower then 1]]>
+
+
+= End then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Result.data[1] -> Result.data[2] etc. ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0 then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4 then // if wrk_RecipeNumber is bigger then 4 set it back to 4.]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=4) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=2) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=3) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=5) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=1) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 AND NOT (PackTags.Command.UnitMode=6) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PackTags.Status.StateCurrent then // compare current state with requested state done above.]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MachineState) OR S:fs then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1 then PackTags.Admin.ModeCurrentTime[1]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 2 then PackTags.Admin.ModeCurrentTime[2]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 3 then PackTags.Admin.ModeCurrentTime[3]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 4 then PackTags.Admin.ModeCurrentTime[4]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 5 then PackTags.Admin.ModeCurrentTime[5]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+ 6 then PackTags.Admin.ModeCurrentTime[6]:=0; end_if; // if machine is not in this state, reset count]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MachineState then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0 then EquipmentModule.EP_SEQ.Aborting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Clearing :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Stopping :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Resetting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Starting :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Unholding :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Unsuspending:=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Completing :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Holding :=0; end_if;]]>
+
+
+0 then EquipmentModule.EP_SEQ.Suspending :=0; end_if;]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/EXAMPLE_FACTORY_Controller.L5X b/tests/real_samples/EXAMPLE_FACTORY_Controller.L5X
new file mode 100644
index 0000000..b57e446
--- /dev/null
+++ b/tests/real_samples/EXAMPLE_FACTORY_Controller.L5X
@@ -0,0 +1,536 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1001769-IF4C
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+
+ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+
+ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+
+ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Games_Program.L5X b/tests/real_samples/Games_Program.L5X
new file mode 100644
index 0000000..adc3446
--- /dev/null
+++ b/tests/real_samples/Games_Program.L5X
@@ -0,0 +1,2164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ . Y^]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+30 then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Snake.HighScore.Score[i]then]]>
+
+
+
+
+
+
+
+
+= i then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+=9 then Random_X:=8; end_if; // set border]]>
+
+
+
+
+
+=9 then Random_Y:=8; end_if; // set border ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+100 then HMI_GameSpeed:=HMI_GameSpeed-50; end_if; // increase gamespeed]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/ISA88_PackML_AOI.L5X b/tests/real_samples/ISA88_PackML_AOI.L5X
new file mode 100644
index 0000000..f1854e1
--- /dev/null
+++ b/tests/real_samples/ISA88_PackML_AOI.L5X
@@ -0,0 +1,1506 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/L5x_Creation_Controller.L5X b/tests/real_samples/L5x_Creation_Controller.L5X
new file mode 100644
index 0000000..09fa387
--- /dev/null
+++ b/tests/real_samples/L5x_Creation_Controller.L5X
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/L5x_Creation_Populated_Controller.L5X b/tests/real_samples/L5x_Creation_Populated_Controller.L5X
new file mode 100644
index 0000000..ebcd6c4
--- /dev/null
+++ b/tests/real_samples/L5x_Creation_Populated_Controller.L5X
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rockwell Automation/Allen-Bradley1756-EN2T4325481
+
+
+
+
+
+
+
+
+1C 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
+01 01 01 01 01 01 01 01 FF FF FF FF FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+1111756-IB16
+
+
+
+
+
+
+
+
+1C 00 00 00 12 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+4011756-OB32
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+00 00
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Ladder_Routine.L5X b/tests/real_samples/Ladder_Routine.L5X
new file mode 100644
index 0000000..efa0ef2
--- /dev/null
+++ b/tests/real_samples/Ladder_Routine.L5X
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+DA 2D 04 C0 88 13 00 00 0D 0F 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Op_Interlock_AOI.L5X b/tests/real_samples/Op_Interlock_AOI.L5X
new file mode 100644
index 0000000..f768381
--- /dev/null
+++ b/tests/real_samples/Op_Interlock_AOI.L5X
@@ -0,0 +1,1081 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0) OR (Inp_Bypass & NBypass <> 0)) & NOT Inp_LatchDefeat;]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0) then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0;]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Op_Permissive_AOI.L5X b/tests/real_samples/Op_Permissive_AOI.L5X
new file mode 100644
index 0000000..6fad99e
--- /dev/null
+++ b/tests/real_samples/Op_Permissive_AOI.L5X
@@ -0,0 +1,694 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/PackML_Rung.L5X b/tests/real_samples/PackML_Rung.L5X
new file mode 100644
index 0000000..8ebface
--- /dev/null
+++ b/tests/real_samples/PackML_Rung.L5X
@@ -0,0 +1,350 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+AAkVkJc+KX3+1nKS1N9ZXoH8bLM12CK3filg4w8MoAFMAnIY7g1X9ss9APRN4qoKrR8HwnGheer6CA/dCs1yqa6tEYHyr5KU7unIsVb+iFsbLhZQg1/SEz2mXspBO4OKcksxmFqyK4ccB5DJaCXKApd12vpkgX9NJpS49aMQL5e0cw2KCS5Jmy874iRLqrL2dF1/87Nu7X+aaBixHnbc5c6KEsMt788jAhuXqBY96ZKUyChttqcGlYHsRATA9qeX27jTqd7c28UsXnydoGVOMrdrNDUBLIOK4XZznmwwC2BLojvW7QNbj6urgFadQWK1qRDGGDU1onOtjNXVEX2v8nG0P5vXihwnRSR8la/cOYkIsj1e/KgJm3wx6z7GtIE6O/Kdp1AMWqLJUsq6Ps9gxP8GQ+VivSbep72924kiiUmXogjVwO9rOL2CA94iAoQGRTfQni/9jNONQS0NjjMlkvUvcYTVcVn2q2ixHIHzoZCmItAW2EN1Pqd48YUe20Zub4J43Sb/umyZUii0frYKy6+JN9VusVy/YcY2zZiWUsPO7QAZlHmypPKOg26UL/8c43L2hSovIjS6RU+hg10NdiSZvH3UzSt1lKBvwDYTLc+2+IBmK23VnMq1/TaI53LST2nASNsvgGXb9LT4KZkhvwbu+FZH+mIzj2xj1tQOf+kO1i7xbFt7B5eVFfMVLIEG5Nrtwz7ADLsoyMObPJEhEn627Y6gCrXEQfr0T/laEClWUGIx7L8U5uRFDguoWDkRWS10ztL2Z2u/dAQXo3zE6Xv6VJHDt4qTva7OQgdr5DS9MFc5HK5xv43RyVgOh5hmBJKsrWG697o/ZRAfCrJfSMqAA+RLsKBP1BwXkTpuxIDc+ba2q1Rx+HP4IV7APMwv85SE8DLz0PzJXqv6Aaj9pngBp6vPVBp1u8yhZKOSWU4PtX4j+xQKpFyloihszT0ISU2lj1iywXDi+UisXghArgXB7uDsThZ6KIMq+vw674Ev8inVsrlFztoea2reW/BryIe0gHvpF63FYujISJPCMSPwPw+K034TqhAeSPf4VU5L1ZKwiRvjx+E+HZu0gwY4znzNSvrcgX4mPZRavu2meb/OCBgof8GaNs7azLIUbcMYgM6zxcA7wkCOXCYv7vHIJQoCWgZEl/WarHhFdKClqFpeCPlyQ1bEKpJCVYhEWvwISdN4FqWBb6KXIg/SFDCvW2llcwkj+QQfTMZaUgJIfMQZ0ycvzmzmARIMOlOwHi4rH6zmd4LBOrbkSEW4q31rM5pTNkqhPM09TiT8A60E0vLjasQrwEcfhcukgdrhszfYQ7AlSuSDuiETYVXr2vTo9QeYuU97YaVSz3lXSDbAB+3uXqbz3DVdnfK7z/H8gSrw8Pa0Qw0/3DlU4meKlqq54esV7uI+w+C/WtX+W3XIn64V0fK902wYFUzCsL+oEW71dVqti2udYm2l+0mLZMYt8oVL28/Uxhz7f0UkiwT80HKlaEzEvizDl9o84QN16+VQSJKvCZIHlUvWt9GX1ANc7FW2w3XIENi2n1CGefKWaSCtHaBIW0+82iacVzxm/CJyE+uV3Y89YjmJ9ahDHggs0BIo+AD662CUoobKC6Xk2xMhaUUs+xlaqRLQD86WSULswjlVEXg/wHP0aUZNjdMeQnm/aOmmebT54ca+aaCAmQDpYmwDiGbFsvrZfseNOUTG5gc65Q16t/0G4DRhuDs8lFBrc7F/yOPv+VSa7RcCw7f3fAoW1pkW0QuZmmnrr8wcjvvUB29E6j0CZIG8KK4EnxYSjr2rVrdzjKu6wJ75mRCrF/EpVO4vshUI+wQjt+dzI7HtpQZYUeaVyZ2Wm5TCh1lV8hoNpZ3Ua2DeDp6EsgCPbfa+xRkQztPfpe/912p6YgN/h3x35d3MjRL/GNB85oXomriOwl8X8jhBqzBz92deHVGOvffdtfmGXzvL2VzGBbhddrhWzKeosz5JcN6kqE1125CrLg8BxBQMsOxYIIQRwgPHphBBFgyJPdQCbKlX1XRIiSgAc0nF78SBAi8elmYoLrsIvmeHH3Pl/LMgYM7ELrsK5ZQmjCAVX2ok039EcT8K1gg4mVRxXkzhiNOZbbxwrRJiasjJ9xNHO0tV8ud3IYgu/YlHO+XN5G+bIQQ/alcVlcxt59g6W1y+2Gd8JjzhdJoBcqXLeN3wUQVj2Nqdq2aCXeNbAOG4yVROWsfOUUD1vCnXAA8HxC5RJT99okXwsED/HkHAHPFLCdSkOOwARscU1eXltwIzEMiDWbe/Px1ylcDHspbAN8z3yuDb0l5xADQDrl225fNKwow4zR2xeZX538X1cVcBLQHJSCBZNF1tspt1LZm5DiM87hRSiFqQ7CuWQxhkdv/NJls6FLNCRbnUAHxXWmTes5AbduC/KYRvpEVX2dXZSQuc7pjYFmXRRxP1m23wuB25si25d1xkbU//6XTDL9FHL5HAhjHHbKXRJmFXownTLvYrydpS6b3giFwtAUGpsZMgYhIJRI84sCUHFDF9wvRMds3H+3GlkI/hnlbbm+IR/wP9T66y+8UcZz1u7PDWwWZMBbR5T5Q2p3bmznrjHCRCFvefNoWnwM15lWoNn93rtjhcBYIPMGdOXhsk/R3Em6YhON75eaNXILj6gwUpAF5ZCDTH9XO2FciACqK8dhlHOs/olIdCN1dpd8rf5tyZBEe8k3wxoi59xALv2E4swa85aMjNzFq0rV5IMcAeeSyev4LxVDn+GkThj1bBa4fTzzO1v9/G7ptaZsfq2OLbGWzDtB0S6mmXTKLiEWbA/kt+sGNno/zJ9OYQBNFUgrJtM6lbHEYoFXHJCeLkMr1fNYDh3H55X1CpK5hddJsYD/i61b4uM0o3V+PB2z+7m4sLGQ7wcvNmZ/Ucvt8rRz/x78S/5ZoZpDaa33L/Ewo5oRg2gnbR4YzORrJO36VDehKNsdyBtVg7xXReTpj9cfeC8l6GfhgQBxy643TloZyhbN+IzIPEiRMb2o+fdSUlmCpWUSxkWxSeLu3fNZdl9JSIO+cos6jZu9+rCZVGN75AU+SN0j9W391yz1aHjgm3rLeXciERoBfpI2f5CyD7kz8fcN7phNCqkoQC2xSnFwnoCU6j2isKv0GmwPvFD6fjlW2LMPzrTmJN0RYlHFmUnazZ3sIZJAf99VuVRgm1Ljk4p/H4JZ94Eq4fRO2iSiMp6Yh9rQZEmspj0JOmqf16OpXTrk40zDusbc8D+hFFJp2ziTLsYSmqmeEvELTnBN5ShmbppE8lsuF7Q4qXI9644SXMPJulSyJwKscHvZHmWll4qMLQJz1nOU10jrXoRHUmxqxP1r+fRmNckj4nOO0RQN3bajkQXgH3+s/bFKTZLWw4s4A70S32rnDZWcjkZYp9prLAXwC2YoxZ+yVeIoiyBLsq5zwuI31U/FyHw/91da7VxeklfqVg1q9k8qffHkNZfzlAIyj3UWo3hM2z2sRRY/hjhGNVLcC1yv19s1MgZG40JqfAxIaQ2JBfOuNhUGBFkWFTUZR9IbC6zscS97qzA9dy6vd/dSvEM4E6qjJloq2vqLfEtLzdWAPwN0E15/FOBl1tK5lJ5bRIeJDsCQQ3R1hAlf/xJshj68DhbKmeNM++g+B3VhCHpo6cOFRiGBbHIbHonaLcRdciLM53ojBnGXPWEya/FjZliANyD5GrcU+BzZxo7QEeyn9DLpxyWSDbpLT5BR2Rqo0R91f4E7QK/eZPLq1voxkQlaoelWQFTHtafMdHZvE95P/Y5EfS+24LHO5iqdDTOBM4UT/1zv1xOEG4zzyAZn3qxbx97bZ27JaDblNFq2kbYOmy9gW0bOC1kyl7CVesYuRbcT1rkVs3cVSNsEs8ooofJ4BS/iF6YAUieqT7sGy6CrhlKPxbVpshVfzhqghMwR0tbwWXYZtMIX3jBQVaubPLuiNXP02FtTeHmvYfIxZhAVmefRAyQlliDGkhn6h1ikrXG5FMwB+THs7pCBv88K5cQpjqWBw/p+UyT1YdomwxG3LRXgxlUn6R90uRcxcmCbxHeHc6pOSLx91yfPi9QYZfkeqAn/UpjWNYntkHPuC24Oc/Gr+PJ6vbtkizbJelDWr7Ys7wEgP5aYn5uR3o73xxxA817DqLp4w9esXXLrVr3341LbyizUH/LvyR8nOKpd/1/u3JGDFJMkvqU+BBoBXfrMJ3CGikxCQv+G3SKwXqeonHgn1w6j/XgFSF2tcrLTCYKpaUA7yRRhXpXa3Y3cfmo4mgxFecX5FFrjlgG9W5lhMj7ntyWQ5SULV4gRvI3UZBCRvOp93XgXlg52+vj4TRqckfboAekPEKcDPPWmYvW0sVyDNLMH1RSrxYj1cfFvmCGsAnj4XgdTHvxbUshizL6LcRdf2J1VgZBlyPf7rw96wVLT9042L6fTsCnekl94dOEVHkzyuaZ8ACN6CmE5ZVrDaDKZQTrQtpOnttnCasvuWDhZuAMziTiM8Qkw6/SzghZiDIrLULbnne809f+1C7YP2m7xyQ905oKLdVI5OiYRgCQD26/wn+EMkuOOqV9fQJ3wh8/fit+AL5uqZ2ydHmNAMbfMO66KeieTH0gXzjoE/xK1FJFdI7N1RWRx5T7+ai2mFo0FGog3EHd0diu/m/kjIMXH3t7CyhcpHYI6DxmSg9j2eEu9zdHl31VQ5wza3N5EvyP4oE5BPcvhWakdR/FXvAGLYo+40Q55wTuicgnd/Q4sT5h2O9dRWjK3kJsSmQeRAVMfSkw3yPq193IDyg5XAG17nX//7RQNWI4jlw9yYthUDrJXuG9BIA52Qs7eybs7gcnXzB5eEwRX55B2fmA4uX1gDoAFeX4UuUYUqzrOO9CCl4qygldaVa38OQ/cJ3XFM0+SZoBP0N4rLb80dNMEa8DSBtdI/b+ehy0bRJMWAxIonIkRPr7TqT8x76aMuIs+azqzdSH9KZ81vUCvT3xvpF+uqpT04N0xSV+LgXKvn9wZWWOlnTr8STdnk4BkFunFsxy9cR/V8hmyHYbtC+8m9KdnfPDO/Z3bmmi+4ABU7Y0bB2g5huxloiciPXMiAthr/t4poWp0NTAuiM2vssuKfPpSeo0et4Slx5hyew2n+/BMh6YI6AzBPnaamv6xju12nOpZjOYKvgG1G/2BLkLZ9aRpOnNMG+6hpd3w2zI0dM53A+TbKqC7585LpM80VT4yswuhADJm5OBZGsjvqrbMI8bddI0G5GkSbexkQuA01Meh9CXTJynEeWL0lklO/A+m/LhLUo1aQgeDYeksGpTdJnvXlyr+UH4weEtZfAyuSHYZDW5sIbX0SPX7aaoXG+vJ41EKBRBbS2F1tQ1LcCC0xQ4blb70WI97OzOsLuLJfQPhk92dPpk+vKXInSCKS8Gjk8/GrWFsmsCGZm9HmIa+MekLaElX0JDVcULBGXaBVcKtiEVcHG5Dp1zjDicWA/5n11nFNEl+hk0S64vvaM30o60JVdRUin6btT5XCNX5wfIM69a/bWjEo+shRuRmutarMWwUCdovwgQvuW284VodhSREqy2yPjTRILxrWhivU5V7mlFpb0QaBBragUGn2AeZteL5cEhdT4ZSbwo1xo+vNDXXXs69EHAajR+ADuOLMtvaaVtq1cEMj2O/jnSrkH3QkTqMUTM+3D7u8uuSx1SzYu2sLtnXaARmsjJj7quXxEMLMhNxAwCvAkP3yF2B7KIy2M9uOf6weBoj8Y/V4wX6yAzh+aJRzQYCpurU+iDbeva9UGb+mqI2c66D1/InpMpCsVWlg8zXxLn4g+hK1OwQugyX06pPU6FZvLOV2tQtjGq9yr8m53k5FOlVzaQe5Aoul+vxnK5kpflb45aM8/vLW/QSh66nYK8O2+Jv629K2ELZisutcXT4txKTht9gBnkcZxSapn4uji8foYir55fL0xffsk1csC4oaIQmKCrrtdJnljz65L+KFdDWcgsrhbbzHRa5o8pXDiAuPe8g5WaBUPGOsY352hhqItE68K3n0uZ55G5x8zGhlwaBdP8ccF3qcs1kKOWk7JGjCiDstzSMW2LCtZoTQ4MVCMhCq2MFX0LlIEXSA2/Ochrod6wjBobLsqrUJtid7/4DqCxavlo7E3d+6iqHd2mTInEK21Ep/yrgN7VBgNncylRxH+sJ869dkZ7h1bO6+3aSRoPz78NBFn2m3BLj508Fwm8+/4c6LiVXmoRKfFakjoLjFxqEkqIcm94SxlQy89iNQSLhCQKviuxHwcq52BLT/4TyOUASZg8q1BIbW31Ao37M6K/1tO5njLrxFHviPACRL0oWwaWZDhwLshy7zszlOQx+nwHytip/TyxWpbpU/50cQbfNwYwDVJys14i5nLCBD8BGcIR/0UY3smZXk+U1hHfWjiEL4KoKdll7nNkL2bNANIlP7JsAiBwUt4Q//pkXXYQrjMKwqpiOBnvmCjHPw/fsNNuUGUDDqSOjex7mJurQX5UN8MnpT8/qlDrTb+1sYeG7SWCzBalFwIeA3FRPRTgcz0UsT9L44nYh7Je2PjmqAIvZN1Al7coxlqQIbwb7FTfabnYBUa5svfhapw4dP4iiQ0VM17Kotii20h53jQt/aAuyWiQZwMa9BjTtPVw21sBaj0u+bNjQ6Dt5dXk+iN0a/iuAPX1hGTyMU1zJBuA/fgH7nMg+4XmYpus8jej33I71/r24eHWdxetS76NKxJ/uzeUeUT35S03wkSQA/JOtMqZ9+lhLOvMLEjr4VVK0UNmB7mP+E9W0vo+Yfks7JTO8fGRdA5d66kQ0AmA+3oqVa4c4yH+WgHiF6HZlVKRZxcnoy/h7LUJTySt2FPAEJ5YxemjXlnLFfZASUvUea8j+nbIG82oyOdTrUdFqs3K+zi49x3XBX8122UzCyLmchYsASTIvXgofXkF+k4AOcFPSwNe+Diks7AGXb9rFsPqfpI6Ne84XLHGXsePEDB4N3xResUkhNJtEJGokbzRV+CXQ5+iQB6P45xo9Y7MRJ7sBWAOPyCATASe+Hs/Kqgb3hsso6X7Fw/fFCWN769dWsx5zGL0RNM/NuSDUcypEOUjfSRc+zhtDc8IlyAvFGUijsRRhwE5Jz+Yad0RQeiF8HPndPp6cJNSukpSi93MJ1jCu7Lz/tc402NFEiBgzq+SLewqNP0ZgVTg6lskVSt9ozTQtPZ/vKQbA1maVDdVsVwiRndNRC32W7V8YCeLneSgbkYVZmp6UosU05o65kiGgqbJiXcZOayid4MJVqooHU48aOW9ITjOhcSimyJrFQHDZOq5iuQYoETIbyDZwXvSGQiJaHoAwYDsUNW8oy541GchCMBARRn8uAtWPBpLtMh5YPcTto2J43Hm0IXR8LFHvOIOA7Tw8gkzWC4s/yNS7x1w7vbF05tdlFLTdwXzrJ72sHu2NVnRq6I552ogYQV4WZxzeolLM4LfRDTug1RKzMp/JOgi2YC5VGZUdopq/xIYDXXR2uP2W976hh7f6bOB3Dw9dPmaxExUi4CQoNIg9ixoiWbqjkH7JDDAX/yjqq6urKW6k53XSrfJh8vrHkXD6q49jcVvGXB0mOPpy0HMioosntYBXh2A4jW+sLNADdYBJnDIPVAqcMGj3jODFOCS7gNJSWfMn6bCy/fLwg0EhkAb/DUacSbUCV7rFH2tYuwm7wQ/xgjq5vlhgiXcbYFkwNInVKnCOfuySzQ4Jt9NEtEHdhIJQ2plqxl/winxd76PlXaDtf3hTS2d1UmuJbfZ/1W1P133hkyouXcFnUIT3430PbXjo1lAIDSbi6gH8WDHVTYotgZANASdJfZJ1vlfQzrc3jem0yxpyU2ciRUdRiUXCXLFwhSpIPvg1PqWuh4aNDto7keAZm8fguz68A1y4TFIzOkWlZf14OG0P0w795N1uneQsWd//SQhWajGblYh+SXPyeeVrN2Umwo0brPftiR2FXsuCFvNfL2z57GOXPwCSgj1hjgEQrr1PxdWrbnIG310ZhndbkcEYSS6pu7jd65Hm7EGxg7oCf6OeyIaRFL3Fl8ZUW1iWa5tEwKxyf0saC/wSf//I4wsKwTy2p6wLAG02IN2jRmuRIY3XMeq8hi/UgdCfllbbGPDtfIMhf4JPbB1LXyC7X5FHU4WcVkVnvDh4As2ZYhGZtgbsj1/mXIK7KuxPN2QWzkgvlQGavgZJTXI0eYh/uuqXb7frTw4IHul5ofFRV+ZfZwJLHsFxQjeUSaiB5Lr0dTRxx13K8gBd+OGn/PD5x/So4ciIOt5jKEEAKhR0ZO6Tk/aSfxTQsPHeAT5ut41gfPlfWXdFL7xhcWxCqq9MOZvEYP8ubhCLmPXAZyDgI9usTRZB7W/F5VZht/hex3LsNrXKFEr/58A1eQMBASE3bi6iUqi+C+nWURWxvdlFzoz5a36axSg8iJODFW9gQLq615UkPx4JHQnL/9KC5UFK2XpEjOb0ddBT630J/eYpZ5cm1lQOfh/WySIPaEnDmp7L7FS6s0g2FT8P6xIkfKSjn41WydY/hB+LZPjQbYxYjCT9T1229IDmAH0Gqz0qbK4OxQNTQ0fYjJvjB6U16qqNKLn2ANIiRYjiTQpieFpH9exosyRU4VOoeQGMvnXcWNNuvIEvLMd5LBQwleYXb3d0BzBNDvwcYkpnVUUObvOm2E7HdgLvm4o9JBlgLzZw25mqudLaStuZSuqRx79aKhC6G3UpZnCycOqClsozxD/wBMrUw0TGPKLenU6f6YgwVHmLGZ6aVY+nPgAUGOtuCRuZhdjchISdrPs4TjB1yPtsqH9M9D4UT5TUJDXxj7b5/LQi3M1HNt1Jp0mFa/klXbQv6m/Jjzr/tSA8WzgDRpdCF1/K26CAXzFga6evVJ5sAkZudWerEYns/47inLS2l3SLiP/F8IN7khAzA29ed3VDG/dE0lrMbnvkX73vQvUrLsrv8GTt84LR/RwusEFPo/zHKQwCWOpPWRA8DCsCRTQ0Zy1eWHjJDsNCtI9TbKBQkL37fGPmk3icN3mkbLbcgbq/Jp72l2B8F9GUb+b0WZArUNGm/tYFNIIdVyL4Ip3V+/CiQTPfMkYnhdnoHILvmh04Mt17W5gLCBf488cXfprZxY8pCnKxqDKRV9O72L6o2ut/16zsosLWJY+RM1WSxSXDrfe4rTet2XnybZt3EH/qkOF3mrF7coEKnD8JhcMTnLzWH5UJv3snoAOFvwhVlMhL8vMx3YUYbx6PYtevakamzT0nhX4GbL3tslTeGXKHThrxqiPhgX+K4o9cRLwlgnQzfq9nzEPPxJPR3AadivxyXUXM1+a1507r28TAc635hQDdOJbMYEpn8zH+kwSFz6PdGD15VfmDv80h2o7ZQ2QVmWG8At55IuYiiZnqVZDK8lHFA8MRd5f2EqS4NZqgBDuBfwUlenHnCAhKraej6h7Iyi6D7bbxxYCDlx+xcorw7hTAbFoqcG66URyUVDIm5IBuUQ0mARBt6c90hIDYyT2SdaS2CO9Ff6t71zwAVNNbIpRURpZK1YoctEooGnVrKiiC7fVl5a7iDQrmtEdD144Vwpvn/FmrYIsuWQAoUw2HZyBH+PpJu8s5QYFKcqTANJBatxAFl0fwn4lwbjq1h/GNUSlZlJnz9PolomZeYVlkk7+Zeu+abFXWZojJgNSFtlIyrMHzjFN0849jtiz7eCn+4WCrE8CAUHChLXtiDHbVIox5eSsI0UDUzV3HhY7y1NPKg9NW5WxZ0PXiXvKQoGFVBidPTlMKBT3t805PE0/ve/iWSbh9k4TLK+A0q0J/9kcNjmZhczKqhz/p3biGiaKLG+zwKk96fW32AhCWoP7dgfcwGRgNfOqBWzYXlfwhPI4ZkJKC7z2puaTBGarNPSVCL8a0AFbLTOdT3EMfFI5NmN5WfMBYD7LP4PDbuLNkelh7z6cL6ywKDwN5RNtJvFeIUIy/keRsQka9GG5czC+WH7cCWkBeEe2KQURSErZ6iU0SjfTh17GIIrdyPjZO+eRNHpohkH1SW7BanXrV4c5HQZHriW1Yqhd/2x/Fdo08YRT3rmZsj0tiUGOKJRkOMMof1twIj2eE9EvOew8abQ8blkoOkV0xlxD3CX3m7IdKgSdSYVivDkrFO8grKSMo+zyPKYaPUpuO3a79jfinNBXpxrarp7xNd07aymVrz4M0neZUyg5ouEC2X5deE4YIvsjxjT0fmdTBg1dAYwdBe5E7eeW5gIIc3EmEG0CHwHzO999MQmXGAa55YmXchGk9jbgc69hq4UU+YsxFaUhe9ZSm59UE8ciKotlBpW/gSwy3RkDNHe/N5DPxE7uvegLVnWxtB3m5moO4tZDazZtV/OAR4JWUA3Pfbtx8ihPUD3eTSW//4/Cxbk00Mj2TIc3xurtjkkfsp/pVJOmE/OJKCcyZzHLe35BAFZE9Z5QaU9DrN4sxJvoIDYmK1kf0sJgDAIkwy+QlNynk95eBt/SOCj3LhAMUii8ABGhLUUHs7i9K01VOr5X6VI7V1xhR0k9QHv+AtIOGX7A9Evh2P7EbZDkeiDsaa9qN41xN9585lvc9a0ZlRH0xFNcon8Q8UIInGk2Sv30ZrtGueQU88sqsPtpUOJIKbMNK6YLVL1rExx/GCQ8Q/dutCuHOQbDoJhUdzXf4dz0/cR9ryVJkC48Cg34SyAmSriy/ogeaHy+nL6mf721YUI6XWGANTQtCwo3nf1xZ9KIwwJH+hAf3p/OW1O86zm4BxgmSAr7OxImLn12PGh9w0z4A9/1vfeUKnu4n22oa3xNjLMpzxAa2+yLuGOL3FVcGF23gv8KPLcRl3p3DiTObuEUDG8uslMzH7Xk9QyuM31dzEOP62AMRqX8sAbXzan9RCRuOPXw67dvivDG9ZlmshUFcsIS0B/C/YzIvolhyhI9AMljEEU81gam4YG74msid4NLxVaO9tHfxEHtMxYeVbHZVa/lm7h/NwvOBuigAiOadghHhgPuoxSkVuCXd48q5+jHRMGS4bddv4qdrIvNiWryb6q8GYIUrrs/cR1Ih+tzhAFcdw/g5lxcE5G0TSKZd+tLyY5UrZmFvMA76euZXJV7NkLCpmmXastL8OScZO20Ui2YxI/ECobJl56gVqPGJB7rauvcTd0RYNrc5L4WnwPewm0QRCfrlLY4aNUMCK+jP9vgNw95MZNfZF7xqA17FlTkLcAU9rz/jzOr+WTVt+Ax8ix6d5uz6J+QdGtNtqAxxLbnF3lqWeR0GZAyk0EjhVUhE1DGc30LA77fEMV8Phfz55rtDLFEuLEzWfd0g9qlJjc4pf85Qqvr6U+sA/paKBOjVuE77p21/NNIkEybU/RcEWjjL+ZnkpESiK4GS3T5jllhvG7IYpGkWvs4F07ucm14YL5dv8W1GiaHUElSBqkyos9IJdD2Ina+j7QieW10w5RndxkruaGcBt+sKTmYV13EGpWb7tT7nxyfVhZQC4jZpTWIlU9X+VCozTnodZXJY1M8JTX+vdCAPo8Vtj1pYKnkw7rnE8wtcMN0CNj2OH1RHO2MoFIc9iiPC3rZftmpHs93zSx/981lMSxdrqLgMPek9UjdX3rCw18GzoxJbOBN76azg3YbrK65UH/KL01jr3wRlY2MMEei1v01ZWly8a3hkxY5/lJ7RY56/7qxao+gF73gGBSM5pJarDVXE3+ptkLEPFDQzLVVa2uAL/7AwRBOD5hxrO1Rmc3nirbikifl+qOpJzSs3A8H9gOjxQynO9kX2txNZhUuHbSGiBqofAuNIbI40YR+gsYcectZ7gZoRSBIHUBuivY4orOn7VUvgCFUcaKILMEX4G7VVHHQBpZl6aus2ie+dznYibIsehbcTJ+JKR2t94ZRvEennBq8abd5vcsTcDeiUzuDKNNuVg3FUeXMr/MeCuM+pZYJiEbSNjt9HYWY0m5ZYOFlLzJZYplnEax+O+IfgQ6FcxsCaWtUw9hOQkSGG5b9i2swwhWbk4RA0WpoxFvWn4kPS6mZUX6jWSeLU4hZyFSHM0oHG/W4hDSmfSJgHtNzooxlDpezdCmsWqhZhZN0tvsE2dXdIkrGsy8pgXxxJcgMEpYFhkLSiA+wSxdKq2UICTXP3EM5n7NDOodtQT22XxwKunHYwcgzmt44aiZ9y1IaznCbTRMz7qdw5aaWTzHz0jngiS+aTOsTRVC2lrEWL6jkFghjnBqxb96S/Uk2dSi90eGnFfx3Zdgmn3Xn2fCzESXUzDqCfr6H9RHFA76uVPbqQn2IUnUUoc6hSr3BVekFKuRgaogCY6nPDIJ9b2UtKrrrZtxfdTScOm5tn5Zr+AKZ9KvB4jRzF8YJ5fhdbEkyrOsRH9CCO/G/nIdo4ayItRjHcBGDV/7cYyj4hz8nLwoYfYbIgKCmtYAW5H7PGyg2ZOZ/CJTjJReD8EPSqEH0RfNnmL0B5c7B1KbDrPJID4hK2BXI3rZ7bR5C5pZFJhBKm5a8t/0w5AV+Nm/d8068VYsJbxf/e2IXNVgb3hcdsxwb+DoM9knvNVETApWJwZQ/QQzEbWWTZdAiqO/QJQjchbKZqG4zY69f/52/cDzkXt40chSOlYYHRtUOW1n2A+s+PGP/BgsR8trCQaa5DDFCoV9X6KOnD2RW4LLNqx28I6C6UoZTzGb9S9Ncwu8CEcleLfugst7Y5Q7av/zd/l8R5j/8kCWNXsWTfi+k9G39qIQ65YuPXkMkZpYZ0L3F/yB6tdZQgLSu6t/bIU5uZhlcaEFa0o2f0FVF1sN++pA9CeVGrdC/aESmFK+wPnZxxpjMTSRgVYa8q176HXB/+3AAMMYaRJTBlycuNM1FnXs3xSFHrSNQ1uE0fKWD1/HUU2Lt64g9+uNvISMlg0KRYpLk7di1rN8yRmAOOCngM4sFkTO81E3otR9NPWRWaWV3y3LSO9MQVZmLzBNaGkSXo4eEvdxgYGXcq8VSB8BMrJEu68DvzvShXNzMoBEvvTRTfsgCslb1atvC/7ysMjjuIm74Us3seItdW12OkYrnl/YCL4t8mHWf+pN/KAMWM86PP8QqDplN4prrA9twtftxvm4FqR2YfJDt7gS60xA3vS3FvROqGys05Jc2HfTXX1XkhS1xm6ufCD6jiv7RANIkRj+rU99K7Z+qqntWEU4rEhvxM8ZVMKnvIEtF8g7n7Idiwh1+0OppGwFkqxrjnrb6Xj9k9zmQ6aGuS6x7lv9ICZS4cDQrCqa235V+Tx8haYv+tAyUhIR12aqd/yICsoFVB1dBmkxU6OZTDYP52TTo2j2emCqvDui0eXwqtcrDbP2R4CaDXM0QhtLr2tCxM3IIoEXrTd97BvnmOL+YV/f63NX2W/+6p/qz6tpRiwgcaosyo9vROJXxRaaulFY/sISFTAZULRGDjd7+/XZDdBCbDBa+53wcThu/IGhkKlIeHqfTeb+s0HAix9mGOAtGmsqGIeaWx6pTSOfXa4E5ABPVPxyvrgWIxQIu+gbXpC+5UQuVLL+hDgPh1IaZf+tYx76u97huHbjIWlzEm1hxe7Xj2s8kuOMhO8OBNP/xEATfgk4adWhurgooXulWdIifuhJ4++LLYlS4a25pF7fnemta8seSdQW3oZ4ZjzQYvA3tFwVcUdp6zndeBAZ3XZMNxfTCKs69bxJRIrmPrBtl+rvEOSyvMhy/bYlZw67KEbWuKPQMTg7gJRz3K5LcdjvO16MFSWRrMtoDTms8xPN9j/1K5teGxbynNUqe1m03vUIgf0Bw9TY99/7sNu2/nGfkHUT6NPGACII7CDIk8UERgXWty6tNJMqiGxHnc9v3IraHehPB9ZaPiAOoLYyVeTj25IKJtLEtkMo6XX3huoRWqYgoabs+c4NBzWJBM+0cRV3sfHqqkSBPj2N0Ed1SEzNwpgKOi318Z4WxDoYONuwRxC5I8bkKiknhiigcoq3fMOxuiWib/q1b0Q7HPnKjD4aMgmTerJyMnFKTo81Au/BdkhNyHOOxuexbtquRtcCYrZpY4UdGw22bPGY8h0Tb1DBjHPuCRKvnS257JL2b3JHh3YDwEIul3Z7KXM8ZYah0eQfwA5rw3STQ7u/XnQj1fYub20lv8EAC+G44EL3NNSOq/SK4LwTAEYw25vpiw8bGRc4cvi4FbiUyiDBK5b8zvI/WCBxmMgf9UzNL4A3e0zjfUa0b1uiy8bD3vdqQqknK+5i1zWNDUPMrUlQ4IfaDY0IC/NjQLnMli2FJMuR1lsRuHKTHPgHmR2Ys6tRrq7AmlCG8wA3kqXd4q1QaUYIH6ks7wyFlRE2ywNX6eqd0s+nIeLD21O4d2S8uyPgy15ZcPc7d61NiQyYNztKRIlo6yElcPvyrqvCzGQmWZcmvHXlCh86qqa8e7Plz8Jxaa/9ctPvdsNbDG6ov0F9fIHifcHr7ZFzO5ks5kE1Wnq2tYJjch0ksa10gCu1dJt/rKz01ob2WXAdRr816bS36tmgHsBgyx7jlMGMIBYGkIY5NQ0sNYFzVte9zL3UXv+WMLMGa3uNu9x9SSYP7c5N6Ny7Q0xIRqjLmrN2mexnSjAhMee8dsPnFPD1uLKx5mcA32i0sXtHIoTnfoBOaWwL80IndOWC8gPHYbeCCxaEAwiMg3spDeWRmryHX4aW3xSsE6TqKu/Z4lgRH7W91urjCej4DZ2jNvKtrQT1wMqLuYlsY0Kje2U0G4D0cbTHkDEN8j1/eyQKF8Oq4nFg77Mg2ZX2MZ9ICc0FijrrE6+scxDAf+gN920Sdvz1hCsGqDyA9KGSI0nelTypqC+I32Y19Pk0zXFyJp5pXNL7lVSgeqk2XhDhAJ64ohazaaz6kGYxH+OW3o2t59qc+C1sRADcMpB0+gMWHtP9B4qxOpFLgZkQyzmtukhc0KppXkd87hGvbYTILjg6CbpSY9N81l/jkd/W9zXf+VXlKfsIEJRvt478k26kbSS9DzXmEwIu0kwsLSSAfbpOQq8W6aCWlZa/FZKzbEY0AMbWoWdjY6TPB8cpYtwLEkDrDWUbMeCw6Oi8U5Hc6g/TIS/RFvrI/MBR2W7u4IURVPAqdSZjxd60orcu+c6xABsgbvqaeCIJlBwas2uDeYuRiwkZ0qTN3sny2MkJGt1jwrEdK8DX0gatprohYpqjjjbNNqEt1q1LNsUIYDQaNpZzJ3tvtzy7fpvUlp8272fe6qlBh0qxXCCpYH0NvOgxbJmXXOw+Obi2YYwHmIrqIz6exQLmVr2IsDnUYIrK108Ba/8IEoF9wr7Ydyeg75W/qUo6JpJP7wjK5jJB94lobxVeUqAMGa9NPqNPkODogN4IHAXgdGQ6D27yQCcp38NqKcGljAyKBDFugrmYEVzRp4Jyhbqtkp8caD1g4l2MdO5o5zObEKzYE+TNwwl13lhaJByn+ChbutwlwAOk7EsgVOPc5fapMN+pGhTGgfB36BHJWpcfyybuUkNKGrp8jyxMuoNiJH4psVevnGUBTYipSfh+CS7SLIa6GPLkhoFe1QY8tfAeYf1ZWVVMkW+o6M1JX/izHQMYM4Lv7F2OFseB35FH0SGTEhvuqonYdt0EhS1YBykCaunJmY1zaKYKD5xQyMvFpAGtiOmSAWg4VM6zhdDaBcJ9H7vQeD1cplVyuMn25JVX8IuHzPi2j59hbF2patjG8ayVtEwU872lANHLKw+Ea3N2R0zDLN9yZT/mAIVjJu3gqGGml3mi8EPE1XwoyzPggEgg8s2bPsmDDipn3bCYQZyIGO7BRBVJaGlRqDvnmE7cnpGgvlMNenhMpnxtJnAaV9otPdR07z0ZFPji6NbnjUm6ekLO7EwkORHbxWw682qog3j8/7AFHBpDa4Yc81WOkA8daxd9/h5IVMNkkaspLS6X3o2lJQHVd3kca3AHVOiaCKvGu6LUhNc9bN6ysBcmratj7q5Syi5eX4Etbz5JPUD9fBvp1ydubmqr+LKlao3vvHdP0UO24JOSGlt9hPx4nIZSIpyXxwPW5w0OXNfaMF6xDAZWYna3/QQ2p58uCW5iU9hPkwzpXIcU9IzRKATynsGvnsKQk37Nz92ZwI/Uc/Oaa3GtJ5N3W2lcy24HKl4ukEdmmeBjrQ+auy9Wgr+HgVUc8ulSnkXcIeUsUviheMP9JAeeeEFEIoJ8uOKSUN+IG5emH8LqL/CZG2Eov9pSQqbyNLPakU5F/hQHlIU1qYo7kEVpuavmhJaKE8Wwfkhb7kWNfsA3L81wEVP/Fnqhd5qZc8A5X11iuMu4OLUE6zzL+2RXTMzjnjObD17uDhxmf4KNaWC9y39QfSmqVu0v9YPC547TvQgHvHX8+oVl2FHJYcLLxZuXvAP8MX4mg0H3cyraY4yK+jIICzXW1msrKexpC+w2PZoiVfRxJ0iAL7dHZlgGj1SQFRAZOPGb/p/M/ED0iEj1Yb/BsPdAikAPmZi899xyytIEePEztjZduiOUmC8bJKV4aPKNzdponbexytuDZw+muRsxN6IWUpCtXC9XsH5/wB3RCP/KisTtU61UPhSaTiF+MYuK0w70q9A64KtwVnZmvXppfRg5oRnyMqyeQ3spkLuy79F6TY6HpRqJ6MuIHvZt1bwKEdV5b5deCAH2iNFYtXuDO+lyWQKB67TZc9BjqKh0pZxBtaDZexE05iVVLc594S9z6V2C2Zj3EMN8ggk/Tg9pM7fJuypvjgf38LyqhYgO8tn4Zq12NHTTm1rC/l5SrDM4vtMnhd31FPbGMNEFpQltp+Ebq+gUIT6qoRqdNQkde1HtTb9mq3yRPk7FnHG3T+rH2b6kCd3pO8ZhRaeJcHQ9fEwCAQ8sN7Zpobe7qBwOQ+r0mppkamnQ/H3TvEprzUXPjiJu605Ejk0UieqGCJXoy2eXcAPF/DrKXpGHg2XrYC9f2dJ5Eg00hDeA9dlQVJtcnmkMaYtLItLu+dkAJc+n4FwQs4yJJm2BTlJ702ne6GJV0x57GXIpT/fZTaC56F/tN3xGKlzZ6nn/7Ek1M1ag6xw2doibAexyY43i3GeWycSzq9VkFoQsXC27Lr+g9vXTHc5SXrCV6t1DBdL34njJRDHehUUvQlYidQDGN/Yh0cNL0n8e1/4Rjc3PWNoL5cbSf1i77h7wyJ9etHhZNw/9G0eZfI4dmKSByoA9YRtaKSG/sYX7BPQVbr2SDoQY1xHwJVu9PTdFcN0n72ZQ7EsP6xRiUZOEgiHTQvnIBPmQbnPc+fgOhGTwbSVjeqe+3DmzL0ZFDeZourrK07f+u+0qozavWSbfK9HEYKrH8PTPkRAqILiQ6Pz6/YHGBBSxEfKDThkgRD0bLUexabycvYuzBz+LyiSF5mGmUPb74U8mhvN3vPxkojLgw/CVDFnCG6uVEB3r5Pgx3sP5hFO4Ke7ePYKoD6g+0BC5U91Ci0g6xnFXZXi/Rrd/I6CNOh5cS6j4H3NdJy5LftcH3/H76fA7JNIjZm//7IAaiH/IvTe9Nki4Bjd0ztq21yA1IKbs/UPaRMN3PV5zXT+aAEqDpRkU5xs8yu+58vRXDC9eRulo/UdfA8siNbrAJ9kN0zK73AWrLBc/RpLZrNHaR8slpWEYdw2vQKNXLtvB58bDOsK2GPNtAM0QTQhojtRIOjc8IxBGWvExS9C0+bN53yVzI+rcykGrLoe2mnjbRd1+su448g6NA4h9auZDqoVU2Y+6ADpz6EI96BaZ5c2mXmvY9tfQjKHpWIXSLo7EN+CAWSTldpCFMN153gPeW0hAQ3WraaT5JBOt0UUuv6I3EGbrV+Zfwi7vRGPz7R4UiA226k5uuxrrdyeuMUsJlNM1TrVkNaQiLm1l8jH/bl578K3soHv6knD+bRoX0AQqbilZ3IW4adLRBmFDH6vEbuESXi0s754UMjZ+gOq0dCE92HwNoR6p74tbd5Dilo4YoU2HDaPY1ETYSIOM5Bt1k5CLHsIRrfwjJYHcGYwpFbWHqLYCDxHtV/7CMXiaRMHhZtSx0yB7nRtLmRxuub9WwSXiOJ67aC8m6XF0LUnVM144Ep8xT7KXs71lnyQX/+n/7BQ+DCkaIi32PajEcnTv+xcfY5Y9OqP45uE3Dghik0b8zgv6Xw5dhtNe2/dRzWgoWDURv2yCqn+ERRj+AGg+A2cHZBRcqt5R1YsZurlV4pjnRekpE8IXLN3kJCxwR7Rn7N+8SReXqlqY/1KbXVnS7N2HKIe0vj8soCmg0AEG73fgewBSzEzu0BFEr94DV9TH4Ka4j5UBxL7VwKpdsdnHROjCGVqPubAkCud+G6U1f8mMPbYStgNo+XVW811z3tArl2nbrw+h+qMar0XYGMkazqmf3YOPZrs1wbaz1ugiMiejWu+rncQ+O4zaepoN+2CYYKnwcFk1DSeJbUZsQX/ogMNhMyb72Dler3GdWCfMUQfjEkMSpqZbRjDAkgOzMJ6WT7h58moWxHemFQIkGN4b9XWr+t4dIeD3BdLXTZLzkEUGdoQ3RQtvTQY/hZBzW0IEZxP6X+esIixCO3uERw1DYrcyHXngEaTYd6NHEGYXNnH5P1LewtNx1xEuqEGH4PjsTkAqLxSZ8sCWusidYlIAFF1GEojiucznPA/zUFfs4Z7ZZgMXId9qEXGiFrTE7zt3xZe5+vuxrnrq/qguLIrGCCRVXK9YnUaAwwRyHzHW0gnFTswcftjJIry0gh6KFYDIXNp4Zs/SuAkMDRIeAWoC+NfgFcYcoQJv0SNW1eCJrxnvGMNEKrfrZ9VUermIm3NJEEEIYmU1OaEPbyd4ZmeJaF0hO+Bj2nLBKHQPc7WScpw01rF8UJM7T/OskiO6T0d/vRzVBlt27P4HEQKQhq2hcOE8PDYkX2KEXCb/cgrTocK+6kZTzDx8oz3cMJKCwNAEnle4Deee60GXB9G9bJ2EG5uaBUDIxNOKdg9JbnQJ+hbAFt3sDUEn6RaxOmQ2bkml5IgS9JE1p4ZOFMLosQO/6nle7OSs91D3XZHvpKABZ3zYAWHXU3PuIgVJu2VmYGoc3CYxRbzfI0yDkG6yJbqyB0wzYcGCW/mhL1h7hkwsMgzgNPlYFMp0WGVlL5sn9qP7bzi4NhEldgr9+kYp6rQ/edzgSkPeBRfR94d34DxDv1MAztCLtJRRZnT7n8tKwQgfTDVqvPruoPR55fKqmJk4j88b1rcADXt0hk0s08gSwmR9egshOtIbmvk32wkDkNc8xe42SLSSVWKwYHm+Eay+f0BSg60I7eRdmPsA5Eadnw5JhrBHH7sDxipWqp7bYf0xofAfD2XtTfQX7ej/XH2L9qFUdJVsOWmP43r5DJS0fX7sA4WMU8/jmlIEwVuwV2PSpCNnCtWb2Jp0lDQIYqHutOPDKaKWMK93vnCi2QcwBbqMygo7zMfQC6OQqcmhd+nKdE5qQTm6GH4BITp4xSY65jmQY2pBoKtBr9JgftP58T8odc58V8M91FSjEIJsB5eL/Y4b7YyY4PCAG13R0aPRmmbietgj9EqNnImGfA96+0nM+Luez9WYh8YTdYCxAxNS1PayYN8bukLGTcuD3j9tS4Y6ILMdWel6nEvhfd68G26aGXxjWtdJxRHzCWI3MzZWK0yotIMqsDDFYICh6N6hAJ/FeVvi94cZZmOu4DMJEDiqyefgmgg7nsNzOMphDa4vH9CB45phGjiQT5SvpIwDQCq9ZTqhVOTJe3tUicy2OQU7MMNqQacXxchH3cOQYn51n1rXRf2FJPB2nhnUDhaGeTBcdEPVN8RZfvuNxieJO5fJZQTdskRMiYnvVoP1bYRHNfJxhorhUpZl8IewMOP8nabgU79JIyJahIhIsjLFTqhBhuOvCzbo8hsB3BAZNzzJumbppmhk9nfx1cTJm5PF8TKxp6v52+SfTgOZ/theBo0dYQqI0EXUQwm7FBUYjEbj9wZjyLmq7KQ+UmpJWr/axO9AYGHh7errkP+/gU1nx7X5aX8nxbYZBOX31HFDVHBoVCmKJ3DwoeM0apjwEfDWjvo6GQL2vV09wBqI6w/0D5V3+g+DrcvwTzZVKDZ+9CQOK/9Ggl6/83ph2/yl1Q6++lEyYunNWM0PdagqK9H6HPwT4n/w63sP6Ikguj14yA+P5PjlahxKiMe2GYu1fhiO79/kX+UcSwkydHXxh3rXsN94TVMn7ZEjxrXc0I0p367LpNQ1rrCPQgJh8uQcZhknRQrLrdNkGDQrufGxLxn4HtOOMPX5hoj3Ikhp5t52qY2rOjCw23wqVN0I/EKGOVtotXtYl1y1GGs4ub+AZsaPYHEOB8nESpBzxilMaQS0WsoknZ6zHDWlB1s9aG6L95wd1TCSaerH6g7fDpKh1ro1hLHEck3kpEBV7aE3zFGX7UYihYed3oMOnh/qrTvR6uVa1uovFUuar8moIo6Tuv7vdF69rIkmQYUbkjRTD2Cy8KkgTP1PzJ0P0V2SDQqkQ7gSSlEoc5J9cYuwj5ktd+y+qKT3YXJvUMt3TMpVESARGQItFvc/shZq/ZH+m+Dt03ovP7yA5LJrDWHjs34wtA9s7D779jnom6E3gOXOd8V7PjqUt5CHVZKc+H4Afbr2A3lUVe97dU4T4fVKJn8p+jnU+DecPXskp3BCi+VPs3/tOlxwyY3wAcKdR+a10zqmxUh4v5oPBUpODJ8XiRIsgRkSUC7uiLPLCMjJIyKLuTCqjAqyuZtXDGo0UYsxJNom25e2n1hbpQ+4O7ua2T6ZTePa63iH8QKiExeYA5H3n3+IlXjth7zTxDI+/fXvC7phWOvuAcBQhdlL9hO+n2CZhQeMvzUKVLnTxdvTDMMefb6LTjcOdwVCwqd+Z73JOFG/jxNwTqORH70n9ZgJ2/8nD06GgfKgt5AP/Pev9wVopUXUvXuLW7xR+f4afW+oNbNtL0mqByQRegyvvNUtmN/qhf4JXD2RcGcNqzXVIOm9QAEHMI/moJ6vpZIh8pmig2Ss7SF3uqYMhiQd66o1TX8Dn8VOGTjr0l/dW3H4PZoPEHkqZkeaSqaqxbbfQC/NkA77D5pBYyB8QPUjvsbEfVjqTQl87zYfb3RNyZviq6xK+BVuLd+eN3eAdzQEomUu/pUBmPjV8N8kipsa3bKXrgiKToga9pWzeEpF1G8w/8JVO4Rs998nrplz91nQS0knkBeLL2dj7+GbwfYSnUeu/KSfUoGb3/RvUvtwoa+aHbl4yvbk+82lUUIoVcr0pLSEvRWT/dHePMHYaFUcbbjkkK1WwGAcAhlOouKU69Mp8kZtEDWllPIAgKREgXFPHQBPXzMwFLxD37bFOr2NazLuOxL01A00qTGAZCml7ux+3TekOfKxkiFOOqTwzrBc2oONdqRuCXbfGSFbsL8ieKeNV+6iLOhs22axbbLZV0QuPYAnMUVaCv/YkvGn4cgkr5N+e6qu8/Nrqgx/Q3uyYMVZpCiePpZfMqBuRWpGcWd2H151c/upLOo88+J3oqFoKY7epBCML/bf4TiYWD8sS90yDxrEjCOQj8vB6U25HUapK5Dr9QXdmbVlUnzlq3EVjAeE1gYg2OEYSav4BJMw8rHK7dQKHZTYRYupBoLWT8MhKvbXga5AP63wwDQRjdbLfZvwuMlnm1sESKOzQBUiH3QDon+VU6YyMXMgJpjP2CK9Iu0HIpL1Ni1ZfApkoVjQlHSjkv3Dd+rJEP8vzGIJoMlGrP5rLr/NBNp57HGh+6zwE/pg3OdG0pdKxl/XLza5n0qpOm8yOFFkHnqNaV3JBa9n27Re4D7/6yhK2ENXS7i9rfA6FNjFX8Lv4X15nVIrwUq+jsjoWrBhB6sTtXcI8D8dtwvX0J1g9X7fR+NHC08muw52ipVyNr+IK7V+K+/SwdxdQ9GduwJjYTlAYJkccyp1jJYMlpfjt33du4yCdhAbc/Sa0igFkUnD0rCpbMAzYdbqYNAPTVVyLFI8h5oJOALbtG2bUrMHheTKIFKCC+FE95mGObOokrTnjqR7pLNQ9oTELYmmrCD8ece2cAgrpxzuKGnqvjulUa0HLa4Hx5MyhxC1GOkZSRgmRryJHk7XudETfbnLb3ujWOrnlCuqhVhngjgdKyRdZyGyYz2HJ0IjKODKTUhuTLidXS+yjLiZFT7gtfJV0ExV7HzO4nDPISIuSn7BI+GKjVueBwxDIhlePVdceBJhQEUiBPDOBe78ynaC/ohQIz7jETjXQtMM4al0351Y5YF2X9Deq2xdwv0pYHvWRe/D2a/sVNX0YXjwLGQZvJ3K7Tj5aKwUKQEmp4XjwfIR3jETaMS/9YeUi3RdeWpLGDlC7KtnGvFm5xLhpnyrCN3m9pSA2e7iP/Xl5/tN4pQbH3c9i4niMxvnC/abHmBaBsXURrWviDdwbnCN4ntymUJcYyvIpN2xTMbObGduX6ZKEC8iVoiul1XebjhQNfRL/i6NQptxZdFlsrbtv81f+IcoWB9O2VUJHEgV8C+jdbZUST1xhtvpQjr8dwAAPKKFW4LxSr8BoKiC0T5DUbWF41IvMvnRPwj/GJN8iY12LgZRIvlTETDio6cABJpuugdPCh60VxDrPLivNG9CItweRzfq6IP5xDdNXGUgUt9DohZsXxbU711KedL/l00V9ety3LXQD3Lqc4RId3JDjmh21gjrHAO5mZGcTMk1KaDocCz9pv6aXn7hvaZOMLFNu8VVdmbIEDd60Q6n4nz8pT7qg1OVoC1kz3WUIVn+X1v5uyVJI5UDLkg0WEuCPkeYRrnF4HkpKNxsY5dflQDYSmSZ5fnxKaGNm3TnBdZmJy1m3Mcmndk7sBJFTlKp7jfitHk1+h+LVXBbsUhzcF1mcPgsrj5y6PmXJsWxodRp+4VJlfYTvgovsI/emHSpNtLEzN2YmTcQbaHKAmPcBm/25EDPPCb9Ddr1QDE1rXIy66RLRhK4Qx+m8imb3TqeSCE2xvEyH0wURUgCyhtFz3XCzQZlBOponG+WSsvOg8mx3B7sW2klesbHnIjIzQFJeHP3+0SscuJlnyc51Rqt9gJhJuDmJ2WkztHYe7ZDwalVahLsOYIFGEMaRhUZHpXIzIlPkbp6JBTiSU9SZ2eIfCA0WZs23TUv5F2E0J3EDHso54rKRqHzoasq2T+MXCzbM31PsweCRrrUYSYWxBbBEX5sN6Wlka9SWPBxzdXqppa1INJxpSnm1NAv4pJscuf4SBHhVhDV46ro67RY9CcfbUyMn13pCH0peidDeFg6tPg8izHB4clFzLySEA+LfeimAZqK/gwgZgZvVFcA7O5po6u44H3WBZVELqr66W0Hu+HRvE8+ofMqONqe+rC2QYL35K5aJtnLO2qQ+0A+QnDHH4g0JpIoEEJ44d63KP9ujkH7w+ZtWegnnrGEKBqBFJo6sgVK6LoM5iaH0cah253Ow7Nvt4Lv4rrPlp+8cN/cMdc4Vho8tHwxkeEs+NH3iAWjFNqtIAvdIMFZkndzsiZ4oS16cXxkwzA4DyRVRg7bDwDZuio5Fkfhczl8t+lXcMN0Ijyrgn6NOYazlFBnkFswU/t5ZrTHt3Tvu3oeyHsEXY4nC6asFmExyFcoIHnFBE+tVSTBOuWwLkepxoEkd8w1SHQfPGxMKhRtTNV2pFYo1uTAnz41uDnHqkYOyj0VF1VP9AdxYL8CNDB+ucK04beUChkyxgSMISA8w07IsppkQ/FTtyvKNV6ro6nzLvMl2ZcrT5BmVnUHyRof49r2bRLGlzxGp5iVc5qAFYIg67c/jwDfHsu2DwCV0haqurGl7LmNJBYU0JyWqAd7Z3puIgXVxo+kw6sA4FuWmEwXGE6U5ENndfgzIOditntVK4uvPO6zCjsCTnSCZr/ldO5JGEYyQo6TcQRcLoD5NWagu1D8wHOO79pVSYpQYF3fuu+HKwYdrjwu9mpg2vRHbSw3+zP5aYfslGFD2WMK3d1u63MOAI3th9O2bjSbUEGEceSKHKK8qnmu+LSju817jYNF1U0uuYRNrN8lCOTxrUF/fD0rmEsqfXidyfOCAXp/RiWULu/xcAVePKwlQ/Tkjr/h9YhQczhW2jlKyB92LMalIDoY7zdScxO0MPbr/B28q3VVSjJ553UQ0CsI0KY7q5tSdRsP8GCx9fPRqQKrWu3L/XZPs9vvmSNGywZlfOxOS4IMivtEZhktNojQ3ZULmjnblAQB3TrxQCLJsTUJJ/ATAV4oRS2BIwxd6T6D9UysO67Mg8LeggDVjTJjaz5aSjhJZAIxuOwVBUekcG+7kAFGGxSvqPDLfgK2LfC+i+kQU6ol9tUSO3NxMyT/xwQpqf0SE32765ZtMARVQ4T4EOMJWgRzEVhobqhkZsl2p3ivh89JOnqRhgbPQW/wOW93DQDl6igZrqt8Yn6Ib2142hGQFgBcF7blvB8Y4k+7DjYxMVC1W/vbGRkvJfDszOQBtKNaICltsZNK7ZyQgAEBLEgWdrv0YbqLRLnfBcxvZvCWHLFGfkmAlFfllkKsNLA9g/m03vBSE19KgQksIHz5hrdNPgCYbC7btA71KppAG9129Ys8v30oj3tQIh9HmjNNUOByzuvK20zBHfgAtNlImWXQBWXPpb6PEXIWKs9ic1gmGx9wd9EqJWgFbQy9/gS14mZbvjbltlwGcYAUoo/2Kni2RRplfRoDhR/QRCibnW7nY6OpeJF+C3q0AWdfERs+w+KoxYmkmA4bR5LnJwXUCajSJr1U451aNtF/wSQTVmjwJ+HHSjOQoa/hjxmn9c26j8ox+QSExvwsUwpGM/e6ddNRa3m1jEe3c9qtu0tkTGFGpZyiWFWVdZ8ajoLRorpP4jUiF+jKibMLdiA+C+9RJMXlq6X0Nowt5gl/DcP3d6kxXIc+HEpb7OySl9uioWBuZgH7bI0IehM0O2gP4aAU6eWaog2KyAdb9ViGNNM7sDTcQYkEXdxoglozDtMXH1C1IhdbTRqRHPG7Ya4uy1sQGW2aLo9XLwIUUYcvwWd6vtdar1lfBhIfUhujZVOulhAnvADDqVSB0cCSuzrmMsOI83RwmaC3v6HJ81SYHe4w7BvK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/PushButton_Routine.L5X b/tests/real_samples/PushButton_Routine.L5X
new file mode 100644
index 0000000..1b9e58a
--- /dev/null
+++ b/tests/real_samples/PushButton_Routine.L5X
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/Safety_Module.L5X b/tests/real_samples/Safety_Module.L5X
new file mode 100644
index 0000000..743651c
--- /dev/null
+++ b/tests/real_samples/Safety_Module.L5X
@@ -0,0 +1 @@
+167772760ETHERNET-SAFETY-STANDARD-MODULE
\ No newline at end of file
diff --git a/tests/real_samples/Sample_DataType.L5X b/tests/real_samples/Sample_DataType.L5X
new file mode 100644
index 0000000..8f5b2a3
--- /dev/null
+++ b/tests/real_samples/Sample_DataType.L5X
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/TimeAndDate_Routine_ST.L5X b/tests/real_samples/TimeAndDate_Routine_ST.L5X
new file mode 100644
index 0000000..a994396
--- /dev/null
+++ b/tests/real_samples/TimeAndDate_Routine_ST.L5X
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+WallClock.Hour then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+WallClock.Minute then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+WallClock.Second then]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/basetest_Controller.L5X b/tests/real_samples/basetest_Controller.L5X
new file mode 100644
index 0000000..33259dc
--- /dev/null
+++ b/tests/real_samples/basetest_Controller.L5X
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/real_samples/pycomm3_Program.L5X b/tests/real_samples/pycomm3_Program.L5X
new file mode 100644
index 0000000..1e341f0
--- /dev/null
+++ b/tests/real_samples/pycomm3_Program.L5X
@@ -0,0 +1,11297 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+01
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+00
+
+
+
+
+
+D2 04 00 00
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+80
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+64 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+1F 00 00 00 A1 A2 A3 A4 A5 A6 A8 A7 A9 AA AB AC
+AD AE AF AF B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC
+BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 80
+
+
+
+
+
+FF FF FF 7F
+
+
+
+
+
+64 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+64 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+01
+
+
+
+
+
+00 00 00 20 01 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+1F 00 00 00 A1 A2 A3 A4 A5 A6 A8 A7 A9 AA AB AC
+AD AE AF AF B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC
+BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20
+01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+D5 60 3C C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 C8 42
+
+
+
+
+
+01
+
+
+
+
+
+FD FF 7F 7F
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 80 80
+
+
+
+
+
+00 00 00 20 01 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 01 FF 01 00
+0A 00 00 00 64 00 00 00 00 00 00 00 93 00 7A 44
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 08 00 00 00 00 00 08 00
+08 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00
+20 00 00 00 00 00 01 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+D5 60 3C C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 0A 00 14 00 1E 00 28 00 32 00 3C 00 46 00
+50 00 5A 00 64 00 6E 00 78 00 82 00 8C 00 96 00
+A0 00 AA 00 B4 00 BE 00 C8 00 D2 00 DC 00 E6 00
+F0 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+10 11 12 13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+64 00 00 00 00 00 00 00
+
+
+
+
+
+FD FF 7F FF
+
+
+
+
+
+00 00 00 00 00 00 00 80
+
+
+
+
+
+64
+
+
+
+
+
+00 00 80 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 41 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 42 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 03 00 00 00 31 32 33 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+20 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00
+00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 11 C7 B1 42 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+09 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+20 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00
+00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 11 C7 B1 42 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+FD FF 7F 7F
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44
+
+
+
+
+
+
+
+
+
+
+
+
+41 08 42 82 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 41 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 42 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 03 00 00 00 31 32 33 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+0B 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+00 00 C8 42
+
+
+
+
+
+00 00 80 00
+
+
+
+
+
+00 00 00 80
+
+
+
+
+
+FF 7F
+
+
+
+
+
+00 80
+
+
+
+
+
+FF FF FF FF FF FF FF 7F
+
+
+
+
+
+2A 00 00 00 41 20 6C 6F 6E 67 65 72 20 73 74 72
+69 6E 67 20 77 69 74 68 20 75 70 20 74 6F 20 34
+38 30 20 63 68 61 72 61 63 74 65 72 73 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 E0 01 00 00 4C 6F 72 65 6D 20 69 70
+73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D
+65 74 2C 20 63 6F 6E 73 65 63 74 65 74 75 72 20
+61 64 69 70 69 73 63 69 6E 67 20 65 6C 69 74 2E
+20 4D 61 75 72 69 73 20 72 68 6F 6E 63 75 73 20
+65 6C 69 74 20 6E 65 63 20 6D 61 75 72 69 73 20
+63 6F 6E 76 61 6C 6C 69 73 20 63 6F 6E 76 61 6C
+6C 69 73 2E 20 4E 75 6E 63 20 74 72 69 73 74 69
+71 75 65 20 76 6F 6C 75 74 70 61 74 20 64 61 70
+69 62 75 73 2E 20 53 75 73 70 65 6E 64 69 73 73
+65 20 70 6F 74 65 6E 74 69 2E 20 51 75 69 73 71
+75 65 20 65 67 65 74 20 61 75 67 75 65 20 76 69
+74 61 65 20 61 6E 74 65 20 63 6F 6E 67 75 65 20
+6D 61 6C 65 73 75 61 64 61 2E 20 43 72 61 73 20
+73 65 64 20 61 6C 69 71 75 61 6D 20 65 73 74 2E
+20 49 6E 74 65 67 65 72 20 73 61 67 69 74 74 69
+73 2C 20 6D 61 75 72 69 73 20 69 64 20 62 69 62
+65 6E 64 75 6D 20 6F 72 6E 61 72 65 2C 20 6D 65
+74 75 73 20 6C 65 63 74 75 73 20 61 63 63 75 6D
+73 61 6E 20 65 78 2C 20 6E 6F 6E 20 65 67 65 73
+74 61 73 20 73 65 6D 20 74 6F 72 74 6F 72 20 61
+74 20 6E 69 62 68 2E 20 56 65 73 74 69 62 75 6C
+75 6D 20 63 6F 6E 73 65 63 74 65 74 75 72 20 65
+78 20 74 65 6C 6C 75 73 2E 20 50 65 6C 6C 65 6E
+74 65 73 71 75 65 20 6E 69 73 6C 20 71 75 61 6D
+2C 20 62 69 62 65 6E 64 75 6D 20 6E 65 63 20 6C
+65 63 74 75 73 20 61 74 2C 20 74 65 6D 70 75 73
+20 76 61 72 69 75 73 20 70 75 72 75 73 2E 20 44
+6F 6E 65 63 20 74 72 69 73 74 69 71 75 65 2C 20
+69 70 73 75 6D 20 61 20 6F 72 6E 61 72 65 20 65
+6C 65 69 66 65 6E 64 2E 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00
+4C 6F 72 65 6D 20 69 70 73 75 6D 20 76 69 76 61
+6D 75 73 2E 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 80
+
+
+
+
+
+80
+
+
+
+
+
+00
+
+
+
+
+
+00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+10 11 12 13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+64 00
+
+
+
+
+
+00 00 00 00 2E 3F C8 42 2E 3F 48 43 63 2F 96 43
+2E 3F C8 43 FA 4E FA 43 63 2F 16 44 48 37 2F 44
+2E 3F 48 44 14 47 61 44 FA 4E 7A 44 70 AB 89 44
+63 2F 96 44 56 B3 A2 44 48 37 AF 44 3B BB BB 44
+2E 3F C8 44 21 C3 D4 44 14 47 E1 44 07 CB ED 44
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+7F
+
+
+
+
+
+00 00 80 80
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20
+01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+FD FF 7F FF
+
+
+
+
+
+00 00
+
+
+
+
+
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 14 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+08 00 00 00 00 00 08 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 01 FF 01 00
+0A 00 00 00 64 00 00 00 00 00 00 00 93 00 7A 44
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 08 00 00 00 00 00 08 00
+08 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00
+20 00 00 00 00 00 01 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00 8C 0A 00 00
+F0 0A 00 00 54 0B 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+FF FF FF FF FF FF FF 7F
+
+
+
+
+
+01
+
+
+
+
+
+08 00 00 00 00 00 08 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+64
+
+
+
+
+
+00
+
+
+
+
+
+E0 01 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 4D 61 75
+72 69 73 20 72 68 6F 6E 63 75 73 20 65 6C 69 74
+20 6E 65 63 20 6D 61 75 72 69 73 20 63 6F 6E 76
+61 6C 6C 69 73 20 63 6F 6E 76 61 6C 6C 69 73 2E
+20 4E 75 6E 63 20 74 72 69 73 74 69 71 75 65 20
+76 6F 6C 75 74 70 61 74 20 64 61 70 69 62 75 73
+2E 20 53 75 73 70 65 6E 64 69 73 73 65 20 70 6F
+74 65 6E 74 69 2E 20 51 75 69 73 71 75 65 20 65
+67 65 74 20 61 75 67 75 65 20 76 69 74 61 65 20
+61 6E 74 65 20 63 6F 6E 67 75 65 20 6D 61 6C 65
+73 75 61 64 61 2E 20 43 72 61 73 20 73 65 64 20
+61 6C 69 71 75 61 6D 20 65 73 74 2E 20 49 6E 74
+65 67 65 72 20 73 61 67 69 74 74 69 73 2C 20 6D
+61 75 72 69 73 20 69 64 20 62 69 62 65 6E 64 75
+6D 20 6F 72 6E 61 72 65 2C 20 6D 65 74 75 73 20
+6C 65 63 74 75 73 20 61 63 63 75 6D 73 61 6E 20
+65 78 2C 20 6E 6F 6E 20 65 67 65 73 74 61 73 20
+73 65 6D 20 74 6F 72 74 6F 72 20 61 74 20 6E 69
+62 68 2E 20 56 65 73 74 69 62 75 6C 75 6D 20 63
+6F 6E 73 65 63 74 65 74 75 72 20 65 78 20 74 65
+6C 6C 75 73 2E 20 50 65 6C 6C 65 6E 74 65 73 71
+75 65 20 6E 69 73 6C 20 71 75 61 6D 2C 20 62 69
+62 65 6E 64 75 6D 20 6E 65 63 20 6C 65 63 74 75
+73 20 61 74 2C 20 74 65 6D 70 75 73 20 76 61 72
+69 75 73 20 70 75 72 75 73 2E 20 44 6F 6E 65 63
+20 74 72 69 73 74 69 71 75 65 2C 20 69 70 73 75
+6D 20 61 20 6F 72 6E 61 72 65 20 65 6C 65 69 66
+65 6E 64 2E
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+52 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 50 65 6C
+6C 65 6E 74 65 73 71 75 65 20 73 6F 64 61 6C 65
+73 20 76 65 6C 2E 00 00
+
+
+
+
+
+52 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 50 65 6C
+6C 65 6E 74 65 73 71 75 65 20 73 6F 64 61 6C 65
+73 20 76 65 6C 2E 00 00
+
+
+
+
+
+14 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+76 69 76 61 6D 75 73 2E
+
+
+
+
+
+10 00 00 00 41 20 73 68 6F 72 74 65 72 20 73 74
+72 69 6E 67 00 00 00 00
+
+
+
+
+
+FF FF FF 7F
+
+
+
+
+
+00 00 00 00 2E 3F C8 42 2E 3F 48 43 62 2F 96 43
+2E 3F C8 43 FA 4E FA 43 62 2F 16 44 48 37 2F 44
+2E 3F 48 44 14 47 61 44 FA 4E 7A 44 70 AB 89 44
+62 2F 96 44 55 B3 A2 44 48 37 AF 44 3B BB BB 44
+2E 3F C8 44 21 C3 D4 44 14 47 E1 44 07 CB ED 44
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FD 7F
+
+
+
+
+
+E0 01 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 4D 61 75
+72 69 73 20 72 68 6F 6E 63 75 73 20 65 6C 69 74
+20 6E 65 63 20 6D 61 75 72 69 73 20 63 6F 6E 76
+61 6C 6C 69 73 20 63 6F 6E 76 61 6C 6C 69 73 2E
+20 4E 75 6E 63 20 74 72 69 73 74 69 71 75 65 20
+76 6F 6C 75 74 70 61 74 20 64 61 70 69 62 75 73
+2E 20 53 75 73 70 65 6E 64 69 73 73 65 20 70 6F
+74 65 6E 74 69 2E 20 51 75 69 73 71 75 65 20 65
+67 65 74 20 61 75 67 75 65 20 76 69 74 61 65 20
+61 6E 74 65 20 63 6F 6E 67 75 65 20 6D 61 6C 65
+73 75 61 64 61 2E 20 43 72 61 73 20 73 65 64 20
+61 6C 69 71 75 61 6D 20 65 73 74 2E 20 49 6E 74
+65 67 65 72 20 73 61 67 69 74 74 69 73 2C 20 6D
+61 75 72 69 73 20 69 64 20 62 69 62 65 6E 64 75
+6D 20 6F 72 6E 61 72 65 2C 20 6D 65 74 75 73 20
+6C 65 63 74 75 73 20 61 63 63 75 6D 73 61 6E 20
+65 78 2C 20 6E 6F 6E 20 65 67 65 73 74 61 73 20
+73 65 6D 20 74 6F 72 74 6F 72 20 61 74 20 6E 69
+62 68 2E 20 56 65 73 74 69 62 75 6C 75 6D 20 63
+6F 6E 73 65 63 74 65 74 75 72 20 65 78 20 74 65
+6C 6C 75 73 2E 20 50 65 6C 6C 65 6E 74 65 73 71
+75 65 20 6E 69 73 6C 20 71 75 61 6D 2C 20 62 69
+62 65 6E 64 75 6D 20 6E 65 63 20 6C 65 63 74 75
+73 20 61 74 2C 20 74 65 6D 70 75 73 20 76 61 72
+69 75 73 20 70 75 72 75 73 2E 20 44 6F 6E 65 63
+20 74 72 69 73 74 69 71 75 65 2C 20 69 70 73 75
+6D 20 61 20 6F 72 6E 61 72 65 20 65 6C 65 69 66
+65 6E 64 2E
+
+
+
+
+
+14 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+76 69 76 61 6D 75 73 2E
+
+
+
+
+
+64 00 00 00
+
+
+
+
+
+00 00
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00 8C 0A 00 00
+F0 0A 00 00 54 0B 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2A 00 00 00 41 20 6C 6F 6E 67 65 72 20 73 74 72
+69 6E 67 20 77 69 74 68 20 75 70 20 74 6F 20 34
+38 30 20 63 68 61 72 61 63 74 65 72 73 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+10 00 00 00 41 20 73 68 6F 72 74 65 72 20 73 74
+72 69 6E 67 00 00 00 00
+
+
+
+
+
+41 08 42 82 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7F
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 80
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 E0 01 00 00 4C 6F 72 65 6D 20 69 70
+73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D
+65 74 2C 20 63 6F 6E 73 65 63 74 65 74 75 72 20
+61 64 69 70 69 73 63 69 6E 67 20 65 6C 69 74 2E
+20 4D 61 75 72 69 73 20 72 68 6F 6E 63 75 73 20
+65 6C 69 74 20 6E 65 63 20 6D 61 75 72 69 73 20
+63 6F 6E 76 61 6C 6C 69 73 20 63 6F 6E 76 61 6C
+6C 69 73 2E 20 4E 75 6E 63 20 74 72 69 73 74 69
+71 75 65 20 76 6F 6C 75 74 70 61 74 20 64 61 70
+69 62 75 73 2E 20 53 75 73 70 65 6E 64 69 73 73
+65 20 70 6F 74 65 6E 74 69 2E 20 51 75 69 73 71
+75 65 20 65 67 65 74 20 61 75 67 75 65 20 76 69
+74 61 65 20 61 6E 74 65 20 63 6F 6E 67 75 65 20
+6D 61 6C 65 73 75 61 64 61 2E 20 43 72 61 73 20
+73 65 64 20 61 6C 69 71 75 61 6D 20 65 73 74 2E
+20 49 6E 74 65 67 65 72 20 73 61 67 69 74 74 69
+73 2C 20 6D 61 75 72 69 73 20 69 64 20 62 69 62
+65 6E 64 75 6D 20 6F 72 6E 61 72 65 2C 20 6D 65
+74 75 73 20 6C 65 63 74 75 73 20 61 63 63 75 6D
+73 61 6E 20 65 78 2C 20 6E 6F 6E 20 65 67 65 73
+74 61 73 20 73 65 6D 20 74 6F 72 74 6F 72 20 61
+74 20 6E 69 62 68 2E 20 56 65 73 74 69 62 75 6C
+75 6D 20 63 6F 6E 73 65 63 74 65 74 75 72 20 65
+78 20 74 65 6C 6C 75 73 2E 20 50 65 6C 6C 65 6E
+74 65 73 71 75 65 20 6E 69 73 6C 20 71 75 61 6D
+2C 20 62 69 62 65 6E 64 75 6D 20 6E 65 63 20 6C
+65 63 74 75 73 20 61 74 2C 20 74 65 6D 70 75 73
+20 76 61 72 69 75 73 20 70 75 72 75 73 2E 20 44
+6F 6E 65 63 20 74 72 69 73 74 69 71 75 65 2C 20
+69 70 73 75 6D 20 61 20 6F 72 6E 61 72 65 20 65
+6C 65 69 66 65 6E 64 2E 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00
+4C 6F 72 65 6D 20 69 70 73 75 6D 20 76 69 76 61
+6D 75 73 2E 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 0A 00 14 00 1E 00 28 00 32 00 3C 00 46 00
+50 00 5A 00 64 00 6E 00 78 00 82 00 8C 00 96 00
+A0 00 AA 00 B4 00 BE 00 C8 00 D2 00 DC 00 E6 00
+F0 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0B 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+01
+
+
+
+
+
+41 08 42 82 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+64 00 00 00
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00 8C 0A 00 00
+F0 0A 00 00 54 0B 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF FF FF 7F
+
+
+
+
+
+00 00 00 80
+
+
+
+
+
+00 00
+
+
+
+
+
+64 00
+
+
+
+
+
+00 00 0A 00 14 00 1E 00 28 00 32 00 3C 00 46 00
+50 00 5A 00 64 00 6E 00 78 00 82 00 8C 00 96 00
+A0 00 AA 00 B4 00 BE 00 C8 00 D2 00 DC 00 E6 00
+F0 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF 7F
+
+
+
+
+
+00 80
+
+
+
+
+
+00 00 00 00 00 00 00 00
+
+
+
+
+
+64 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF FF FF FF FF FF FF 7F
+
+
+
+
+
+00 00 00 00 00 00 00 80
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 01 FF 01 00
+0A 00 00 00 64 00 00 00 00 00 00 00 93 00 7A 44
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 08 00 00 00 00 00 08 00
+08 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00
+20 00 00 00 00 00 01 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+00 00 C8 42
+
+
+
+
+
+00 00 00 00 2E 3F C8 42 2E 3F 48 43 62 2F 96 43
+2E 3F C8 43 FA 4E FA 43 62 2F 16 44 48 37 2F 44
+2E 3F 48 44 14 47 61 44 FA 4E 7A 44 70 AB 89 44
+62 2F 96 44 55 B3 A2 44 48 37 AF 44 3B BB BB 44
+2E 3F C8 44 21 C3 D4 44 14 47 E1 44 07 CB ED 44
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FD FF 7F 7F
+
+
+
+
+
+00 00 80 00
+
+
+
+
+
+FD FF 7F FF
+
+
+
+
+
+00 00 80 80
+
+
+
+
+
+00
+
+
+
+
+
+64
+
+
+
+
+
+00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+10 11 12 13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7F
+
+
+
+
+
+80
+
+
+
+
+
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+10 00 00 00 41 20 73 68 6F 72 74 65 72 20 73 74
+72 69 6E 67 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+14 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+76 69 76 61 6D 75 73 2E
+
+
+
+
+
+52 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 50 65 6C
+6C 65 6E 74 65 73 71 75 65 20 73 6F 64 61 6C 65
+73 20 76 65 6C 2E 00 00
+
+
+
+
+
+2A 00 00 00 41 20 6C 6F 6E 67 65 72 20 73 74 72
+69 6E 67 20 77 69 74 68 20 75 70 20 74 6F 20 34
+38 30 20 63 68 61 72 61 63 74 65 72 73 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+E0 01 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 4D 61 75
+72 69 73 20 72 68 6F 6E 63 75 73 20 65 6C 69 74
+20 6E 65 63 20 6D 61 75 72 69 73 20 63 6F 6E 76
+61 6C 6C 69 73 20 63 6F 6E 76 61 6C 6C 69 73 2E
+20 4E 75 6E 63 20 74 72 69 73 74 69 71 75 65 20
+76 6F 6C 75 74 70 61 74 20 64 61 70 69 62 75 73
+2E 20 53 75 73 70 65 6E 64 69 73 73 65 20 70 6F
+74 65 6E 74 69 2E 20 51 75 69 73 71 75 65 20 65
+67 65 74 20 61 75 67 75 65 20 76 69 74 61 65 20
+61 6E 74 65 20 63 6F 6E 67 75 65 20 6D 61 6C 65
+73 75 61 64 61 2E 20 43 72 61 73 20 73 65 64 20
+61 6C 69 71 75 61 6D 20 65 73 74 2E 20 49 6E 74
+65 67 65 72 20 73 61 67 69 74 74 69 73 2C 20 6D
+61 75 72 69 73 20 69 64 20 62 69 62 65 6E 64 75
+6D 20 6F 72 6E 61 72 65 2C 20 6D 65 74 75 73 20
+6C 65 63 74 75 73 20 61 63 63 75 6D 73 61 6E 20
+65 78 2C 20 6E 6F 6E 20 65 67 65 73 74 61 73 20
+73 65 6D 20 74 6F 72 74 6F 72 20 61 74 20 6E 69
+62 68 2E 20 56 65 73 74 69 62 75 6C 75 6D 20 63
+6F 6E 73 65 63 74 65 74 75 72 20 65 78 20 74 65
+6C 6C 75 73 2E 20 50 65 6C 6C 65 6E 74 65 73 71
+75 65 20 6E 69 73 6C 20 71 75 61 6D 2C 20 62 69
+62 65 6E 64 75 6D 20 6E 65 63 20 6C 65 63 74 75
+73 20 61 74 2C 20 74 65 6D 70 75 73 20 76 61 72
+69 75 73 20 70 75 72 75 73 2E 20 44 6F 6E 65 63
+20 74 72 69 73 74 69 71 75 65 2C 20 69 70 73 75
+6D 20 61 20 6F 72 6E 61 72 65 20 65 6C 65 69 66
+65 6E 64 2E
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 E0 01 00 00 4C 6F 72 65 6D 20 69 70
+73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D
+65 74 2C 20 63 6F 6E 73 65 63 74 65 74 75 72 20
+61 64 69 70 69 73 63 69 6E 67 20 65 6C 69 74 2E
+20 4D 61 75 72 69 73 20 72 68 6F 6E 63 75 73 20
+65 6C 69 74 20 6E 65 63 20 6D 61 75 72 69 73 20
+63 6F 6E 76 61 6C 6C 69 73 20 63 6F 6E 76 61 6C
+6C 69 73 2E 20 4E 75 6E 63 20 74 72 69 73 74 69
+71 75 65 20 76 6F 6C 75 74 70 61 74 20 64 61 70
+69 62 75 73 2E 20 53 75 73 70 65 6E 64 69 73 73
+65 20 70 6F 74 65 6E 74 69 2E 20 51 75 69 73 71
+75 65 20 65 67 65 74 20 61 75 67 75 65 20 76 69
+74 61 65 20 61 6E 74 65 20 63 6F 6E 67 75 65 20
+6D 61 6C 65 73 75 61 64 61 2E 20 43 72 61 73 20
+73 65 64 20 61 6C 69 71 75 61 6D 20 65 73 74 2E
+20 49 6E 74 65 67 65 72 20 73 61 67 69 74 74 69
+73 2C 20 6D 61 75 72 69 73 20 69 64 20 62 69 62
+65 6E 64 75 6D 20 6F 72 6E 61 72 65 2C 20 6D 65
+74 75 73 20 6C 65 63 74 75 73 20 61 63 63 75 6D
+73 61 6E 20 65 78 2C 20 6E 6F 6E 20 65 67 65 73
+74 61 73 20 73 65 6D 20 74 6F 72 74 6F 72 20 61
+74 20 6E 69 62 68 2E 20 56 65 73 74 69 62 75 6C
+75 6D 20 63 6F 6E 73 65 63 74 65 74 75 72 20 65
+78 20 74 65 6C 6C 75 73 2E 20 50 65 6C 6C 65 6E
+74 65 73 71 75 65 20 6E 69 73 6C 20 71 75 61 6D
+2C 20 62 69 62 65 6E 64 75 6D 20 6E 65 63 20 6C
+65 63 74 75 73 20 61 74 2C 20 74 65 6D 70 75 73
+20 76 61 72 69 75 73 20 70 75 72 75 73 2E 20 44
+6F 6E 65 63 20 74 72 69 73 74 69 71 75 65 2C 20
+69 70 73 75 6D 20 61 20 6F 72 6E 61 72 65 20 65
+6C 65 69 66 65 6E 64 2E 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00
+4C 6F 72 65 6D 20 69 70 73 75 6D 20 76 69 76 61
+6D 75 73 2E 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 41 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 42 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 03 00 00 00 31 32 33 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+1F 00 00 00 A1 A2 A3 A4 A5 A6 A8 A7 A9 AA AB AC
+AD AE AF AF B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC
+BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 20 01 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20
+01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+D5 60 3C C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44
+
+
+
+
+
+
+
+
+
+
+
+
+20 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00
+00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 11 C7 B1 42 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+08 00 00 00 00 00 08 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+09 00 00 00 D2 04 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00
+
+
+
+
+
+01
+
+
+
+
+
+41 08 42 82 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+64 00 00 00
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 64 00 00 00 C8 00 00 00 2C 01 00 00
+90 01 00 00 F4 01 00 00 58 02 00 00 BC 02 00 00
+20 03 00 00 84 03 00 00 E8 03 00 00 4C 04 00 00
+B0 04 00 00 14 05 00 00 78 05 00 00 DC 05 00 00
+40 06 00 00 A4 06 00 00 08 07 00 00 6C 07 00 00
+D0 07 00 00 34 08 00 00 98 08 00 00 FC 08 00 00
+60 09 00 00 C4 09 00 00 28 0A 00 00 8C 0A 00 00
+F0 0A 00 00 54 0B 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF FF FF 7F
+
+
+
+
+
+00 00 00 80
+
+
+
+
+
+00 00
+
+
+
+
+
+64 00
+
+
+
+
+
+00 00 0A 00 14 00 1E 00 28 00 32 00 3C 00 46 00
+50 00 5A 00 64 00 6E 00 78 00 82 00 8C 00 96 00
+A0 00 AA 00 B4 00 BE 00 C8 00 D2 00 DC 00 E6 00
+F0 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF 7F
+
+
+
+
+
+00 80
+
+
+
+
+
+00 00 00 00 00 00 00 00
+
+
+
+
+
+64 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+FF FF FF FF FF FF FF 7F 00 00 00 00 00 00 00 80
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FF FF FF FF FF FF FF 7F
+
+
+
+
+
+00 00 00 00 00 00 00 80
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 01 FF 01 00
+0A 00 00 00 64 00 00 00 00 00 00 00 93 00 7A 44
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00
+00 00 FE 00 00 00 00 00 00 00 00 00 00 00 02 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 11 C7 B1 42
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF
+00 00 00 00 FF FF FF FF 08 00 00 00 00 00 08 00
+08 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00
+20 00 00 00 00 00 01 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00
+
+
+
+
+
+00 00 C8 42
+
+
+
+
+
+00 00 00 00 2E 3F C8 42 2E 3F 48 43 63 2F 96 43
+2E 3F C8 43 FA 4E FA 43 63 2F 16 44 48 37 2F 44
+2E 3F 48 44 14 47 61 44 FA 4E 7A 44 70 AB 89 44
+63 2F 96 44 56 B3 A2 44 48 37 AF 44 3B BB BB 44
+2E 3F C8 44 21 C3 D4 44 14 47 E1 44 07 CB ED 44
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+FD FF 7F 7F
+
+
+
+
+
+00 00 80 00
+
+
+
+
+
+FD FF 7F FF
+
+
+
+
+
+00 00 80 80
+
+
+
+
+
+00
+
+
+
+
+
+64
+
+
+
+
+
+00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+10 11 12 13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7F
+
+
+
+
+
+80
+
+
+
+
+
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+10 00 00 00 41 20 73 68 6F 72 74 65 72 20 73 74
+72 69 6E 67 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+14 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+76 69 76 61 6D 75 73 2E
+
+
+
+
+
+52 00 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 50 65 6C
+6C 65 6E 74 65 73 71 75 65 20 73 6F 64 61 6C 65
+73 20 76 65 6C 2E 00 00
+
+
+
+
+
+2A 00 00 00 41 20 6C 6F 6E 67 65 72 20 73 74 72
+69 6E 67 20 77 69 74 68 20 75 70 20 74 6F 20 34
+38 30 20 63 68 61 72 61 63 74 65 72 73 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00
+
+
+
+
+
+E0 01 00 00 4C 6F 72 65 6D 20 69 70 73 75 6D 20
+64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74 2C 20
+63 6F 6E 73 65 63 74 65 74 75 72 20 61 64 69 70
+69 73 63 69 6E 67 20 65 6C 69 74 2E 20 4D 61 75
+72 69 73 20 72 68 6F 6E 63 75 73 20 65 6C 69 74
+20 6E 65 63 20 6D 61 75 72 69 73 20 63 6F 6E 76
+61 6C 6C 69 73 20 63 6F 6E 76 61 6C 6C 69 73 2E
+20 4E 75 6E 63 20 74 72 69 73 74 69 71 75 65 20
+76 6F 6C 75 74 70 61 74 20 64 61 70 69 62 75 73
+2E 20 53 75 73 70 65 6E 64 69 73 73 65 20 70 6F
+74 65 6E 74 69 2E 20 51 75 69 73 71 75 65 20 65
+67 65 74 20 61 75 67 75 65 20 76 69 74 61 65 20
+61 6E 74 65 20 63 6F 6E 67 75 65 20 6D 61 6C 65
+73 75 61 64 61 2E 20 43 72 61 73 20 73 65 64 20
+61 6C 69 71 75 61 6D 20 65 73 74 2E 20 49 6E 74
+65 67 65 72 20 73 61 67 69 74 74 69 73 2C 20 6D
+61 75 72 69 73 20 69 64 20 62 69 62 65 6E 64 75
+6D 20 6F 72 6E 61 72 65 2C 20 6D 65 74 75 73 20
+6C 65 63 74 75 73 20 61 63 63 75 6D 73 61 6E 20
+65 78 2C 20 6E 6F 6E 20 65 67 65 73 74 61 73 20
+73 65 6D 20 74 6F 72 74 6F 72 20 61 74 20 6E 69
+62 68 2E 20 56 65 73 74 69 62 75 6C 75 6D 20 63
+6F 6E 73 65 63 74 65 74 75 72 20 65 78 20 74 65
+6C 6C 75 73 2E 20 50 65 6C 6C 65 6E 74 65 73 71
+75 65 20 6E 69 73 6C 20 71 75 61 6D 2C 20 62 69
+62 65 6E 64 75 6D 20 6E 65 63 20 6C 65 63 74 75
+73 20 61 74 2C 20 74 65 6D 70 75 73 20 76 61 72
+69 75 73 20 70 75 72 75 73 2E 20 44 6F 6E 65 63
+20 74 72 69 73 74 69 71 75 65 2C 20 69 70 73 75
+6D 20 61 20 6F 72 6E 61 72 65 20 65 6C 65 69 66
+65 6E 64 2E
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 E0 01 00 00 4C 6F 72 65 6D 20 69 70
+73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D
+65 74 2C 20 63 6F 6E 73 65 63 74 65 74 75 72 20
+61 64 69 70 69 73 63 69 6E 67 20 65 6C 69 74 2E
+20 4D 61 75 72 69 73 20 72 68 6F 6E 63 75 73 20
+65 6C 69 74 20 6E 65 63 20 6D 61 75 72 69 73 20
+63 6F 6E 76 61 6C 6C 69 73 20 63 6F 6E 76 61 6C
+6C 69 73 2E 20 4E 75 6E 63 20 74 72 69 73 74 69
+71 75 65 20 76 6F 6C 75 74 70 61 74 20 64 61 70
+69 62 75 73 2E 20 53 75 73 70 65 6E 64 69 73 73
+65 20 70 6F 74 65 6E 74 69 2E 20 51 75 69 73 71
+75 65 20 65 67 65 74 20 61 75 67 75 65 20 76 69
+74 61 65 20 61 6E 74 65 20 63 6F 6E 67 75 65 20
+6D 61 6C 65 73 75 61 64 61 2E 20 43 72 61 73 20
+73 65 64 20 61 6C 69 71 75 61 6D 20 65 73 74 2E
+20 49 6E 74 65 67 65 72 20 73 61 67 69 74 74 69
+73 2C 20 6D 61 75 72 69 73 20 69 64 20 62 69 62
+65 6E 64 75 6D 20 6F 72 6E 61 72 65 2C 20 6D 65
+74 75 73 20 6C 65 63 74 75 73 20 61 63 63 75 6D
+73 61 6E 20 65 78 2C 20 6E 6F 6E 20 65 67 65 73
+74 61 73 20 73 65 6D 20 74 6F 72 74 6F 72 20 61
+74 20 6E 69 62 68 2E 20 56 65 73 74 69 62 75 6C
+75 6D 20 63 6F 6E 73 65 63 74 65 74 75 72 20 65
+78 20 74 65 6C 6C 75 73 2E 20 50 65 6C 6C 65 6E
+74 65 73 71 75 65 20 6E 69 73 6C 20 71 75 61 6D
+2C 20 62 69 62 65 6E 64 75 6D 20 6E 65 63 20 6C
+65 63 74 75 73 20 61 74 2C 20 74 65 6D 70 75 73
+20 76 61 72 69 75 73 20 70 75 72 75 73 2E 20 44
+6F 6E 65 63 20 74 72 69 73 74 69 71 75 65 2C 20
+69 70 73 75 6D 20 61 20 6F 72 6E 61 72 65 20 65
+6C 65 69 66 65 6E 64 2E 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00
+4C 6F 72 65 6D 20 69 70 73 75 6D 20 76 69 76 61
+6D 75 73 2E 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 52 00 00 00 4C 6F 72 65
+6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69
+74 20 61 6D 65 74 2C 20 63 6F 6E 73 65 63 74 65
+74 75 72 20 61 64 69 70 69 73 63 69 6E 67 20 65
+6C 69 74 2E 20 50 65 6C 6C 65 6E 74 65 73 71 75
+65 20 73 6F 64 61 6C 65 73 20 76 65 6C 2E 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1D 00 00 00 41 20 6E 6F 72 6D 61 6C 20 62 75 69
+6C 74 2D 69 6E 20 73 74 72 69 6E 67 20 74 79 70
+65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 41 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 01 00 00 00 42 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+01 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 03 00 00 00 31 32 33 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+
+
+
+1F 00 00 00 A1 A2 A3 A4 A5 A6 A8 A7 A9 AA AB AC
+AD AE AF AF B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC
+BD BE BF 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+00 00 00 20 01 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20
+01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 C0 30 75 00 00 D2 04 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 FF 01 00 0A 00 00 00 64 00 00 00 00 00 00 00
+93 00 7A 44
+
+
+
+
+
+
+
+
+
+
+
+
+20 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00
+00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 11 C7 B1 42 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF
+
+
+
+
+
+
+
+
+
+
+
+08 00 00 00 00 00 08 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5F 00 00 00
+
+
+
+
+
+00 00 00 A0 1E 00 00 00 1D 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 A0 19 00 00 00 18 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+64 00 00 00 00 00 00 00
+
+
+
+
+
+
+
+
+FF FF FF FF FF FF FF 7F
+
+
+
+
+
+
+
+
+00 00 00 00 00 00 00 80
+
+
+
+
+
+
+
+
+00 00 00 A0 14 00 00 00 13 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+00 00 00 A0 14 00 00 00 13 00 00 00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/samples/sample_project.L5K b/tests/samples/sample_project.L5K
new file mode 100644
index 0000000..4a9cbc5
--- /dev/null
+++ b/tests/samples/sample_project.L5K
@@ -0,0 +1,304 @@
+(* ===================================================================== *)
+(* Sample Rockwell L5K Project File — Water Treatment Plant Controller *)
+(* Format: Legacy ASCII Project File (L5K) *)
+(* Controller: CompactLogix 5380 *)
+(* ===================================================================== *)
+
+IE_VER := 2.20;
+
+CONTROLLER WaterTreatment (ProcessorType := "1769-L33ER",
+ MajorRev := 33,
+ MinorRev := 11,
+ TimeSlice := 20,
+ ShareUnusedTimeSlice := 1,
+ CommPath := "AB_ETH-1\\10.10.1.1\\Backplane\\0",
+ Description := "Water Treatment Plant - Main Controller")
+
+ DATATYPE HMI_PumpControl (Family := NoFamily,
+ Class := User,
+ Description := "HMI interface structure for pump control")
+ MEMBER Status : DINT (Description := "Pump status word");
+ MEMBER Command : DINT (Description := "Pump command word");
+ MEMBER Speed_SP : REAL (Description := "Speed setpoint 0-100%");
+ MEMBER Speed_PV : REAL (Description := "Actual speed feedback 0-100%");
+ MEMBER RunHours : REAL (Description := "Accumulated run hours");
+ MEMBER FaultCode : INT (Description := "Active fault code");
+ MEMBER AutoMode : BOOL (Description := "Auto mode active");
+ MEMBER ManualMode : BOOL (Description := "Manual mode active");
+ MEMBER RunCmd : BOOL (Description := "Run command from HMI");
+ MEMBER StopCmd : BOOL (Description := "Stop command from HMI");
+ MEMBER ResetCmd : BOOL (Description := "Fault reset command");
+ MEMBER Running : BOOL (Description := "Pump running feedback");
+ MEMBER Faulted : BOOL (Description := "Pump in fault state");
+ MEMBER Ready : BOOL (Description := "Pump ready to start");
+ END_DATATYPE
+
+ DATATYPE PID_Config (Family := NoFamily,
+ Class := User,
+ Description := "PID loop configuration")
+ MEMBER Kp : REAL (Description := "Proportional gain");
+ MEMBER Ki : REAL (Description := "Integral gain");
+ MEMBER Kd : REAL (Description := "Derivative gain");
+ MEMBER SP_High : REAL (Description := "Setpoint high limit");
+ MEMBER SP_Low : REAL (Description := "Setpoint low limit");
+ MEMBER CV_High : REAL (Description := "Control output high limit");
+ MEMBER CV_Low : REAL (Description := "Control output low limit");
+ MEMBER DeadBand : REAL (Description := "Process variable deadband");
+ MEMBER SampleTime : REAL (Description := "PID sample time in seconds");
+ END_DATATYPE
+
+ DATATYPE AnalogInput (Family := NoFamily,
+ Class := User,
+ Description := "Scaled analog input")
+ MEMBER RawValue : INT (Description := "Raw ADC value 0-32767");
+ MEMBER ScaledValue : REAL (Description := "Engineering units value");
+ MEMBER HighAlarm : BOOL (Description := "High alarm active");
+ MEMBER LowAlarm : BOOL (Description := "Low alarm active");
+ MEMBER HighHighAlarm : BOOL (Description := "High-high alarm active");
+ MEMBER LowLowAlarm : BOOL (Description := "Low-low alarm active");
+ MEMBER SensorFault : BOOL (Description := "Sensor fault detected");
+ MEMBER EU_High : REAL (Description := "Engineering units high range");
+ MEMBER EU_Low : REAL (Description := "Engineering units low range");
+ MEMBER AlarmHH : REAL (Description := "High-high alarm setpoint");
+ MEMBER AlarmH : REAL (Description := "High alarm setpoint");
+ MEMBER AlarmL : REAL (Description := "Low alarm setpoint");
+ MEMBER AlarmLL : REAL (Description := "Low-low alarm setpoint");
+ END_DATATYPE
+
+ ADD_ON_INSTRUCTION_DEFINITION PumpControl (Revision := 3.1,
+ Vendor := "WaterTech",
+ Description := "VFD pump control with fault handling and auto/manual modes")
+ TAG EnableIn : BOOL (Usage := Input);
+ TAG EnableOut : BOOL (Usage := Output);
+ TAG i_AutoMode : BOOL (Usage := Input, Description := "Auto mode select from HMI");
+ TAG i_ManualMode : BOOL (Usage := Input, Description := "Manual mode select from HMI");
+ TAG i_RunCmd : BOOL (Usage := Input, Description := "Run command from HMI or auto logic");
+ TAG i_StopCmd : BOOL (Usage := Input, Description := "Stop command from HMI");
+ TAG i_ResetCmd : BOOL (Usage := Input, Description := "Fault reset command");
+ TAG i_SpeedSP : REAL (Usage := Input, Description := "Speed setpoint 0-100%");
+ TAG i_RunFeedback : BOOL (Usage := Input, Description := "Motor running feedback from drive");
+ TAG i_FaultFeedback : BOOL (Usage := Input, Description := "Drive fault signal");
+ TAG i_ReadyFeedback : BOOL (Usage := Input, Description := "Drive ready signal");
+ TAG i_SpeedFeedback : REAL (Usage := Input, Description := "Actual speed from drive 0-100%");
+ TAG i_EStop : BOOL (Usage := Input, Description := "Emergency stop signal");
+ TAG o_RunOutput : BOOL (Usage := Output, Description := "Run command to VFD");
+ TAG o_SpeedRef : REAL (Usage := Output, Description := "Speed reference to VFD 0-100%");
+ TAG o_Running : BOOL (Usage := Output, Description := "Pump running status");
+ TAG o_Faulted : BOOL (Usage := Output, Description := "Pump fault status");
+ TAG o_Ready : BOOL (Usage := Output, Description := "Pump ready status");
+ TAG o_FaultCode : INT (Usage := Output, Description := "Active fault code");
+ TAG io_HMI : HMI_PumpControl (Usage := InOut, Description := "HMI interface data");
+ LOCAL_TAG TON_StartDelay : TIMER;
+ LOCAL_TAG TON_FaultDelay : TIMER;
+ LOCAL_TAG TON_RunConfirm : TIMER;
+ LOCAL_TAG RunRequest : BOOL;
+ LOCAL_TAG FaultLatch : BOOL;
+ LOCAL_TAG StartConfirmed : BOOL;
+
+ ROUTINE Logic (Type := RLL)
+ RC := "Determine run request based on mode";
+ N: [XIC(i_AutoMode) ,XIC(i_RunCmd) ]OTE(RunRequest);
+ RC := "Manual mode run request";
+ N: [XIC(i_ManualMode) ,XIC(i_RunCmd) ,XIO(i_FaultFeedback) ]OTE(RunRequest);
+ RC := "E-Stop override - stop everything";
+ N: XIC(i_EStop) OTU(RunRequest);
+ RC := "Start delay timer - prevent rapid cycling";
+ N: XIC(RunRequest) XIO(FaultLatch) XIC(i_ReadyFeedback) TON(TON_StartDelay,?,5000,?);
+ RC := "Run output to drive";
+ N: XIC(TON_StartDelay.DN) OTE(o_RunOutput);
+ RC := "Run confirmation timer - detect failed start";
+ N: XIC(o_RunOutput) XIO(i_RunFeedback) TON(TON_RunConfirm,?,10000,?);
+ RC := "Failed to start fault";
+ N: XIC(TON_RunConfirm.DN) OTL(FaultLatch);
+ RC := "Drive fault detection";
+ N: XIC(i_FaultFeedback) TON(TON_FaultDelay,?,500,?);
+ N: XIC(TON_FaultDelay.DN) OTL(FaultLatch);
+ RC := "Fault reset";
+ N: XIC(i_ResetCmd) XIO(i_FaultFeedback) OTU(FaultLatch);
+ RC := "Speed reference output";
+ N: XIC(o_RunOutput) MOV(i_SpeedSP,o_SpeedRef);
+ N: XIO(o_RunOutput) MOV(0,o_SpeedRef);
+ RC := "Status outputs";
+ N: XIC(i_RunFeedback) OTE(o_Running);
+ N: XIC(FaultLatch) OTE(o_Faulted);
+ N: XIC(i_ReadyFeedback) XIO(FaultLatch) OTE(o_Ready);
+ END_ROUTINE
+ END_ADD_ON_INSTRUCTION_DEFINITION
+
+ ADD_ON_INSTRUCTION_DEFINITION AnalogScale (Revision := 1.2,
+ Vendor := "WaterTech",
+ Description := "Analog input scaling with alarm detection")
+ TAG EnableIn : BOOL (Usage := Input);
+ TAG EnableOut : BOOL (Usage := Output);
+ TAG i_RawValue : INT (Usage := Input, Description := "Raw ADC input 0-32767");
+ TAG i_EU_High : REAL (Usage := Input, Description := "Engineering units at full scale");
+ TAG i_EU_Low : REAL (Usage := Input, Description := "Engineering units at zero scale");
+ TAG i_AlarmHH : REAL (Usage := Input, Description := "High-high alarm setpoint");
+ TAG i_AlarmH : REAL (Usage := Input, Description := "High alarm setpoint");
+ TAG i_AlarmL : REAL (Usage := Input, Description := "Low alarm setpoint");
+ TAG i_AlarmLL : REAL (Usage := Input, Description := "Low-low alarm setpoint");
+ TAG o_ScaledValue : REAL (Usage := Output, Description := "Scaled engineering value");
+ TAG o_HighAlarm : BOOL (Usage := Output, Description := "High alarm active");
+ TAG o_LowAlarm : BOOL (Usage := Output, Description := "Low alarm active");
+ TAG o_HighHighAlarm : BOOL (Usage := Output, Description := "High-high alarm active");
+ TAG o_LowLowAlarm : BOOL (Usage := Output, Description := "Low-low alarm active");
+ TAG o_SensorFault : BOOL (Usage := Output, Description := "Sensor out of range");
+ LOCAL_TAG ScaledTemp : REAL;
+ LOCAL_TAG RawReal : REAL;
+
+ ROUTINE Logic (Type := ST)
+ (* Scale raw value to engineering units *)
+ RawReal := INT_TO_REAL(i_RawValue);
+ ScaledTemp := i_EU_Low + ((RawReal / 32767.0) * (i_EU_High - i_EU_Low));
+ o_ScaledValue := ScaledTemp;
+
+ (* Sensor fault detection — out of range *)
+ o_SensorFault := (i_RawValue < 1000) OR (i_RawValue > 31000);
+
+ (* Alarm evaluation *)
+ IF NOT o_SensorFault THEN
+ o_HighHighAlarm := ScaledTemp >= i_AlarmHH;
+ o_HighAlarm := ScaledTemp >= i_AlarmH;
+ o_LowAlarm := ScaledTemp <= i_AlarmL;
+ o_LowLowAlarm := ScaledTemp <= i_AlarmLL;
+ ELSE
+ o_HighHighAlarm := FALSE;
+ o_HighAlarm := FALSE;
+ o_LowAlarm := FALSE;
+ o_LowLowAlarm := FALSE;
+ END_IF;
+ END_ROUTINE
+ END_ADD_ON_INSTRUCTION_DEFINITION
+
+ TAG Pump1 : HMI_PumpControl (Description := "Intake pump 1 HMI data");
+ TAG Pump2 : HMI_PumpControl (Description := "Intake pump 2 HMI data");
+ TAG ChlorineDosingPump : HMI_PumpControl (Description := "Chlorine dosing pump");
+ TAG LT100 : AnalogInput (Description := "Raw water tank level transmitter");
+ TAG LT200 : AnalogInput (Description := "Treated water tank level transmitter");
+ TAG FT100 : AnalogInput (Description := "Inlet flow transmitter");
+ TAG PT100 : AnalogInput (Description := "Filter inlet pressure");
+ TAG PT200 : AnalogInput (Description := "Filter outlet pressure");
+ TAG AT100 : AnalogInput (Description := "pH analyzer");
+ TAG AT200 : AnalogInput (Description := "Chlorine residual analyzer");
+ TAG TT100 : AnalogInput (Description := "Water temperature transmitter");
+ TAG SystemMode : INT (Description := "0=Off, 1=Manual, 2=Auto, 3=Flush");
+ TAG SystemFault : BOOL (Description := "Any system-level fault active");
+ TAG EStopActive : BOOL (Description := "Emergency stop circuit broken");
+ TAG FilterDP : REAL (Description := "Differential pressure across filter bank");
+ TAG FilterBackwashReq : BOOL (Description := "Filter backwash required");
+ TAG PID_Level : PID_Config (Description := "Level control PID configuration");
+ TAG PID_Chlorine : PID_Config (Description := "Chlorine dosing PID configuration");
+
+ TASK MainTask (Type := CONTINUOUS,
+ Rate := 10,
+ Priority := 1,
+ Watchdog := 500,
+ DisableUpdateOutputs := 0,
+ InhibitTask := 0)
+
+ PROGRAM MainProgram (Description := "Main control logic")
+ TAG PumpCtrl1 : PumpControl;
+ TAG PumpCtrl2 : PumpControl;
+ TAG ChlorineCtrl : PumpControl;
+ TAG LevelScale : AnalogScale;
+ TAG FlowScale : AnalogScale;
+ TAG PHScale : AnalogScale;
+ TAG ClScale : AnalogScale;
+ TAG TempScale : AnalogScale;
+ TAG PressIn : AnalogScale;
+ TAG PressOut : AnalogScale;
+ TAG AutoStartPump1 : BOOL;
+ TAG AutoStartPump2 : BOOL;
+ TAG LevelPIDOutput : REAL;
+ TAG ChlorinePIDOutput : REAL;
+
+ ROUTINE MainRoutine (Type := RLL,
+ Description := "Main program scan routine")
+ RC := "Scale analog inputs";
+ N: AnalogScale(LevelScale,LT100.RawValue,100.0,0.0,95.0,90.0,10.0,5.0);
+ N: AnalogScale(FlowScale,FT100.RawValue,1000.0,0.0,950.0,900.0,50.0,25.0);
+ N: AnalogScale(PHScale,AT100.RawValue,14.0,0.0,9.0,8.5,6.0,5.5);
+ N: AnalogScale(ClScale,AT200.RawValue,5.0,0.0,4.0,3.5,0.2,0.1);
+ N: AnalogScale(TempScale,TT100.RawValue,50.0,0.0,40.0,35.0,2.0,1.0);
+ N: AnalogScale(PressIn,PT100.RawValue,100.0,0.0,90.0,85.0,10.0,5.0);
+ N: AnalogScale(PressOut,PT200.RawValue,100.0,0.0,90.0,85.0,10.0,5.0);
+ RC := "Calculate filter differential pressure";
+ N: SUB(PressIn.o_ScaledValue,PressOut.o_ScaledValue,FilterDP);
+ RC := "Filter backwash required if DP > 15 PSI";
+ N: GRT(FilterDP,15.0) OTE(FilterBackwashReq);
+ RC := "Auto mode - level control starts pump 1";
+ N: EQU(SystemMode,2) LES(LevelScale.o_ScaledValue,50.0) OTE(AutoStartPump1);
+ RC := "Auto mode - high demand starts pump 2";
+ N: EQU(SystemMode,2) LES(LevelScale.o_ScaledValue,30.0) OTE(AutoStartPump2);
+ RC := "Pump 1 control";
+ N: PumpControl(PumpCtrl1,Pump1.AutoMode,Pump1.ManualMode,AutoStartPump1,Pump1.StopCmd,Pump1.ResetCmd,Pump1.Speed_SP,Pump1.Running,Pump1.Faulted,Pump1.Ready,Pump1.Speed_PV,EStopActive,Pump1);
+ RC := "Pump 2 control";
+ N: PumpControl(PumpCtrl2,Pump2.AutoMode,Pump2.ManualMode,AutoStartPump2,Pump2.StopCmd,Pump2.ResetCmd,Pump2.Speed_SP,Pump2.Running,Pump2.Faulted,Pump2.Ready,Pump2.Speed_PV,EStopActive,Pump2);
+ RC := "System fault detection";
+ N: [XIC(PumpCtrl1.o_Faulted) ,XIC(PumpCtrl2.o_Faulted) ,XIC(LevelScale.o_SensorFault) ]OTE(SystemFault);
+ END_ROUTINE
+
+ ROUTINE ChlorineControl (Type := ST,
+ Description := "Chlorine dosing PID control")
+ (* Simple proportional chlorine control based on flow and residual *)
+ IF SystemMode = 2 THEN
+ (* Auto mode — PID control *)
+ ChlorinePIDOutput := PID_Chlorine.Kp * (PID_Chlorine.SP_High - ClScale.o_ScaledValue);
+
+ (* Clamp output *)
+ IF ChlorinePIDOutput > PID_Chlorine.CV_High THEN
+ ChlorinePIDOutput := PID_Chlorine.CV_High;
+ ELSIF ChlorinePIDOutput < PID_Chlorine.CV_Low THEN
+ ChlorinePIDOutput := PID_Chlorine.CV_Low;
+ END_IF;
+
+ ChlorineDosingPump.Speed_SP := ChlorinePIDOutput;
+ ChlorineDosingPump.RunCmd := TRUE;
+ ELSE
+ ChlorinePIDOutput := 0.0;
+ ChlorineDosingPump.RunCmd := FALSE;
+ END_IF;
+ END_ROUTINE
+ END_PROGRAM
+ END_TASK
+
+ MODULE Local (Type := "1769-L33ER",
+ ParentModule := Local,
+ ParentModPortId := 1,
+ CatalogNumber := "1769-L33ER",
+ Vendor := 1,
+ ProductType := 14,
+ ProductCode := 55,
+ Major := 33,
+ Minor := 11,
+ PortId := 1,
+ Slot := 0)
+ END_MODULE
+
+ MODULE AI_Mod1 (Type := "1769-IF8",
+ ParentModule := Local,
+ ParentModPortId := 1,
+ CatalogNumber := "1769-IF8",
+ Vendor := 1,
+ ProductType := 10,
+ ProductCode := 8,
+ Major := 3,
+ Minor := 1,
+ Slot := 1,
+ Description := "8-Channel Analog Input Module")
+ END_MODULE
+
+ MODULE DO_Mod1 (Type := "1769-OB16",
+ ParentModule := Local,
+ ParentModPortId := 1,
+ CatalogNumber := "1769-OB16",
+ Vendor := 1,
+ ProductType := 7,
+ ProductCode := 9,
+ Major := 3,
+ Minor := 1,
+ Slot := 2,
+ Description := "16-Point Digital Output Module")
+ END_MODULE
+
+END_CONTROLLER
diff --git a/tests/samples/sample_project.L5X b/tests/samples/sample_project.L5X
new file mode 100644
index 0000000..00577db
--- /dev/null
+++ b/tests/samples/sample_project.L5X
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
+ Data structure for a single conveyor zone
+
+
+ Zone motor running
+
+
+ Zone fault active
+
+
+ Speed setpoint in FPM
+
+
+ Actual speed in FPM
+
+
+ Photoeye detects item on zone
+
+
+ Items counted through zone
+
+
+ Jam condition detected
+
+
+ Motor current in Amps
+
+
+ Motor temperature in deg C
+
+
+
+
+
+ Sorting diverter destination configuration
+
+
+ Diverter solenoid energized
+
+
+ Barcode prefix for this destination
+
+
+ Items diverted to this destination
+
+
+ Downstream lane full sensor
+
+
+
+
+
+
+
+ Controls a single conveyor zone with jam detection and speed regulation
+
+
+
+
+
+ Zone run enable from upstream logic
+
+
+ Speed setpoint in feet per minute
+
+
+ Zone photoeye sensor (TRUE = item present)
+
+
+ Drive fault feedback
+
+
+ Actual speed feedback from drive
+
+
+ Motor current feedback
+
+
+ Emergency stop
+
+
+ Run command to drive
+
+
+ Speed reference to drive
+
+
+ Zone running status
+
+
+ Zone fault status
+
+
+ Jam condition detected
+
+
+ Zone data structure for HMI
+
+
+
+
+
+ Jam detection timer — PE blocked too long with motor running
+
+
+ Anti-cycling start delay
+
+
+ Jam timeout in ms
+
+
+
+
+
+
+
+
+
+
+
+ Start delay — prevent rapid cycling
+ XIC(i_RunEnable)XIO(FaultLatch)XIO(i_EStop)TON(TON_StartDelay,?,2000,?);
+
+
+ Run command to drive
+ XIC(TON_StartDelay.DN)OTE(o_RunCmd);
+
+
+ Speed reference — ramp to setpoint when running
+ XIC(o_RunCmd)MOV(i_SpeedSP,o_SpeedRef);
+
+
+ Zero speed when stopped
+ XIO(o_RunCmd)MOV(0,o_SpeedRef);
+
+
+ Jam detection — photoeye blocked while running for too long
+ XIC(o_RunCmd)XIC(i_PhotoEye)TON(TON_JamTimer,?,JamTimeout,?);
+
+
+ Jam detected — latch fault
+ XIC(TON_JamTimer.DN)OTL(FaultLatch);
+
+
+ Motor fault — latch fault
+ XIC(i_MotorFault)OTL(FaultLatch);
+
+
+ Status outputs
+ [XIC(o_RunCmd),XIC(i_SpeedFeedback)]OTE(o_Running);
+
+
+ XIC(FaultLatch)OTE(o_Faulted);
+
+
+ XIC(TON_JamTimer.DN)OTE(o_JamDetected);
+
+
+ Update HMI zone data
+ MOV(o_Running,io_ZoneData.Running)MOV(o_Faulted,io_ZoneData.Faulted)MOV(i_SpeedSP,io_ZoneData.Speed_SP)MOV(i_SpeedFeedback,io_ZoneData.Speed_PV)MOV(i_PhotoEye,io_ZoneData.ItemPresent)MOV(o_JamDetected,io_ZoneData.JamDetected)MOV(i_MotorCurrent,io_ZoneData.MotorCurrent);
+
+
+
+
+
+
+
+
+
+ Infeed conveyor zone
+
+
+ Accumulation zone
+
+
+ Sort/divert zone
+
+
+ Left diverter lane
+
+
+ Right diverter lane
+
+
+ Master conveyor system run enable
+
+
+ Emergency stop circuit status
+
+
+ Default conveyor speed in FPM
+
+
+ Total items processed since last reset
+
+
+
+
+
+ Main conveyor control program — manages all zones and sorting
+
+
+ Zone 1 controller instance
+
+
+ Zone 2 controller instance
+
+
+ Zone 3 controller instance
+
+
+ Last barcode scan result
+
+
+ Sort decision: 0=straight, 1=left, 2=right
+
+
+
+
+ Main scan routine — zone control and monitoring
+
+
+ Zone 1 — Infeed conveyor control
+ ConveyorZoneCtrl(ZoneCtrl1,SystemRunEnable,DefaultSpeed,Zone1.ItemPresent,0,Zone1.Speed_PV,Zone1.MotorCurrent,EStopActive,Zone1);
+
+
+ Zone 2 — Accumulation zone control (slow down if zone 3 jammed)
+ ConveyorZoneCtrl(ZoneCtrl2,SystemRunEnable,DefaultSpeed,Zone2.ItemPresent,0,Zone2.Speed_PV,Zone2.MotorCurrent,EStopActive,Zone2);
+
+
+ Zone 3 — Sort zone control
+ ConveyorZoneCtrl(ZoneCtrl3,SystemRunEnable,DefaultSpeed,Zone3.ItemPresent,0,Zone3.Speed_PV,Zone3.MotorCurrent,EStopActive,Zone3);
+
+
+ Total item count from all zones
+ ADD(Zone1.ItemCount,Zone2.ItemCount,TotalItemCount);
+
+
+
+
+ Barcode-based sorting decision logic
+
+ (* Sorting logic based on barcode scan result *)
+ IF Zone3.ItemPresent AND (BarcodeResult <> '') THEN
+ (* Check barcode prefix for destination *)
+ IF MID(BarcodeResult, 2, 1) = 'LA' THEN
+ SortDecision := 1; (* Left lane *)
+ Diverter1.DiverterActive := TRUE;
+ Diverter2.DiverterActive := FALSE;
+ ELSIF MID(BarcodeResult, 2, 1) = 'RA' THEN
+ SortDecision := 2; (* Right lane *)
+ Diverter1.DiverterActive := FALSE;
+ Diverter2.DiverterActive := TRUE;
+ ELSE
+ SortDecision := 0; (* Straight through *)
+ Diverter1.DiverterActive := FALSE;
+ Diverter2.DiverterActive := FALSE;
+ END_IF;
+ ELSE
+ Diverter1.DiverterActive := FALSE;
+ Diverter2.DiverterActive := FALSE;
+ END_IF;
+
+
+
+
+
+
+
+
diff --git a/tests/test_rockwell_parsers.py b/tests/test_rockwell_parsers.py
new file mode 100644
index 0000000..9d497e7
--- /dev/null
+++ b/tests/test_rockwell_parsers.py
@@ -0,0 +1,439 @@
+#!/usr/bin/env python3
+"""
+Automated tests for Rockwell PLC file parsers.
+
+Tests L5X, L5K, and unified rockwell_export parsers against both
+synthetic sample files and real-world L5X exports from GitHub.
+"""
+
+import os
+import sys
+import unittest
+from pathlib import Path
+
+# Add scripts/ to path for imports
+sys.path.insert(0, str(Path(__file__).parent.parent / 'scripts'))
+
+from sc_parser import SCFile, Tag, LogicRung
+from l5x_export import L5XParser
+from l5k_parser import L5KParser, _write_sc_file, _sanitize_comment
+from rockwell_export import (
+ detect_rockwell_format, is_rockwell_file,
+ find_rockwell_files, parse_rockwell_file,
+)
+
+SAMPLES_DIR = Path(__file__).parent / 'samples'
+REAL_SAMPLES_DIR = Path(__file__).parent / 'real_samples'
+
+
+class TestFormatDetection(unittest.TestCase):
+ """Test Rockwell file format detection."""
+
+ def test_detect_l5x(self):
+ for f in SAMPLES_DIR.glob('*.L5X'):
+ self.assertEqual(detect_rockwell_format(str(f)), 'L5X', f.name)
+
+ def test_detect_l5k(self):
+ for f in SAMPLES_DIR.glob('*.L5K'):
+ self.assertEqual(detect_rockwell_format(str(f)), 'L5K', f.name)
+
+ def test_detect_real_l5x(self):
+ if not REAL_SAMPLES_DIR.exists():
+ self.skipTest("No real samples directory")
+ for f in REAL_SAMPLES_DIR.glob('*.L5X'):
+ self.assertEqual(detect_rockwell_format(str(f)), 'L5X', f.name)
+
+ def test_is_rockwell_file(self):
+ for f in SAMPLES_DIR.glob('*.L5X'):
+ self.assertTrue(is_rockwell_file(str(f)), f.name)
+ for f in SAMPLES_DIR.glob('*.L5K'):
+ self.assertTrue(is_rockwell_file(str(f)), f.name)
+
+ def test_non_rockwell_file(self):
+ self.assertIsNone(detect_rockwell_format(__file__))
+ self.assertFalse(is_rockwell_file(__file__))
+
+ def test_find_rockwell_files(self):
+ files = find_rockwell_files(str(SAMPLES_DIR))
+ self.assertGreater(len(files), 0)
+ for fp, fmt in files:
+ self.assertIn(fmt, ('L5X', 'L5K', 'ACD', 'RSS'))
+
+
+class TestL5XParser(unittest.TestCase):
+ """Test L5X XML parser."""
+
+ def setUp(self):
+ self.parser = L5XParser()
+
+ def test_parse_sample_project(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5X'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertGreater(len(results), 0)
+
+ # Check we got expected component types
+ types = {sc.type for sc in results}
+ self.assertIn('UDT', types)
+ self.assertIn('AOI', types)
+
+ # Verify SCFile structure
+ for sc in results:
+ self.assertIsInstance(sc, SCFile)
+ self.assertTrue(sc.name)
+ self.assertIn(sc.type, ('AOI', 'UDT', 'PROGRAM', 'CONTROLLER'))
+
+ def test_parse_aoi_with_tags(self):
+ """Test AOI parsing extracts input/output/local tags."""
+ fpath = SAMPLES_DIR / 'sample_project.L5X'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ aois = [sc for sc in results if sc.type == 'AOI']
+ self.assertGreater(len(aois), 0)
+
+ for aoi in aois:
+ # AOIs should have at least some tags
+ total_tags = (len(aoi.input_tags) + len(aoi.output_tags) +
+ len(aoi.inout_tags) + len(aoi.local_tags))
+ self.assertGreater(total_tags, 0, f"AOI {aoi.name} has no tags")
+ # AOIs should have at least one routine
+ self.assertGreater(len(aoi.routines), 0,
+ f"AOI {aoi.name} has no routines")
+
+ def test_parse_udt_with_members(self):
+ """Test UDT parsing extracts members as local tags."""
+ fpath = SAMPLES_DIR / 'sample_project.L5X'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ udts = [sc for sc in results if sc.type == 'UDT']
+ self.assertGreater(len(udts), 0)
+
+ for udt in udts:
+ self.assertGreater(len(udt.local_tags), 0,
+ f"UDT {udt.name} has no members")
+
+
+class TestL5XParserRealSamples(unittest.TestCase):
+ """Test L5X parser against real-world L5X files from GitHub."""
+
+ def setUp(self):
+ self.parser = L5XParser()
+ if not REAL_SAMPLES_DIR.exists():
+ self.skipTest("No real samples directory")
+
+ def test_parse_aoi_debouncer(self):
+ fpath = REAL_SAMPLES_DIR / 'AOI_DEBOUNCER.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_DEBOUNCER.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertEqual(len(results), 1)
+
+ aoi = results[0]
+ self.assertEqual(aoi.name, 'AOI_DEBOUNCER')
+ self.assertEqual(aoi.type, 'AOI')
+ self.assertEqual(aoi.revision, '1.0')
+ self.assertEqual(len(aoi.input_tags), 5)
+ self.assertEqual(len(aoi.output_tags), 1)
+ self.assertEqual(len(aoi.local_tags), 5)
+ self.assertEqual(len(aoi.routines), 1)
+ self.assertEqual(aoi.routines[0]['name'], 'Logic')
+ self.assertEqual(aoi.routines[0]['type'], 'RLL')
+ self.assertEqual(len(aoi.routines[0]['rungs']), 7)
+
+ def test_parse_aoi_cv_control(self):
+ fpath = REAL_SAMPLES_DIR / 'AOI_CV_CONTROL.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_CV_CONTROL.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertEqual(len(results), 1)
+
+ aoi = results[0]
+ self.assertEqual(aoi.name, 'AOI_CV_CONTROL')
+ self.assertEqual(aoi.type, 'AOI')
+ self.assertEqual(len(aoi.input_tags), 14)
+ self.assertEqual(len(aoi.output_tags), 1)
+ self.assertEqual(len(aoi.local_tags), 18)
+ self.assertEqual(len(aoi.routines[0]['rungs']), 19)
+
+ def test_parse_aoi_ramp_basic(self):
+ fpath = REAL_SAMPLES_DIR / 'AOI_RAMP_BASIC.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_RAMP_BASIC.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertEqual(len(results), 1)
+
+ aoi = results[0]
+ self.assertEqual(aoi.name, 'AOI_RAMP_BASIC')
+ self.assertEqual(aoi.type, 'AOI')
+ self.assertEqual(len(aoi.routines[0]['rungs']), 15)
+
+ def test_parse_meter_orifice_with_udts(self):
+ """Test multi-component L5X file with AOI + dependent UDTs."""
+ fpath = REAL_SAMPLES_DIR / 'AOI_METER_ORIFICE.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_METER_ORIFICE.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertEqual(len(results), 3)
+
+ types = {sc.type for sc in results}
+ self.assertIn('AOI', types)
+ self.assertIn('UDT', types)
+
+ udts = [sc for sc in results if sc.type == 'UDT']
+ aois = [sc for sc in results if sc.type == 'AOI']
+ self.assertEqual(len(udts), 2)
+ self.assertEqual(len(aois), 1)
+ self.assertEqual(aois[0].name, 'AOI_METER_ORIFICE')
+ self.assertIn(aois[0].inout_tags[0].data_type, ('METER_DPCALC',))
+
+ def test_parse_op_interlock_structured_text(self):
+ """Test production-grade structured text AOI with dependencies."""
+ fpath = REAL_SAMPLES_DIR / 'Op_Interlock_AOI.L5X'
+ if not fpath.exists():
+ self.skipTest("Op_Interlock_AOI.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertGreaterEqual(len(results), 3) # STR_40 UDT + Str_Size + Str_Clear + Op_Interlock
+
+ # Find Op_Interlock
+ interlock = next(sc for sc in results if sc.name == 'Op_Interlock')
+ self.assertEqual(interlock.type, 'AOI')
+ self.assertGreater(len(interlock.input_tags), 40)
+ self.assertGreater(len(interlock.output_tags), 5)
+
+ # Verify has ST routines with content
+ self.assertEqual(len(interlock.routines), 2)
+ logic = next(r for r in interlock.routines if r['name'] == 'Logic')
+ self.assertEqual(logic['type'], 'ST')
+ self.assertIn('raw_content', logic)
+ self.assertGreater(len(logic['raw_content']), 100)
+
+ # Verify Prescan routine exists
+ prescan = next(r for r in interlock.routines if r['name'] == 'Prescan')
+ self.assertEqual(prescan['type'], 'ST')
+
+ def test_parse_op_permissive(self):
+ fpath = REAL_SAMPLES_DIR / 'Op_Permissive_AOI.L5X'
+ if not fpath.exists():
+ self.skipTest("Op_Permissive_AOI.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertGreaterEqual(len(results), 2)
+
+ permissive = next(sc for sc in results if sc.name == 'Op_Permissive')
+ self.assertEqual(permissive.type, 'AOI')
+ self.assertGreater(len(permissive.input_tags), 30)
+
+ def test_tag_descriptions_extracted(self):
+ """Test that CDATA descriptions are properly extracted from tags."""
+ fpath = REAL_SAMPLES_DIR / 'AOI_CV_CONTROL.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_CV_CONTROL.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ aoi = results[0]
+
+ # AutoPctRef should have a description
+ auto_pct = next(t for t in aoi.input_tags if t.name == 'AutoPctRef')
+ self.assertIsNotNone(auto_pct.description)
+ self.assertIn('SpeedRef', auto_pct.description)
+
+ def test_rung_comments_extracted(self):
+ """Test that rung comments are properly extracted."""
+ fpath = REAL_SAMPLES_DIR / 'AOI_CV_CONTROL.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_CV_CONTROL.L5X not found")
+
+ results = self.parser.parse_file(str(fpath))
+ aoi = results[0]
+ rungs = aoi.routines[0]['rungs']
+
+ # Some rungs should have comments
+ commented_rungs = [r for r in rungs if r.comment]
+ self.assertGreater(len(commented_rungs), 0,
+ "No rung comments were extracted")
+
+ def test_all_real_samples_parse(self):
+ """Ensure every L5X file in real_samples/ parses without errors."""
+ # Module-only exports legitimately return no parseable components
+ module_only_files = {'Safety_Module.L5X'}
+ for fpath in sorted(REAL_SAMPLES_DIR.glob('*.L5X')):
+ with self.subTest(file=fpath.name):
+ results = self.parser.parse_file(str(fpath))
+ if fpath.name in module_only_files:
+ self.assertIsInstance(results, list)
+ else:
+ self.assertGreater(len(results), 0,
+ f"No components parsed from {fpath.name}")
+ for sc in results:
+ self.assertIsInstance(sc, SCFile)
+ self.assertTrue(sc.name)
+
+
+class TestL5KParser(unittest.TestCase):
+ """Test L5K ASCII text parser."""
+
+ def setUp(self):
+ self.parser = L5KParser()
+
+ def test_parse_sample_project(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = self.parser.parse_file(str(fpath))
+ self.assertGreater(len(results), 0)
+
+ types = {sc.type for sc in results}
+ self.assertIn('UDT', types)
+ self.assertIn('AOI', types)
+ self.assertIn('PROGRAM', types)
+ self.assertIn('CONTROLLER', types)
+
+ def test_udt_parsing(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = self.parser.parse_file(str(fpath))
+ udts = [sc for sc in results if sc.type == 'UDT']
+ self.assertEqual(len(udts), 3)
+
+ udt_names = {sc.name for sc in udts}
+ self.assertIn('HMI_PumpControl', udt_names)
+ self.assertIn('PID_Config', udt_names)
+ self.assertIn('AnalogInput', udt_names)
+
+ def test_aoi_parsing(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = self.parser.parse_file(str(fpath))
+ aois = [sc for sc in results if sc.type == 'AOI']
+ self.assertEqual(len(aois), 2)
+
+ pump = next(sc for sc in aois if sc.name == 'PumpControl')
+ self.assertGreater(len(pump.input_tags), 0)
+ self.assertGreater(len(pump.output_tags), 0)
+ self.assertGreater(len(pump.routines), 0)
+
+ def test_program_parsing(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = self.parser.parse_file(str(fpath))
+ programs = [sc for sc in results if sc.type == 'PROGRAM']
+ self.assertEqual(len(programs), 1)
+ self.assertEqual(programs[0].name, 'MainProgram')
+ self.assertGreater(len(programs[0].routines), 0)
+
+ def test_controller_tags(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = self.parser.parse_file(str(fpath))
+ controller = next(sc for sc in results if sc.type == 'CONTROLLER')
+ self.assertEqual(controller.name, 'WaterTreatment')
+ # Controller should have tags
+ total_tags = (len(controller.input_tags) + len(controller.output_tags) +
+ len(controller.local_tags))
+ self.assertGreater(total_tags, 0)
+
+
+class TestUnifiedParser(unittest.TestCase):
+ """Test the unified rockwell_export parser."""
+
+ def test_parse_l5x_via_unified(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5X'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5X not found")
+
+ results = parse_rockwell_file(str(fpath))
+ self.assertGreater(len(results), 0)
+
+ def test_parse_l5k_via_unified(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5K'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5K not found")
+
+ results = parse_rockwell_file(str(fpath))
+ self.assertGreater(len(results), 0)
+
+ def test_format_hint_override(self):
+ fpath = SAMPLES_DIR / 'sample_project.L5X'
+ if not fpath.exists():
+ self.skipTest("sample_project.L5X not found")
+
+ results = parse_rockwell_file(str(fpath), format_hint='L5X')
+ self.assertGreater(len(results), 0)
+
+
+class TestSCFileExport(unittest.TestCase):
+ """Test .sc file export functionality."""
+
+ def test_sanitize_comment_single_line(self):
+ self.assertEqual(_sanitize_comment("Hello world"), "Hello world")
+
+ def test_sanitize_comment_multi_line(self):
+ self.assertEqual(
+ _sanitize_comment("0 = Normal\n1 = Inverted"),
+ "0 = Normal | 1 = Inverted"
+ )
+
+ def test_sanitize_comment_empty_lines(self):
+ self.assertEqual(
+ _sanitize_comment("Line 1\n\nLine 3"),
+ "Line 1 | Line 3"
+ )
+
+ def test_export_round_trip(self):
+ """Test that parsing and exporting produces valid .sc files."""
+ import tempfile
+
+ fpath = REAL_SAMPLES_DIR / 'AOI_DEBOUNCER.L5X'
+ if not fpath.exists():
+ self.skipTest("AOI_DEBOUNCER.L5X not found")
+
+ parser = L5XParser()
+ results = parser.parse_file(str(fpath))
+ self.assertEqual(len(results), 1)
+
+ # Write to temp file
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.sc',
+ delete=False) as tmp:
+ tmp_path = tmp.name
+
+ try:
+ _write_sc_file(results[0], tmp_path)
+ # Verify file was created and has content
+ self.assertTrue(os.path.exists(tmp_path))
+ with open(tmp_path) as f:
+ content = f.read()
+ self.assertIn('AOI_DEBOUNCER', content)
+ self.assertIn('VAR_INPUT', content)
+ self.assertIn('VAR_OUTPUT', content)
+ self.assertIn('Rung 0', content)
+ # Verify no stray newlines in comments
+ for line in content.split('\n'):
+ if line.strip().startswith('//') or ' //' in line:
+ # Comment lines should be single-line
+ self.assertNotIn('\n', line)
+ finally:
+ os.unlink(tmp_path)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)